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 "ble_advertiser.h" 29 #include "bt_types.h" 30 #include "btm_int.h" 31 #include "btu.h" 32 #include "device/include/controller.h" 33 #include "hcimsgs.h" 34 #include "vendor_hcidefs.h" 35 36 /* RPA offload VSC specifics */ 37 #define BTM_BLE_META_IRK_ENABLE 0x01 38 #define BTM_BLE_META_ADD_IRK_ENTRY 0x02 39 #define BTM_BLE_META_REMOVE_IRK_ENTRY 0x03 40 #define BTM_BLE_META_CLEAR_IRK_LIST 0x04 41 #define BTM_BLE_META_READ_IRK_ENTRY 0x05 42 #define BTM_BLE_META_CS_RESOLVE_ADDR 0x00000001 43 #define BTM_BLE_IRK_ENABLE_LEN 2 44 45 #define BTM_BLE_META_ADD_IRK_LEN 24 46 #define BTM_BLE_META_REMOVE_IRK_LEN 8 47 #define BTM_BLE_META_CLEAR_IRK_LEN 1 48 #define BTM_BLE_META_READ_IRK_LEN 2 49 #define BTM_BLE_META_ADD_WL_ATTR_LEN 9 50 51 /******************************************************************************* 52 * Functions implemented controller based privacy using Resolving List 53 ******************************************************************************/ 54 /******************************************************************************* 55 * 56 * Function btm_ble_enq_resolving_list_pending 57 * 58 * Description add target address into resolving pending operation queue 59 * 60 * Parameters target_bda: target device address 61 * add_entry: true for add entry, false for remove entry 62 * 63 * Returns void 64 * 65 ******************************************************************************/ 66 void btm_ble_enq_resolving_list_pending(const RawAddress& pseudo_bda, 67 uint8_t op_code) { 68 tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q; 69 70 p_q->resolve_q_random_pseudo[p_q->q_next] = pseudo_bda; 71 p_q->resolve_q_action[p_q->q_next] = op_code; 72 p_q->q_next++; 73 p_q->q_next %= controller_get_interface()->get_ble_resolving_list_max_size(); 74 } 75 76 /******************************************************************************* 77 * 78 * Function btm_ble_brcm_find_resolving_pending_entry 79 * 80 * Description check to see if the action is in pending list 81 * 82 * Parameters true: action pending; 83 * false: new action 84 * 85 * Returns void 86 * 87 ******************************************************************************/ 88 bool btm_ble_brcm_find_resolving_pending_entry(const RawAddress& pseudo_addr, 89 uint8_t action) { 90 tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q; 91 92 for (uint8_t i = p_q->q_pending; i != p_q->q_next;) { 93 if (p_q->resolve_q_random_pseudo[i] == pseudo_addr && 94 action == p_q->resolve_q_action[i]) 95 return true; 96 97 i++; 98 i %= controller_get_interface()->get_ble_resolving_list_max_size(); 99 } 100 return false; 101 } 102 103 /******************************************************************************* 104 * 105 * Function btm_ble_deq_resolving_pending 106 * 107 * Description dequeue target address from resolving pending operation 108 * queue 109 * 110 * Parameters pseudo_addr: pseudo_addr device address 111 * 112 * Returns void 113 * 114 ******************************************************************************/ 115 bool btm_ble_deq_resolving_pending(RawAddress& pseudo_addr) { 116 tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q; 117 118 if (p_q->q_next != p_q->q_pending) { 119 pseudo_addr = p_q->resolve_q_random_pseudo[p_q->q_pending]; 120 p_q->resolve_q_random_pseudo[p_q->q_pending] = RawAddress::kEmpty; 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(const RawAddress& 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 RawAddress 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 RawAddress 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 RawAddress 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 VLOG(2) << __func__ << " peer_addr: " << rra; 359 } else { 360 STREAM_TO_BDADDR(rra, p); 361 } 362 btm_ble_refresh_peer_resolvable_private_addr(pseudo_bda, rra, rra_type); 363 } 364 } 365 /******************************************************************************* 366 VSC that implement controller based privacy 367 ******************************************************************************/ 368 /******************************************************************************* 369 * 370 * Function btm_ble_resolving_list_vsc_op_cmpl 371 * 372 * Description IRK operation VSC complete handler 373 * 374 * Parameters 375 * 376 * Returns void 377 * 378 ******************************************************************************/ 379 void btm_ble_resolving_list_vsc_op_cmpl(tBTM_VSC_CMPL* p_params) { 380 uint8_t *p = p_params->p_param_buf, op_subcode; 381 uint16_t evt_len = p_params->param_len; 382 383 op_subcode = *(p + 1); 384 385 BTM_TRACE_DEBUG("%s op_subcode = %d", __func__, op_subcode); 386 387 if (op_subcode == BTM_BLE_META_CLEAR_IRK_LIST) { 388 btm_ble_clear_resolving_list_complete(p, evt_len); 389 } else if (op_subcode == BTM_BLE_META_ADD_IRK_ENTRY) { 390 btm_ble_add_resolving_list_entry_complete(p, evt_len); 391 } else if (op_subcode == BTM_BLE_META_REMOVE_IRK_ENTRY) { 392 btm_ble_remove_resolving_list_entry_complete(p, evt_len); 393 } else if (op_subcode == BTM_BLE_META_READ_IRK_ENTRY) { 394 btm_ble_read_resolving_list_entry_complete(p, evt_len); 395 } else if (op_subcode == BTM_BLE_META_IRK_ENABLE) { 396 /* RPA offloading enable/disabled */ 397 } 398 } 399 400 /******************************************************************************* 401 * 402 * Function btm_ble_remove_resolving_list_entry 403 * 404 * Description This function to remove an IRK entry from the list 405 * 406 * Parameters ble_addr_type: address type 407 * ble_addr: LE adddress 408 * 409 * Returns status 410 * 411 ******************************************************************************/ 412 tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC* p_dev_rec) { 413 /* if controller does not support RPA offloading or privacy 1.2, skip */ 414 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) 415 return BTM_WRONG_MODE; 416 417 if (controller_get_interface()->supports_ble_privacy()) { 418 btsnd_hcic_ble_rm_device_resolving_list(p_dev_rec->ble.static_addr_type, 419 p_dev_rec->ble.static_addr); 420 } else { 421 uint8_t param[20] = {0}; 422 uint8_t* p = param; 423 424 UINT8_TO_STREAM(p, BTM_BLE_META_REMOVE_IRK_ENTRY); 425 UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type); 426 BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr); 427 428 BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, 429 BTM_BLE_META_REMOVE_IRK_LEN, param, 430 btm_ble_resolving_list_vsc_op_cmpl); 431 } 432 433 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr, 434 BTM_BLE_META_REMOVE_IRK_ENTRY); 435 return BTM_CMD_STARTED; 436 } 437 438 /******************************************************************************* 439 * 440 * Function btm_ble_clear_resolving_list 441 * 442 * Description This function clears the resolving list 443 * 444 * Parameters None. 445 * 446 ******************************************************************************/ 447 void btm_ble_clear_resolving_list(void) { 448 if (controller_get_interface()->supports_ble_privacy()) { 449 btsnd_hcic_ble_clear_resolving_list(); 450 } else { 451 uint8_t param[20] = {0}; 452 uint8_t* p = param; 453 454 UINT8_TO_STREAM(p, BTM_BLE_META_CLEAR_IRK_LIST); 455 BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, 456 BTM_BLE_META_CLEAR_IRK_LEN, param, 457 btm_ble_resolving_list_vsc_op_cmpl); 458 } 459 } 460 461 /******************************************************************************* 462 * 463 * Function btm_ble_read_resolving_list_entry 464 * 465 * Description This function read an IRK entry by index 466 * 467 * Parameters entry index. 468 * 469 * Returns status 470 * 471 ******************************************************************************/ 472 tBTM_STATUS btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC* p_dev_rec) { 473 if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT)) 474 return BTM_WRONG_MODE; 475 476 if (controller_get_interface()->supports_ble_privacy()) { 477 btsnd_hcic_ble_read_resolvable_addr_peer(p_dev_rec->ble.static_addr_type, 478 p_dev_rec->ble.static_addr); 479 } else { 480 uint8_t param[20] = {0}; 481 uint8_t* p = param; 482 483 UINT8_TO_STREAM(p, BTM_BLE_META_READ_IRK_ENTRY); 484 UINT8_TO_STREAM(p, p_dev_rec->ble.resolving_list_index); 485 486 BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_META_READ_IRK_LEN, 487 param, btm_ble_resolving_list_vsc_op_cmpl); 488 } 489 490 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr, 491 BTM_BLE_META_READ_IRK_ENTRY); 492 493 return BTM_CMD_STARTED; 494 } 495 496 /******************************************************************************* 497 * 498 * Function btm_ble_suspend_resolving_list_activity 499 * 500 * Description This function suspends all resolving list activity, 501 * including scanning, initiating, and advertising, if 502 * resolving list is being enabled. 503 * 504 * Parameters 505 * 506 * Returns true if suspended; false otherwise 507 * 508 ******************************************************************************/ 509 bool btm_ble_suspend_resolving_list_activity(void) { 510 tBTM_BLE_CB* p_ble_cb = &btm_cb.ble_ctr_cb; 511 512 /* if resolving list is not enabled, do not need to terminate any activity */ 513 /* if asking for stop all activity */ 514 /* if already suspended */ 515 if (p_ble_cb->suspended_rl_state != BTM_BLE_RL_IDLE) return true; 516 517 /* direct connection active, wait until it completed */ 518 if (btm_ble_get_conn_st() == BLE_DIR_CONN) { 519 BTM_TRACE_ERROR("resolving list can not be edited, EnQ now"); 520 return false; 521 } 522 523 p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE; 524 525 if (p_ble_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE) { 526 btm_ble_stop_adv(); 527 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_ADV; 528 } 529 530 // If it's non-VSC implementation, suspend 531 if (BleAdvertisingManager::IsInitialized() && 532 (controller_get_interface()->supports_ble_extended_advertising() || 533 BTM_BleMaxMultiAdvInstanceCount() == 0)) { 534 BleAdvertisingManager::Get()->Suspend(); 535 } 536 537 if (BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) { 538 btm_ble_stop_scan(); 539 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_SCAN; 540 } 541 542 if (btm_ble_suspend_bg_conn()) 543 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_INIT; 544 545 return true; 546 } 547 548 /******************************************************************************* 549 * 550 * Function btm_ble_resume_resolving_list_activity 551 * 552 * Description This function resumes the resolving list activity, including 553 * scanning, initiating, and advertising, if any of these 554 * activities has been suspended earlier. 555 * 556 * Returns none 557 * 558 ******************************************************************************/ 559 void btm_ble_resume_resolving_list_activity(void) { 560 tBTM_BLE_CB* p_ble_cb = &btm_cb.ble_ctr_cb; 561 562 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_ADV) btm_ble_start_adv(); 563 564 // If it's non-VSC implementation, resume 565 if (BleAdvertisingManager::IsInitialized() && 566 (controller_get_interface()->supports_ble_extended_advertising() || 567 BTM_BleMaxMultiAdvInstanceCount() == 0)) { 568 BleAdvertisingManager::Get()->Resume(); 569 } 570 571 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_SCAN) btm_ble_start_scan(); 572 573 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_INIT) btm_ble_resume_bg_conn(); 574 575 p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE; 576 } 577 578 /******************************************************************************* 579 * 580 * Function btm_ble_vendor_enable_irk_feature 581 * 582 * Description This function is called to enable or disable the RRA 583 * offloading feature. 584 * 585 * Parameters enable: enable or disable the RRA offloading feature 586 * 587 ******************************************************************************/ 588 void btm_ble_vendor_enable_irk_feature(bool enable) { 589 uint8_t param[20], *p; 590 591 p = param; 592 memset(param, 0, 20); 593 594 /* select feature based on control block settings */ 595 UINT8_TO_STREAM(p, BTM_BLE_META_IRK_ENABLE); 596 UINT8_TO_STREAM(p, enable ? 0x01 : 0x00); 597 598 BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_IRK_ENABLE_LEN, 599 param, btm_ble_resolving_list_vsc_op_cmpl); 600 } 601 602 /******************************************************************************* 603 * 604 * Function btm_ble_exe_disable_resolving_list 605 * 606 * Description execute resolving list disable 607 * 608 * Returns none 609 * 610 ******************************************************************************/ 611 bool btm_ble_exe_disable_resolving_list(void) { 612 if (!btm_ble_suspend_resolving_list_activity()) return false; 613 614 if (!controller_get_interface()->supports_ble_privacy()) 615 btm_ble_vendor_enable_irk_feature(false); 616 else 617 btsnd_hcic_ble_set_addr_resolution_enable(false); 618 619 return true; 620 } 621 622 /******************************************************************************* 623 * 624 * Function btm_ble_exe_enable_resolving_list 625 * 626 * Description enable LE resolve address list 627 * 628 * Returns none 629 * 630 ******************************************************************************/ 631 void btm_ble_exe_enable_resolving_list(void) { 632 if (!btm_ble_suspend_resolving_list_activity()) return; 633 634 if (!controller_get_interface()->supports_ble_privacy()) 635 btm_ble_vendor_enable_irk_feature(true); 636 else 637 btsnd_hcic_ble_set_addr_resolution_enable(true); 638 } 639 640 /******************************************************************************* 641 * 642 * Function btm_ble_disable_resolving_list 643 * 644 * Description Disable LE Address resolution 645 * 646 * Returns none 647 * 648 ******************************************************************************/ 649 bool btm_ble_disable_resolving_list(uint8_t rl_mask, bool to_resume) { 650 uint8_t rl_state = btm_cb.ble_ctr_cb.rl_state; 651 652 /* if controller does not support RPA offloading or privacy 1.2, skip */ 653 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) 654 return false; 655 656 btm_cb.ble_ctr_cb.rl_state &= ~rl_mask; 657 658 if (rl_state != BTM_BLE_RL_IDLE && 659 btm_cb.ble_ctr_cb.rl_state == BTM_BLE_RL_IDLE) { 660 if (btm_ble_exe_disable_resolving_list()) { 661 if (to_resume) btm_ble_resume_resolving_list_activity(); 662 663 return true; 664 } else 665 return false; 666 } 667 668 return true; 669 } 670 671 /******************************************************************************* 672 * 673 * Function btm_ble_resolving_list_load_dev 674 * 675 * Description This function adds a device which is using RPA into the 676 * white list. 677 * 678 * Parameters pointer to device security record 679 * 680 * Returns true if device added, otherwise falase. 681 * 682 ******************************************************************************/ 683 bool btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC* p_dev_rec) { 684 bool rt = false; 685 uint8_t rl_mask = btm_cb.ble_ctr_cb.rl_state; 686 687 BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d", __func__, 688 btm_cb.ble_ctr_cb.privacy_mode); 689 690 /* if controller does not support RPA offloading or privacy 1.2, skip */ 691 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) 692 return false; 693 694 BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d", __func__, 695 btm_cb.ble_ctr_cb.privacy_mode); 696 697 /* only add RPA enabled device into resolving list */ 698 if (p_dev_rec != NULL && /* RPA is being used and PID is known */ 699 ((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0 || 700 (p_dev_rec->ble.key_type & BTM_LE_KEY_LID) != 0)) { 701 if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) && 702 btm_ble_brcm_find_resolving_pending_entry( 703 p_dev_rec->bd_addr, BTM_BLE_META_ADD_IRK_ENTRY) == false) { 704 if (btm_cb.ble_ctr_cb.resolving_list_avail_size > 0) { 705 if (rl_mask) { 706 if (!btm_ble_disable_resolving_list(rl_mask, false)) return false; 707 } 708 709 btm_ble_update_resolving_list(p_dev_rec->bd_addr, true); 710 if (controller_get_interface()->supports_ble_privacy()) { 711 uint8_t* peer_irk = p_dev_rec->ble.keys.irk; 712 uint8_t* local_irk = btm_cb.devcb.id_keys.irk; 713 714 if (p_dev_rec->ble.static_addr.IsEmpty()) { 715 p_dev_rec->ble.static_addr = p_dev_rec->bd_addr; 716 p_dev_rec->ble.static_addr_type = p_dev_rec->ble.ble_addr_type; 717 } 718 719 BTM_TRACE_DEBUG("%s:adding device to controller resolving list", 720 __func__); 721 // use identical IRK for now 722 btsnd_hcic_ble_add_device_resolving_list( 723 p_dev_rec->ble.static_addr_type, p_dev_rec->ble.static_addr, 724 peer_irk, local_irk); 725 726 if (controller_get_interface()->supports_ble_set_privacy_mode()) { 727 BTM_TRACE_DEBUG("%s: adding device privacy mode", __func__); 728 btsnd_hcic_ble_set_privacy_mode(p_dev_rec->ble.static_addr_type, 729 p_dev_rec->ble.static_addr, 0x01); 730 } 731 } else { 732 uint8_t param[40] = {0}; 733 uint8_t* p = param; 734 735 UINT8_TO_STREAM(p, BTM_BLE_META_ADD_IRK_ENTRY); 736 ARRAY_TO_STREAM(p, p_dev_rec->ble.keys.irk, BT_OCTET16_LEN); 737 UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type); 738 BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr); 739 740 BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, 741 BTM_BLE_META_ADD_IRK_LEN, param, 742 btm_ble_resolving_list_vsc_op_cmpl); 743 } 744 745 rt = true; 746 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr, 747 BTM_BLE_META_ADD_IRK_ENTRY); 748 749 /* if resolving list has been turned on, re-enable it */ 750 if (rl_mask) 751 btm_ble_enable_resolving_list(rl_mask); 752 else 753 btm_ble_enable_resolving_list(BTM_BLE_RL_INIT); 754 } 755 } else { 756 BTM_TRACE_ERROR("Device already in Resolving list"); 757 rt = true; 758 } 759 } else { 760 BTM_TRACE_DEBUG("Device not a RPA enabled device"); 761 } 762 return rt; 763 } 764 765 /******************************************************************************* 766 * 767 * Function btm_ble_resolving_list_remove_dev 768 * 769 * Description This function removes the device from resolving list 770 * 771 * Parameters 772 * 773 * Returns status 774 * 775 ******************************************************************************/ 776 void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC* p_dev_rec) { 777 uint8_t rl_mask = btm_cb.ble_ctr_cb.rl_state; 778 779 BTM_TRACE_EVENT("%s", __func__); 780 if (rl_mask) { 781 if (!btm_ble_disable_resolving_list(rl_mask, false)) return; 782 } 783 784 if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) && 785 btm_ble_brcm_find_resolving_pending_entry( 786 p_dev_rec->bd_addr, BTM_BLE_META_REMOVE_IRK_ENTRY) == false) { 787 btm_ble_update_resolving_list(p_dev_rec->bd_addr, false); 788 btm_ble_remove_resolving_list_entry(p_dev_rec); 789 } else { 790 BTM_TRACE_DEBUG("Device not in resolving list"); 791 } 792 793 /* if resolving list has been turned on, re-enable it */ 794 if (rl_mask) btm_ble_enable_resolving_list(rl_mask); 795 } 796 797 /******************************************************************************* 798 * 799 * Function btm_ble_enable_resolving_list 800 * 801 * Description enable LE resolve address list 802 * 803 * Returns none 804 * 805 ******************************************************************************/ 806 void btm_ble_enable_resolving_list(uint8_t rl_mask) { 807 uint8_t rl_state = btm_cb.ble_ctr_cb.rl_state; 808 809 btm_cb.ble_ctr_cb.rl_state |= rl_mask; 810 if (rl_state == BTM_BLE_RL_IDLE && 811 btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE && 812 controller_get_interface()->get_ble_resolving_list_max_size() != 0) { 813 btm_ble_exe_enable_resolving_list(); 814 btm_ble_resume_resolving_list_activity(); 815 } 816 } 817 818 /******************************************************************************* 819 * 820 * Function btm_ble_resolving_list_empty 821 * 822 * Description check to see if resoving list is empty or not 823 * 824 * Returns true: empty; false non-empty 825 * 826 ******************************************************************************/ 827 bool btm_ble_resolving_list_empty(void) { 828 return (controller_get_interface()->get_ble_resolving_list_max_size() == 829 btm_cb.ble_ctr_cb.resolving_list_avail_size); 830 } 831 832 bool is_on_resolving_list(void* data, void* context) { 833 tBTM_SEC_DEV_REC* p_dev = static_cast<tBTM_SEC_DEV_REC*>(data); 834 if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) && 835 (p_dev->ble.in_controller_list & BTM_WHITE_LIST_BIT)) 836 return false; 837 838 return true; 839 } 840 841 /******************************************************************************* 842 * 843 * Function btm_ble_enable_resolving_list_for_platform 844 * 845 * Description enable/disable resolving list feature depending on if any 846 * resolving list is empty and whitelist is involoved in the 847 * operation. 848 * 849 * Returns none 850 * 851 ******************************************************************************/ 852 void btm_ble_enable_resolving_list_for_platform(uint8_t rl_mask) { 853 /* if controller does not support, skip */ 854 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) 855 return; 856 857 if (btm_cb.ble_ctr_cb.wl_state == BTM_BLE_WL_IDLE) { 858 if (controller_get_interface()->get_ble_resolving_list_max_size() > 859 btm_cb.ble_ctr_cb.resolving_list_avail_size) 860 btm_ble_enable_resolving_list(rl_mask); 861 else 862 btm_ble_disable_resolving_list(rl_mask, true); 863 return; 864 } 865 866 list_node_t* n = list_foreach(btm_cb.sec_dev_rec, is_on_resolving_list, NULL); 867 if (n) 868 btm_ble_enable_resolving_list(rl_mask); 869 else 870 btm_ble_disable_resolving_list(rl_mask, true); 871 } 872 873 /******************************************************************************* 874 * 875 * Function btm_ble_resolving_list_init 876 * 877 * Description Initialize resolving list in host stack 878 * 879 * Parameters Max resolving list size 880 * 881 * Returns void 882 * 883 ******************************************************************************/ 884 void btm_ble_resolving_list_init(uint8_t max_irk_list_sz) { 885 tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q; 886 uint8_t irk_mask_size = 887 (max_irk_list_sz % 8) ? (max_irk_list_sz / 8 + 1) : (max_irk_list_sz / 8); 888 889 if (max_irk_list_sz > 0) { 890 p_q->resolve_q_random_pseudo = 891 (RawAddress*)osi_malloc(sizeof(RawAddress) * max_irk_list_sz); 892 p_q->resolve_q_action = (uint8_t*)osi_malloc(max_irk_list_sz); 893 894 /* RPA offloading feature */ 895 if (btm_cb.ble_ctr_cb.irk_list_mask == NULL) 896 btm_cb.ble_ctr_cb.irk_list_mask = (uint8_t*)osi_malloc(irk_mask_size); 897 898 BTM_TRACE_DEBUG("%s max_irk_list_sz = %d", __func__, max_irk_list_sz); 899 } 900 901 controller_get_interface()->set_ble_resolving_list_max_size(max_irk_list_sz); 902 btm_ble_clear_resolving_list(); 903 btm_cb.ble_ctr_cb.resolving_list_avail_size = max_irk_list_sz; 904 } 905 906 /******************************************************************************* 907 * 908 * Function btm_ble_resolving_list_cleanup 909 * 910 * Description Cleanup resolving list dynamic memory 911 * 912 * Parameters 913 * 914 * Returns void 915 * 916 ******************************************************************************/ 917 void btm_ble_resolving_list_cleanup(void) { 918 tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q; 919 920 osi_free_and_reset((void**)&p_q->resolve_q_random_pseudo); 921 osi_free_and_reset((void**)&p_q->resolve_q_action); 922 923 controller_get_interface()->set_ble_resolving_list_max_size(0); 924 925 osi_free_and_reset((void**)&btm_cb.ble_ctr_cb.irk_list_mask); 926 } 927 #endif 928