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
diff --git a/btif/include/btif_gatt_multi_adv_util.h b/btif/include/btif_gatt_multi_adv_util.h
index 9c4a253..ea46034 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 <hardware/bluetooth.h>
-#include "alarm.h"
#include "bta_api.h"
#define CLNT_IF_IDX 0
@@ -60,7 +59,7 @@
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 @@
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 f215426..2c0a3d1 100644
--- a/btif/src/btif_gatt_client.c
+++ b/btif/src/btif_gatt_client.c
@@ -242,9 +242,9 @@
********************************************************************************/
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 @@
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 @@
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 d5e4322..cb178ed 100644
--- a/btif/src/btif_gatt_multi_adv_util.c
+++ b/btif/src/btif_gatt_multi_adv_util.c
@@ -27,6 +27,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include "btu.h"
#include "bt_target.h"
#define LOG_TAG "BtGatt.btif"
@@ -493,9 +494,12 @@
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 @@
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 @@
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].tle_limited_timer.in_use)
+ btu_stop_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_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);
- }
+ 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 c71a565..d7cf784 100644
--- a/gki/common/gki.h
+++ b/gki/common/gki.h
@@ -92,6 +92,7 @@
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 23429a3..3db8d7e 100644
--- a/stack/btu/btu_task.c
+++ b/stack/btu/btu_task.c
@@ -603,6 +603,13 @@
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 @@
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 @@
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();
}