mirror of
https://github.com/google/pebble.git
synced 2025-03-20 19:01:21 +00:00
217 lines
8.2 KiB
C
217 lines
8.2 KiB
C
|
/*
|
||
|
* Copyright 2024 Google LLC
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
#include "clar.h"
|
||
|
|
||
|
#include "comm/ble/gap_le_connection.h"
|
||
|
#include "comm/bt_conn_mgr.h"
|
||
|
#include "comm/bt_conn_mgr_impl.h"
|
||
|
#include "services/common/regular_timer.h"
|
||
|
|
||
|
// Fakes
|
||
|
#include "fake_gap_le_connect_params.h"
|
||
|
#include "fake_new_timer.h"
|
||
|
#include "fake_rtc.h"
|
||
|
#include "fake_system_task.h"
|
||
|
#include "fake_pbl_malloc.h"
|
||
|
|
||
|
// Stubs
|
||
|
#include "stubs_bluetopia_interface.h"
|
||
|
#include "stubs_bt_lock.h"
|
||
|
#include "stubs_logging.h"
|
||
|
#include "stubs_mutex.h"
|
||
|
#include "stubs_passert.h"
|
||
|
|
||
|
extern void conn_mgr_handle_desired_state_granted(GAPLEConnection *hdl,
|
||
|
ResponseTimeState granted_state);
|
||
|
|
||
|
// Stubs
|
||
|
/////
|
||
|
bool gap_le_connection_is_valid(const GAPLEConnection *conn) {
|
||
|
return (conn != NULL);
|
||
|
}
|
||
|
|
||
|
GAPLEConnection *gap_le_connection_any(void) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
void prv_regular_timer_spend_seconds(uint32_t seconds) {
|
||
|
for (uint32_t i = 0; i < seconds; ++i) {
|
||
|
fake_rtc_increment_ticks(RTC_TICKS_HZ);
|
||
|
regular_timer_fire_seconds(1);
|
||
|
|
||
|
// bt_conn_mgr offloads the callback to KernelBG
|
||
|
fake_system_task_callbacks_invoke_pending();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void launcher_task_add_callback(void (*callback)(void *data), void *data) {
|
||
|
callback(data);
|
||
|
}
|
||
|
|
||
|
// Tests
|
||
|
///////////////////////////////////////////////////////////
|
||
|
|
||
|
static int s_granted_count;
|
||
|
static GAPLEConnection s_hdl;
|
||
|
|
||
|
void test_bt_conn_mgr__initialize(void) {
|
||
|
s_granted_count = 0;
|
||
|
fake_rtc_init(0, 0);
|
||
|
regular_timer_init();
|
||
|
fake_gap_le_connect_params_init();
|
||
|
s_hdl.conn_mgr_info = bt_conn_mgr_info_init();
|
||
|
}
|
||
|
|
||
|
void test_bt_conn_mgr__cleanup(void) {
|
||
|
regular_timer_deinit();
|
||
|
}
|
||
|
|
||
|
void test_bt_conn_mgr__ble_latency_mgr(void) {
|
||
|
// 1 consumer at fastest rate should result in fastest rate getting scheduled
|
||
|
conn_mgr_set_ble_conn_response_time(
|
||
|
&s_hdl, BtConsumerLeServiceDiscovery, ResponseTimeMin, 100);
|
||
|
|
||
|
uint16_t secs_to_wait;
|
||
|
ResponseTimeState state;
|
||
|
|
||
|
state = conn_mgr_get_latency_for_le_connection(&s_hdl, &secs_to_wait);
|
||
|
cl_assert_equal_i(state, ResponseTimeMin);
|
||
|
cl_assert_equal_i(secs_to_wait, 100);
|
||
|
cl_assert_equal_i(fake_gap_le_connect_params_get_last_requested(), ResponseTimeMin);
|
||
|
|
||
|
// another consumer at lower rate should not have any effect
|
||
|
fake_gap_le_connect_params_reset_last_requested();
|
||
|
conn_mgr_set_ble_conn_response_time(
|
||
|
&s_hdl, BtConsumerUnitTests, ResponseTimeMiddle, 30);
|
||
|
state = conn_mgr_get_latency_for_le_connection(&s_hdl, &secs_to_wait);
|
||
|
cl_assert_equal_i(state, ResponseTimeMin);
|
||
|
cl_assert_equal_i(secs_to_wait, 100);
|
||
|
cl_assert_equal_i(fake_gap_le_connect_params_get_last_requested(), ResponseTimeInvalid);
|
||
|
|
||
|
// removing the fastest consumer should result in the next fastest being scheduled, but only
|
||
|
// after an "inactivity timeout":
|
||
|
conn_mgr_set_ble_conn_response_time(
|
||
|
&s_hdl, BtConsumerLeServiceDiscovery, ResponseTimeMax, 0);
|
||
|
|
||
|
state = conn_mgr_get_latency_for_le_connection(&s_hdl, &secs_to_wait);
|
||
|
cl_assert_equal_i(state, ResponseTimeMin);
|
||
|
cl_assert_equal_i(secs_to_wait, BT_CONN_MGR_INACTIVITY_TIMEOUT_SECS);
|
||
|
cl_assert_equal_i(fake_gap_le_connect_params_get_last_requested(), ResponseTimeInvalid);
|
||
|
|
||
|
prv_regular_timer_spend_seconds(BT_CONN_MGR_INACTIVITY_TIMEOUT_SECS);
|
||
|
|
||
|
state = conn_mgr_get_latency_for_le_connection(&s_hdl, &secs_to_wait);
|
||
|
cl_assert_equal_i(state, ResponseTimeMiddle);
|
||
|
cl_assert_equal_i(secs_to_wait, 30 - BT_CONN_MGR_INACTIVITY_TIMEOUT_SECS);
|
||
|
cl_assert_equal_i(fake_gap_le_connect_params_get_last_requested(), ResponseTimeMiddle);
|
||
|
|
||
|
// removing all consumers we should fall back to slowest interval, but only
|
||
|
// after an "inactivity timeout":
|
||
|
fake_gap_le_connect_params_reset_last_requested();
|
||
|
conn_mgr_set_ble_conn_response_time(
|
||
|
&s_hdl, BtConsumerUnitTests, ResponseTimeMax, 0);
|
||
|
|
||
|
prv_regular_timer_spend_seconds(BT_CONN_MGR_INACTIVITY_TIMEOUT_SECS);
|
||
|
state = conn_mgr_get_latency_for_le_connection(&s_hdl, &secs_to_wait);
|
||
|
cl_assert_equal_i(state, ResponseTimeMax);
|
||
|
cl_assert_equal_i(fake_gap_le_connect_params_get_last_requested(), ResponseTimeMax);
|
||
|
|
||
|
// if nothing else is scheduled, middle rate should get picked up right away
|
||
|
conn_mgr_set_ble_conn_response_time(
|
||
|
&s_hdl, BtConsumerUnitTests, ResponseTimeMiddle, 30);
|
||
|
state = conn_mgr_get_latency_for_le_connection(&s_hdl, &secs_to_wait);
|
||
|
cl_assert_equal_i(state, ResponseTimeMiddle);
|
||
|
cl_assert_equal_i(secs_to_wait, 30);
|
||
|
cl_assert_equal_i(fake_gap_le_connect_params_get_last_requested(), ResponseTimeMiddle);
|
||
|
|
||
|
// higher rate should take over lower rate already scheduled
|
||
|
conn_mgr_set_ble_conn_response_time(
|
||
|
&s_hdl, BtConsumerLeServiceDiscovery, ResponseTimeMin, 25);
|
||
|
state = conn_mgr_get_latency_for_le_connection(&s_hdl, &secs_to_wait);
|
||
|
cl_assert_equal_i(state, ResponseTimeMin);
|
||
|
cl_assert_equal_i(secs_to_wait, 25);
|
||
|
cl_assert_equal_i(fake_gap_le_connect_params_get_last_requested(), ResponseTimeMin);
|
||
|
|
||
|
// two requests at same high rate, longest time should be selected as timeout
|
||
|
fake_gap_le_connect_params_reset_last_requested();
|
||
|
conn_mgr_set_ble_conn_response_time(
|
||
|
&s_hdl, BtConsumerUnitTests, ResponseTimeMin, 250);
|
||
|
state = conn_mgr_get_latency_for_le_connection(&s_hdl, &secs_to_wait);
|
||
|
cl_assert_equal_i(state, ResponseTimeMin);
|
||
|
cl_assert_equal_i(secs_to_wait, 250);
|
||
|
cl_assert_equal_i(fake_gap_le_connect_params_get_last_requested(), ResponseTimeInvalid);
|
||
|
|
||
|
bt_conn_mgr_info_deinit(&s_hdl.conn_mgr_info);
|
||
|
}
|
||
|
|
||
|
static void prv_granted_handler(void) {
|
||
|
++s_granted_count;
|
||
|
}
|
||
|
|
||
|
void test_bt_conn_mgr__granted_handler_request_max_no_existing_node(void) {
|
||
|
fake_gap_le_connect_params_set_actual_state(ResponseTimeMax);
|
||
|
conn_mgr_set_ble_conn_response_time_ext(&s_hdl, BtConsumerLeServiceDiscovery, ResponseTimeMax, 1,
|
||
|
prv_granted_handler);
|
||
|
// Expect granted handler to be called immediately:
|
||
|
cl_assert_equal_i(s_granted_count, 1);
|
||
|
}
|
||
|
|
||
|
void test_bt_conn_mgr__granted_handler_request_existing(void) {
|
||
|
fake_gap_le_connect_params_set_actual_state(ResponseTimeMax);
|
||
|
conn_mgr_set_ble_conn_response_time_ext(&s_hdl, BtConsumerLeServiceDiscovery, ResponseTimeMin, 1,
|
||
|
prv_granted_handler);
|
||
|
cl_assert_equal_i(s_granted_count, 0);
|
||
|
|
||
|
// Simulate that the requested state takes effect:
|
||
|
fake_gap_le_connect_params_set_actual_state(ResponseTimeMin);
|
||
|
conn_mgr_handle_desired_state_granted(&s_hdl, ResponseTimeMin);
|
||
|
cl_assert_equal_i(s_granted_count, 1);
|
||
|
|
||
|
conn_mgr_set_ble_conn_response_time_ext(&s_hdl, BtConsumerLeServiceDiscovery, ResponseTimeMin, 1,
|
||
|
prv_granted_handler);
|
||
|
cl_assert_equal_i(s_granted_count, 2);
|
||
|
|
||
|
conn_mgr_set_ble_conn_response_time_ext(&s_hdl, BtConsumerLeServiceDiscovery, ResponseTimeMiddle,
|
||
|
1, prv_granted_handler);
|
||
|
cl_assert_equal_i(s_granted_count, 3);
|
||
|
|
||
|
conn_mgr_set_ble_conn_response_time_ext(&s_hdl, BtConsumerLeServiceDiscovery, ResponseTimeMax,
|
||
|
1, prv_granted_handler);
|
||
|
cl_assert_equal_i(s_granted_count, 4);
|
||
|
}
|
||
|
|
||
|
void test_bt_conn_mgr__request_max_time_while_no_requests_are_running(void) {
|
||
|
uint16_t secs_to_wait;
|
||
|
ResponseTimeState state;
|
||
|
|
||
|
// Always start off with ResponseTimeMax:
|
||
|
state = conn_mgr_get_latency_for_le_connection(&s_hdl, &secs_to_wait);
|
||
|
cl_assert_equal_i(state, ResponseTimeMax);
|
||
|
|
||
|
// Requesting ResponseTimeMax should have no effect:
|
||
|
conn_mgr_set_ble_conn_response_time(&s_hdl, BtConsumerLeServiceDiscovery, ResponseTimeMax, 1);
|
||
|
state = conn_mgr_get_latency_for_le_connection(&s_hdl, &secs_to_wait);
|
||
|
cl_assert_equal_i(state, ResponseTimeMax);
|
||
|
|
||
|
// Not even after waiting 10 seconds:
|
||
|
prv_regular_timer_spend_seconds(10);
|
||
|
state = conn_mgr_get_latency_for_le_connection(&s_hdl, &secs_to_wait);
|
||
|
cl_assert_equal_i(state, ResponseTimeMax);
|
||
|
|
||
|
bt_conn_mgr_info_deinit(&s_hdl.conn_mgr_info);
|
||
|
}
|