btif_gatt_multi_adv_util.c revision cf32e8d4e0cabac8432a3c6c6d8ece27d6067770
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 *
22 *  Filename:      btif_gatt_multi_adv_util.c
23 *
24 *  Description:   Multi ADV helper implementation
25 *
26 *******************************************************************************/
27
28#include <stdio.h>
29#include <stdlib.h>
30#include "btu.h"
31#include "bt_target.h"
32
33#define LOG_TAG "BtGatt.btif"
34#if (BLE_INCLUDED == TRUE)
35
36#include "btif_gatt_multi_adv_util.h"
37#include "btif_common.h"
38#include <hardware/bt_gatt.h>
39#include "bta_gatt_api.h"
40#include "btif_gatt_util.h"
41
42/*******************************************************************************
43**  Static variables
44********************************************************************************/
45static int multi_adv_enable_count = 0;
46static btgatt_multi_adv_common_data *p_multi_adv_com_data_cb = NULL;
47
48btgatt_multi_adv_common_data *btif_obtain_multi_adv_data_cb()
49{
50    if(0 == BTM_BleMaxMultiAdvInstanceCount())
51    {
52        BTIF_TRACE_WARNING("%s - No instances found", __FUNCTION__);
53        return NULL;
54    }
55
56    BTIF_TRACE_DEBUG("%s, Count:%d", __FUNCTION__, BTM_BleMaxMultiAdvInstanceCount());
57    if (NULL == p_multi_adv_com_data_cb)
58    {
59        BTIF_TRACE_DEBUG("Initializing in %s", __FUNCTION__);
60        p_multi_adv_com_data_cb = GKI_getbuf(sizeof(btgatt_multi_adv_common_data));
61        if (NULL != p_multi_adv_com_data_cb)
62        {
63            memset(p_multi_adv_com_data_cb, 0, sizeof(btgatt_multi_adv_common_data));
64
65            /* Storing both client_if and inst_id details */
66            p_multi_adv_com_data_cb->clntif_map =
67                  GKI_getbuf(( BTM_BleMaxMultiAdvInstanceCount() * INST_ID_IDX_MAX)* sizeof(INT8));
68            memset(p_multi_adv_com_data_cb->clntif_map, 0 ,
69                  ( BTM_BleMaxMultiAdvInstanceCount() * INST_ID_IDX_MAX)* sizeof(INT8));
70
71            p_multi_adv_com_data_cb->inst_cb = GKI_getbuf(( BTM_BleMaxMultiAdvInstanceCount() + 1 )
72                                              * sizeof(btgatt_multi_adv_inst_cb));
73            memset(p_multi_adv_com_data_cb->inst_cb, 0 ,
74                 ( BTM_BleMaxMultiAdvInstanceCount() + 1) * sizeof(btgatt_multi_adv_inst_cb));
75
76            for (int i=0; i < BTM_BleMaxMultiAdvInstanceCount()*2; i += 2)
77            {
78                p_multi_adv_com_data_cb->clntif_map[i] = INVALID_ADV_INST;
79                p_multi_adv_com_data_cb->clntif_map[i+1] = INVALID_ADV_INST;
80            }
81        }
82    }
83
84    return p_multi_adv_com_data_cb;
85}
86
87void btif_gattc_init_multi_adv_cb(void)
88{
89    // TODO: Instead of using a fragile reference counter here, one could
90    //       simply track the client_if instances that are in the map.
91    ++multi_adv_enable_count;
92}
93
94void btif_gattc_destroy_multi_adv_cb(int client_if)
95{
96    if (multi_adv_enable_count > 0)
97        multi_adv_enable_count --;
98
99    if(multi_adv_enable_count == 0 && p_multi_adv_com_data_cb != 0)
100    {
101        if (NULL != p_multi_adv_com_data_cb)
102        {
103            GKI_freebuf (p_multi_adv_com_data_cb->clntif_map);
104            GKI_freebuf (p_multi_adv_com_data_cb->inst_cb);
105            GKI_freebuf(p_multi_adv_com_data_cb);
106            p_multi_adv_com_data_cb = NULL;
107        }
108    }
109}
110
111int btif_multi_adv_add_instid_map(int client_if, int inst_id, BOOLEAN gen_temp_instid)
112{
113    int i=1;
114
115    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
116    if (NULL == p_multi_adv_data_cb)
117        return INVALID_ADV_INST;
118
119    for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
120    {
121       if (client_if == p_multi_adv_data_cb->clntif_map[i + i])
122       {
123          if (!gen_temp_instid)
124          {
125             // Write the final inst_id value obtained from stack layer
126             p_multi_adv_data_cb->clntif_map[i + (i + 1)] = inst_id;
127             BTIF_TRACE_DEBUG("%s -Index: %d, Found client_if: %d", __FUNCTION__,
128                i, p_multi_adv_data_cb->clntif_map[i + i]);
129             break;
130          }
131          else
132          {
133              //Store the passed in inst_id value
134             if (inst_id != INVALID_ADV_INST)
135                 p_multi_adv_data_cb->clntif_map[i + (i + 1)] = inst_id;
136             else
137                 p_multi_adv_data_cb->clntif_map[i + (i + 1)] = (i + 1);
138
139             BTIF_TRACE_DEBUG("%s - Index:%d,Found client_if: %d", __FUNCTION__,
140                i, p_multi_adv_data_cb->clntif_map[i + i]);
141             break;
142          }
143       }
144    }
145
146    if (i <  BTM_BleMaxMultiAdvInstanceCount())
147        return i;
148
149    // If client ID if is not found, then write both values
150    for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
151    {
152        if (INVALID_ADV_INST == p_multi_adv_data_cb->clntif_map[i + i])
153        {
154            p_multi_adv_data_cb->clntif_map[i + i] = client_if;
155            if (inst_id != INVALID_ADV_INST)
156               p_multi_adv_data_cb->clntif_map[i + (i + 1)] = inst_id;
157            else
158                p_multi_adv_data_cb->clntif_map[i + (i + 1)] = (i + 1);
159            BTIF_TRACE_DEBUG("%s -Not found - Index:%d, client_if: %d, Inst ID: %d",
160                            __FUNCTION__,i,
161                            p_multi_adv_data_cb->clntif_map[i + i],
162                            p_multi_adv_data_cb->clntif_map[i + (i + 1)]);
163            break;
164        }
165    }
166
167    if (i <  BTM_BleMaxMultiAdvInstanceCount())
168        return i;
169    return INVALID_ADV_INST;
170}
171
172int btif_multi_adv_instid_for_clientif(int client_if)
173{
174    int i=1, ret = INVALID_ADV_INST;
175
176    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
177
178    if (NULL == p_multi_adv_data_cb)
179        return INVALID_ADV_INST;
180
181    // Retrieve the existing inst_id for the client_if value
182    for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
183    {
184       if (client_if == p_multi_adv_data_cb->clntif_map[i + i])
185       {
186           BTIF_TRACE_DEBUG("%s - Client if found", __FUNCTION__, client_if);
187           ret = p_multi_adv_data_cb->clntif_map[i + (i + 1)];
188       }
189    }
190
191    return ret;
192}
193
194int btif_gattc_obtain_idx_for_datacb(int value, int clnt_inst_index)
195{
196    int i=1;
197
198    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
199
200    if (NULL == p_multi_adv_data_cb)
201        return INVALID_ADV_INST;
202
203    // Retrieve the array index for the inst_id value
204    for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
205    {
206       if (value == p_multi_adv_data_cb->clntif_map[i + (i + clnt_inst_index)])
207           break;
208    }
209
210    if (i <  BTM_BleMaxMultiAdvInstanceCount())
211    {
212        BTIF_TRACE_DEBUG("%s, %d",__FUNCTION__,i);
213        return i;
214    }
215
216    BTIF_TRACE_DEBUG("%s Invalid instance",__FUNCTION__);
217    return INVALID_ADV_INST;
218}
219
220
221void btif_gattc_adv_data_packager(int client_if, bool set_scan_rsp,
222                bool include_name, bool include_txpower, int min_interval, int max_interval,
223                int appearance, int manufacturer_len, char* manufacturer_data,
224                int service_data_len, char* service_data, int service_uuid_len,
225                char* service_uuid, btif_adv_data_t *p_multi_adv_inst)
226{
227    memset(p_multi_adv_inst, 0 , sizeof(btif_adv_data_t));
228
229    p_multi_adv_inst->client_if = (uint8_t) client_if;
230    p_multi_adv_inst->set_scan_rsp = set_scan_rsp;
231    p_multi_adv_inst->include_name = include_name;
232    p_multi_adv_inst->include_txpower = include_txpower;
233    p_multi_adv_inst->min_interval = min_interval;
234    p_multi_adv_inst->max_interval = max_interval;
235    p_multi_adv_inst->appearance = appearance;
236    p_multi_adv_inst->manufacturer_len = manufacturer_len;
237
238    if (manufacturer_len > 0)
239    {
240        p_multi_adv_inst->p_manufacturer_data = GKI_getbuf(manufacturer_len);
241        memcpy(p_multi_adv_inst->p_manufacturer_data, manufacturer_data, manufacturer_len);
242    }
243
244    p_multi_adv_inst->service_data_len = service_data_len;
245    if (service_data_len > 0)
246    {
247        p_multi_adv_inst->p_service_data = GKI_getbuf(service_data_len);
248        memcpy(p_multi_adv_inst->p_service_data, service_data, service_data_len);
249    }
250
251    p_multi_adv_inst->service_uuid_len = service_uuid_len;
252    if (service_uuid_len > 0)
253    {
254        p_multi_adv_inst->p_service_uuid = GKI_getbuf(service_uuid_len);
255        memcpy(p_multi_adv_inst->p_service_uuid, service_uuid, service_uuid_len);
256    }
257}
258
259BOOLEAN btif_gattc_copy_datacb(int cbindex, btif_adv_data_t *p_adv_data, BOOLEAN bInstData)
260{
261    int i=0;
262    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
263    if (NULL == p_multi_adv_data_cb || cbindex < 0)
264       return false;
265
266    BTIF_TRACE_DEBUG("%s", __FUNCTION__);
267    memset(&p_multi_adv_data_cb->inst_cb[cbindex].data, 0, sizeof(tBTA_BLE_ADV_DATA));
268
269    p_multi_adv_data_cb->inst_cb[cbindex].is_scan_rsp = p_adv_data->set_scan_rsp ? 1 : 0;
270    if (!p_adv_data->set_scan_rsp)
271    {
272         p_multi_adv_data_cb->inst_cb[cbindex].mask = BTM_BLE_AD_BIT_FLAGS;
273         p_multi_adv_data_cb->inst_cb[cbindex].data.flag = ADV_FLAGS_GENERAL;
274         if (p_multi_adv_data_cb->inst_cb[cbindex].timeout_s)
275             p_multi_adv_data_cb->inst_cb[cbindex].data.flag = ADV_FLAGS_LIMITED;
276    }
277
278    if (p_adv_data->include_name)
279        p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_DEV_NAME;
280
281    if (p_adv_data->include_txpower)
282        p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_TX_PWR;
283
284    if (false == bInstData && p_adv_data->min_interval > 0 && p_adv_data->max_interval > 0 &&
285        p_adv_data->max_interval > p_adv_data->min_interval)
286    {
287        p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_INT_RANGE;
288        p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.low =
289                                        p_adv_data->min_interval;
290        p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.hi =
291                                        p_adv_data->max_interval;
292    }
293    else
294    if (true == bInstData)
295    {
296        if (p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min > 0 &&
297            p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max > 0 &&
298            p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max >
299            p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min)
300        {
301              p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.low =
302              p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min;
303              p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.hi =
304              p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max;
305        }
306
307        if (p_adv_data->include_txpower)
308        {
309            p_multi_adv_data_cb->inst_cb[cbindex].data.tx_power =
310                p_multi_adv_data_cb->inst_cb[cbindex].param.tx_power;
311        }
312    }
313
314    if (p_adv_data->appearance != 0)
315    {
316        p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_APPEARANCE;
317        p_multi_adv_data_cb->inst_cb[cbindex].data.appearance = p_adv_data->appearance;
318    }
319
320    if (p_adv_data->manufacturer_len > 0 && p_adv_data->p_manufacturer_data != NULL)
321    {
322         p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu =
323                            GKI_getbuf(sizeof(tBTA_BLE_MANU));
324         if (p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu != NULL)
325         {
326            p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->p_val =
327                            GKI_getbuf(p_adv_data->manufacturer_len);
328            if (p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->p_val != NULL)
329            {
330                 p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_MANU;
331                 p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->len =
332                                p_adv_data->manufacturer_len;
333                 memcpy(p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->p_val,
334                    p_adv_data->p_manufacturer_data, p_adv_data->manufacturer_len);
335            }
336         }
337     }
338
339     tBTA_BLE_PROP_ELEM *p_elem_service_data = NULL;
340     tBTA_BLE_PROP_ELEM *p_elem_service_128 = NULL;
341
342     if (p_adv_data->service_data_len > 0 && p_adv_data->p_service_data != NULL)
343     {
344         BTIF_TRACE_DEBUG("%s - In service_data", __FUNCTION__);
345         p_elem_service_data = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM));
346         if (p_elem_service_data != NULL)
347         {
348             p_elem_service_data->p_val = GKI_getbuf(p_adv_data->service_data_len);
349             if (p_elem_service_data->p_val != NULL)
350             {
351                 p_elem_service_data->adv_type = BTM_BLE_AD_TYPE_SERVICE_DATA;
352                 p_elem_service_data->len = p_adv_data->service_data_len;
353                 memcpy(p_elem_service_data->p_val, p_adv_data->p_service_data,
354                             p_adv_data->service_data_len);
355             } else {
356                     GKI_freebuf(p_elem_service_data);
357                     p_elem_service_data = NULL;
358               }
359             }
360         }
361
362         if (p_adv_data->service_uuid_len > 0 && p_adv_data->p_service_uuid != NULL)
363         {
364             p_multi_adv_data_cb->inst_cb[cbindex].data.p_services =
365                                            GKI_getbuf(sizeof(tBTA_BLE_SERVICE));
366             p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->list_cmpl = FALSE;
367             p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->num_service = 0;
368             p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->p_uuid =
369                 GKI_getbuf(p_adv_data->service_uuid_len / LEN_UUID_128 * LEN_UUID_16);
370             if (p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->p_uuid != NULL)
371             {
372                 UINT16 *p_uuid_out = p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->p_uuid;
373                 while (p_adv_data->service_uuid_len >= LEN_UUID_128)
374                 {
375                     bt_uuid_t uuid;
376                     memset(&uuid, 0, sizeof(bt_uuid_t));
377                     memcpy(&uuid.uu, p_adv_data->p_service_uuid, LEN_UUID_128);
378                     tBT_UUID bt_uuid;
379                     memset(&bt_uuid, 0, sizeof(tBT_UUID));
380                     btif_to_bta_uuid(&bt_uuid, &uuid);
381
382                     if (bt_uuid.len == LEN_UUID_16)
383                     {
384                         p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_SERVICE;
385                         ++p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->num_service;
386                         *p_uuid_out++ = bt_uuid.uu.uuid16;
387                     } else if (bt_uuid.len == LEN_UUID_128 && p_elem_service_128 == NULL) {
388                         /* Currently, only one 128-bit UUID is supported */
389                         p_elem_service_128 = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM));
390                         if (p_elem_service_128 != NULL)
391                         {
392                             p_elem_service_128->p_val = GKI_getbuf(LEN_UUID_128);
393                             if (p_elem_service_128->p_val != NULL)
394                             {
395                                 p_elem_service_128->adv_type = BTM_BLE_AD_TYPE_128SRV_PART;
396                                 p_elem_service_128->len = LEN_UUID_128;
397                                 memcpy(p_elem_service_128->p_val, bt_uuid.uu.uuid128, LEN_UUID_128);
398                             } else {
399                                 GKI_freebuf(p_elem_service_128);
400                                 p_elem_service_128 = NULL;
401                             }
402                         }
403                     }
404                     p_adv_data->p_service_uuid += LEN_UUID_128;
405                     p_adv_data->service_uuid_len -= LEN_UUID_128;
406                 }
407             }
408         }
409
410         if (p_elem_service_data != NULL || p_elem_service_128 != NULL)
411         {
412             p_multi_adv_data_cb->inst_cb[cbindex].data.p_proprietary =
413                                                GKI_getbuf(sizeof(tBTA_BLE_PROPRIETARY));
414             if (p_multi_adv_data_cb->inst_cb[cbindex].data.p_proprietary != NULL)
415             {
416                 tBTA_BLE_PROPRIETARY *p_prop = p_multi_adv_data_cb->inst_cb[cbindex].
417                            data.p_proprietary;
418                 tBTA_BLE_PROP_ELEM *p_elem = NULL;
419                 p_prop->num_elem = 0;
420                 p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_PROPRIETARY;
421                 if (p_elem_service_128 != NULL)
422                     ++p_prop->num_elem;
423                 if (p_elem_service_data != NULL)
424                     ++p_prop->num_elem;
425                 p_prop->p_elem = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM) * p_prop->num_elem);
426                 p_elem = p_prop->p_elem;
427                 if (p_elem_service_128 != NULL)
428                 {
429                     memcpy(p_elem++, p_elem_service_128, sizeof(tBTA_BLE_PROP_ELEM));
430                     GKI_freebuf(p_elem_service_128);
431                 }
432                 if (p_elem_service_data != NULL)
433                 {
434                     memcpy(p_elem++, p_elem_service_data, sizeof(tBTA_BLE_PROP_ELEM));
435                     GKI_freebuf(p_elem_service_data);
436                 }
437             }
438         }
439
440#if (defined(BLE_PERIPHERAL_ADV_NAME) && (BLE_PERIPHERAL_ADV_NAME == TRUE))
441     p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_DEV_NAME;
442#endif
443     return true;
444}
445
446void btif_gattc_clear_clientif(int client_if)
447{
448    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
449    if (NULL == p_multi_adv_data_cb)
450        return;
451
452    // Clear both the inst_id and client_if values
453    for (int i=0; i < BTM_BleMaxMultiAdvInstanceCount()*2; i+=2)
454    {
455        if (client_if == p_multi_adv_data_cb->clntif_map[i])
456        {
457            btif_gattc_cleanup_inst_cb(p_multi_adv_data_cb->clntif_map[i+1]);
458            p_multi_adv_data_cb->clntif_map[i] = INVALID_ADV_INST;
459            p_multi_adv_data_cb->clntif_map[i+1] = INVALID_ADV_INST;
460            BTIF_TRACE_DEBUG("Cleaning up index %d for clnt_if :%d,", i/2, client_if);
461            break;
462        }
463    }
464}
465
466void btif_gattc_cleanup_inst_cb(int inst_id)
467{
468    int cbindex = 0;
469    // Check for invalid instance id
470    if (inst_id < 0 || inst_id >= BTM_BleMaxMultiAdvInstanceCount())
471        return;
472
473    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
474    if (NULL == p_multi_adv_data_cb)
475        return;
476
477    if (inst_id > 0)
478    {
479        cbindex = btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
480        if (cbindex < 0)
481            return;
482    } else {
483        if (STD_ADV_INSTID == inst_id)
484          cbindex = STD_ADV_INSTID;
485    }
486
487    if (inst_id != INVALID_ADV_INST)
488    {
489        BTIF_TRACE_DEBUG("Cleaning up multi_inst_cb for inst_id %d, cbindex %d", inst_id, cbindex);
490        btif_gattc_cleanup_multi_inst_cb(&p_multi_adv_data_cb->inst_cb[cbindex]);
491        p_multi_adv_data_cb->inst_cb[cbindex].inst_id = INVALID_ADV_INST;
492    }
493}
494
495void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_multi_inst_cb)
496{
497    if (p_multi_inst_cb == NULL)
498        return;
499
500    // Discoverability timer cleanup
501    if (p_multi_inst_cb->tle_limited_timer.in_use)
502        btu_stop_timer_oneshot(&p_multi_inst_cb->tle_limited_timer);
503
504    // Manufacturer data cleanup
505    if (p_multi_inst_cb->data.p_manu != NULL)
506    {
507        if (p_multi_inst_cb->data.p_manu->p_val != NULL)
508           GKI_freebuf(p_multi_inst_cb->data.p_manu->p_val);
509        GKI_freebuf(p_multi_inst_cb->data.p_manu);
510    }
511
512    // Proprietary data cleanup
513    if (p_multi_inst_cb->data.p_proprietary != NULL)
514    {
515        int i = 0;
516        tBTA_BLE_PROP_ELEM *p_elem = p_multi_inst_cb->data.p_proprietary->p_elem;
517        while (i++ != p_multi_inst_cb->data.p_proprietary->num_elem
518            && p_elem)
519        {
520            if (p_elem->p_val != NULL)
521                GKI_freebuf(p_elem->p_val);
522            ++p_elem;
523        }
524
525        if (p_multi_inst_cb->data.p_proprietary->p_elem != NULL)
526            GKI_freebuf(p_multi_inst_cb->data.p_proprietary->p_elem);
527        GKI_freebuf(p_multi_inst_cb->data.p_proprietary);
528    }
529
530    // Service list cleanup
531    if (p_multi_inst_cb->data.p_services != NULL)
532    {
533        if (p_multi_inst_cb->data.p_services->p_uuid != NULL)
534           GKI_freebuf(p_multi_inst_cb->data.p_services->p_uuid);
535        GKI_freebuf(p_multi_inst_cb->data.p_services);
536    }
537
538    // Service data cleanup
539    if (p_multi_inst_cb->data.p_service_data != NULL)
540    {
541        if (p_multi_inst_cb->data.p_service_data->p_val != NULL)
542           GKI_freebuf(p_multi_inst_cb->data.p_service_data->p_val);
543        GKI_freebuf(p_multi_inst_cb->data.p_service_data);
544    }
545
546    if (p_multi_inst_cb->data.p_services_128b != NULL)
547        GKI_freebuf(p_multi_inst_cb->data.p_services_128b);
548
549    if (p_multi_inst_cb->data.p_service_32b != NULL)
550    {
551        if (p_multi_inst_cb->data.p_service_32b->p_uuid != NULL)
552           GKI_freebuf(p_multi_inst_cb->data.p_service_32b->p_uuid);
553        GKI_freebuf(p_multi_inst_cb->data.p_service_32b);
554    }
555
556    if (p_multi_inst_cb->data.p_sol_services != NULL)
557    {
558        if (p_multi_inst_cb->data.p_sol_services->p_uuid != NULL)
559           GKI_freebuf(p_multi_inst_cb->data.p_sol_services->p_uuid);
560        GKI_freebuf(p_multi_inst_cb->data.p_sol_services);
561    }
562
563    if (p_multi_inst_cb->data.p_sol_service_32b != NULL)
564    {
565        if (p_multi_inst_cb->data.p_sol_service_32b->p_uuid != NULL)
566           GKI_freebuf(p_multi_inst_cb->data.p_sol_service_32b->p_uuid);
567        GKI_freebuf(p_multi_inst_cb->data.p_sol_service_32b);
568    }
569
570    if (p_multi_inst_cb->data.p_sol_service_128b != NULL)
571        GKI_freebuf(p_multi_inst_cb->data.p_sol_service_128b);
572}
573
574void btif_multi_adv_timer_ctrl(int client_if, TIMER_CBACK cb)
575{
576    int inst_id = btif_multi_adv_instid_for_clientif(client_if);
577    if (inst_id == INVALID_ADV_INST)
578        return;
579
580    int cbindex = btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
581    if (cbindex == INVALID_ADV_INST)
582        return;
583
584    btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
585    if (p_multi_adv_data_cb == NULL)
586        return;
587
588    if (cb == NULL)
589    {
590        if (p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.in_use)
591            btu_stop_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer);
592    } else {
593        if (p_multi_adv_data_cb->inst_cb[cbindex].timeout_s != 0)
594        {
595            if (p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.in_use)
596                btu_stop_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer);
597
598            memset(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer, 0, sizeof(TIMER_LIST_ENT));
599            p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.param = (UINT32)cb;
600            p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.data = (UINT32)client_if;
601            btu_start_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer,
602                    BTU_TTYPE_USER_FUNC, p_multi_adv_data_cb->inst_cb[cbindex].timeout_s);
603        }
604    }
605}
606
607#endif
608