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