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
btif_obtain_multi_adv_data_cb()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
btif_gattc_incr_app_count(void)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
btif_gattc_decr_app_count(void)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
btif_multi_adv_add_instid_map(int client_if,int inst_id,BOOLEAN gen_temp_instid)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
btif_multi_adv_instid_for_clientif(int client_if)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
btif_gattc_obtain_idx_for_datacb(int value,int clnt_inst_index)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
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)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
btif_gattc_adv_data_cleanup(const btif_adv_data_t * adv)255 void btif_gattc_adv_data_cleanup(const btif_adv_data_t* adv)
256 {
257 if (adv->p_service_data)
258 GKI_freebuf(adv->p_service_data);
259
260 if (adv->p_service_uuid)
261 GKI_freebuf(adv->p_service_uuid);
262
263 if (adv->p_manufacturer_data)
264 GKI_freebuf(adv->p_manufacturer_data);
265 }
266
267
btif_gattc_copy_datacb(int cbindex,const btif_adv_data_t * p_adv_data,BOOLEAN bInstData)268 BOOLEAN btif_gattc_copy_datacb(int cbindex, const btif_adv_data_t *p_adv_data,
269 BOOLEAN bInstData) {
270 btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
271 if (NULL == p_multi_adv_data_cb || cbindex < 0)
272 return false;
273
274 BTIF_TRACE_DEBUG("%s", __FUNCTION__);
275 memset(&p_multi_adv_data_cb->inst_cb[cbindex].data, 0, sizeof(tBTA_BLE_ADV_DATA));
276 p_multi_adv_data_cb->inst_cb[cbindex].mask = 0;
277
278 p_multi_adv_data_cb->inst_cb[cbindex].is_scan_rsp = p_adv_data->set_scan_rsp ? 1 : 0;
279 if (!p_adv_data->set_scan_rsp)
280 {
281 p_multi_adv_data_cb->inst_cb[cbindex].mask = BTM_BLE_AD_BIT_FLAGS;
282 p_multi_adv_data_cb->inst_cb[cbindex].data.flag = ADV_FLAGS_GENERAL;
283 if (p_multi_adv_data_cb->inst_cb[cbindex].timeout_s)
284 p_multi_adv_data_cb->inst_cb[cbindex].data.flag = ADV_FLAGS_LIMITED;
285 if (p_multi_adv_data_cb->inst_cb[cbindex].param.adv_type == BTA_BLE_NON_CONNECT_EVT)
286 p_multi_adv_data_cb->inst_cb[cbindex].data.flag &=
287 ~(BTA_DM_LIMITED_DISC | BTA_DM_GENERAL_DISC);
288 if (p_multi_adv_data_cb->inst_cb[cbindex].data.flag == 0)
289 p_multi_adv_data_cb->inst_cb[cbindex].mask = 0;
290 }
291
292 if (p_adv_data->include_name)
293 p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_DEV_NAME;
294
295 if (p_adv_data->include_txpower)
296 p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_TX_PWR;
297
298 if (false == bInstData && p_adv_data->min_interval > 0 && p_adv_data->max_interval > 0 &&
299 p_adv_data->max_interval > p_adv_data->min_interval)
300 {
301 p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_INT_RANGE;
302 p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.low =
303 p_adv_data->min_interval;
304 p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.hi =
305 p_adv_data->max_interval;
306 }
307 else
308 if (true == bInstData)
309 {
310 if (p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min > 0 &&
311 p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max > 0 &&
312 p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max >
313 p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min)
314 {
315 p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.low =
316 p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_min;
317 p_multi_adv_data_cb->inst_cb[cbindex].data.int_range.hi =
318 p_multi_adv_data_cb->inst_cb[cbindex].param.adv_int_max;
319 }
320
321 if (p_adv_data->include_txpower)
322 {
323 p_multi_adv_data_cb->inst_cb[cbindex].data.tx_power =
324 p_multi_adv_data_cb->inst_cb[cbindex].param.tx_power;
325 }
326 }
327
328 if (p_adv_data->appearance != 0)
329 {
330 p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_APPEARANCE;
331 p_multi_adv_data_cb->inst_cb[cbindex].data.appearance = p_adv_data->appearance;
332 }
333
334 if (p_adv_data->manufacturer_len > 0 && p_adv_data->p_manufacturer_data != NULL)
335 {
336 p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu =
337 GKI_getbuf(sizeof(tBTA_BLE_MANU));
338 if (p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu != NULL)
339 {
340 p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->p_val =
341 GKI_getbuf(p_adv_data->manufacturer_len);
342 if (p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->p_val != NULL)
343 {
344 p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_MANU;
345 p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->len =
346 p_adv_data->manufacturer_len;
347 memcpy(p_multi_adv_data_cb->inst_cb[cbindex].data.p_manu->p_val,
348 p_adv_data->p_manufacturer_data, p_adv_data->manufacturer_len);
349 }
350 }
351 }
352
353 tBTA_BLE_PROP_ELEM *p_elem_service_data = NULL;
354 if (p_adv_data->service_data_len > 0 && p_adv_data->p_service_data != NULL)
355 {
356 BTIF_TRACE_DEBUG("%s - In service_data", __FUNCTION__);
357 p_elem_service_data = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM));
358 if (p_elem_service_data != NULL)
359 {
360 p_elem_service_data->p_val = GKI_getbuf(p_adv_data->service_data_len);
361 if (p_elem_service_data->p_val != NULL)
362 {
363 p_elem_service_data->adv_type = BTM_BLE_AD_TYPE_SERVICE_DATA;
364 p_elem_service_data->len = p_adv_data->service_data_len;
365 memcpy(p_elem_service_data->p_val, p_adv_data->p_service_data,
366 p_adv_data->service_data_len);
367 } else {
368 GKI_freebuf(p_elem_service_data);
369 p_elem_service_data = NULL;
370 }
371 }
372 }
373
374 if (NULL != p_elem_service_data)
375 {
376 p_multi_adv_data_cb->inst_cb[cbindex].data.p_proprietary =
377 GKI_getbuf(sizeof(tBTA_BLE_PROPRIETARY));
378 if (NULL != p_multi_adv_data_cb->inst_cb[cbindex].data.p_proprietary)
379 {
380 tBTA_BLE_PROP_ELEM *p_elem = NULL;
381 tBTA_BLE_PROPRIETARY *p_prop = p_multi_adv_data_cb->inst_cb[cbindex].data.p_proprietary;
382 p_prop->num_elem = 0;
383 p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_PROPRIETARY;
384 p_prop->num_elem = 1;
385 p_prop->p_elem = GKI_getbuf(sizeof(tBTA_BLE_PROP_ELEM) * p_prop->num_elem);
386 p_elem = p_prop->p_elem;
387 if (NULL != p_elem)
388 memcpy(p_elem++, p_elem_service_data, sizeof(tBTA_BLE_PROP_ELEM));
389 GKI_freebuf(p_elem_service_data);
390 }
391 }
392
393 if (p_adv_data->service_uuid_len && p_adv_data->p_service_uuid)
394 {
395 UINT16 *p_uuid_out16 = NULL;
396 UINT32 *p_uuid_out32 = NULL;
397 for (int position = 0; position < p_adv_data->service_uuid_len; position += LEN_UUID_128)
398 {
399 bt_uuid_t uuid;
400 memset(&uuid, 0, sizeof(uuid));
401 memcpy(&uuid.uu, p_adv_data->p_service_uuid + position, LEN_UUID_128);
402
403 tBT_UUID bt_uuid;
404 memset(&bt_uuid, 0, sizeof(bt_uuid));
405 btif_to_bta_uuid(&bt_uuid, &uuid);
406
407 switch(bt_uuid.len)
408 {
409 case (LEN_UUID_16):
410 {
411 if (NULL == p_multi_adv_data_cb->inst_cb[cbindex].data.p_services)
412 {
413 p_multi_adv_data_cb->inst_cb[cbindex].data.p_services =
414 GKI_getbuf(sizeof(tBTA_BLE_SERVICE));
415 p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->list_cmpl = FALSE;
416 p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->num_service = 0;
417 p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->p_uuid =
418 GKI_getbuf(p_adv_data->service_uuid_len / LEN_UUID_128 * LEN_UUID_16);
419 p_uuid_out16 = p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->p_uuid;
420 }
421
422 if (NULL != p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->p_uuid)
423 {
424 BTIF_TRACE_DEBUG("%s - In 16-UUID_data", __FUNCTION__);
425 p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_SERVICE;
426 ++p_multi_adv_data_cb->inst_cb[cbindex].data.p_services->num_service;
427 *p_uuid_out16++ = bt_uuid.uu.uuid16;
428 }
429 break;
430 }
431
432 case (LEN_UUID_32):
433 {
434 if (NULL == p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b)
435 {
436 p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b =
437 GKI_getbuf(sizeof(tBTA_BLE_32SERVICE));
438 p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b->list_cmpl = FALSE;
439 p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b->num_service = 0;
440 p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b->p_uuid =
441 GKI_getbuf(p_adv_data->service_uuid_len / LEN_UUID_128 * LEN_UUID_32);
442 p_uuid_out32 = p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b->p_uuid;
443 }
444
445 if (NULL != p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b->p_uuid)
446 {
447 BTIF_TRACE_DEBUG("%s - In 32-UUID_data", __FUNCTION__);
448 p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_SERVICE_32;
449 ++p_multi_adv_data_cb->inst_cb[cbindex].data.p_service_32b->num_service;
450 *p_uuid_out32++ = bt_uuid.uu.uuid32;
451 }
452 break;
453 }
454
455 case (LEN_UUID_128):
456 {
457 /* Currently, only one 128-bit UUID is supported */
458 if (NULL == p_multi_adv_data_cb->inst_cb[cbindex].data.p_services_128b)
459 {
460 p_multi_adv_data_cb->inst_cb[cbindex].data.p_services_128b =
461 GKI_getbuf(sizeof(tBTA_BLE_128SERVICE));
462 if (NULL != p_multi_adv_data_cb->inst_cb[cbindex].data.p_services_128b)
463 {
464 BTIF_TRACE_DEBUG("%s - In 128-UUID_data", __FUNCTION__);
465 p_multi_adv_data_cb->inst_cb[cbindex].mask |= BTM_BLE_AD_BIT_SERVICE_128;
466 memcpy(p_multi_adv_data_cb->inst_cb[cbindex].data.p_services_128b->uuid128,
467 bt_uuid.uu.uuid128, LEN_UUID_128);
468 BTIF_TRACE_DEBUG("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x", bt_uuid.uu.uuid128[0],
469 bt_uuid.uu.uuid128[1],bt_uuid.uu.uuid128[2], bt_uuid.uu.uuid128[3],
470 bt_uuid.uu.uuid128[4],bt_uuid.uu.uuid128[5],bt_uuid.uu.uuid128[6],
471 bt_uuid.uu.uuid128[7],bt_uuid.uu.uuid128[8],bt_uuid.uu.uuid128[9],
472 bt_uuid.uu.uuid128[10],bt_uuid.uu.uuid128[11],bt_uuid.uu.uuid128[12],
473 bt_uuid.uu.uuid128[13],bt_uuid.uu.uuid128[14],bt_uuid.uu.uuid128[15]);
474 p_multi_adv_data_cb->inst_cb[cbindex].data.p_services_128b->list_cmpl = TRUE;
475 }
476 }
477 break;
478 }
479
480 default:
481 break;
482 }
483 }
484 }
485
486 return true;
487 }
488
btif_gattc_clear_clientif(int client_if,BOOLEAN stop_timer)489 void btif_gattc_clear_clientif(int client_if, BOOLEAN stop_timer)
490 {
491 btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
492 if (NULL == p_multi_adv_data_cb)
493 return;
494
495 // Clear both the inst_id and client_if values
496 for (int i=0; i < BTM_BleMaxMultiAdvInstanceCount()*2; i+=2)
497 {
498 if (client_if == p_multi_adv_data_cb->clntif_map[i])
499 {
500 btif_gattc_cleanup_inst_cb(p_multi_adv_data_cb->clntif_map[i+1], stop_timer);
501 if (stop_timer)
502 {
503 p_multi_adv_data_cb->clntif_map[i] = INVALID_ADV_INST;
504 p_multi_adv_data_cb->clntif_map[i+1] = INVALID_ADV_INST;
505 BTIF_TRACE_DEBUG("Cleaning up index %d for clnt_if :%d,", i/2, client_if);
506 }
507 break;
508 }
509 }
510 }
511
btif_gattc_cleanup_inst_cb(int inst_id,BOOLEAN stop_timer)512 void btif_gattc_cleanup_inst_cb(int inst_id, BOOLEAN stop_timer)
513 {
514 // Check for invalid instance id
515 if (inst_id < 0 || inst_id >= BTM_BleMaxMultiAdvInstanceCount())
516 return;
517
518 btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
519 if (NULL == p_multi_adv_data_cb)
520 return;
521
522 int cbindex = (STD_ADV_INSTID == inst_id) ?
523 STD_ADV_INSTID : btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
524 if (cbindex < 0) return;
525
526 BTIF_TRACE_DEBUG("Cleaning up multi_inst_cb for inst_id %d, cbindex %d", inst_id, cbindex);
527 btif_gattc_cleanup_multi_inst_cb(&p_multi_adv_data_cb->inst_cb[cbindex], stop_timer);
528 }
529
btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb * p_multi_inst_cb,BOOLEAN stop_timer)530 void btif_gattc_cleanup_multi_inst_cb(btgatt_multi_adv_inst_cb *p_multi_inst_cb,
531 BOOLEAN stop_timer)
532 {
533 if (p_multi_inst_cb == NULL)
534 return;
535
536 // Discoverability timer cleanup
537 if (stop_timer)
538 {
539 if (p_multi_inst_cb->tle_limited_timer.in_use)
540 btu_stop_timer_oneshot(&p_multi_inst_cb->tle_limited_timer);
541 p_multi_inst_cb->tle_limited_timer.in_use = 0;
542 }
543
544 // Manufacturer data cleanup
545 if (p_multi_inst_cb->data.p_manu != NULL)
546 {
547 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_manu->p_val);
548 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_manu);
549 }
550
551 // Proprietary data cleanup
552 if (p_multi_inst_cb->data.p_proprietary != NULL)
553 {
554 int i = 0;
555 tBTA_BLE_PROP_ELEM *p_elem = p_multi_inst_cb->data.p_proprietary->p_elem;
556 while (i++ != p_multi_inst_cb->data.p_proprietary->num_elem
557 && p_elem)
558 {
559 btif_gattc_cleanup((void**) &p_elem->p_val);
560 ++p_elem;
561 }
562
563 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_proprietary->p_elem);
564 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_proprietary);
565 }
566
567 // Service list cleanup
568 if (p_multi_inst_cb->data.p_services != NULL)
569 {
570 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_services->p_uuid);
571 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_services);
572 }
573
574 // Service data cleanup
575 if (p_multi_inst_cb->data.p_service_data != NULL)
576 {
577 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_data->p_val);
578 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_data);
579 }
580
581 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_services_128b);
582
583 if (p_multi_inst_cb->data.p_service_32b != NULL)
584 {
585 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_32b->p_uuid);
586 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_service_32b);
587 }
588
589 if (p_multi_inst_cb->data.p_sol_services != NULL)
590 {
591 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_services->p_uuid);
592 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_services);
593 }
594
595 if (p_multi_inst_cb->data.p_sol_service_32b != NULL)
596 {
597 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_service_32b->p_uuid);
598 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_service_32b);
599 }
600
601 btif_gattc_cleanup((void**) &p_multi_inst_cb->data.p_sol_service_128b);
602 }
603
btif_gattc_cleanup(void ** buf)604 void btif_gattc_cleanup(void** buf)
605 {
606 if (NULL == *buf) return;
607 GKI_freebuf(*buf);
608 *buf = NULL;
609 }
610
btif_multi_adv_timer_ctrl(int client_if,TIMER_CBACK cb)611 void btif_multi_adv_timer_ctrl(int client_if, TIMER_CBACK cb)
612 {
613 int inst_id = btif_multi_adv_instid_for_clientif(client_if);
614 if (inst_id == INVALID_ADV_INST)
615 return;
616
617 int cbindex = btif_gattc_obtain_idx_for_datacb(inst_id, INST_ID_IDX);
618 if (cbindex == INVALID_ADV_INST)
619 return;
620
621 btgatt_multi_adv_common_data *p_multi_adv_data_cb = btif_obtain_multi_adv_data_cb();
622 if (p_multi_adv_data_cb == NULL)
623 return;
624
625 if (cb == NULL)
626 {
627 if (p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.in_use)
628 btu_stop_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer);
629 } else {
630 if (p_multi_adv_data_cb->inst_cb[cbindex].timeout_s != 0)
631 {
632 if (p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.in_use)
633 btu_stop_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer);
634
635 memset(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer, 0, sizeof(TIMER_LIST_ENT));
636 p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.param = (UINT32)cb;
637 p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer.data = (UINT32)client_if;
638 btu_start_timer_oneshot(&p_multi_adv_data_cb->inst_cb[cbindex].tle_limited_timer,
639 BTU_TTYPE_USER_FUNC, p_multi_adv_data_cb->inst_cb[cbindex].timeout_s);
640 }
641 }
642 }
643
644 #endif
645