• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
btif_obtain_multi_adv_data_cb()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 
btif_gattc_incr_app_count(void)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 
btif_gattc_decr_app_count(void)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 
btif_multi_adv_add_instid_map(int client_if,int inst_id,BOOLEAN gen_temp_instid)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 
btif_multi_adv_instid_for_clientif(int client_if)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 
btif_gattc_obtain_idx_for_datacb(int value,int clnt_inst_index)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 
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,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)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 
btif_gattc_adv_data_cleanup(btif_adv_data_t * adv)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 
btif_gattc_copy_datacb(int cbindex,const btif_adv_data_t * p_adv_data,BOOLEAN bInstData)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 
btif_gattc_clear_clientif(int client_if,BOOLEAN stop_timer)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 
btif_gattc_cleanup_inst_cb(int inst_id,BOOLEAN stop_timer)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 
btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb * p_multi_inst_cb,BOOLEAN stop_timer)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 
btif_multi_adv_timer_ctrl(int client_if,alarm_callback_t cb)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