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