1 /****************************************************************************** 2 * 3 * Copyright (C) 1999-2012 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 * This file contains functions for BLE controller based privacy. 22 * 23 ******************************************************************************/ 24 #include <string.h> 25 #include "bt_target.h" 26 27 #if (BLE_PRIVACY_SPT == TRUE) 28 #include "bt_types.h" 29 #include "btm_int.h" 30 #include "btu.h" 31 #include "device/include/controller.h" 32 #include "hcimsgs.h" 33 #include "vendor_hcidefs.h" 34 35 /* RPA offload VSC specifics */ 36 #define BTM_BLE_META_IRK_ENABLE 0x01 37 #define BTM_BLE_META_ADD_IRK_ENTRY 0x02 38 #define BTM_BLE_META_REMOVE_IRK_ENTRY 0x03 39 #define BTM_BLE_META_CLEAR_IRK_LIST 0x04 40 #define BTM_BLE_META_READ_IRK_ENTRY 0x05 41 #define BTM_BLE_META_CS_RESOLVE_ADDR 0x00000001 42 #define BTM_BLE_IRK_ENABLE_LEN 2 43 44 #define BTM_BLE_META_ADD_IRK_LEN 24 45 #define BTM_BLE_META_REMOVE_IRK_LEN 8 46 #define BTM_BLE_META_CLEAR_IRK_LEN 1 47 #define BTM_BLE_META_READ_IRK_LEN 2 48 #define BTM_BLE_META_ADD_WL_ATTR_LEN 9 49 50 /******************************************************************************* 51 * Functions implemented controller based privacy using Resolving List 52 ******************************************************************************/ 53 /******************************************************************************* 54 * 55 * Function btm_ble_enq_resolving_list_pending 56 * 57 * Description add target address into resolving pending operation queue 58 * 59 * Parameters target_bda: target device address 60 * add_entry: true for add entry, false for remove entry 61 * 62 * Returns void 63 * 64 ******************************************************************************/ 65 void btm_ble_enq_resolving_list_pending(BD_ADDR pseudo_bda, uint8_t op_code) { 66 tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q; 67 68 memcpy(p_q->resolve_q_random_pseudo[p_q->q_next], pseudo_bda, BD_ADDR_LEN); 69 p_q->resolve_q_action[p_q->q_next] = op_code; 70 p_q->q_next++; 71 p_q->q_next %= controller_get_interface()->get_ble_resolving_list_max_size(); 72 } 73 74 /******************************************************************************* 75 * 76 * Function btm_ble_brcm_find_resolving_pending_entry 77 * 78 * Description check to see if the action is in pending list 79 * 80 * Parameters true: action pending; 81 * false: new action 82 * 83 * Returns void 84 * 85 ******************************************************************************/ 86 bool btm_ble_brcm_find_resolving_pending_entry(BD_ADDR pseudo_addr, 87 uint8_t action) { 88 tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q; 89 90 for (uint8_t i = p_q->q_pending; i != p_q->q_next;) { 91 if (memcmp(p_q->resolve_q_random_pseudo[i], pseudo_addr, BD_ADDR_LEN) == 92 0 && 93 action == p_q->resolve_q_action[i]) 94 return true; 95 96 i++; 97 i %= controller_get_interface()->get_ble_resolving_list_max_size(); 98 } 99 return false; 100 } 101 102 /******************************************************************************* 103 * 104 * Function btm_ble_deq_resolving_pending 105 * 106 * Description dequeue target address from resolving pending operation 107 * queue 108 * 109 * Parameters pseudo_addr: pseudo_addr device address 110 * 111 * Returns void 112 * 113 ******************************************************************************/ 114 bool btm_ble_deq_resolving_pending(BD_ADDR pseudo_addr) { 115 tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q; 116 117 if (p_q->q_next != p_q->q_pending) { 118 memcpy(pseudo_addr, p_q->resolve_q_random_pseudo[p_q->q_pending], 119 BD_ADDR_LEN); 120 memset(p_q->resolve_q_random_pseudo[p_q->q_pending], 0, BD_ADDR_LEN); 121 p_q->q_pending++; 122 p_q->q_pending %= 123 controller_get_interface()->get_ble_resolving_list_max_size(); 124 return true; 125 } 126 127 return false; 128 } 129 130 /******************************************************************************* 131 * 132 * Function btm_ble_clear_irk_index 133 * 134 * Description clear IRK list index mask for availability 135 * 136 * Returns none 137 * 138 ******************************************************************************/ 139 void btm_ble_clear_irk_index(uint8_t index) { 140 uint8_t byte; 141 uint8_t bit; 142 143 if (index < controller_get_interface()->get_ble_resolving_list_max_size()) { 144 byte = index / 8; 145 bit = index % 8; 146 btm_cb.ble_ctr_cb.irk_list_mask[byte] &= (~(1 << bit)); 147 } 148 } 149 150 /******************************************************************************* 151 * 152 * Function btm_ble_find_irk_index 153 * 154 * Description find the first available IRK list index 155 * 156 * Returns index from 0 ~ max (127 default) 157 * 158 ******************************************************************************/ 159 uint8_t btm_ble_find_irk_index(void) { 160 uint8_t i = 0; 161 uint8_t byte; 162 uint8_t bit; 163 164 while (i < controller_get_interface()->get_ble_resolving_list_max_size()) { 165 byte = i / 8; 166 bit = i % 8; 167 168 if ((btm_cb.ble_ctr_cb.irk_list_mask[byte] & (1 << bit)) == 0) { 169 btm_cb.ble_ctr_cb.irk_list_mask[byte] |= (1 << bit); 170 return i; 171 } 172 i++; 173 } 174 175 BTM_TRACE_ERROR("%s failed, list full", __func__); 176 return i; 177 } 178 179 /******************************************************************************* 180 * 181 * Function btm_ble_update_resolving_list 182 * 183 * Description update resolving list entry in host maintained record 184 * 185 * Returns void 186 * 187 ******************************************************************************/ 188 void btm_ble_update_resolving_list(BD_ADDR pseudo_bda, bool add) { 189 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(pseudo_bda); 190 if (p_dev_rec == NULL) return; 191 192 if (add) { 193 p_dev_rec->ble.in_controller_list |= BTM_RESOLVING_LIST_BIT; 194 if (!controller_get_interface()->supports_ble_privacy()) 195 p_dev_rec->ble.resolving_list_index = btm_ble_find_irk_index(); 196 } else { 197 p_dev_rec->ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT; 198 if (!controller_get_interface()->supports_ble_privacy()) { 199 /* clear IRK list index mask */ 200 btm_ble_clear_irk_index(p_dev_rec->ble.resolving_list_index); 201 p_dev_rec->ble.resolving_list_index = 0; 202 } 203 } 204 } 205 206 bool clear_resolving_list_bit(void* data, void* context) { 207 tBTM_SEC_DEV_REC* p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(data); 208 p_dev_rec->ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT; 209 return true; 210 } 211 212 /******************************************************************************* 213 * 214 * Function btm_ble_clear_resolving_list_complete 215 * 216 * Description This function is called when command complete for 217 * clear resolving list 218 * 219 * Returns void 220 * 221 ******************************************************************************/ 222 void btm_ble_clear_resolving_list_complete(uint8_t* p, uint16_t evt_len) { 223 uint8_t status = 0; 224 STREAM_TO_UINT8(status, p); 225 226 BTM_TRACE_DEBUG("%s status=%d", __func__, status); 227 228 if (status == HCI_SUCCESS) { 229 if (evt_len >= 3) { 230 /* VSC complete has one extra byte for op code and list size, skip it here 231 */ 232 p++; 233 234 /* updated the available list size, and current list size */ 235 uint8_t irk_list_sz_max = 0; 236 STREAM_TO_UINT8(irk_list_sz_max, p); 237 238 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) 239 btm_ble_resolving_list_init(irk_list_sz_max); 240 241 uint8_t irk_mask_size = (irk_list_sz_max % 8) ? (irk_list_sz_max / 8 + 1) 242 : (irk_list_sz_max / 8); 243 memset(btm_cb.ble_ctr_cb.irk_list_mask, 0, irk_mask_size); 244 } 245 246 btm_cb.ble_ctr_cb.resolving_list_avail_size = 247 controller_get_interface()->get_ble_resolving_list_max_size(); 248 249 BTM_TRACE_DEBUG("%s resolving_list_avail_size=%d", __func__, 250 btm_cb.ble_ctr_cb.resolving_list_avail_size); 251 252 list_foreach(btm_cb.sec_dev_rec, clear_resolving_list_bit, NULL); 253 } 254 } 255 256 /******************************************************************************* 257 * 258 * Function btm_ble_add_resolving_list_entry_complete 259 * 260 * Description This function is called when command complete for 261 * add resolving list entry 262 * 263 * Returns void 264 * 265 ******************************************************************************/ 266 void btm_ble_add_resolving_list_entry_complete(uint8_t* p, uint16_t evt_len) { 267 uint8_t status; 268 STREAM_TO_UINT8(status, p); 269 270 BTM_TRACE_DEBUG("%s status = %d", __func__, status); 271 272 BD_ADDR pseudo_bda; 273 if (!btm_ble_deq_resolving_pending(pseudo_bda)) { 274 BTM_TRACE_DEBUG("no pending resolving list operation"); 275 return; 276 } 277 278 if (status == HCI_SUCCESS) { 279 /* privacy 1.2 command complete does not have these extra byte */ 280 if (evt_len > 2) { 281 /* VSC complete has one extra byte for op code, skip it here */ 282 p++; 283 STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p); 284 } else 285 btm_cb.ble_ctr_cb.resolving_list_avail_size--; 286 } else if (status == 287 HCI_ERR_MEMORY_FULL) /* BT_ERROR_CODE_MEMORY_CAPACITY_EXCEEDED */ 288 { 289 btm_cb.ble_ctr_cb.resolving_list_avail_size = 0; 290 BTM_TRACE_DEBUG("%s Resolving list Full ", __func__); 291 } 292 } 293 294 /******************************************************************************* 295 * 296 * Function btm_ble_remove_resolving_list_entry_complete 297 * 298 * Description This function is called when command complete for 299 * remove resolving list entry 300 * 301 * Returns void 302 * 303 ******************************************************************************/ 304 void btm_ble_remove_resolving_list_entry_complete(uint8_t* p, 305 uint16_t evt_len) { 306 BD_ADDR pseudo_bda; 307 uint8_t status; 308 309 STREAM_TO_UINT8(status, p); 310 311 BTM_TRACE_DEBUG("%s status = %d", __func__, status); 312 313 if (!btm_ble_deq_resolving_pending(pseudo_bda)) { 314 BTM_TRACE_ERROR("%s no pending resolving list operation", __func__); 315 return; 316 } 317 318 if (status == HCI_SUCCESS) { 319 /* proprietary: spec does not have these extra bytes */ 320 if (evt_len > 2) { 321 p++; /* skip opcode */ 322 STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p); 323 } else 324 btm_cb.ble_ctr_cb.resolving_list_avail_size++; 325 } 326 } 327 328 /******************************************************************************* 329 * 330 * Function btm_ble_read_resolving_list_entry_complete 331 * 332 * Description This function is called when command complete for 333 * remove resolving list entry 334 * 335 * Returns void 336 * 337 ******************************************************************************/ 338 void btm_ble_read_resolving_list_entry_complete(uint8_t* p, uint16_t evt_len) { 339 uint8_t status, rra_type = BTM_BLE_ADDR_PSEUDO; 340 BD_ADDR rra, pseudo_bda; 341 342 STREAM_TO_UINT8(status, p); 343 344 BTM_TRACE_DEBUG("%s status = %d", __func__, status); 345 346 if (!btm_ble_deq_resolving_pending(pseudo_bda)) { 347 BTM_TRACE_ERROR("no pending resolving list operation"); 348 return; 349 } 350 351 if (status == HCI_SUCCESS) { 352 /* proprietary spec has extra bytes */ 353 if (evt_len > 8) { 354 /* skip subcode, index, IRK value, address type, identity addr type */ 355 p += (2 + 16 + 1 + 6); 356 STREAM_TO_BDADDR(rra, p); 357 358 BTM_TRACE_ERROR("%s peer_addr: %02x:%02x:%02x:%02x:%02x:%02x", __func__, 359 rra[0], rra[1], rra[2], rra[3], rra[4], rra[5]); 360 } else { 361 STREAM_TO_BDADDR(rra, p); 362 } 363 btm_ble_refresh_peer_resolvable_private_addr(pseudo_bda, rra, rra_type); 364 } 365 } 366 /******************************************************************************* 367 VSC that implement controller based privacy 368 ******************************************************************************/ 369 /******************************************************************************* 370 * 371 * Function btm_ble_resolving_list_vsc_op_cmpl 372 * 373 * Description IRK operation VSC complete handler 374 * 375 * Parameters 376 * 377 * Returns void 378 * 379 ******************************************************************************/ 380 void btm_ble_resolving_list_vsc_op_cmpl(tBTM_VSC_CMPL* p_params) { 381 uint8_t *p = p_params->p_param_buf, op_subcode; 382 uint16_t evt_len = p_params->param_len; 383 384 op_subcode = *(p + 1); 385 386 BTM_TRACE_DEBUG("%s op_subcode = %d", __func__, op_subcode); 387 388 if (op_subcode == BTM_BLE_META_CLEAR_IRK_LIST) { 389 btm_ble_clear_resolving_list_complete(p, evt_len); 390 } else if (op_subcode == BTM_BLE_META_ADD_IRK_ENTRY) { 391 btm_ble_add_resolving_list_entry_complete(p, evt_len); 392 } else if (op_subcode == BTM_BLE_META_REMOVE_IRK_ENTRY) { 393 btm_ble_remove_resolving_list_entry_complete(p, evt_len); 394 } else if (op_subcode == BTM_BLE_META_READ_IRK_ENTRY) { 395 btm_ble_read_resolving_list_entry_complete(p, evt_len); 396 } else if (op_subcode == BTM_BLE_META_IRK_ENABLE) { 397 /* RPA offloading enable/disabled */ 398 } 399 } 400 401 /******************************************************************************* 402 * 403 * Function btm_ble_remove_resolving_list_entry 404 * 405 * Description This function to remove an IRK entry from the list 406 * 407 * Parameters ble_addr_type: address type 408 * ble_addr: LE adddress 409 * 410 * Returns status 411 * 412 ******************************************************************************/ 413 tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC* p_dev_rec) { 414 /* if controller does not support RPA offloading or privacy 1.2, skip */ 415 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) 416 return BTM_WRONG_MODE; 417 418 if (controller_get_interface()->supports_ble_privacy()) { 419 btsnd_hcic_ble_rm_device_resolving_list(p_dev_rec->ble.static_addr_type, 420 p_dev_rec->ble.static_addr); 421 } else { 422 uint8_t param[20] = {0}; 423 uint8_t* p = param; 424 425 UINT8_TO_STREAM(p, BTM_BLE_META_REMOVE_IRK_ENTRY); 426 UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type); 427 BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr); 428 429 BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, 430 BTM_BLE_META_REMOVE_IRK_LEN, param, 431 btm_ble_resolving_list_vsc_op_cmpl); 432 } 433 434 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr, 435 BTM_BLE_META_REMOVE_IRK_ENTRY); 436 return BTM_CMD_STARTED; 437 } 438 439 /******************************************************************************* 440 * 441 * Function btm_ble_clear_resolving_list 442 * 443 * Description This function clears the resolving list 444 * 445 * Parameters None. 446 * 447 ******************************************************************************/ 448 void btm_ble_clear_resolving_list(void) { 449 if (controller_get_interface()->supports_ble_privacy()) { 450 btsnd_hcic_ble_clear_resolving_list(); 451 } else { 452 uint8_t param[20] = {0}; 453 uint8_t* p = param; 454 455 UINT8_TO_STREAM(p, BTM_BLE_META_CLEAR_IRK_LIST); 456 BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, 457 BTM_BLE_META_CLEAR_IRK_LEN, param, 458 btm_ble_resolving_list_vsc_op_cmpl); 459 } 460 } 461 462 /******************************************************************************* 463 * 464 * Function btm_ble_read_resolving_list_entry 465 * 466 * Description This function read an IRK entry by index 467 * 468 * Parameters entry index. 469 * 470 * Returns status 471 * 472 ******************************************************************************/ 473 tBTM_STATUS btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC* p_dev_rec) { 474 if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT)) 475 return BTM_WRONG_MODE; 476 477 if (controller_get_interface()->supports_ble_privacy()) { 478 btsnd_hcic_ble_read_resolvable_addr_peer(p_dev_rec->ble.static_addr_type, 479 p_dev_rec->ble.static_addr); 480 } else { 481 uint8_t param[20] = {0}; 482 uint8_t* p = param; 483 484 UINT8_TO_STREAM(p, BTM_BLE_META_READ_IRK_ENTRY); 485 UINT8_TO_STREAM(p, p_dev_rec->ble.resolving_list_index); 486 487 BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_META_READ_IRK_LEN, 488 param, btm_ble_resolving_list_vsc_op_cmpl); 489 } 490 491 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr, 492 BTM_BLE_META_READ_IRK_ENTRY); 493 494 return BTM_CMD_STARTED; 495 } 496 497 /******************************************************************************* 498 * 499 * Function btm_ble_suspend_resolving_list_activity 500 * 501 * Description This function suspends all resolving list activity, 502 * including scanning, initiating, and advertising, if 503 * resolving list is being enabled. 504 * 505 * Parameters 506 * 507 * Returns true if suspended; false otherwise 508 * 509 ******************************************************************************/ 510 bool btm_ble_suspend_resolving_list_activity(void) { 511 tBTM_BLE_CB* p_ble_cb = &btm_cb.ble_ctr_cb; 512 513 /* if resolving list is not enabled, do not need to terminate any activity */ 514 /* if asking for stop all activity */ 515 /* if already suspended */ 516 if (p_ble_cb->suspended_rl_state != BTM_BLE_RL_IDLE) return true; 517 518 /* direct connection active, wait until it completed */ 519 if (btm_ble_get_conn_st() == BLE_DIR_CONN) { 520 BTM_TRACE_ERROR("resolving list can not be edited, EnQ now"); 521 return false; 522 } 523 524 p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE; 525 526 if (p_ble_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE) { 527 btm_ble_stop_adv(); 528 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_ADV; 529 } 530 531 if (BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) { 532 btm_ble_stop_scan(); 533 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_SCAN; 534 } 535 536 if (btm_ble_suspend_bg_conn()) 537 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_INIT; 538 539 return true; 540 } 541 542 /******************************************************************************* 543 * 544 * Function btm_ble_resume_resolving_list_activity 545 * 546 * Description This function resumes the resolving list activity, including 547 * scanning, initiating, and advertising, if any of these 548 * activities has been suspended earlier. 549 * 550 * Returns none 551 * 552 ******************************************************************************/ 553 void btm_ble_resume_resolving_list_activity(void) { 554 tBTM_BLE_CB* p_ble_cb = &btm_cb.ble_ctr_cb; 555 556 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_ADV) btm_ble_start_adv(); 557 558 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_SCAN) btm_ble_start_scan(); 559 560 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_INIT) btm_ble_resume_bg_conn(); 561 562 p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE; 563 } 564 565 /******************************************************************************* 566 * 567 * Function btm_ble_vendor_enable_irk_feature 568 * 569 * Description This function is called to enable or disable the RRA 570 * offloading feature. 571 * 572 * Parameters enable: enable or disable the RRA offloading feature 573 * 574 ******************************************************************************/ 575 void btm_ble_vendor_enable_irk_feature(bool enable) { 576 uint8_t param[20], *p; 577 578 p = param; 579 memset(param, 0, 20); 580 581 /* select feature based on control block settings */ 582 UINT8_TO_STREAM(p, BTM_BLE_META_IRK_ENABLE); 583 UINT8_TO_STREAM(p, enable ? 0x01 : 0x00); 584 585 BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_IRK_ENABLE_LEN, 586 param, btm_ble_resolving_list_vsc_op_cmpl); 587 } 588 589 /******************************************************************************* 590 * 591 * Function btm_ble_exe_disable_resolving_list 592 * 593 * Description execute resolving list disable 594 * 595 * Returns none 596 * 597 ******************************************************************************/ 598 bool btm_ble_exe_disable_resolving_list(void) { 599 if (!btm_ble_suspend_resolving_list_activity()) return false; 600 601 if (!controller_get_interface()->supports_ble_privacy()) 602 btm_ble_vendor_enable_irk_feature(false); 603 else 604 btsnd_hcic_ble_set_addr_resolution_enable(false); 605 606 return true; 607 } 608 609 /******************************************************************************* 610 * 611 * Function btm_ble_exe_enable_resolving_list 612 * 613 * Description enable LE resolve address list 614 * 615 * Returns none 616 * 617 ******************************************************************************/ 618 void btm_ble_exe_enable_resolving_list(void) { 619 if (!btm_ble_suspend_resolving_list_activity()) return; 620 621 if (!controller_get_interface()->supports_ble_privacy()) 622 btm_ble_vendor_enable_irk_feature(true); 623 else 624 btsnd_hcic_ble_set_addr_resolution_enable(true); 625 } 626 627 /******************************************************************************* 628 * 629 * Function btm_ble_disable_resolving_list 630 * 631 * Description Disable LE Address resolution 632 * 633 * Returns none 634 * 635 ******************************************************************************/ 636 bool btm_ble_disable_resolving_list(uint8_t rl_mask, bool to_resume) { 637 uint8_t rl_state = btm_cb.ble_ctr_cb.rl_state; 638 639 /* if controller does not support RPA offloading or privacy 1.2, skip */ 640 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) 641 return false; 642 643 btm_cb.ble_ctr_cb.rl_state &= ~rl_mask; 644 645 if (rl_state != BTM_BLE_RL_IDLE && 646 btm_cb.ble_ctr_cb.rl_state == BTM_BLE_RL_IDLE) { 647 if (btm_ble_exe_disable_resolving_list()) { 648 if (to_resume) btm_ble_resume_resolving_list_activity(); 649 650 return true; 651 } else 652 return false; 653 } 654 655 return true; 656 } 657 658 /******************************************************************************* 659 * 660 * Function btm_ble_resolving_list_load_dev 661 * 662 * Description This function adds a device which is using RPA into the 663 * white list. 664 * 665 * Parameters pointer to device security record 666 * 667 * Returns true if device added, otherwise falase. 668 * 669 ******************************************************************************/ 670 bool btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC* p_dev_rec) { 671 bool rt = false; 672 uint8_t rl_mask = btm_cb.ble_ctr_cb.rl_state; 673 674 BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d", __func__, 675 btm_cb.ble_ctr_cb.privacy_mode); 676 677 /* if controller does not support RPA offloading or privacy 1.2, skip */ 678 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) 679 return false; 680 681 BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d", __func__, 682 btm_cb.ble_ctr_cb.privacy_mode); 683 684 /* only add RPA enabled device into resolving list */ 685 if (p_dev_rec != NULL && /* RPA is being used and PID is known */ 686 ((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0 || 687 (p_dev_rec->ble.key_type & BTM_LE_KEY_LID) != 0)) { 688 if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) && 689 btm_ble_brcm_find_resolving_pending_entry( 690 p_dev_rec->bd_addr, BTM_BLE_META_ADD_IRK_ENTRY) == false) { 691 if (btm_cb.ble_ctr_cb.resolving_list_avail_size > 0) { 692 if (rl_mask) { 693 if (!btm_ble_disable_resolving_list(rl_mask, false)) return false; 694 } 695 696 btm_ble_update_resolving_list(p_dev_rec->bd_addr, true); 697 if (controller_get_interface()->supports_ble_privacy()) { 698 BD_ADDR dummy_bda = {0}; 699 uint8_t* peer_irk = p_dev_rec->ble.keys.irk; 700 uint8_t* local_irk = btm_cb.devcb.id_keys.irk; 701 702 if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) == 0) { 703 memcpy(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, BD_ADDR_LEN); 704 p_dev_rec->ble.static_addr_type = p_dev_rec->ble.ble_addr_type; 705 } 706 707 BTM_TRACE_DEBUG("%s:adding device to controller resolving list", 708 __func__); 709 // use identical IRK for now 710 btsnd_hcic_ble_add_device_resolving_list( 711 p_dev_rec->ble.static_addr_type, p_dev_rec->ble.static_addr, 712 peer_irk, local_irk); 713 714 if (controller_get_interface()->supports_ble_privacy()) { 715 BTM_TRACE_DEBUG("%s: adding device privacy mode", __func__); 716 btsnd_hcic_ble_set_privacy_mode(p_dev_rec->ble.static_addr_type, 717 p_dev_rec->ble.static_addr, 0x01); 718 } 719 } else { 720 uint8_t param[40] = {0}; 721 uint8_t* p = param; 722 723 UINT8_TO_STREAM(p, BTM_BLE_META_ADD_IRK_ENTRY); 724 ARRAY_TO_STREAM(p, p_dev_rec->ble.keys.irk, BT_OCTET16_LEN); 725 UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type); 726 BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr); 727 728 BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, 729 BTM_BLE_META_ADD_IRK_LEN, param, 730 btm_ble_resolving_list_vsc_op_cmpl); 731 } 732 733 rt = true; 734 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr, 735 BTM_BLE_META_ADD_IRK_ENTRY); 736 737 /* if resolving list has been turned on, re-enable it */ 738 if (rl_mask) 739 btm_ble_enable_resolving_list(rl_mask); 740 else 741 btm_ble_enable_resolving_list(BTM_BLE_RL_INIT); 742 } 743 } else { 744 BTM_TRACE_ERROR("Device already in Resolving list"); 745 rt = true; 746 } 747 } else { 748 BTM_TRACE_DEBUG("Device not a RPA enabled device"); 749 } 750 return rt; 751 } 752 753 /******************************************************************************* 754 * 755 * Function btm_ble_resolving_list_remove_dev 756 * 757 * Description This function removes the device from resolving list 758 * 759 * Parameters 760 * 761 * Returns status 762 * 763 ******************************************************************************/ 764 void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC* p_dev_rec) { 765 uint8_t rl_mask = btm_cb.ble_ctr_cb.rl_state; 766 767 BTM_TRACE_EVENT("%s", __func__); 768 if (rl_mask) { 769 if (!btm_ble_disable_resolving_list(rl_mask, false)) return; 770 } 771 772 if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) && 773 btm_ble_brcm_find_resolving_pending_entry( 774 p_dev_rec->bd_addr, BTM_BLE_META_REMOVE_IRK_ENTRY) == false) { 775 btm_ble_update_resolving_list(p_dev_rec->bd_addr, false); 776 btm_ble_remove_resolving_list_entry(p_dev_rec); 777 } else { 778 BTM_TRACE_DEBUG("Device not in resolving list"); 779 } 780 781 /* if resolving list has been turned on, re-enable it */ 782 if (rl_mask) btm_ble_enable_resolving_list(rl_mask); 783 } 784 785 /******************************************************************************* 786 * 787 * Function btm_ble_enable_resolving_list 788 * 789 * Description enable LE resolve address list 790 * 791 * Returns none 792 * 793 ******************************************************************************/ 794 void btm_ble_enable_resolving_list(uint8_t rl_mask) { 795 uint8_t rl_state = btm_cb.ble_ctr_cb.rl_state; 796 797 btm_cb.ble_ctr_cb.rl_state |= rl_mask; 798 if (rl_state == BTM_BLE_RL_IDLE && 799 btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE && 800 controller_get_interface()->get_ble_resolving_list_max_size() != 0) { 801 btm_ble_exe_enable_resolving_list(); 802 btm_ble_resume_resolving_list_activity(); 803 } 804 } 805 806 /******************************************************************************* 807 * 808 * Function btm_ble_resolving_list_empty 809 * 810 * Description check to see if resoving list is empty or not 811 * 812 * Returns true: empty; false non-empty 813 * 814 ******************************************************************************/ 815 bool btm_ble_resolving_list_empty(void) { 816 return (controller_get_interface()->get_ble_resolving_list_max_size() == 817 btm_cb.ble_ctr_cb.resolving_list_avail_size); 818 } 819 820 bool is_on_resolving_list(void* data, void* context) { 821 tBTM_SEC_DEV_REC* p_dev = static_cast<tBTM_SEC_DEV_REC*>(data); 822 if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) && 823 (p_dev->ble.in_controller_list & BTM_WHITE_LIST_BIT)) 824 return false; 825 826 return true; 827 } 828 829 /******************************************************************************* 830 * 831 * Function btm_ble_enable_resolving_list_for_platform 832 * 833 * Description enable/disable resolving list feature depending on if any 834 * resolving list is empty and whitelist is involoved in the 835 * operation. 836 * 837 * Returns none 838 * 839 ******************************************************************************/ 840 void btm_ble_enable_resolving_list_for_platform(uint8_t rl_mask) { 841 /* if controller does not support, skip */ 842 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) 843 return; 844 845 if (btm_cb.ble_ctr_cb.wl_state == BTM_BLE_WL_IDLE) { 846 if (controller_get_interface()->get_ble_resolving_list_max_size() > 847 btm_cb.ble_ctr_cb.resolving_list_avail_size) 848 btm_ble_enable_resolving_list(rl_mask); 849 else 850 btm_ble_disable_resolving_list(rl_mask, true); 851 return; 852 } 853 854 list_node_t* n = list_foreach(btm_cb.sec_dev_rec, is_on_resolving_list, NULL); 855 if (n) 856 btm_ble_enable_resolving_list(rl_mask); 857 else 858 btm_ble_disable_resolving_list(rl_mask, true); 859 } 860 861 /******************************************************************************* 862 * 863 * Function btm_ble_resolving_list_init 864 * 865 * Description Initialize resolving list in host stack 866 * 867 * Parameters Max resolving list size 868 * 869 * Returns void 870 * 871 ******************************************************************************/ 872 void btm_ble_resolving_list_init(uint8_t max_irk_list_sz) { 873 tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q; 874 uint8_t irk_mask_size = 875 (max_irk_list_sz % 8) ? (max_irk_list_sz / 8 + 1) : (max_irk_list_sz / 8); 876 877 if (max_irk_list_sz > 0) { 878 p_q->resolve_q_random_pseudo = 879 (BD_ADDR*)osi_malloc(sizeof(BD_ADDR) * max_irk_list_sz); 880 p_q->resolve_q_action = (uint8_t*)osi_malloc(max_irk_list_sz); 881 882 /* RPA offloading feature */ 883 if (btm_cb.ble_ctr_cb.irk_list_mask == NULL) 884 btm_cb.ble_ctr_cb.irk_list_mask = (uint8_t*)osi_malloc(irk_mask_size); 885 886 BTM_TRACE_DEBUG("%s max_irk_list_sz = %d", __func__, max_irk_list_sz); 887 } 888 889 controller_get_interface()->set_ble_resolving_list_max_size(max_irk_list_sz); 890 btm_ble_clear_resolving_list(); 891 btm_cb.ble_ctr_cb.resolving_list_avail_size = max_irk_list_sz; 892 } 893 894 /******************************************************************************* 895 * 896 * Function btm_ble_resolving_list_cleanup 897 * 898 * Description Cleanup resolving list dynamic memory 899 * 900 * Parameters 901 * 902 * Returns void 903 * 904 ******************************************************************************/ 905 void btm_ble_resolving_list_cleanup(void) { 906 tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q; 907 908 osi_free_and_reset((void**)&p_q->resolve_q_random_pseudo); 909 osi_free_and_reset((void**)&p_q->resolve_q_action); 910 911 controller_get_interface()->set_ble_resolving_list_max_size(0); 912 913 osi_free_and_reset((void**)&btm_cb.ble_ctr_cb.irk_list_mask); 914 } 915 #endif 916