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