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