Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2014  Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /*******************************************************************************
     20  *
     21  *  Filename:      btif_gatt_multi_adv_util.c
     22  *
     23  *  Description:   Multi ADV helper implementation
     24  *
     25  *******************************************************************************/
     26 
     27 #define LOG_TAG "bt_btif_gatt"
     28 
     29 
     30 #include <stdio.h>
     31 #include <stdlib.h>
     32 #include <string.h>
     33 
     34 #include "btu.h"
     35 #include "bt_target.h"
     36 
     37 #if (BLE_INCLUDED == TRUE)
     38 
     39 #include <hardware/bluetooth.h>
     40 #include <hardware/bt_gatt.h>
     41 
     42 #include "bta_gatt_api.h"
     43 #include "btif_common.h"
     44 #include "btif_gatt_multi_adv_util.h"
     45 #include "btif_gatt_util.h"
     46 
     47 extern fixed_queue_t *btu_general_alarm_queue;
     48 
     49 /*******************************************************************************
     50 **  Static variables
     51 ********************************************************************************/
     52 static int user_app_count = 0;
     53 static btgatt_multi_adv_common_data *p_multi_adv_com_data_cb = NULL;
     54 
     55 btgatt_multi_adv_common_data *btif_obtain_multi_adv_data_cb()
     56 {
     57     int max_adv_inst = BTM_BleMaxMultiAdvInstanceCount();
     58     if (0 == max_adv_inst)
     59         max_adv_inst = 1;
     60 
     61     BTIF_TRACE_DEBUG("%s, Count:%d", __FUNCTION__, max_adv_inst);
     62 
     63     if (NULL == p_multi_adv_com_data_cb)
     64     {
     65         p_multi_adv_com_data_cb = osi_calloc(sizeof(btgatt_multi_adv_common_data));
     66         /* Storing both client_if and inst_id details */
     67         p_multi_adv_com_data_cb->clntif_map =
     68             osi_calloc((max_adv_inst * INST_ID_IDX_MAX) * sizeof(INT8));
     69 
     70         p_multi_adv_com_data_cb->inst_cb =
     71             osi_calloc((max_adv_inst + 1) * sizeof(btgatt_multi_adv_inst_cb));
     72 
     73         for (int i = 0; i < max_adv_inst * 2; i += 2) {
     74             p_multi_adv_com_data_cb->clntif_map[i] = INVALID_ADV_INST;
     75             p_multi_adv_com_data_cb->clntif_map[i+1] = INVALID_ADV_INST;
     76         }
     77     }
     78 
     79     return p_multi_adv_com_data_cb;
     80 }
     81 
     82 void btif_gattc_incr_app_count(void)
     83 {
     84     // TODO: Instead of using a fragile reference counter here, one could
     85     //       simply track the client_if instances that are in the map.
     86     ++user_app_count;
     87 }
     88 
     89 void btif_gattc_decr_app_count(void)
     90 {
     91     if (user_app_count > 0)
     92         user_app_count--;
     93 
     94     if ((user_app_count == 0) && (p_multi_adv_com_data_cb != NULL)) {
     95        osi_free(p_multi_adv_com_data_cb->clntif_map);
     96        osi_free(p_multi_adv_com_data_cb->inst_cb);
     97        osi_free_and_reset((void **)&p_multi_adv_com_data_cb);
     98     }
     99 }
    100 
    101 int btif_multi_adv_add_instid_map(int client_if, int inst_id, BOOLEAN gen_temp_instid)
    102 {
    103     int i=1;
    104 
    105     btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
    106     if (NULL == p_multi_adv_data_cb)
    107         return INVALID_ADV_INST;
    108 
    109     for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
    110     {
    111        if (client_if == p_multi_adv_data_cb->clntif_map[i + i])
    112        {
    113           if (!gen_temp_instid)
    114           {
    115              // Write the final inst_id value obtained from stack layer
    116              p_multi_adv_data_cb->clntif_map[i + (i + 1)] = inst_id;
    117              BTIF_TRACE_DEBUG("%s -Index: %d, Found client_if: %d", __FUNCTION__,
    118                 i, p_multi_adv_data_cb->clntif_map[i + i]);
    119              break;
    120           }
    121           else
    122           {
    123               //Store the passed in inst_id value
    124              if (inst_id != INVALID_ADV_INST)
    125                  p_multi_adv_data_cb->clntif_map[i + (i + 1)] = inst_id;
    126              else
    127                  p_multi_adv_data_cb->clntif_map[i + (i + 1)] = (i + 1);
    128 
    129              BTIF_TRACE_DEBUG("%s - Index:%d,Found client_if: %d", __FUNCTION__,
    130                 i, p_multi_adv_data_cb->clntif_map[i + i]);
    131              break;
    132           }
    133        }
    134     }
    135 
    136     if (i <  BTM_BleMaxMultiAdvInstanceCount())
    137         return i;
    138 
    139     // If client ID if is not found, then write both values
    140     for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
    141     {
    142         if (INVALID_ADV_INST == p_multi_adv_data_cb->clntif_map[i + i])
    143         {
    144             p_multi_adv_data_cb->clntif_map[i + i] = client_if;
    145             if (inst_id != INVALID_ADV_INST)
    146                p_multi_adv_data_cb->clntif_map[i + (i + 1)] = inst_id;
    147             else
    148                 p_multi_adv_data_cb->clntif_map[i + (i + 1)] = (i + 1);
    149             BTIF_TRACE_DEBUG("%s -Not found - Index:%d, client_if: %d, Inst ID: %d",
    150                             __FUNCTION__,i,
    151                             p_multi_adv_data_cb->clntif_map[i + i],
    152                             p_multi_adv_data_cb->clntif_map[i + (i + 1)]);
    153             break;
    154         }
    155     }
    156 
    157     if (i <  BTM_BleMaxMultiAdvInstanceCount())
    158         return i;
    159     return INVALID_ADV_INST;
    160 }
    161 
    162 int btif_multi_adv_instid_for_clientif(int client_if)
    163 {
    164     int i=1, ret = INVALID_ADV_INST;
    165 
    166     btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
    167 
    168     if (NULL == p_multi_adv_data_cb)
    169         return INVALID_ADV_INST;
    170 
    171     // Retrieve the existing inst_id for the client_if value
    172     for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
    173     {
    174        if (client_if == p_multi_adv_data_cb->clntif_map[i + i])
    175        {
    176            BTIF_TRACE_DEBUG("%s - Client if found", __FUNCTION__, client_if);
    177            ret = p_multi_adv_data_cb->clntif_map[i + (i + 1)];
    178        }
    179     }
    180 
    181     return ret;
    182 }
    183 
    184 int btif_gattc_obtain_idx_for_datacb(int value, int clnt_inst_index)
    185 {
    186     int i=1;
    187 
    188     btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
    189 
    190     if (NULL == p_multi_adv_data_cb)
    191         return INVALID_ADV_INST;
    192 
    193     // Retrieve the array index for the inst_id value
    194     for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
    195     {
    196        if (value == p_multi_adv_data_cb->clntif_map[i + (i + clnt_inst_index)])
    197            break;
    198     }
    199 
    200     if (i <  BTM_BleMaxMultiAdvInstanceCount())
    201     {
    202         BTIF_TRACE_DEBUG("%s, %d",__FUNCTION__,i);
    203         return i;
    204     }
    205 
    206     BTIF_TRACE_DEBUG("%s Invalid instance",__FUNCTION__);
    207     return INVALID_ADV_INST;
    208 }
    209 
    210 void btif_gattc_adv_data_packager(int client_if, bool set_scan_rsp,
    211                 bool include_name, bool include_txpower, int min_interval, int max_interval,
    212                 int appearance, int manufacturer_len, char* manufacturer_data,
    213                 int service_data_len, char* service_data, int service_uuid_len,
    214                 char* service_uuid, btif_adv_data_t *p_multi_adv_inst)
    215 {
    216     memset(p_multi_adv_inst, 0 , sizeof(btif_adv_data_t));
    217 
    218     p_multi_adv_inst->client_if = (uint8_t) client_if;
    219     p_multi_adv_inst->set_scan_rsp = set_scan_rsp;
    220     p_multi_adv_inst->include_name = include_name;
    221     p_multi_adv_inst->include_txpower = include_txpower;
    222     p_multi_adv_inst->min_interval = min_interval;
    223     p_multi_adv_inst->max_interval = max_interval;
    224     p_multi_adv_inst->appearance = appearance;
    225     p_multi_adv_inst->manufacturer_len = manufacturer_len;
    226 
    227     if (manufacturer_len > 0)
    228     {
    229         p_multi_adv_inst->p_manufacturer_data = osi_malloc(manufacturer_len);
    230         memcpy(p_multi_adv_inst->p_manufacturer_data, manufacturer_data, manufacturer_len);
    231     }
    232 
    233     p_multi_adv_inst->service_data_len = service_data_len;
    234     if (service_data_len > 0)
    235     {
    236         p_multi_adv_inst->p_service_data = osi_malloc(service_data_len);
    237         memcpy(p_multi_adv_inst->p_service_data, service_data, service_data_len);
    238     }
    239 
    240     p_multi_adv_inst->service_uuid_len = service_uuid_len;
    241     if (service_uuid_len > 0)
    242     {
    243         p_multi_adv_inst->p_service_uuid = osi_malloc(service_uuid_len);
    244         memcpy(p_multi_adv_inst->p_service_uuid, service_uuid, service_uuid_len);
    245     }
    246 }
    247 
    248 void btif_gattc_adv_data_cleanup(btif_adv_data_t* adv)
    249 {
    250     osi_free_and_reset((void **)&adv->p_service_data);
    251     osi_free_and_reset((void **)&adv->p_service_uuid);
    252     osi_free_and_reset((void **)&adv->p_manufacturer_data);
    253 }
    254 
    255 BOOLEAN btif_gattc_copy_datacb(int cbindex, const btif_adv_data_t *p_adv_data,
    256                                BOOLEAN bInstData) {
    257     btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
    258     if (NULL == p_multi_adv_data_cb || cbindex < 0)
    259        return false;
    260 
    261     BTIF_TRACE_DEBUG("%s", __func__);
    262 
    263     memset(&p_multi_adv_data_cb->inst_cb[cbindex].data, 0,
    264            sizeof(p_multi_adv_data_cb->inst_cb[cbindex].data));
    265     p_multi_adv_data_cb->inst_cb[cbindex].mask = 0;
    266 
    267     if (!p_adv_data->set_scan_rsp)
    268     {
    269          p_multi_adv_data_cb->inst_cb[cbindex].mask = BTM_BLE_AD_BIT_FLAGS;
    270          p_multi_adv_data_cb->inst_cb[cbindex].data.flag = ADV_FLAGS_GENERAL;
    271          if (p_multi_adv_data_cb->inst_cb[cbindex].timeout_s)
    272              p_multi_adv_data_cb->inst_cb[cbindex].data.flag = ADV_FLAGS_LIMITED;
    273          if (p_multi_adv_data_cb->inst_cb[cbindex].param.adv_type == BTA_BLE_NON_CONNECT_EVT)
    274              p_multi_adv_data_cb->inst_cb[cbindex].data.flag &=
    275                     ~(BTA_DM_LIMITED_DISC | BTA_DM_GENERAL_DISC);
    276          if (p_multi_adv_data_cb->inst_cb[cbindex].data.flag == 0)
    277             p_multi_adv_data_cb->inst_cb[cbindex].mask = 0;
    278     }
    279 
    280     if (p_adv_data->include_name)
    281         p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_DEV_NAME;
    282 
    283     if (p_adv_data->include_txpower)
    284         p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_TX_PWR;
    285 
    286     if (false == bInstData && p_adv_data->min_interval > 0 && p_adv_data->max_interval > 0 &&
    287         p_adv_data->max_interval > p_adv_data->min_interval)
    288     {
    289         p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_INT_RANGE;
    290         p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.low =
    291                                         p_adv_data->min_interval;
    292         p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.hi =
    293                                         p_adv_data->max_interval;
    294     }
    295     else
    296     if (true == bInstData)
    297     {
    298         if (p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min > 0 &&
    299             p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max > 0 &&
    300             p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max >
    301             p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min)
    302         {
    303               p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.low =
    304               p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min;
    305               p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.hi =
    306               p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max;
    307         }
    308 
    309         if (p_adv_data->include_txpower)
    310         {
    311             p_multi_adv_data_cb->inst_cb[cbindex].data.tx_power =
    312                 p_multi_adv_data_cb->inst_cb[cbindex].param.tx_power;
    313         }
    314     }
    315 
    316     if (p_adv_data->appearance != 0)
    317     {
    318         p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_APPEARANCE;
    319         p_multi_adv_data_cb->inst_cb[cbindex].data.appearance = p_adv_data->appearance;
    320     }
    321 
    322     if (p_adv_data->manufacturer_len > 0 &&
    323         p_adv_data->p_manufacturer_data != NULL &&
    324         p_adv_data->manufacturer_len < MAX_SIZE_MANUFACTURER_DATA)
    325     {
    326       p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_MANU;
    327       p_multi_adv_data_cb->inst_cb[cbindex].data.manu.len =
    328           p_adv_data->manufacturer_len;
    329       memcpy(&p_multi_adv_data_cb->inst_cb[cbindex].data.manu.val,
    330              p_adv_data->p_manufacturer_data, p_adv_data->manufacturer_len);
    331     }
    332 
    333     if (p_adv_data->service_data_len > 0 &&
    334         p_adv_data->p_service_data != NULL &&
    335         p_adv_data->service_data_len < MAX_SIZE_PROPRIETARY_ELEMENT)
    336     {
    337       BTIF_TRACE_DEBUG("%s - In service_data", __func__);
    338       tBTA_BLE_PROPRIETARY *p_prop = &p_multi_adv_data_cb->inst_cb[cbindex].data.proprietary;
    339       p_prop->num_elem = 1;
    340 
    341       tBTA_BLE_PROP_ELEM *p_elem = &p_prop->elem[0];
    342       p_elem->adv_type = BTM_BLE_AD_TYPE_SERVICE_DATA;
    343       p_elem->len = p_adv_data->service_data_len;
    344       memcpy(p_elem->val, p_adv_data->p_service_data,
    345              p_adv_data->service_data_len);
    346 
    347       p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_PROPRIETARY;
    348     }
    349 
    350     if (p_adv_data->service_uuid_len && p_adv_data->p_service_uuid)
    351     {
    352         UINT16 *p_uuid_out16 = NULL;
    353         UINT32 *p_uuid_out32 = NULL;
    354         for (int position = 0; position < p_adv_data->service_uuid_len; position += LEN_UUID_128)
    355         {
    356              bt_uuid_t uuid;
    357              memset(&uuid, 0, sizeof(uuid));
    358              memcpy(&uuid.uu, p_adv_data->p_service_uuid + position, LEN_UUID_128);
    359 
    360              tBT_UUID bt_uuid;
    361              memset(&bt_uuid, 0, sizeof(bt_uuid));
    362              btif_to_bta_uuid(&bt_uuid, &uuid);
    363 
    364              switch(bt_uuid.len)
    365              {
    366                 case (LEN_UUID_16):
    367                 {
    368                   if (p_multi_adv_data_cb->inst_cb[cbindex].data.services.num_service == 0)
    369                   {
    370                       p_multi_adv_data_cb->inst_cb[cbindex].data.services.list_cmpl = FALSE;
    371                       p_uuid_out16 = p_multi_adv_data_cb->inst_cb[cbindex].data.services.uuid;
    372                   }
    373 
    374                   if (p_multi_adv_data_cb->inst_cb[cbindex].data.services.num_service < MAX_16BIT_SERVICES)
    375                   {
    376                      BTIF_TRACE_DEBUG("%s - In 16-UUID_data", __func__);
    377                      p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_SERVICE;
    378                      ++p_multi_adv_data_cb->inst_cb[cbindex].data.services.num_service;
    379                      *p_uuid_out16++ = bt_uuid.uu.uuid16;
    380                   }
    381                   break;
    382                 }
    383 
    384                 case (LEN_UUID_32):
    385                 {
    386                    if (p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.num_service == 0)
    387                    {
    388                       p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.list_cmpl = FALSE;
    389                       p_uuid_out32 = p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.uuid;
    390                    }
    391 
    392                    if (p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.num_service < MAX_32BIT_SERVICES)
    393                    {
    394                       BTIF_TRACE_DEBUG("%s - In 32-UUID_data", __func__);
    395                       p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_SERVICE_32;
    396                       ++p_multi_adv_data_cb->inst_cb[cbindex].data.service_32b.num_service;
    397                       *p_uuid_out32++ = bt_uuid.uu.uuid32;
    398                    }
    399                    break;
    400                 }
    401 
    402                 case (LEN_UUID_128):
    403                 {
    404                    /* Currently, only one 128-bit UUID is supported */
    405                    if (p_multi_adv_data_cb->inst_cb[cbindex].data.services_128b.num_service == 0)
    406                    {
    407                      BTIF_TRACE_DEBUG("%s - In 128-UUID_data", __FUNCTION__);
    408                      p_multi_adv_data_cb->inst_cb[cbindex].mask |=
    409                          BTM_BLE_AD_BIT_SERVICE_128;
    410                      memcpy(p_multi_adv_data_cb->inst_cb[cbindex]
    411                                 .data.services_128b.uuid128,
    412                             bt_uuid.uu.uuid128, LEN_UUID_128);
    413                      BTIF_TRACE_DEBUG(
    414                          "%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x",
    415                          bt_uuid.uu.uuid128[0], bt_uuid.uu.uuid128[1],
    416                          bt_uuid.uu.uuid128[2], bt_uuid.uu.uuid128[3],
    417                          bt_uuid.uu.uuid128[4], bt_uuid.uu.uuid128[5],
    418                          bt_uuid.uu.uuid128[6], bt_uuid.uu.uuid128[7],
    419                          bt_uuid.uu.uuid128[8], bt_uuid.uu.uuid128[9],
    420                          bt_uuid.uu.uuid128[10], bt_uuid.uu.uuid128[11],
    421                          bt_uuid.uu.uuid128[12], bt_uuid.uu.uuid128[13],
    422                          bt_uuid.uu.uuid128[14], bt_uuid.uu.uuid128[15]);
    423                      ++p_multi_adv_data_cb->inst_cb[cbindex]
    424                            .data.services_128b.num_service;
    425                      p_multi_adv_data_cb->inst_cb[cbindex]
    426                          .data.services_128b.list_cmpl = TRUE;
    427                    }
    428                    break;
    429                 }
    430 
    431                 default:
    432                      break;
    433              }
    434         }
    435     }
    436 
    437      return true;
    438 }
    439 
    440 void btif_gattc_clear_clientif(int client_if, BOOLEAN stop_timer)
    441 {
    442     btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
    443     if (NULL == p_multi_adv_data_cb)
    444         return;
    445 
    446     // Clear both the inst_id and client_if values
    447     for (int i=0; i < BTM_BleMaxMultiAdvInstanceCount()*2; i+=2)
    448     {
    449         if (client_if == p_multi_adv_data_cb->clntif_map[i])
    450         {
    451             btif_gattc_cleanup_inst_cb(p_multi_adv_data_cb->clntif_map[i+1], stop_timer);
    452             if (stop_timer)
    453             {
    454                 p_multi_adv_data_cb->clntif_map[i] = INVALID_ADV_INST;
    455                 p_multi_adv_data_cb->clntif_map[i+1] = INVALID_ADV_INST;
    456                 BTIF_TRACE_DEBUG("Cleaning up index %d for clnt_if :%d,", i/2, client_if);
    457             }
    458             break;
    459         }
    460     }
    461 }
    462 
    463 void btif_gattc_cleanup_inst_cb(int inst_id, BOOLEAN stop_timer)
    464 {
    465     // Check for invalid instance id
    466     if (inst_id < 0 || inst_id >= BTM_BleMaxMultiAdvInstanceCount())
    467         return;
    468 
    469     btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
    470     if (NULL == p_multi_adv_data_cb)
    471         return;
    472 
    473     int cbindex = (STD_ADV_INSTID == inst_id) ?
    474         STD_ADV_INSTID : btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
    475     if (cbindex < 0) return;
    476 
    477     BTIF_TRACE_DEBUG("%s: inst_id %d, cbindex %d", __func__, inst_id, cbindex);
    478     btif_gattc_cleanup_multi_inst_cb(&p_multi_adv_data_cb->inst_cb[cbindex], stop_timer);
    479 }
    480 
    481 void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_multi_inst_cb,
    482                                              BOOLEAN stop_timer)
    483 {
    484     if (p_multi_inst_cb == NULL)
    485         return;
    486 
    487     // Discoverability timer cleanup
    488     if (stop_timer)
    489     {
    490         alarm_free(p_multi_inst_cb->multi_adv_timer);
    491         p_multi_inst_cb->multi_adv_timer = NULL;
    492     }
    493 
    494     memset(&p_multi_inst_cb->data, 0, sizeof(p_multi_inst_cb->data));
    495 }
    496 
    497 void btif_multi_adv_timer_ctrl(int client_if, alarm_callback_t cb)
    498 {
    499     int inst_id = btif_multi_adv_instid_for_clientif(client_if);
    500     if (inst_id == INVALID_ADV_INST)
    501         return;
    502 
    503     int cbindex = btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
    504     if (cbindex == INVALID_ADV_INST)
    505         return;
    506 
    507     btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
    508     if (p_multi_adv_data_cb == NULL)
    509         return;
    510 
    511     btgatt_multi_adv_inst_cb *inst_cb = &p_multi_adv_data_cb->inst_cb[cbindex];
    512     if (cb == NULL)
    513     {
    514         alarm_free(inst_cb->multi_adv_timer);
    515         inst_cb->multi_adv_timer = NULL;
    516     } else {
    517         if (inst_cb->timeout_s != 0)
    518         {
    519             alarm_free(inst_cb->multi_adv_timer);
    520             inst_cb->multi_adv_timer = alarm_new("btif_gatt.multi_adv_timer");
    521             alarm_set_on_queue(inst_cb->multi_adv_timer,
    522                                inst_cb->timeout_s * 1000,
    523                                cb, INT_TO_PTR(client_if),
    524                                btu_general_alarm_queue);
    525         }
    526     }
    527 }
    528 
    529 #endif
    530