OSDN Git Service

am f29a2fb..e07ad10 from mirror-m-wireless-internal-release
[android-x86/system-bt.git] / btif / src / btif_gatt_multi_adv_util.c
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 <string.h>
31 #include "btu.h"
32 #include "bt_target.h"
33
34 #define LOG_TAG "bt_btif_gatt"
35 #if (BLE_INCLUDED == TRUE)
36
37 #include "btif_gatt_multi_adv_util.h"
38 #include "btif_common.h"
39 #include <hardware/bt_gatt.h>
40 #include "bta_gatt_api.h"
41 #include "btif_gatt_util.h"
42
43 /*******************************************************************************
44 **  Static variables
45 ********************************************************************************/
46 static int user_app_count = 0;
47 static btgatt_multi_adv_common_data *p_multi_adv_com_data_cb = NULL;
48
49 btgatt_multi_adv_common_data *btif_obtain_multi_adv_data_cb()
50 {
51     int max_adv_inst = BTM_BleMaxMultiAdvInstanceCount();
52     if (0 == max_adv_inst)
53         max_adv_inst = 1;
54
55     BTIF_TRACE_DEBUG("%s, Count:%d", __FUNCTION__, max_adv_inst);
56
57     if (NULL == p_multi_adv_com_data_cb)
58     {
59         p_multi_adv_com_data_cb = GKI_getbuf(sizeof(btgatt_multi_adv_common_data));
60         if (NULL != p_multi_adv_com_data_cb)
61         {
62             memset(p_multi_adv_com_data_cb, 0, sizeof(btgatt_multi_adv_common_data));
63
64             /* Storing both client_if and inst_id details */
65             p_multi_adv_com_data_cb->clntif_map =
66                   GKI_getbuf(( max_adv_inst * INST_ID_IDX_MAX)* sizeof(INT8));
67             memset(p_multi_adv_com_data_cb->clntif_map, 0 ,
68                   ( max_adv_inst * INST_ID_IDX_MAX)* sizeof(INT8));
69
70             p_multi_adv_com_data_cb->inst_cb = GKI_getbuf(( max_adv_inst + 1 )
71                                               * sizeof(btgatt_multi_adv_inst_cb));
72             memset(p_multi_adv_com_data_cb->inst_cb, 0 ,
73                  ( max_adv_inst + 1) * sizeof(btgatt_multi_adv_inst_cb));
74
75             for (int i=0; i < max_adv_inst * 2; i += 2)
76             {
77                 p_multi_adv_com_data_cb->clntif_map[i] = INVALID_ADV_INST;
78                 p_multi_adv_com_data_cb->clntif_map[i+1] = INVALID_ADV_INST;
79             }
80         }
81     }
82
83     return p_multi_adv_com_data_cb;
84 }
85
86 void btif_gattc_incr_app_count(void)
87 {
88     // TODO: Instead of using a fragile reference counter here, one could
89     //       simply track the client_if instances that are in the map.
90     ++user_app_count;
91 }
92
93 void btif_gattc_decr_app_count(void)
94 {
95     if (user_app_count > 0)
96         user_app_count --;
97
98     if(user_app_count == 0 && NULL != p_multi_adv_com_data_cb)
99     {
100        GKI_freebuf (p_multi_adv_com_data_cb->clntif_map);
101        GKI_freebuf (p_multi_adv_com_data_cb->inst_cb);
102        GKI_freebuf(p_multi_adv_com_data_cb);
103        p_multi_adv_com_data_cb = NULL;
104     }
105 }
106
107 int btif_multi_adv_add_instid_map(int client_if, int inst_id, BOOLEAN gen_temp_instid)
108 {
109     int i=1;
110
111     btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
112     if (NULL == p_multi_adv_data_cb)
113         return INVALID_ADV_INST;
114
115     for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
116     {
117        if (client_if == p_multi_adv_data_cb->clntif_map[i + i])
118        {
119           if (!gen_temp_instid)
120           {
121              // Write the final inst_id value obtained from stack layer
122              p_multi_adv_data_cb->clntif_map[i + (i + 1)] = inst_id;
123              BTIF_TRACE_DEBUG("%s -Index: %d, Found client_if: %d", __FUNCTION__,
124                 i, p_multi_adv_data_cb->clntif_map[i + i]);
125              break;
126           }
127           else
128           {
129               //Store the passed in inst_id value
130              if (inst_id != INVALID_ADV_INST)
131                  p_multi_adv_data_cb->clntif_map[i + (i + 1)] = inst_id;
132              else
133                  p_multi_adv_data_cb->clntif_map[i + (i + 1)] = (i + 1);
134
135              BTIF_TRACE_DEBUG("%s - Index:%d,Found client_if: %d", __FUNCTION__,
136                 i, p_multi_adv_data_cb->clntif_map[i + i]);
137              break;
138           }
139        }
140     }
141
142     if (i <  BTM_BleMaxMultiAdvInstanceCount())
143         return i;
144
145     // If client ID if is not found, then write both values
146     for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
147     {
148         if (INVALID_ADV_INST == p_multi_adv_data_cb->clntif_map[i + i])
149         {
150             p_multi_adv_data_cb->clntif_map[i + i] = client_if;
151             if (inst_id != INVALID_ADV_INST)
152                p_multi_adv_data_cb->clntif_map[i + (i + 1)] = inst_id;
153             else
154                 p_multi_adv_data_cb->clntif_map[i + (i + 1)] = (i + 1);
155             BTIF_TRACE_DEBUG("%s -Not found - Index:%d, client_if: %d, Inst ID: %d",
156                             __FUNCTION__,i,
157                             p_multi_adv_data_cb->clntif_map[i + i],
158                             p_multi_adv_data_cb->clntif_map[i + (i + 1)]);
159             break;
160         }
161     }
162
163     if (i <  BTM_BleMaxMultiAdvInstanceCount())
164         return i;
165     return INVALID_ADV_INST;
166 }
167
168 int btif_multi_adv_instid_for_clientif(int client_if)
169 {
170     int i=1, ret = INVALID_ADV_INST;
171
172     btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
173
174     if (NULL == p_multi_adv_data_cb)
175         return INVALID_ADV_INST;
176
177     // Retrieve the existing inst_id for the client_if value
178     for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
179     {
180        if (client_if == p_multi_adv_data_cb->clntif_map[i + i])
181        {
182            BTIF_TRACE_DEBUG("%s - Client if found", __FUNCTION__, client_if);
183            ret = p_multi_adv_data_cb->clntif_map[i + (i + 1)];
184        }
185     }
186
187     return ret;
188 }
189
190 int btif_gattc_obtain_idx_for_datacb(int value, int clnt_inst_index)
191 {
192     int i=1;
193
194     btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
195
196     if (NULL == p_multi_adv_data_cb)
197         return INVALID_ADV_INST;
198
199     // Retrieve the array index for the inst_id value
200     for (i=1; i <  BTM_BleMaxMultiAdvInstanceCount(); i++)
201     {
202        if (value == p_multi_adv_data_cb->clntif_map[i + (i + clnt_inst_index)])
203            break;
204     }
205
206     if (i <  BTM_BleMaxMultiAdvInstanceCount())
207     {
208         BTIF_TRACE_DEBUG("%s, %d",__FUNCTION__,i);
209         return i;
210     }
211
212     BTIF_TRACE_DEBUG("%s Invalid instance",__FUNCTION__);
213     return INVALID_ADV_INST;
214 }
215
216
217 void btif_gattc_adv_data_packager(int client_if, bool set_scan_rsp,
218                 bool include_name, bool include_txpower, int min_interval, int max_interval,
219                 int appearance, int manufacturer_len, char* manufacturer_data,
220                 int service_data_len, char* service_data, int service_uuid_len,
221                 char* service_uuid, btif_adv_data_t *p_multi_adv_inst)
222 {
223     memset(p_multi_adv_inst, 0 , sizeof(btif_adv_data_t));
224
225     p_multi_adv_inst->client_if = (uint8_t) client_if;
226     p_multi_adv_inst->set_scan_rsp = set_scan_rsp;
227     p_multi_adv_inst->include_name = include_name;
228     p_multi_adv_inst->include_txpower = include_txpower;
229     p_multi_adv_inst->min_interval = min_interval;
230     p_multi_adv_inst->max_interval = max_interval;
231     p_multi_adv_inst->appearance = appearance;
232     p_multi_adv_inst->manufacturer_len = manufacturer_len;
233
234     if (manufacturer_len > 0)
235     {
236         p_multi_adv_inst->p_manufacturer_data = GKI_getbuf(manufacturer_len);
237         memcpy(p_multi_adv_inst->p_manufacturer_data, manufacturer_data, manufacturer_len);
238     }
239
240     p_multi_adv_inst->service_data_len = service_data_len;
241     if (service_data_len > 0)
242     {
243         p_multi_adv_inst->p_service_data = GKI_getbuf(service_data_len);
244         memcpy(p_multi_adv_inst->p_service_data, service_data, service_data_len);
245     }
246
247     p_multi_adv_inst->service_uuid_len = service_uuid_len;
248     if (service_uuid_len > 0)
249     {
250         p_multi_adv_inst->p_service_uuid = GKI_getbuf(service_uuid_len);
251         memcpy(p_multi_adv_inst->p_service_uuid, service_uuid, service_uuid_len);
252     }
253 }
254
255 BOOLEAN btif_gattc_copy_datacb(int cbindex, btif_adv_data_t *p_adv_data, BOOLEAN bInstData)
256 {
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      return true;
477 }
478
479 void btif_gattc_clear_clientif(int client_if, BOOLEAN stop_timer)
480 {
481     btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
482     if (NULL == p_multi_adv_data_cb)
483         return;
484
485     // Clear both the inst_id and client_if values
486     for (int i=0; i < BTM_BleMaxMultiAdvInstanceCount()*2; i+=2)
487     {
488         if (client_if == p_multi_adv_data_cb->clntif_map[i])
489         {
490             btif_gattc_cleanup_inst_cb(p_multi_adv_data_cb->clntif_map[i+1], stop_timer);
491             if (stop_timer)
492             {
493                 p_multi_adv_data_cb->clntif_map[i] = INVALID_ADV_INST;
494                 p_multi_adv_data_cb->clntif_map[i+1] = INVALID_ADV_INST;
495                 BTIF_TRACE_DEBUG("Cleaning up index %d for clnt_if :%d,", i/2, client_if);
496             }
497             break;
498         }
499     }
500 }
501
502 void btif_gattc_cleanup_inst_cb(int inst_id, BOOLEAN stop_timer)
503 {
504     // Check for invalid instance id
505     if (inst_id < 0 || inst_id >= BTM_BleMaxMultiAdvInstanceCount())
506         return;
507
508     btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
509     if (NULL == p_multi_adv_data_cb)
510         return;
511
512     int cbindex = (STD_ADV_INSTID == inst_id) ?
513         STD_ADV_INSTID : btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
514     if (cbindex < 0) return;
515
516     BTIF_TRACE_DEBUG("Cleaning up multi_inst_cb for inst_id %d, cbindex %d", inst_id, cbindex);
517     btif_gattc_cleanup_multi_inst_cb(&p_multi_adv_data_cb->inst_cb[cbindex], stop_timer);
518 }
519
520 void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_multi_inst_cb,
521                                              BOOLEAN stop_timer)
522 {
523     if (p_multi_inst_cb == NULL)
524         return;
525
526     // Discoverability timer cleanup
527     if (stop_timer)
528     {
529         if (p_multi_inst_cb->tle_limited_timer.in_use)
530             btu_stop_timer_oneshot(&p_multi_inst_cb->tle_limited_timer);
531         p_multi_inst_cb->tle_limited_timer.in_use = 0;
532     }
533
534     // Manufacturer data cleanup
535     if (p_multi_inst_cb->data.p_manu != NULL)
536     {
537         btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_manu->p_val);
538         btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_manu);
539     }
540
541     // Proprietary data cleanup
542     if (p_multi_inst_cb->data.p_proprietary != NULL)
543     {
544         int i = 0;
545         tBTA_BLE_PROP_ELEM *p_elem = p_multi_inst_cb->data.p_proprietary->p_elem;
546         while (i++ != p_multi_inst_cb->data.p_proprietary->num_elem
547             && p_elem)
548         {
549             btif_gattc_cleanup((void**) &p_elem->p_val);
550             ++p_elem;
551         }
552
553         btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_proprietary->p_elem);
554         btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_proprietary);
555     }
556
557     // Service list cleanup
558     if (p_multi_inst_cb->data.p_services != NULL)
559     {
560         btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_services->p_uuid);
561         btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_services);
562     }
563
564     // Service data cleanup
565     if (p_multi_inst_cb->data.p_service_data != NULL)
566     {
567         btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_data->p_val);
568         btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_data);
569     }
570
571     btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_services_128b);
572
573     if (p_multi_inst_cb->data.p_service_32b != NULL)
574     {
575         btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_32b->p_uuid);
576         btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_32b);
577     }
578
579     if (p_multi_inst_cb->data.p_sol_services != NULL)
580     {
581         btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_services->p_uuid);
582         btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_services);
583     }
584
585     if (p_multi_inst_cb->data.p_sol_service_32b != NULL)
586     {
587         btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_service_32b->p_uuid);
588         btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_service_32b);
589     }
590
591     btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_service_128b);
592 }
593
594 void btif_gattc_cleanup(void** buf)
595 {
596    if (NULL == *buf) return;
597    GKI_freebuf(*buf);
598    *buf = NULL;
599 }
600
601 void btif_multi_adv_timer_ctrl(int client_if, TIMER_CBACK cb)
602 {
603     int inst_id = btif_multi_adv_instid_for_clientif(client_if);
604     if (inst_id == INVALID_ADV_INST)
605         return;
606
607     int cbindex = btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
608     if (cbindex == INVALID_ADV_INST)
609         return;
610
611     btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
612     if (p_multi_adv_data_cb == NULL)
613         return;
614
615     if (cb == NULL)
616     {
617         if (p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.in_use)
618             btu_stop_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer);
619     } else {
620         if (p_multi_adv_data_cb->inst_cb[cbindex].timeout_s != 0)
621         {
622             if (p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.in_use)
623                 btu_stop_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer);
624
625             memset(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer, 0, sizeof(TIMER_LIST_ENT));
626             p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.param = (UINT32)cb;
627             p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.data = (UINT32)client_if;
628             btu_start_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer,
629                     BTU_TTYPE_USER_FUNC, p_multi_adv_data_cb->inst_cb[cbindex].timeout_s);
630         }
631     }
632 }
633
634 #endif