1 /******************************************************************************
3 * Copyright (C) 1999-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This file contains functions for BLE controller based privacy.
23 ******************************************************************************/
25 #include "common/bt_target.h"
27 #if (BLE_INCLUDED == TRUE && BLE_PRIVACY_SPT == TRUE)
28 #include "stack/bt_types.h"
29 #include "stack/hcimsgs.h"
30 #include "stack/btu.h"
31 //#include "vendor_hcidefs.h"
33 #include "device/controller.h"
34 #include "stack/hcidefs.h"
36 #define HCI_VENDOR_BLE_RPA_VSC (0x0155 | HCI_GRP_VENDOR_SPECIFIC)
38 /* RPA offload VSC specifics */
39 #define BTM_BLE_META_IRK_ENABLE 0x01
40 #define BTM_BLE_META_ADD_IRK_ENTRY 0x02
41 #define BTM_BLE_META_REMOVE_IRK_ENTRY 0x03
42 #define BTM_BLE_META_CLEAR_IRK_LIST 0x04
43 #define BTM_BLE_META_READ_IRK_ENTRY 0x05
44 #define BTM_BLE_META_CS_RESOLVE_ADDR 0x00000001
45 #define BTM_BLE_IRK_ENABLE_LEN 2
47 #define BTM_BLE_META_ADD_IRK_LEN 24
48 #define BTM_BLE_META_REMOVE_IRK_LEN 8
49 #define BTM_BLE_META_CLEAR_IRK_LEN 1
50 #define BTM_BLE_META_READ_IRK_LEN 2
51 #define BTM_BLE_META_ADD_WL_ATTR_LEN 9
53 /*******************************************************************************
54 ** Functions implemented controller based privacy using Resolving List
55 *******************************************************************************/
56 /*******************************************************************************
58 ** Function btm_ble_enq_resolving_list_pending
60 ** Description add target address into resolving pending operation queue
62 ** Parameters target_bda: target device address
63 ** add_entry: TRUE for add entry, FALSE for remove entry
67 *******************************************************************************/
68 void btm_ble_enq_resolving_list_pending(BD_ADDR pseudo_bda, UINT8 op_code)
70 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
72 memcpy(p_q->resolve_q_random_pseudo[p_q->q_next], pseudo_bda, BD_ADDR_LEN);
73 p_q->resolve_q_action[p_q->q_next] = op_code;
75 p_q->q_next %= controller_get_interface()->get_ble_resolving_list_max_size();
78 /*******************************************************************************
80 ** Function btm_ble_brcm_find_resolving_pending_entry
82 ** Description check to see if the action is in pending list
84 ** Parameters TRUE: action pending;
89 *******************************************************************************/
90 BOOLEAN btm_ble_brcm_find_resolving_pending_entry(BD_ADDR pseudo_addr, UINT8 action)
92 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
94 for (UINT8 i = p_q->q_pending; i != p_q->q_next;) {
95 if (memcmp(p_q->resolve_q_random_pseudo[i], pseudo_addr, BD_ADDR_LEN) == 0 &&
96 action == p_q->resolve_q_action[i]) {
101 i %= controller_get_interface()->get_ble_resolving_list_max_size();
106 /*******************************************************************************
108 ** Function btm_ble_deq_resolving_pending
110 ** Description dequeue target address from resolving pending operation queue
112 ** Parameters pseudo_addr: pseudo_addr device address
116 *******************************************************************************/
117 BOOLEAN btm_ble_deq_resolving_pending(BD_ADDR pseudo_addr)
119 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
121 if (p_q->q_next != p_q->q_pending) {
122 memcpy(pseudo_addr, p_q->resolve_q_random_pseudo[p_q->q_pending], BD_ADDR_LEN);
123 memset(p_q->resolve_q_random_pseudo[p_q->q_pending], 0, BD_ADDR_LEN);
125 p_q->q_pending %= controller_get_interface()->get_ble_resolving_list_max_size();
132 /*******************************************************************************
134 ** Function btm_ble_clear_irk_index
136 ** Description clear IRK list index mask for availability
140 *******************************************************************************/
141 void btm_ble_clear_irk_index(UINT8 index)
146 if (index < controller_get_interface()->get_ble_resolving_list_max_size()) {
149 btm_cb.ble_ctr_cb.irk_list_mask[byte] &= (~(1 << bit));
153 /*******************************************************************************
155 ** Function btm_ble_find_irk_index
157 ** Description find the first available IRK list index
159 ** Returns index from 0 ~ max (127 default)
161 *******************************************************************************/
162 UINT8 btm_ble_find_irk_index(void)
168 while (i < controller_get_interface()->get_ble_resolving_list_max_size()) {
172 if ((btm_cb.ble_ctr_cb.irk_list_mask[byte] & (1 << bit)) == 0) {
173 btm_cb.ble_ctr_cb.irk_list_mask[byte] |= (1 << bit);
179 BTM_TRACE_ERROR ("%s failed, list full", __func__);
183 /*******************************************************************************
185 ** Function btm_ble_update_resolving_list
187 ** Description update resolving list entry in host maintained record
191 *******************************************************************************/
192 void btm_ble_update_resolving_list(BD_ADDR pseudo_bda, BOOLEAN add)
194 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_bda);
195 if (p_dev_rec == NULL) {
200 p_dev_rec->ble.in_controller_list |= BTM_RESOLVING_LIST_BIT;
201 if (!controller_get_interface()->supports_ble_privacy()) {
202 p_dev_rec->ble.resolving_list_index = btm_ble_find_irk_index();
205 p_dev_rec->ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT;
206 if (!controller_get_interface()->supports_ble_privacy()) {
207 /* clear IRK list index mask */
208 btm_ble_clear_irk_index(p_dev_rec->ble.resolving_list_index);
209 p_dev_rec->ble.resolving_list_index = 0;
214 /*******************************************************************************
216 ** Function btm_ble_clear_resolving_list_complete
218 ** Description This function is called when command complete for
219 ** clear resolving list
223 *******************************************************************************/
224 void btm_ble_clear_resolving_list_complete(UINT8 *p, UINT16 evt_len)
227 STREAM_TO_UINT8(status, p);
229 BTM_TRACE_DEBUG("%s status=%d", __func__, status);
231 if (status == HCI_SUCCESS) {
233 /* VSC complete has one extra byte for op code and list size, skip it here */
236 /* updated the available list size, and current list size */
237 uint8_t irk_list_sz_max = 0;
238 STREAM_TO_UINT8(irk_list_sz_max, p);
240 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
241 btm_ble_resolving_list_init(irk_list_sz_max);
244 uint8_t irk_mask_size = (irk_list_sz_max % 8) ?
245 (irk_list_sz_max / 8 + 1) : (irk_list_sz_max / 8);
246 memset(btm_cb.ble_ctr_cb.irk_list_mask, 0, irk_mask_size);
249 btm_cb.ble_ctr_cb.resolving_list_avail_size =
250 controller_get_interface()->get_ble_resolving_list_max_size();
252 BTM_TRACE_DEBUG("%s resolving_list_avail_size=%d",
253 __func__, btm_cb.ble_ctr_cb.resolving_list_avail_size);
255 for (UINT8 i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; ++i) {
256 btm_cb.sec_dev_rec[i].ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT;
261 /*******************************************************************************
263 ** Function btm_ble_add_resolving_list_entry_complete
265 ** Description This function is called when command complete for
266 ** add resolving list entry
270 *******************************************************************************/
271 void btm_ble_add_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
274 STREAM_TO_UINT8(status, p);
276 BTM_TRACE_DEBUG("%s status = %d", __func__, status);
279 if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
280 BTM_TRACE_DEBUG("no pending resolving list operation");
284 if (status == HCI_SUCCESS) {
285 /* privacy 1.2 command complete does not have these extra byte */
287 /* VSC complete has one extra byte for op code, skip it here */
289 STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
291 btm_cb.ble_ctr_cb.resolving_list_avail_size --;
293 } else if (status == HCI_ERR_MEMORY_FULL) { /* BT_ERROR_CODE_MEMORY_CAPACITY_EXCEEDED */
294 btm_cb.ble_ctr_cb.resolving_list_avail_size = 0;
295 BTM_TRACE_DEBUG("%s Resolving list Full ", __func__);
299 /*******************************************************************************
301 ** Function btm_ble_remove_resolving_list_entry_complete
303 ** Description This function is called when command complete for
304 ** remove resolving list entry
308 *******************************************************************************/
309 void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
314 STREAM_TO_UINT8(status, p);
316 BTM_TRACE_DEBUG("%s status = %d", __func__, status);
318 if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
319 BTM_TRACE_ERROR("%s no pending resolving list operation", __func__);
323 if (status == HCI_SUCCESS) {
324 /* proprietary: spec does not have these extra bytes */
326 p ++; /* skip opcode */
327 STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
329 btm_cb.ble_ctr_cb.resolving_list_avail_size++;
334 /*******************************************************************************
336 ** Function btm_ble_read_resolving_list_entry_complete
338 ** Description This function is called when command complete for
339 ** remove resolving list entry
343 *******************************************************************************/
344 void btm_ble_read_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
346 UINT8 status, rra_type = BTM_BLE_ADDR_PSEUDO;
347 BD_ADDR rra, pseudo_bda;
349 STREAM_TO_UINT8 (status, p);
351 BTM_TRACE_DEBUG("%s status = %d", __func__, status);
353 if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
354 BTM_TRACE_ERROR("no pending resolving list operation");
358 if (status == HCI_SUCCESS) {
359 /* proprietary spec has extra bytes */
361 p += (2 + 16 + 1 + 6); /* skip subcode, index, IRK value, address type, identity addr type */
362 STREAM_TO_BDADDR(rra, p);
364 BTM_TRACE_ERROR("%s peer_addr: %02x:%02x:%02x:%02x:%02x:%02x",
365 __func__, rra[0], rra[1], rra[2], rra[3], rra[4], rra[5]);
367 STREAM_TO_BDADDR(rra, p);
369 btm_ble_refresh_peer_resolvable_private_addr(pseudo_bda, rra, rra_type);
372 /*******************************************************************************
373 VSC that implement controller based privacy
374 ********************************************************************************/
375 /*******************************************************************************
377 ** Function btm_ble_resolving_list_vsc_op_cmpl
379 ** Description IRK operation VSC complete handler
385 *******************************************************************************/
386 void btm_ble_resolving_list_vsc_op_cmpl (tBTM_VSC_CMPL *p_params)
388 UINT8 *p = p_params->p_param_buf, op_subcode;
389 UINT16 evt_len = p_params->param_len;
391 op_subcode = *(p + 1);
393 BTM_TRACE_DEBUG("%s op_subcode = %d", __func__, op_subcode);
395 if (op_subcode == BTM_BLE_META_CLEAR_IRK_LIST) {
396 btm_ble_clear_resolving_list_complete(p, evt_len);
397 } else if (op_subcode == BTM_BLE_META_ADD_IRK_ENTRY) {
398 btm_ble_add_resolving_list_entry_complete(p, evt_len);
399 } else if (op_subcode == BTM_BLE_META_REMOVE_IRK_ENTRY) {
400 btm_ble_remove_resolving_list_entry_complete(p, evt_len);
401 } else if (op_subcode == BTM_BLE_META_READ_IRK_ENTRY) {
402 btm_ble_read_resolving_list_entry_complete(p, evt_len);
403 } else if (op_subcode == BTM_BLE_META_IRK_ENABLE) {
404 /* RPA offloading enable/disabled */
408 /*******************************************************************************
410 ** Function btm_ble_remove_resolving_list_entry
412 ** Description This function to remove an IRK entry from the list
414 ** Parameters ble_addr_type: address type
415 ** ble_addr: LE adddress
419 *******************************************************************************/
420 tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
422 /* if controller does not support RPA offloading or privacy 1.2, skip */
423 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
424 return BTM_WRONG_MODE;
427 tBTM_STATUS st = BTM_NO_RESOURCES;
428 if (controller_get_interface()->supports_ble_privacy()) {
429 if (btsnd_hcic_ble_rm_device_resolving_list(p_dev_rec->ble.static_addr_type,
430 p_dev_rec->ble.static_addr)) {
431 st = BTM_CMD_STARTED;
434 UINT8 param[20] = {0};
437 UINT8_TO_STREAM(p, BTM_BLE_META_REMOVE_IRK_ENTRY);
438 UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
439 BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);
441 st = BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC,
442 BTM_BLE_META_REMOVE_IRK_LEN,
444 btm_ble_resolving_list_vsc_op_cmpl);
447 if (st == BTM_CMD_STARTED) {
448 btm_ble_enq_resolving_list_pending( p_dev_rec->bd_addr, BTM_BLE_META_REMOVE_IRK_ENTRY);
454 /*******************************************************************************
456 ** Function btm_ble_clear_resolving_list
458 ** Description This function clears the resolving list
464 *******************************************************************************/
465 tBTM_STATUS btm_ble_clear_resolving_list(void)
467 tBTM_STATUS st = BTM_NO_RESOURCES;
469 if (controller_get_interface()->supports_ble_privacy()) {
470 if (btsnd_hcic_ble_clear_resolving_list()) {
474 UINT8 param[20] = {0};
477 UINT8_TO_STREAM(p, BTM_BLE_META_CLEAR_IRK_LIST);
478 st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
479 BTM_BLE_META_CLEAR_IRK_LEN,
481 btm_ble_resolving_list_vsc_op_cmpl);
487 /*******************************************************************************
489 ** Function btm_ble_read_resolving_list_entry
491 ** Description This function read an IRK entry by index
493 ** Parameters entry index.
497 *******************************************************************************/
498 tBTM_STATUS btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
500 tBTM_STATUS st = BTM_NO_RESOURCES;
502 if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT)) {
503 return BTM_WRONG_MODE;
506 if (controller_get_interface()->supports_ble_privacy()) {
507 if (btsnd_hcic_ble_read_resolvable_addr_peer(p_dev_rec->ble.static_addr_type,
508 p_dev_rec->ble.static_addr)) {
509 st = BTM_CMD_STARTED;
512 UINT8 param[20] = {0};
515 UINT8_TO_STREAM(p, BTM_BLE_META_READ_IRK_ENTRY);
516 UINT8_TO_STREAM(p, p_dev_rec->ble.resolving_list_index);
518 st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
519 BTM_BLE_META_READ_IRK_LEN,
521 btm_ble_resolving_list_vsc_op_cmpl);
524 if (st == BTM_CMD_STARTED)
525 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
526 BTM_BLE_META_READ_IRK_ENTRY);
532 /*******************************************************************************
534 ** Function btm_ble_suspend_resolving_list_activity
536 ** Description This function suspends all resolving list activity, including
537 ** scan, initiating, and advertising, if resolving list is being
542 ** Returns TRUE if suspended; FALSE otherwise
544 *******************************************************************************/
545 BOOLEAN btm_ble_suspend_resolving_list_activity(void)
547 tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
549 /* if resolving list is not enabled, do not need to terminate any activity */
550 /* if asking for stop all activity */
551 /* if already suspended */
552 if (p_ble_cb->suspended_rl_state != BTM_BLE_RL_IDLE) {
556 /* direct connection active, wait until it completed */
557 if (btm_ble_get_conn_st() == BLE_DIR_CONN) {
558 BTM_TRACE_ERROR("resolving list can not be edited, EnQ now");
562 p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
564 if (p_ble_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE) {
566 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_ADV;
569 if (BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) {
571 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_SCAN;
574 if (btm_ble_suspend_bg_conn()) {
575 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_INIT;
581 /*******************************************************************************
583 ** Function btm_ble_resume_resolving_list_activity
585 ** Description This function resumes the resolving list activity, including
586 ** scanning, initiating, and advertising, if any of these
587 ** activities has been suspended earlier.
591 *******************************************************************************/
592 void btm_ble_resume_resolving_list_activity(void)
594 tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
596 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_ADV) {
600 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_SCAN) {
601 btm_ble_start_scan();
604 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_INIT) {
605 btm_ble_resume_bg_conn();
608 p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
611 /*******************************************************************************
613 ** Function btm_ble_vendor_enable_irk_feature
615 ** Description This function is called to enable or disable the RRA
616 ** offloading feature.
618 ** Parameters enable: enable or disable the RRA offloading feature
620 ** Returns BTM_SUCCESS if successful
622 *******************************************************************************/
623 tBTM_STATUS btm_ble_vendor_enable_irk_feature(BOOLEAN enable)
626 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
629 memset(param, 0, 20);
631 /* select feature based on control block settings */
632 UINT8_TO_STREAM(p, BTM_BLE_META_IRK_ENABLE);
633 UINT8_TO_STREAM(p, enable ? 0x01 : 0x00);
635 st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_IRK_ENABLE_LEN,
636 param, btm_ble_resolving_list_vsc_op_cmpl);
641 /*******************************************************************************
643 ** Function btm_ble_exe_disable_resolving_list
645 ** Description execute resolving list disable
649 *******************************************************************************/
650 BOOLEAN btm_ble_exe_disable_resolving_list(void)
652 if (!btm_ble_suspend_resolving_list_activity()) {
656 if (!controller_get_interface()->supports_ble_privacy()) {
657 btm_ble_vendor_enable_irk_feature(FALSE);
659 btsnd_hcic_ble_set_addr_resolution_enable(FALSE);
665 /*******************************************************************************
667 ** Function btm_ble_exe_enable_resolving_list
669 ** Description enable LE resolve address list
673 *******************************************************************************/
674 void btm_ble_exe_enable_resolving_list(void)
676 if (!btm_ble_suspend_resolving_list_activity()) {
680 if (!controller_get_interface()->supports_ble_privacy()) {
681 btm_ble_vendor_enable_irk_feature(TRUE);
683 btsnd_hcic_ble_set_addr_resolution_enable(TRUE);
687 /*******************************************************************************
689 ** Function btm_ble_disable_resolving_list
691 ** Description Disable LE Address resolution
695 *******************************************************************************/
696 BOOLEAN btm_ble_disable_resolving_list(UINT8 rl_mask, BOOLEAN to_resume )
698 UINT8 rl_state = btm_cb.ble_ctr_cb.rl_state;
700 /* if controller does not support RPA offloading or privacy 1.2, skip */
701 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
705 btm_cb.ble_ctr_cb.rl_state &= ~rl_mask;
707 if (rl_state != BTM_BLE_RL_IDLE && btm_cb.ble_ctr_cb.rl_state == BTM_BLE_RL_IDLE) {
708 if (btm_ble_exe_disable_resolving_list()) {
710 btm_ble_resume_resolving_list_activity();
722 /*******************************************************************************
724 ** Function btm_ble_resolving_list_load_dev
726 ** Description This function add a device which is using RPA into white list
728 ** Parameters pointer to device security record
730 ** Returns TRUE if device added, otherwise falase.
732 *******************************************************************************/
733 BOOLEAN btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec)
736 #if (SMP_INCLUDED == TRUE)
737 UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;
739 BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d\n", __func__,
740 btm_cb.ble_ctr_cb.privacy_mode);
742 /* if controller does not support RPA offloading or privacy 1.2, skip */
743 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
747 BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d\n",
748 __func__, btm_cb.ble_ctr_cb.privacy_mode);
750 /* only add RPA enabled device into resolving list */
751 if (p_dev_rec != NULL && /* RPA is being used and PID is known */
752 (p_dev_rec->sec_flags & BTM_SEC_IN_USE) != 0 &&
753 ((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0 ||
754 (p_dev_rec->ble.key_type & BTM_LE_KEY_LID) != 0)) {
755 if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
756 btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
757 BTM_BLE_META_ADD_IRK_ENTRY) == FALSE) {
758 if (btm_cb.ble_ctr_cb.resolving_list_avail_size > 0) {
760 if (!btm_ble_disable_resolving_list (rl_mask, FALSE)) {
765 btm_ble_update_resolving_list(p_dev_rec->bd_addr, TRUE);
766 if (controller_get_interface()->supports_ble_privacy()) {
767 BD_ADDR dummy_bda = {0};
768 if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) == 0) {
769 memcpy(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
770 p_dev_rec->ble.static_addr_type = p_dev_rec->ble.ble_addr_type;
772 /* It will cause that scanner doesn't send scan request to advertiser
773 * which has sent IRK to us and we have stored the IRK in controller.
774 * It is a design problem of hardware. The temporal solution is not to
775 * send the key to the controller and then resolve the random address in host. */
777 BTM_TRACE_DEBUG("%s:adding device to controller resolving list\n", __func__);
778 UINT8 *peer_irk = p_dev_rec->ble.keys.irk;
779 UINT8 *local_irk = btm_cb.devcb.id_keys.irk;
780 //use identical IRK for now
781 rt = btsnd_hcic_ble_add_device_resolving_list(p_dev_rec->ble.static_addr_type,
782 p_dev_rec->ble.static_addr, peer_irk, local_irk);
785 UINT8 param[40] = {0};
788 UINT8_TO_STREAM(p, BTM_BLE_META_ADD_IRK_ENTRY);
789 ARRAY_TO_STREAM(p, p_dev_rec->ble.keys.irk, BT_OCTET16_LEN);
790 UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
791 BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);
793 if (BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
794 BTM_BLE_META_ADD_IRK_LEN,
796 btm_ble_resolving_list_vsc_op_cmpl)
797 == BTM_CMD_STARTED) {
803 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
804 BTM_BLE_META_ADD_IRK_ENTRY);
806 /* if resolving list has been turned on, re-enable it */
808 btm_ble_enable_resolving_list(rl_mask);
810 btm_ble_enable_resolving_list(BTM_BLE_RL_INIT);
814 BTM_TRACE_DEBUG("Device already in Resolving list\n");
818 BTM_TRACE_DEBUG("Device not a RPA enabled device\n");
820 #endif ///SMP_INCLUDED == TRUE
824 /*******************************************************************************
826 ** Function btm_ble_resolving_list_remove_dev
828 ** Description This function removes the device from resolving list
834 *******************************************************************************/
835 void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC *p_dev_rec)
837 UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;
839 BTM_TRACE_EVENT ("%s\n", __func__);
841 if (!btm_ble_disable_resolving_list (rl_mask, FALSE)) {
846 if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
847 btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
848 BTM_BLE_META_REMOVE_IRK_ENTRY) == FALSE) {
849 btm_ble_update_resolving_list( p_dev_rec->bd_addr, FALSE);
850 btm_ble_remove_resolving_list_entry(p_dev_rec);
852 BTM_TRACE_DEBUG("Device not in resolving list\n");
855 /* if resolving list has been turned on, re-enable it */
857 btm_ble_enable_resolving_list(rl_mask);
861 /*******************************************************************************
863 ** Function btm_ble_enable_resolving_list
865 ** Description enable LE resolve address list
869 *******************************************************************************/
870 void btm_ble_enable_resolving_list(UINT8 rl_mask)
872 UINT8 rl_state = btm_cb.ble_ctr_cb.rl_state;
874 btm_cb.ble_ctr_cb.rl_state |= rl_mask;
875 if (rl_state == BTM_BLE_RL_IDLE &&
876 btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE &&
877 controller_get_interface()->get_ble_resolving_list_max_size() != 0) {
878 btm_ble_exe_enable_resolving_list();
879 btm_ble_resume_resolving_list_activity();
883 /*******************************************************************************
885 ** Function btm_ble_resolving_list_empty
887 ** Description check to see if resoving list is empty or not
889 ** Returns TRUE: empty; FALSE non-empty
891 *******************************************************************************/
892 BOOLEAN btm_ble_resolving_list_empty(void)
894 return (controller_get_interface()->get_ble_resolving_list_max_size() ==
895 btm_cb.ble_ctr_cb.resolving_list_avail_size);
898 /*******************************************************************************
900 ** Function btm_ble_enable_resolving_list_for_platform
902 ** Description enable/disable resolving list feature depending on if any
903 ** resolving list is empty and whitelist is involoved in the
908 *******************************************************************************/
909 void btm_ble_enable_resolving_list_for_platform (UINT8 rl_mask)
911 /* if controller does not support, skip */
912 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
916 if (btm_cb.ble_ctr_cb.wl_state == BTM_BLE_WL_IDLE) {
917 if (controller_get_interface()->get_ble_resolving_list_max_size() >
918 btm_cb.ble_ctr_cb.resolving_list_avail_size) {
919 btm_ble_enable_resolving_list(rl_mask);
921 btm_ble_disable_resolving_list(rl_mask, TRUE);
926 tBTM_SEC_DEV_REC *p_dev = &btm_cb.sec_dev_rec[0];
927 for (UINT8 i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++, p_dev ++) {
928 if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
929 (p_dev->ble.in_controller_list & BTM_WHITE_LIST_BIT)) {
930 btm_ble_enable_resolving_list(rl_mask);
934 btm_ble_disable_resolving_list(rl_mask, TRUE);
937 /*******************************************************************************
939 ** Function btm_ble_resolving_list_init
941 ** Description Initialize resolving list in host stack
943 ** Parameters Max resolving list size
947 *******************************************************************************/
948 void btm_ble_resolving_list_init(UINT8 max_irk_list_sz)
950 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
951 UINT8 irk_mask_size = (max_irk_list_sz % 8) ?
952 (max_irk_list_sz / 8 + 1) : (max_irk_list_sz / 8);
954 if (max_irk_list_sz > 0) {
955 p_q->resolve_q_random_pseudo = (BD_ADDR *)osi_malloc(sizeof(BD_ADDR) * max_irk_list_sz);
956 p_q->resolve_q_action = (UINT8 *)osi_malloc(max_irk_list_sz);
958 /* RPA offloading feature */
959 if (btm_cb.ble_ctr_cb.irk_list_mask == NULL) {
960 btm_cb.ble_ctr_cb.irk_list_mask = (UINT8 *)osi_malloc(irk_mask_size);
963 BTM_TRACE_DEBUG ("%s max_irk_list_sz = %d", __func__, max_irk_list_sz);
966 controller_get_interface()->set_ble_resolving_list_max_size(max_irk_list_sz);
967 btm_ble_clear_resolving_list();
968 btm_cb.ble_ctr_cb.resolving_list_avail_size = max_irk_list_sz;
971 /*******************************************************************************
973 ** Function btm_ble_resolving_list_cleanup
975 ** Description Cleanup resolving list dynamic memory
981 *******************************************************************************/
982 void btm_ble_resolving_list_cleanup(void)
984 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
986 if (p_q->resolve_q_random_pseudo) {
987 osi_free(p_q->resolve_q_random_pseudo);
988 p_q->resolve_q_random_pseudo = NULL;
991 if (p_q->resolve_q_action) {
992 osi_free(p_q->resolve_q_action);
993 p_q->resolve_q_action = NULL;
996 controller_get_interface()->set_ble_resolving_list_max_size(0);
997 if (btm_cb.ble_ctr_cb.irk_list_mask) {
998 osi_free(btm_cb.ble_ctr_cb.irk_list_mask);
999 btm_cb.ble_ctr_cb.irk_list_mask = NULL;