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