From cf32e8d4e0cabac8432a3c6c6d8ece27d6067770 Mon Sep 17 00:00:00 2001 From: Andre Eisenbach Date: Tue, 12 Aug 2014 16:46:51 -0700 Subject: [PATCH] LE: Fix limited advertising not stopping after timeout When starting to advertise with a given timeout, the alarm did not fire and thus not stop the advertising. This patch switchs from the new alarm system to use BTU timers. Also fixes a bug in the oneshot timer handling where adding a new timer with a short timeout value would not actually restart the timer to pull in the deadline. Bug: 16988160 Change-Id: Ia556562675636be440ddca7682ac7d092bc0b48b --- btif/include/btif_gatt_multi_adv_util.h | 5 ++--- btif/src/btif_gatt_client.c | 6 +++--- btif/src/btif_gatt_multi_adv_util.c | 33 +++++++++++++++++---------------- gki/common/gki.h | 1 + stack/btu/btu_task.c | 32 ++++++++++++++++++++------------ 5 files changed, 43 insertions(+), 34 deletions(-) diff --git a/btif/include/btif_gatt_multi_adv_util.h b/btif/include/btif_gatt_multi_adv_util.h index 9c4a25307..ea4603428 100644 --- a/btif/include/btif_gatt_multi_adv_util.h +++ b/btif/include/btif_gatt_multi_adv_util.h @@ -21,7 +21,6 @@ #define BTIF_GATT_MULTI_ADV_UTIL_H #include -#include "alarm.h" #include "bta_api.h" #define CLNT_IF_IDX 0 @@ -60,7 +59,7 @@ typedef struct tBTA_BLE_AD_MASK mask; tBTA_BLE_ADV_DATA data; tBTA_BLE_ADV_PARAMS param; - alarm_t* limited_timer; + TIMER_LIST_ENT tle_limited_timer; int timeout_s; }btgatt_multi_adv_inst_cb; @@ -89,7 +88,7 @@ extern void btif_gattc_adv_data_packager(int client_if, bool set_scan_rsp, int appearance, int manufacturer_len, char* manufacturer_data, int service_data_len, char* service_data, int service_uuid_len, char* service_uuid, btif_adv_data_t *p_multi_adv_inst); -void btif_multi_adv_timer_ctrl(int client_if, alarm_callback_t cb); +void btif_multi_adv_timer_ctrl(int client_if, TIMER_CBACK cb); #endif diff --git a/btif/src/btif_gatt_client.c b/btif/src/btif_gatt_client.c index f21542659..2c0a3d136 100644 --- a/btif/src/btif_gatt_client.c +++ b/btif/src/btif_gatt_client.c @@ -242,9 +242,9 @@ static uint8_t rssi_request_client_if; ********************************************************************************/ static bt_status_t btif_gattc_multi_adv_disable(int client_if); -static void btif_multi_adv_stop_cb(void *data) +static void btif_multi_adv_stop_cb(void *p_tle) { - int client_if = (int)data; + int client_if = ((TIMER_LIST_ENT*)p_tle)->data; btif_gattc_multi_adv_disable(client_if); // Does context switch } @@ -657,7 +657,6 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) case BTA_GATTC_MULT_ADV_DATA_EVT: { btif_gattc_cb_t *p_btif_cb = (btif_gattc_cb_t*) p_param; - btif_gattc_cleanup_inst_cb(p_btif_cb->inst_id); HAL_CBACK(bt_gatt_callbacks, client->multi_adv_data_cb , p_btif_cb->client_if , p_btif_cb->status @@ -1520,6 +1519,7 @@ static void btgattc_handle_event(uint16_t event, char* p_param) btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb(); memcpy(&p_multi_adv_data_cb->inst_cb[cbindex].param, &p_inst_cb->param, sizeof(tBTA_BLE_ADV_PARAMS)); + p_multi_adv_data_cb->inst_cb[cbindex].timeout_s = p_inst_cb->timeout_s; BTIF_TRACE_DEBUG("%s, client_if value: %d", __FUNCTION__, p_multi_adv_data_cb->clntif_map[arrindex + arrindex]); BTA_BleEnableAdvInstance(&(p_multi_adv_data_cb->inst_cb[cbindex].param), diff --git a/btif/src/btif_gatt_multi_adv_util.c b/btif/src/btif_gatt_multi_adv_util.c index d5e4322a8..cb178ed48 100644 --- a/btif/src/btif_gatt_multi_adv_util.c +++ b/btif/src/btif_gatt_multi_adv_util.c @@ -27,6 +27,7 @@ #include #include +#include "btu.h" #include "bt_target.h" #define LOG_TAG "BtGatt.btif" @@ -493,9 +494,12 @@ void btif_gattc_cleanup_inst_cb(int inst_id) void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_multi_inst_cb) { + if (p_multi_inst_cb == NULL) + return; + // Discoverability timer cleanup - alarm_free(p_multi_inst_cb->limited_timer); - p_multi_inst_cb->limited_timer = NULL; + if (p_multi_inst_cb->tle_limited_timer.in_use) + btu_stop_timer_oneshot(&p_multi_inst_cb->tle_limited_timer); // Manufacturer data cleanup if (p_multi_inst_cb->data.p_manu != NULL) @@ -567,7 +571,7 @@ void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_multi_inst_cb) GKI_freebuf(p_multi_inst_cb->data.p_sol_service_128b); } -void btif_multi_adv_timer_ctrl(int client_if, alarm_callback_t cb) +void btif_multi_adv_timer_ctrl(int client_if, TIMER_CBACK cb) { int inst_id = btif_multi_adv_instid_for_clientif(client_if); if (inst_id == INVALID_ADV_INST) @@ -583,22 +587,19 @@ void btif_multi_adv_timer_ctrl(int client_if, alarm_callback_t cb) if (cb == NULL) { - alarm_free(p_multi_adv_data_cb->inst_cb[cbindex].limited_timer); - p_multi_adv_data_cb->inst_cb[cbindex].limited_timer = NULL; + if (p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.in_use) + btu_stop_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer); } else { if (p_multi_adv_data_cb->inst_cb[cbindex].timeout_s != 0) { - if (p_multi_adv_data_cb->inst_cb[cbindex].limited_timer == NULL) - p_multi_adv_data_cb->inst_cb[cbindex].limited_timer = alarm_new(); - else - alarm_cancel(p_multi_adv_data_cb->inst_cb[cbindex].limited_timer); - - if (p_multi_adv_data_cb->inst_cb[cbindex].limited_timer) - { - alarm_set(p_multi_adv_data_cb->inst_cb[cbindex].limited_timer, - p_multi_adv_data_cb->inst_cb[cbindex].timeout_s * 1000, - cb, (void*)inst_id); - } + if (p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.in_use) + btu_stop_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer); + + memset(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer, 0, sizeof(TIMER_LIST_ENT)); + p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.param = (UINT32)cb; + p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.data = (UINT32)client_if; + btu_start_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer, + BTU_TTYPE_USER_FUNC, p_multi_adv_data_cb->inst_cb[cbindex].timeout_s); } } } diff --git a/gki/common/gki.h b/gki/common/gki.h index c71a565db..d7cf78464 100644 --- a/gki/common/gki.h +++ b/gki/common/gki.h @@ -92,6 +92,7 @@ typedef struct _tle INT32 ticks; INT32 ticks_initial; TIMER_PARAM_TYPE param; + TIMER_PARAM_TYPE data; UINT16 event; UINT8 in_use; } TIMER_LIST_ENT; diff --git a/stack/btu/btu_task.c b/stack/btu/btu_task.c index 23429a32f..3db8d7eab 100644 --- a/stack/btu/btu_task.c +++ b/stack/btu/btu_task.c @@ -603,6 +603,13 @@ BTU_API UINT32 btu_task (UINT32 param) break; #endif + case BTU_TTYPE_USER_FUNC: + { + tUSER_TIMEOUT_FUNC *p_uf = (tUSER_TIMEOUT_FUNC *)p_tle->param; + (*p_uf)(p_tle); + } + break; + default: // FAIL BTM_TRACE_WARNING("Received unexpected oneshot timer event:0x%x\n", @@ -854,18 +861,6 @@ void btu_start_timer_oneshot(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_ BTM_TRACE_DEBUG("Starting oneshot timer type:%d timeout:%ds", type, timeout_in_secs); GKI_disable(); if (GKI_timer_queue_is_empty(&btu_cb.timer_queue_oneshot)) { - /* RPC to BTU thread if timer start request from non-BTU task */ - if (GKI_get_taskid() != BTU_TASK) { - /* post event to start timer in BTU task */ - BTM_TRACE_WARNING("Posting oneshot timer event to btu_task"); - BT_HDR *p_msg = (BT_HDR *)GKI_getbuf(BT_HDR_SIZE); - if (p_msg != NULL) { - p_msg->event = BT_EVT_TO_START_TIMER_ONESHOT; - GKI_send_msg (BTU_TASK, TASK_MBOX_0, p_msg); - } - } else { - GKI_start_timer(TIMER_3, timeout_in_ticks, FALSE); - } } GKI_remove_from_timer_list(&btu_cb.timer_queue_oneshot, p_tle); @@ -875,6 +870,19 @@ void btu_start_timer_oneshot(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_ p_tle->ticks_initial = timeout_in_ticks; GKI_add_to_timer_list(&btu_cb.timer_queue_oneshot, p_tle); + /* RPC to BTU thread if timer start request from non-BTU task */ + if (GKI_get_taskid() != BTU_TASK) { + /* post event to start timer in BTU task */ + BTM_TRACE_WARNING("Posting oneshot timer event to btu_task"); + BT_HDR *p_msg = (BT_HDR *)GKI_getbuf(BT_HDR_SIZE); + if (p_msg != NULL) { + p_msg->event = BT_EVT_TO_START_TIMER_ONESHOT; + GKI_send_msg (BTU_TASK, TASK_MBOX_0, p_msg); + } + } else { + TIMER_LIST_ENT *tle = GKI_timer_getfirst(&btu_cb.timer_queue_oneshot); + GKI_start_timer(TIMER_3, tle->ticks, FALSE); + } GKI_enable(); } -- 2.11.0