Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6435ac9 authored by Andre Eisenbach's avatar Andre Eisenbach
Browse files

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
parent 39d355c8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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;
+2 −3
Original line number Diff line number Diff line
@@ -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

+3 −3
Original line number Diff line number Diff line
@@ -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),
+17 −16
Original line number Diff line number Diff line
@@ -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].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);
        }
    }
}
+20 −12
Original line number Diff line number Diff line
@@ -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,6 +861,15 @@ 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)) {
    }

    GKI_remove_from_timer_list(&btu_cb.timer_queue_oneshot, p_tle);

    p_tle->event = type;
    p_tle->ticks = timeout_in_ticks;
    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 */
@@ -864,17 +880,9 @@ void btu_start_timer_oneshot(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_
            GKI_send_msg (BTU_TASK, TASK_MBOX_0, p_msg);
        }
    } else {
            GKI_start_timer(TIMER_3, timeout_in_ticks, FALSE);
        }
        TIMER_LIST_ENT *tle = GKI_timer_getfirst(&btu_cb.timer_queue_oneshot);
        GKI_start_timer(TIMER_3, tle->ticks, FALSE);
    }

    GKI_remove_from_timer_list(&btu_cb.timer_queue_oneshot, p_tle);

    p_tle->event = type;
    p_tle->ticks = timeout_in_ticks;
    p_tle->ticks_initial = timeout_in_ticks;

    GKI_add_to_timer_list(&btu_cb.timer_queue_oneshot, p_tle);
    GKI_enable();
}