OSDN Git Service

LE: Fix limited advertising not stopping after timeout
authorAndre Eisenbach <eisenbach@google.com>
Tue, 12 Aug 2014 23:46:51 +0000 (16:46 -0700)
committerAndre Eisenbach <eisenbach@google.com>
Tue, 12 Aug 2014 23:54:34 +0000 (16:54 -0700)
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
btif/src/btif_gatt_client.c
btif/src/btif_gatt_multi_adv_util.c
gki/common/gki.h
stack/btu/btu_task.c

index 9c4a253..ea46034 100644 (file)
@@ -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 @@ 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
 
 
index f215426..2c0a3d1 100644 (file)
@@ -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),
index d5e4322..cb178ed 100644 (file)
@@ -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_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);
         }
     }
 }
index c71a565..d7cf784 100644 (file)
@@ -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;
index 23429a3..3db8d7e 100644 (file)
@@ -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();
 }