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

Commit 06fa7a98 authored by Andre Eisenbach's avatar Andre Eisenbach
Browse files

LE: Add limited advertising duration capability (2/3)

Change-Id: Id2ebc353f1bcd94978c5c8dc55a235c92ebc7658
parent 5206fbe3
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#define BTIF_GATT_MULTI_ADV_UTIL_H

#include <hardware/bluetooth.h>
#include "alarm.h"
#include "bta_api.h"

#define CLNT_IF_IDX 0
@@ -28,7 +29,10 @@
#define INST_ID_IDX_MAX INST_ID_IDX + 1
#define INVALID_ADV_INST -1
#define STD_ADV_INSTID 0
#define ADV_FLAGS 0x02

/* Default ADV flags for general and limited discoverability */
#define ADV_FLAGS_LIMITED 0x01
#define ADV_FLAGS_GENERAL 0x02

typedef struct
{
@@ -56,6 +60,8 @@ typedef struct
    tBTA_BLE_AD_MASK mask;
    tBTA_BLE_ADV_DATA data;
    tBTA_BLE_ADV_PARAMS param;
    alarm_t* limited_timer;
    int timeout_s;
}btgatt_multi_adv_inst_cb;

typedef struct
@@ -80,10 +86,10 @@ extern BOOLEAN btif_gattc_copy_datacb(int arrindex, btif_adv_data_t *p_adv_data,
                                            BOOLEAN bInstData);
extern void btif_gattc_adv_data_packager(int client_if, bool set_scan_rsp,
                bool include_name, bool include_txpower, int min_interval, int max_interval,
                int appearance, uint16_t manufacturer_len, char* manufacturer_data,
                uint16_t service_data_len, char* service_data, uint16_t service_uuid_len,
                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);
#endif

+20 −8
Original line number Diff line number Diff line
@@ -241,6 +241,13 @@ static uint8_t rssi_request_client_if;
**  Static functions
********************************************************************************/

static bt_status_t btif_gattc_multi_adv_disable(int client_if);
static void btif_multi_adv_stop_cb(void *data)
{
    int client_if = (int)data;
    btif_gattc_multi_adv_disable(client_if); // Does context switch
}

static void btapp_gattc_req_data(UINT16 event, char *p_dest, char *p_src)
{
    tBTA_GATTC *p_dest_data = (tBTA_GATTC*) p_dest;
@@ -630,6 +637,8 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param)
                    , p_btif_cb->client_if
                    , p_btif_cb->status
                );
            btif_multi_adv_timer_ctrl(p_btif_cb->client_if,
                    (p_btif_cb->status==0 ? btif_multi_adv_stop_cb : NULL));
            break;
        }

@@ -640,6 +649,8 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param)
                , p_btif_cb->client_if
                , p_btif_cb->status
            );
            btif_multi_adv_timer_ctrl(p_btif_cb->client_if,
                    (p_btif_cb->status==0 ? btif_multi_adv_stop_cb : NULL));
            break;
        }

@@ -1076,6 +1087,7 @@ static void btgattc_handle_event(uint16_t event, char* p_param)
            break;

        case BTIF_GATTC_UNREGISTER_APP:
            btif_gattc_clear_clientif(p_cb->client_if);
            btif_gattc_destroy_multi_adv_cb();
            BTA_GATTC_AppDeregister(p_cb->client_if);
            break;
@@ -2060,7 +2072,7 @@ static int btif_gattc_get_device_type( const bt_bdaddr_t *bd_addr )
}

static bt_status_t btif_gattc_multi_adv_enable(int client_if, int min_interval, int max_interval,
                                            int adv_type, int chnl_map, int tx_power)
                                            int adv_type, int chnl_map, int tx_power, int timeout_s)
{
    CHECK_BTGATT_INIT();
    btgatt_multi_adv_inst_cb adv_cb;
@@ -2072,12 +2084,13 @@ static bt_status_t btif_gattc_multi_adv_enable(int client_if, int min_interval,
    adv_cb.param.channel_map = chnl_map;
    adv_cb.param.adv_filter_policy = 0;
    adv_cb.param.tx_power = tx_power;
    adv_cb.timeout_s = timeout_s;
    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_ADV_INSTANCE_ENABLE,
                             (char*) &adv_cb, sizeof(btgatt_multi_adv_inst_cb), NULL);
}

static bt_status_t btif_gattc_multi_adv_update(int client_if, int min_interval, int max_interval,
                                            int adv_type, int chnl_map,int tx_power)
                                            int adv_type, int chnl_map,int tx_power, int timeout_s)
{
    CHECK_BTGATT_INIT();
    btgatt_multi_adv_inst_cb adv_cb;
@@ -2089,17 +2102,16 @@ static bt_status_t btif_gattc_multi_adv_update(int client_if, int min_interval,
    adv_cb.param.channel_map = chnl_map;
    adv_cb.param.adv_filter_policy = 0;
    adv_cb.param.tx_power = tx_power;
    adv_cb.timeout_s = timeout_s;
    return btif_transfer_context(btgattc_handle_event, BTIF_GATTC_ADV_INSTANCE_UPDATE,
                         (char*) &adv_cb, sizeof(btgatt_multi_adv_inst_cb), NULL);
}

static bt_status_t btif_gattc_multi_adv_setdata(int client_if, bool set_scan_rsp,
                                                   bool include_name, bool incl_txpower,
                                                   int appearance, uint16_t manufacturer_len,
                                                   char* manufacturer_data,
                                                   uint16_t service_data_len,
                                                   char* service_data, uint16_t service_uuid_len,
                                                   char* service_uuid)
                bool include_name, bool incl_txpower, int appearance,
                int manufacturer_len, char* manufacturer_data,
                int service_data_len, char* service_data,
                int service_uuid_len, char* service_uuid)
{
    CHECK_BTGATT_INIT();

+81 −44
Original line number Diff line number Diff line
@@ -71,6 +71,13 @@ btgatt_multi_adv_common_data *btif_obtain_multi_adv_data_cb()
                                              * sizeof(btgatt_multi_adv_inst_cb));
            memset(p_multi_adv_com_data_cb->inst_cb, 0 ,
                 ( BTM_BleMaxMultiAdvInstanceCount() + 1) * sizeof(btgatt_multi_adv_inst_cb));

            for (int i=0; i <  BTM_BleMaxMultiAdvInstanceCount(); i += 2)
            for (int i=0; i < BTM_BLE_MULTI_ADV_MAX; i++)
            {
                p_multi_adv_com_data_cb->clntif_map[i] = INVALID_ADV_INST;
                p_multi_adv_com_data_cb->clntif_map[i+1] = INVALID_ADV_INST;
            }
        }
    }

@@ -79,29 +86,17 @@ btgatt_multi_adv_common_data *btif_obtain_multi_adv_data_cb()

void btif_gattc_init_multi_adv_cb(void)
{
    int i;
    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();

    if (NULL == p_multi_adv_data_cb)
        return;

    if (0 == multi_adv_enable_count)
    {
        for (i=0; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
        {
           p_multi_adv_data_cb->clntif_map[i + i] = INVALID_ADV_INST;
           p_multi_adv_data_cb->clntif_map[i + (i + 1)] = INVALID_ADV_INST;
        }
    }
    multi_adv_enable_count++;
    // TODO: Instead of using a fragile reference counter here, one could
    //       simply track the client_if instances that are in the map.
    ++multi_adv_enable_count;
}

void btif_gattc_destroy_multi_adv_cb()
void btif_gattc_destroy_multi_adv_cb(int client_if)
{
    if (multi_adv_enable_count > 0)
        multi_adv_enable_count --;

    if (0 == multi_adv_enable_count)
    if(multi_adv_enable_count == 0 && p_multi_adv_com_data_cb != 0)
    {
        if (NULL != p_multi_adv_com_data_cb)
        {
@@ -118,7 +113,6 @@ int btif_multi_adv_add_instid_map(int client_if, int inst_id, BOOLEAN gen_temp_i
    int i=1;

    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();

    if (NULL == p_multi_adv_data_cb)
        return INVALID_ADV_INST;

@@ -226,8 +220,8 @@ int btif_gattc_obtain_idx_for_datacb(int value, int clnt_inst_index)

void btif_gattc_adv_data_packager(int client_if, bool set_scan_rsp,
                bool include_name, bool include_txpower, int min_interval, int max_interval,
                int appearance, uint16_t manufacturer_len, char* manufacturer_data,
                uint16_t service_data_len, char* service_data, uint16_t service_uuid_len,
                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)
{
    memset(p_multi_adv_inst, 0 , sizeof(btif_adv_data_t));
@@ -276,7 +270,9 @@ BOOLEAN btif_gattc_copy_datacb(int cbindex, btif_adv_data_t *p_adv_data, BOOLEAN
    if (!p_adv_data->set_scan_rsp)
    {
         p_multi_adv_data_cb->inst_cb[cbindex].mask = BTM_BLE_AD_BIT_FLAGS;
         p_multi_adv_data_cb->inst_cb[cbindex].data.flag = ADV_FLAGS;
         p_multi_adv_data_cb->inst_cb[cbindex].data.flag = ADV_FLAGS_GENERAL;
         if (p_multi_adv_data_cb->inst_cb[cbindex].timeout_s)
             p_multi_adv_data_cb->inst_cb[cbindex].data.flag = ADV_FLAGS_LIMITED;
    }

    if (p_adv_data->include_name)
@@ -449,20 +445,18 @@ BOOLEAN btif_gattc_copy_datacb(int cbindex, btif_adv_data_t *p_adv_data, BOOLEAN

void btif_gattc_clear_clientif(int client_if)
{
    int i=0;

    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();

    if (NULL == p_multi_adv_data_cb)
        return;

    // Clear both the inst_id and client_if values
    for (i=0; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
    for (i=0; i <  BTM_BleMaxMultiAdvInstanceCount(); i+=2)
    {
       if (client_if == p_multi_adv_data_cb->clntif_map[i + i])
        if (client_if == p_multi_adv_data_cb->clntif_map[i])
        {
          p_multi_adv_data_cb->clntif_map[i + (i + 1)] = INVALID_ADV_INST;
          p_multi_adv_data_cb->clntif_map[i + i] = INVALID_ADV_INST;
            btif_gattc_cleanup_inst_cb(p_multi_adv_data_cb->clntif_map[i+1]);
            p_multi_adv_data_cb->clntif_map[i] = INVALID_ADV_INST;
            p_multi_adv_data_cb->clntif_map[i+1] = INVALID_ADV_INST;
            BTIF_TRACE_DEBUG("Cleaning up index %d for clnt_if :%d,", i, client_if);
            break;
        }
@@ -477,7 +471,6 @@ void btif_gattc_cleanup_inst_cb(int inst_id)
        return;

    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();

    if (NULL == p_multi_adv_data_cb)
        return;

@@ -486,17 +479,25 @@ void btif_gattc_cleanup_inst_cb(int inst_id)
        cbindex = btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
        if (cbindex < 0)
            return;
    }
    else
    } else {
        if (STD_ADV_INSTID == inst_id)
          cbindex = STD_ADV_INSTID;
    }

    if (inst_id != INVALID_ADV_INST)
    {
        BTIF_TRACE_DEBUG("Cleaning up multi_inst_cb for inst_id %d, cbindex %d", inst_id, cbindex);
        btif_gattc_cleanup_multi_inst_cb(&p_multi_adv_data_cb->inst_cb[cbindex]);
        p_multi_adv_data_cb->inst_cb[cbindex].inst_id = INVALID_ADV_INST;
    }
}

void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_multi_inst_cb)
{
    // Discoverability timer cleanup
    alarm_free(p_multi_inst_cb->limited_timer);
    p_multi_inst_cb->limited_timer = NULL;

    // Manufacturer data cleanup
    if (p_multi_inst_cb->data.p_manu != NULL)
    {
@@ -567,4 +568,40 @@ 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)
{
    int inst_id = btif_multi_adv_instid_for_clientif(client_if);
    if (inst_id == INVALID_ADV_INST)
        return;

    int cbindex = btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
    if (cbindex == INVALID_ADV_INST)
        return;

    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
    if (p_multi_adv_data_cb == NULL)
        return;

    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;
    } 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);
            }
        }
    }
}

#endif