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 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 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 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 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 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 604 void btif_gattc_cleanup(void** buf) 605 { 606 if (NULL == *buf) return; 607 GKI_freebuf(*buf); 608 *buf = NULL; 609 } 610 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