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