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 "common/bt_target.h"
26
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"
32 #include "btm_int.h"
33 #include "device/controller.h"
34 #include "stack/hcidefs.h"
35
36 #define HCI_VENDOR_BLE_RPA_VSC (0x0155 | HCI_GRP_VENDOR_SPECIFIC)
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(BD_ADDR pseudo_bda,UINT8 op_code)68 void btm_ble_enq_resolving_list_pending(BD_ADDR pseudo_bda, UINT8 op_code)
69 {
70 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
71
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;
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(BD_ADDR pseudo_addr,UINT8 action)90 BOOLEAN btm_ble_brcm_find_resolving_pending_entry(BD_ADDR pseudo_addr, UINT8 action)
91 {
92 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
93
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]) {
97 return TRUE;
98 }
99
100 i ++;
101 i %= controller_get_interface()->get_ble_resolving_list_max_size();
102 }
103 return FALSE;
104 }
105
106 /*******************************************************************************
107 **
108 ** Function btm_ble_deq_resolving_pending
109 **
110 ** Description dequeue target address from resolving pending operation queue
111 **
112 ** Parameters pseudo_addr: pseudo_addr device address
113 **
114 ** Returns void
115 **
116 *******************************************************************************/
btm_ble_deq_resolving_pending(BD_ADDR pseudo_addr)117 BOOLEAN btm_ble_deq_resolving_pending(BD_ADDR pseudo_addr)
118 {
119 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
120
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);
124 p_q->q_pending ++;
125 p_q->q_pending %= 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 index)141 void btm_ble_clear_irk_index(UINT8 index)
142 {
143 UINT8 byte;
144 UINT8 bit;
145
146 if (index < controller_get_interface()->get_ble_resolving_list_max_size()) {
147 byte = index / 8;
148 bit = index % 8;
149 btm_cb.ble_ctr_cb.irk_list_mask[byte] &= (~(1 << bit));
150 }
151 }
152
153 /*******************************************************************************
154 **
155 ** Function btm_ble_find_irk_index
156 **
157 ** Description find the first available IRK list index
158 **
159 ** Returns index from 0 ~ max (127 default)
160 **
161 *******************************************************************************/
btm_ble_find_irk_index(void)162 UINT8 btm_ble_find_irk_index(void)
163 {
164 UINT8 i = 0;
165 UINT8 byte;
166 UINT8 bit;
167
168 while (i < controller_get_interface()->get_ble_resolving_list_max_size()) {
169 byte = i / 8;
170 bit = i % 8;
171
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);
174 return i;
175 }
176 i++;
177 }
178
179 BTM_TRACE_ERROR ("%s failed, list full", __func__);
180 return i;
181 }
182
183 /*******************************************************************************
184 **
185 ** Function btm_ble_update_resolving_list
186 **
187 ** Description update resolving list entry in host maintained record
188 **
189 ** Returns void
190 **
191 *******************************************************************************/
btm_ble_update_resolving_list(BD_ADDR pseudo_bda,BOOLEAN add)192 void btm_ble_update_resolving_list(BD_ADDR pseudo_bda, BOOLEAN add)
193 {
194 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_bda);
195 if (p_dev_rec == NULL) {
196 return;
197 }
198
199 if (add) {
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();
203 }
204 } else {
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;
210 }
211 }
212 }
213
214 /*******************************************************************************
215 **
216 ** Function btm_ble_clear_resolving_list_complete
217 **
218 ** Description This function is called when command complete for
219 ** clear resolving list
220 **
221 ** Returns void
222 **
223 *******************************************************************************/
btm_ble_clear_resolving_list_complete(UINT8 * p,UINT16 evt_len)224 void btm_ble_clear_resolving_list_complete(UINT8 *p, UINT16 evt_len)
225 {
226 UINT8 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 p ++;
235
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);
239
240 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
241 btm_ble_resolving_list_init(irk_list_sz_max);
242 }
243
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);
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",
253 __func__, btm_cb.ble_ctr_cb.resolving_list_avail_size);
254
255 list_node_t *p_node = NULL;
256 tBTM_SEC_DEV_REC *p_dev_rec = NULL;
257 for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) {
258 p_dev_rec = list_node(p_node);
259 p_dev_rec->ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT;
260 }
261 }
262 }
263
264 /*******************************************************************************
265 **
266 ** Function btm_ble_add_resolving_list_entry_complete
267 **
268 ** Description This function is called when command complete for
269 ** add resolving list entry
270 **
271 ** Returns void
272 **
273 *******************************************************************************/
btm_ble_add_resolving_list_entry_complete(UINT8 * p,UINT16 evt_len)274 void btm_ble_add_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
275 {
276 UINT8 status;
277 STREAM_TO_UINT8(status, p);
278 if (btm_cb.devcb.p_add_dev_to_resolving_list_cmpl_cb) {
279 tBTM_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK *p_cb = btm_cb.devcb.p_add_dev_to_resolving_list_cmpl_cb;
280 if (p_cb) {
281 (*p_cb)(status);
282 }
283 } else {
284 BTM_TRACE_DEBUG("no resolving list callback");
285 }
286
287 BTM_TRACE_DEBUG("%s status = %d", __func__, status);
288
289 BD_ADDR pseudo_bda;
290 if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
291 BTM_TRACE_DEBUG("no pending resolving list operation");
292 return;
293 }
294
295 if (status == HCI_SUCCESS) {
296 /* privacy 1.2 command complete does not have these extra byte */
297 if (evt_len > 2) {
298 /* VSC complete has one extra byte for op code, skip it here */
299 p ++;
300 STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
301 } else {
302 btm_cb.ble_ctr_cb.resolving_list_avail_size --;
303 }
304 } else if (status == HCI_ERR_MEMORY_FULL) { /* BT_ERROR_CODE_MEMORY_CAPACITY_EXCEEDED */
305 btm_cb.ble_ctr_cb.resolving_list_avail_size = 0;
306 BTM_TRACE_ERROR("%s Resolving list Full ", __func__);
307 } else {
308 BTM_TRACE_ERROR("%s Add resolving list error %d ", __func__, status);
309 }
310
311 }
312
313 /*******************************************************************************
314 **
315 ** Function btm_ble_remove_resolving_list_entry_complete
316 **
317 ** Description This function is called when command complete for
318 ** remove resolving list entry
319 **
320 ** Returns void
321 **
322 *******************************************************************************/
btm_ble_remove_resolving_list_entry_complete(UINT8 * p,UINT16 evt_len)323 void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
324 {
325 BD_ADDR pseudo_bda;
326 UINT8 status;
327
328 STREAM_TO_UINT8(status, p);
329
330 BTM_TRACE_DEBUG("%s status = %d", __func__, status);
331
332 if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
333 BTM_TRACE_DEBUG("%s no pending resolving list operation", __func__);
334 return;
335 }
336
337 if (status == HCI_SUCCESS) {
338 /* proprietary: spec does not have these extra bytes */
339 if (evt_len > 2) {
340 p ++; /* skip opcode */
341 STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
342 } else {
343 btm_cb.ble_ctr_cb.resolving_list_avail_size++;
344 }
345 } else {
346 BTM_TRACE_ERROR("%s remove resolving list error 0x%x", __func__, status);
347 }
348 }
349
350 /*******************************************************************************
351 **
352 ** Function btm_ble_read_resolving_list_entry_complete
353 **
354 ** Description This function is called when command complete for
355 ** remove resolving list entry
356 **
357 ** Returns void
358 **
359 *******************************************************************************/
btm_ble_read_resolving_list_entry_complete(UINT8 * p,UINT16 evt_len)360 void btm_ble_read_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
361 {
362 UINT8 status, rra_type = BTM_BLE_ADDR_PSEUDO;
363 BD_ADDR rra, pseudo_bda;
364
365 STREAM_TO_UINT8 (status, p);
366
367 BTM_TRACE_DEBUG("%s status = %d", __func__, status);
368
369 if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
370 BTM_TRACE_ERROR("no pending resolving list operation");
371 return;
372 }
373
374 if (status == HCI_SUCCESS) {
375 /* proprietary spec has extra bytes */
376 if (evt_len > 8) {
377 p += (2 + 16 + 1 + 6); /* skip subcode, index, IRK value, address type, identity addr type */
378 STREAM_TO_BDADDR(rra, p);
379
380 BTM_TRACE_ERROR("%s peer_addr: %02x:%02x:%02x:%02x:%02x:%02x",
381 __func__, rra[0], rra[1], rra[2], rra[3], rra[4], rra[5]);
382 } else {
383 STREAM_TO_BDADDR(rra, p);
384 }
385 btm_ble_refresh_peer_resolvable_private_addr(pseudo_bda, rra, rra_type);
386 }
387 }
388
389 /*******************************************************************************
390 **
391 ** Function btm_ble_set_addr_resolution_enable_complete
392 **
393 ** Description This function is called when the command to set address
394 ** resolution enable completes.
395 **
396 ** Parameters p: Pointer to the command complete event data.
397 ** evt_len: Length of the event data.
398 **
399 ** Returns void
400 **
401 *******************************************************************************/
btm_ble_set_addr_resolution_enable_complete(UINT8 * p,UINT16 evt_len)402 void btm_ble_set_addr_resolution_enable_complete(UINT8 *p, UINT16 evt_len)
403 {
404 UINT8 status;
405
406 STREAM_TO_UINT8(status, p);
407
408 BTM_TRACE_DEBUG("%s status = %d", __func__, status);
409
410 tBTM_LE_RANDOM_CB *random_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
411
412 if (!(random_cb && random_cb->set_local_privacy_cback)) {
413 return;
414 }
415
416 if (status == HCI_SUCCESS) {
417 random_cb->set_local_privacy_cback(BTM_SUCCESS);
418 return;
419 } else if (status == HCI_ERR_COMMAND_DISALLOWED) {
420 BTM_TRACE_ERROR("a non-connected activity is ongoing, such as advertising and scanning");
421 } else {
422 BTM_TRACE_ERROR("set local privacy failed");
423 }
424 random_cb->set_local_privacy_cback(BTM_ILLEGAL_VALUE);
425 }
426
427 /*******************************************************************************
428 **
429 ** Function btm_ble_set_rpa_timeout_complete
430 **
431 ** Description This function is called when the LE Set Resolvable Private
432 ** Address Timeout command completes.
433 **
434 ** Parameters p: Pointer to the command complete event data.
435 ** evt_len: Length of the event data.
436 **
437 ** Returns void
438 **
439 *******************************************************************************/
btm_ble_set_rpa_timeout_complete(UINT8 * p,UINT16 evt_len)440 void btm_ble_set_rpa_timeout_complete(UINT8 *p, UINT16 evt_len)
441 {
442 UINT8 status;
443
444 // Extract the status of the command completion from the event data
445 STREAM_TO_UINT8(status, p);
446
447 BTM_TRACE_DEBUG("%s status = %d", __func__, status);
448
449 tBTM_SET_RPA_TIMEOUT_CMPL_CBACK *p_cb = btm_cb.devcb.p_ble_set_rpa_timeout_cmpl_cb;
450
451 if (p_cb) {
452 (*p_cb)(status);
453 }
454
455 }
456
457 /*******************************************************************************
458 **
459 ** Function btm_ble_set_privacy_mode_complete
460 **
461 ** Description This function is called when the LE Set Privacy Mode command completes.
462 **
463 ** Parameters p: Pointer to the command complete event data.
464 ** evt_len: Length of the event data.
465 **
466 ** Returns void
467 **
468 *******************************************************************************/
btm_ble_set_privacy_mode_complete(UINT8 * p,UINT16 evt_len)469 void btm_ble_set_privacy_mode_complete(UINT8 *p, UINT16 evt_len)
470 {
471 UINT8 status;
472
473 // Extract the status of the command completion from the event data
474 STREAM_TO_UINT8(status, p);
475
476 BTM_TRACE_DEBUG("%s status = 0x%x", __func__, status);
477
478 tBTM_SET_PRIVACY_MODE_CMPL_CBACK *p_cb = btm_cb.devcb.p_set_privacy_mode_cmpl_cb;
479
480 if (p_cb) {
481 (*p_cb)(status);
482 }
483 }
484
485 /*******************************************************************************
486 VSC that implement controller based privacy
487 ********************************************************************************/
488 /*******************************************************************************
489 **
490 ** Function btm_ble_resolving_list_vsc_op_cmpl
491 **
492 ** Description IRK operation VSC complete handler
493 **
494 ** Parameters
495 **
496 ** Returns void
497 **
498 *******************************************************************************/
btm_ble_resolving_list_vsc_op_cmpl(tBTM_VSC_CMPL * p_params)499 void btm_ble_resolving_list_vsc_op_cmpl (tBTM_VSC_CMPL *p_params)
500 {
501 UINT8 *p = p_params->p_param_buf, op_subcode;
502 UINT16 evt_len = p_params->param_len;
503
504 op_subcode = *(p + 1);
505
506 BTM_TRACE_DEBUG("%s op_subcode = %d", __func__, op_subcode);
507
508 if (op_subcode == BTM_BLE_META_CLEAR_IRK_LIST) {
509 btm_ble_clear_resolving_list_complete(p, evt_len);
510 } else if (op_subcode == BTM_BLE_META_ADD_IRK_ENTRY) {
511 btm_ble_add_resolving_list_entry_complete(p, evt_len);
512 } else if (op_subcode == BTM_BLE_META_REMOVE_IRK_ENTRY) {
513 btm_ble_remove_resolving_list_entry_complete(p, evt_len);
514 } else if (op_subcode == BTM_BLE_META_READ_IRK_ENTRY) {
515 btm_ble_read_resolving_list_entry_complete(p, evt_len);
516 } else if (op_subcode == BTM_BLE_META_IRK_ENABLE) {
517 /* RPA offloading enable/disabled */
518 }
519 }
520
521 /*******************************************************************************
522 **
523 ** Function btm_ble_remove_resolving_list_entry
524 **
525 ** Description This function to remove an IRK entry from the list
526 **
527 ** Parameters ble_addr_type: address type
528 ** ble_addr: LE address
529 **
530 ** Returns status
531 **
532 *******************************************************************************/
btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC * p_dev_rec)533 tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
534 {
535 /* if controller does not support RPA offloading or privacy 1.2, skip */
536 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
537 return BTM_WRONG_MODE;
538 }
539
540 tBTM_STATUS st = BTM_NO_RESOURCES;
541 if (controller_get_interface()->supports_ble_privacy()) {
542 #if CONTROLLER_RPA_LIST_ENABLE
543 if (btsnd_hcic_ble_rm_device_resolving_list(p_dev_rec->ble.static_addr_type,
544 p_dev_rec->ble.static_addr)) {
545 st = BTM_CMD_STARTED;
546 }
547 #else
548 // do nothing
549 /* It will cause that scanner doesn't send scan request to advertiser
550 * which has sent IRK to us and we have stored the IRK in controller.
551 * It is a hardware limitation. The preliminary solution is not to
552 * send key to the controller, but to resolve the random address in host. */
553 #endif
554 } else {
555 UINT8 param[20] = {0};
556 UINT8 *p = param;
557
558 UINT8_TO_STREAM(p, BTM_BLE_META_REMOVE_IRK_ENTRY);
559 UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
560 BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);
561
562 st = BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC,
563 BTM_BLE_META_REMOVE_IRK_LEN,
564 param,
565 btm_ble_resolving_list_vsc_op_cmpl);
566 }
567
568 if (st == BTM_CMD_STARTED) {
569 btm_ble_enq_resolving_list_pending( p_dev_rec->bd_addr, BTM_BLE_META_REMOVE_IRK_ENTRY);
570 }
571
572 return st;
573 }
574
575 /*******************************************************************************
576 **
577 ** Function btm_ble_clear_resolving_list
578 **
579 ** Description This function clears the resolving list
580 **
581 ** Parameters None.
582 **
583 ** Returns status
584 **
585 *******************************************************************************/
btm_ble_clear_resolving_list(void)586 tBTM_STATUS btm_ble_clear_resolving_list(void)
587 {
588 tBTM_STATUS st = BTM_NO_RESOURCES;
589
590 if (controller_get_interface()->supports_ble_privacy()) {
591 if (btsnd_hcic_ble_clear_resolving_list()) {
592 st = BTM_SUCCESS;
593 }
594 } else {
595 UINT8 param[20] = {0};
596 UINT8 *p = param;
597
598 UINT8_TO_STREAM(p, BTM_BLE_META_CLEAR_IRK_LIST);
599 st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
600 BTM_BLE_META_CLEAR_IRK_LEN,
601 param,
602 btm_ble_resolving_list_vsc_op_cmpl);
603 }
604
605 return st;
606 }
607
608 /*******************************************************************************
609 **
610 ** Function btm_ble_read_resolving_list_entry
611 **
612 ** Description This function read an IRK entry by index
613 **
614 ** Parameters entry index.
615 **
616 ** Returns status
617 **
618 *******************************************************************************/
btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC * p_dev_rec)619 tBTM_STATUS btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
620 {
621 tBTM_STATUS st = BTM_NO_RESOURCES;
622
623 if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT)) {
624 return BTM_WRONG_MODE;
625 }
626
627 if (controller_get_interface()->supports_ble_privacy()) {
628 if (btsnd_hcic_ble_read_resolvable_addr_peer(p_dev_rec->ble.static_addr_type,
629 p_dev_rec->ble.static_addr)) {
630 st = BTM_CMD_STARTED;
631 }
632 } else {
633 UINT8 param[20] = {0};
634 UINT8 *p = param;
635
636 UINT8_TO_STREAM(p, BTM_BLE_META_READ_IRK_ENTRY);
637 UINT8_TO_STREAM(p, p_dev_rec->ble.resolving_list_index);
638
639 st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
640 BTM_BLE_META_READ_IRK_LEN,
641 param,
642 btm_ble_resolving_list_vsc_op_cmpl);
643 }
644
645 if (st == BTM_CMD_STARTED) {
646 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
647 BTM_BLE_META_READ_IRK_ENTRY);
648 }
649
650 return st;
651 }
652
653
654 /*******************************************************************************
655 **
656 ** Function btm_ble_suspend_resolving_list_activity
657 **
658 ** Description This function suspends all resolving list activity, including
659 ** scan, initiating, and advertising, if resolving list is being
660 ** enabled.
661 **
662 ** Parameters
663 **
664 ** Returns TRUE if suspended; FALSE otherwise
665 **
666 *******************************************************************************/
btm_ble_suspend_resolving_list_activity(void)667 BOOLEAN btm_ble_suspend_resolving_list_activity(void)
668 {
669 tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
670
671 /* if resolving list is not enabled, do not need to terminate any activity */
672 /* if asking for stop all activity */
673 /* if already suspended */
674 if (p_ble_cb->suspended_rl_state != BTM_BLE_RL_IDLE) {
675 return TRUE;
676 }
677
678 /* direct connection active, wait until it completed */
679 if (btm_ble_get_conn_st() == BLE_DIR_CONN) {
680 BTM_TRACE_ERROR("resolving list can not be edited, EnQ now");
681 return FALSE;
682 }
683
684 p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
685
686 if (p_ble_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE) {
687 btm_ble_stop_adv();
688 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_ADV;
689 }
690
691 if (BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) {
692 btm_ble_stop_scan();
693 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_SCAN;
694 }
695
696 if (btm_ble_suspend_bg_conn()) {
697 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_INIT;
698 }
699
700 return TRUE;
701 }
702
703 /*******************************************************************************
704 **
705 ** Function btm_ble_resume_resolving_list_activity
706 **
707 ** Description This function resumes the resolving list activity, including
708 ** scanning, initiating, and advertising, if any of these
709 ** activities has been suspended earlier.
710 **
711 ** Returns none
712 **
713 *******************************************************************************/
btm_ble_resume_resolving_list_activity(void)714 void btm_ble_resume_resolving_list_activity(void)
715 {
716 tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
717
718 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_ADV) {
719 btm_ble_start_adv();
720 }
721
722 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_SCAN) {
723 btm_ble_start_scan();
724 }
725
726 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_INIT) {
727 btm_ble_resume_bg_conn();
728 }
729
730 p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
731 }
732
733 /*******************************************************************************
734 **
735 ** Function btm_ble_vendor_enable_irk_feature
736 **
737 ** Description This function is called to enable or disable the RRA
738 ** offloading feature.
739 **
740 ** Parameters enable: enable or disable the RRA offloading feature
741 **
742 ** Returns BTM_SUCCESS if successful
743 **
744 *******************************************************************************/
btm_ble_vendor_enable_irk_feature(BOOLEAN enable)745 tBTM_STATUS btm_ble_vendor_enable_irk_feature(BOOLEAN enable)
746 {
747 UINT8 param[20], *p;
748 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
749
750 p = param;
751 memset(param, 0, 20);
752
753 /* select feature based on control block settings */
754 UINT8_TO_STREAM(p, BTM_BLE_META_IRK_ENABLE);
755 UINT8_TO_STREAM(p, enable ? 0x01 : 0x00);
756
757 st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_IRK_ENABLE_LEN,
758 param, btm_ble_resolving_list_vsc_op_cmpl);
759
760 return st;
761 }
762
763 /*******************************************************************************
764 **
765 ** Function btm_ble_exe_disable_resolving_list
766 **
767 ** Description execute resolving list disable
768 **
769 ** Returns none
770 **
771 *******************************************************************************/
btm_ble_exe_disable_resolving_list(void)772 BOOLEAN btm_ble_exe_disable_resolving_list(void)
773 {
774 if (!btm_ble_suspend_resolving_list_activity()) {
775 return FALSE;
776 }
777
778 if (!controller_get_interface()->supports_ble_privacy()) {
779 btm_ble_vendor_enable_irk_feature(FALSE);
780 } else {
781 //btsnd_hcic_ble_set_addr_resolution_enable(FALSE);
782 }
783
784 return TRUE;
785 }
786
787 /*******************************************************************************
788 **
789 ** Function btm_ble_exe_enable_resolving_list
790 **
791 ** Description enable LE resolve address list
792 **
793 ** Returns none
794 **
795 *******************************************************************************/
btm_ble_exe_enable_resolving_list(void)796 void btm_ble_exe_enable_resolving_list(void)
797 {
798 if (!btm_ble_suspend_resolving_list_activity()) {
799 return;
800 }
801
802 if (!controller_get_interface()->supports_ble_privacy()) {
803 btm_ble_vendor_enable_irk_feature(TRUE);
804 } else {
805 //btsnd_hcic_ble_set_addr_resolution_enable(TRUE);
806 }
807 }
808
809 /*******************************************************************************
810 **
811 ** Function btm_ble_disable_resolving_list
812 **
813 ** Description Disable LE Address resolution
814 **
815 ** Returns none
816 **
817 *******************************************************************************/
btm_ble_disable_resolving_list(UINT8 rl_mask,BOOLEAN to_resume)818 BOOLEAN btm_ble_disable_resolving_list(UINT8 rl_mask, BOOLEAN to_resume )
819 {
820 UINT8 rl_state = btm_cb.ble_ctr_cb.rl_state;
821
822 /* if controller does not support RPA offloading or privacy 1.2, skip */
823 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
824 return FALSE;
825 }
826
827 btm_cb.ble_ctr_cb.rl_state &= ~rl_mask;
828
829 if (rl_state != BTM_BLE_RL_IDLE && btm_cb.ble_ctr_cb.rl_state == BTM_BLE_RL_IDLE) {
830 if (btm_ble_exe_disable_resolving_list()) {
831 if (to_resume) {
832 btm_ble_resume_resolving_list_activity();
833 }
834
835 return TRUE;
836 } else {
837 return FALSE;
838 }
839 }
840
841 return TRUE;
842 }
843
844 /*******************************************************************************
845 **
846 ** Function btm_ble_resolving_list_load_dev
847 **
848 ** Description This function add a device which is using RPA into white list
849 **
850 ** Parameters pointer to device security record
851 **
852 ** Returns TRUE if device added, otherwise falase.
853 **
854 *******************************************************************************/
btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC * p_dev_rec)855 BOOLEAN btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec)
856 {
857 BOOLEAN rt = FALSE;
858 #if (SMP_INCLUDED == TRUE)
859 UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;
860
861 BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d\n", __func__,
862 btm_cb.ble_ctr_cb.privacy_mode);
863
864 /* if controller does not support RPA offloading or privacy 1.2, skip */
865 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
866 return FALSE;
867 }
868
869 BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d\n",
870 __func__, btm_cb.ble_ctr_cb.privacy_mode);
871
872 /* only add RPA enabled device into resolving list */
873 if (p_dev_rec != NULL && /* RPA is being used and PID is known */
874 (p_dev_rec->sec_flags & BTM_SEC_IN_USE) != 0 &&
875 ((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0 ||
876 (p_dev_rec->ble.key_type & BTM_LE_KEY_LID) != 0)) {
877 if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
878 btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
879 BTM_BLE_META_ADD_IRK_ENTRY) == FALSE) {
880 if (btm_cb.ble_ctr_cb.resolving_list_avail_size > 0) {
881 if (rl_mask) {
882 if (!btm_ble_disable_resolving_list (rl_mask, FALSE)) {
883 return FALSE;
884 }
885 }
886
887 btm_ble_update_resolving_list(p_dev_rec->bd_addr, TRUE);
888 if (controller_get_interface()->supports_ble_privacy()) {
889 BD_ADDR dummy_bda = {0};
890 if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) == 0) {
891 memcpy(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
892 p_dev_rec->ble.static_addr_type = p_dev_rec->ble.ble_addr_type;
893 }
894
895 #if CONTROLLER_RPA_LIST_ENABLE
896 BTM_TRACE_DEBUG("%s:adding device to controller resolving list\n", __func__);
897 UINT8 *peer_irk = p_dev_rec->ble.keys.irk;
898 UINT8 *local_irk = btm_cb.devcb.id_keys.irk;
899 //use identical IRK for now
900 rt = btsnd_hcic_ble_add_device_resolving_list(p_dev_rec->ble.static_addr_type,
901 p_dev_rec->ble.static_addr, peer_irk, local_irk);
902 #else
903 // do nothing
904 /* It will cause that scanner doesn't send scan request to advertiser
905 * which has sent IRK to us and we have stored the IRK in controller.
906 * It is a hardware limitation. The preliminary solution is not to
907 * send key to the controller, but to resolve the random address in host. */
908
909 #endif
910
911 } else {
912 UINT8 param[40] = {0};
913 UINT8 *p = param;
914
915 UINT8_TO_STREAM(p, BTM_BLE_META_ADD_IRK_ENTRY);
916 ARRAY_TO_STREAM(p, p_dev_rec->ble.keys.irk, BT_OCTET16_LEN);
917 UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
918 BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);
919
920 if (BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
921 BTM_BLE_META_ADD_IRK_LEN,
922 param,
923 btm_ble_resolving_list_vsc_op_cmpl)
924 == BTM_CMD_STARTED) {
925 rt = TRUE;
926 }
927 }
928
929 if (rt) {
930 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
931 BTM_BLE_META_ADD_IRK_ENTRY);
932 }
933
934 /* if resolving list has been turned on, re-enable it */
935 // if (rl_mask) {
936 // btm_ble_enable_resolving_list(rl_mask);
937 // } else {
938 // btm_ble_enable_resolving_list(BTM_BLE_RL_INIT);
939 // }
940 } else {
941 BTM_TRACE_WARNING("%s Resolving list full ", __func__);
942 }
943 } else {
944 BTM_TRACE_DEBUG("Device already in Resolving list\n");
945 rt = TRUE;
946 }
947 } else {
948 BTM_TRACE_DEBUG("Device not a RPA enabled device\n");
949 }
950 #endif ///SMP_INCLUDED == TRUE
951 return rt;
952 }
953
954 /*******************************************************************************
955 **
956 ** Function btm_ble_resolving_list_remove_dev
957 **
958 ** Description This function removes the device from resolving list
959 **
960 ** Parameters
961 **
962 ** Returns status
963 **
964 *******************************************************************************/
btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC * p_dev_rec)965 void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC *p_dev_rec)
966 {
967 UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;
968
969 BTM_TRACE_EVENT ("%s\n", __func__);
970 if (rl_mask) {
971 if (!btm_ble_disable_resolving_list (rl_mask, FALSE)) {
972 return;
973 }
974 }
975
976 if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
977 btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
978 BTM_BLE_META_REMOVE_IRK_ENTRY) == FALSE) {
979 btm_ble_update_resolving_list( p_dev_rec->bd_addr, FALSE);
980 btm_ble_remove_resolving_list_entry(p_dev_rec);
981 } else {
982 BTM_TRACE_DEBUG("Device not in resolving list\n");
983 }
984
985 /* if resolving list has been turned on, re-enable it */
986 // if (rl_mask) {
987 // btm_ble_enable_resolving_list(rl_mask);
988 // }
989 }
990
991 /*******************************************************************************
992 **
993 ** Function btm_ble_enable_resolving_list
994 **
995 ** Description enable LE resolve address list
996 **
997 ** Returns none
998 **
999 *******************************************************************************/
btm_ble_enable_resolving_list(UINT8 rl_mask)1000 void btm_ble_enable_resolving_list(UINT8 rl_mask)
1001 {
1002 UINT8 rl_state = btm_cb.ble_ctr_cb.rl_state;
1003
1004 btm_cb.ble_ctr_cb.rl_state |= rl_mask;
1005 if (rl_state == BTM_BLE_RL_IDLE &&
1006 btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE &&
1007 controller_get_interface()->get_ble_resolving_list_max_size() != 0) {
1008 btm_ble_exe_enable_resolving_list();
1009 btm_ble_resume_resolving_list_activity();
1010 }
1011 }
1012
1013 #if 0 //Unused
1014 /*******************************************************************************
1015 **
1016 ** Function btm_ble_resolving_list_empty
1017 **
1018 ** Description check to see if resolving list is empty or not
1019 **
1020 ** Returns TRUE: empty; FALSE non-empty
1021 **
1022 *******************************************************************************/
1023 BOOLEAN btm_ble_resolving_list_empty(void)
1024 {
1025 return (controller_get_interface()->get_ble_resolving_list_max_size() ==
1026 btm_cb.ble_ctr_cb.resolving_list_avail_size);
1027 }
1028 #endif
1029
1030 /*******************************************************************************
1031 **
1032 ** Function btm_ble_enable_resolving_list_for_platform
1033 **
1034 ** Description enable/disable resolving list feature depending on if any
1035 ** resolving list is empty and whitelist is involoved in the
1036 ** operation.
1037 **
1038 ** Returns none
1039 **
1040 *******************************************************************************/
btm_ble_enable_resolving_list_for_platform(UINT8 rl_mask)1041 void btm_ble_enable_resolving_list_for_platform (UINT8 rl_mask)
1042 {
1043 /* if controller does not support, skip */
1044 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
1045 return;
1046 }
1047
1048 if (btm_cb.ble_ctr_cb.wl_state == BTM_BLE_WL_IDLE) {
1049 if (controller_get_interface()->get_ble_resolving_list_max_size() >
1050 btm_cb.ble_ctr_cb.resolving_list_avail_size) {
1051 btm_ble_enable_resolving_list(rl_mask);
1052 } else {
1053 btm_ble_disable_resolving_list(rl_mask, TRUE);
1054 }
1055 return;
1056 }
1057
1058 tBTM_SEC_DEV_REC *p_dev = NULL;
1059 list_node_t *p_node = NULL;
1060 for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) {
1061 p_dev = list_node(p_node);
1062 if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
1063 (p_dev->ble.in_controller_list & BTM_WHITE_LIST_BIT)) {
1064 btm_ble_enable_resolving_list(rl_mask);
1065 return;
1066 }
1067 }
1068 btm_ble_disable_resolving_list(rl_mask, TRUE);
1069 }
1070
1071 /*******************************************************************************
1072 **
1073 ** Function btm_ble_resolving_list_init
1074 **
1075 ** Description Initialize resolving list in host stack
1076 **
1077 ** Parameters Max resolving list size
1078 **
1079 ** Returns void
1080 **
1081 *******************************************************************************/
btm_ble_resolving_list_init(UINT8 max_irk_list_sz)1082 void btm_ble_resolving_list_init(UINT8 max_irk_list_sz)
1083 {
1084 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
1085 UINT8 irk_mask_size = (max_irk_list_sz % 8) ?
1086 (max_irk_list_sz / 8 + 1) : (max_irk_list_sz / 8);
1087
1088 if (max_irk_list_sz > 0) {
1089 p_q->resolve_q_random_pseudo = (BD_ADDR *)osi_malloc(sizeof(BD_ADDR) * max_irk_list_sz);
1090 p_q->resolve_q_action = (UINT8 *)osi_malloc(max_irk_list_sz);
1091
1092 /* RPA offloading feature */
1093 if (btm_cb.ble_ctr_cb.irk_list_mask == NULL) {
1094 btm_cb.ble_ctr_cb.irk_list_mask = (UINT8 *)osi_malloc(irk_mask_size);
1095 }
1096
1097 BTM_TRACE_DEBUG ("%s max_irk_list_sz = %d", __func__, max_irk_list_sz);
1098 }
1099
1100 controller_get_interface()->set_ble_resolving_list_max_size(max_irk_list_sz);
1101 btm_ble_clear_resolving_list();
1102 btm_cb.ble_ctr_cb.resolving_list_avail_size = max_irk_list_sz;
1103 }
1104
1105 /*******************************************************************************
1106 **
1107 ** Function btm_ble_resolving_list_cleanup
1108 **
1109 ** Description Cleanup resolving list dynamic memory
1110 **
1111 ** Parameters
1112 **
1113 ** Returns void
1114 **
1115 *******************************************************************************/
btm_ble_resolving_list_cleanup(void)1116 void btm_ble_resolving_list_cleanup(void)
1117 {
1118 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
1119
1120 if (p_q->resolve_q_random_pseudo) {
1121 osi_free(p_q->resolve_q_random_pseudo);
1122 p_q->resolve_q_random_pseudo = NULL;
1123 }
1124
1125 if (p_q->resolve_q_action) {
1126 osi_free(p_q->resolve_q_action);
1127 p_q->resolve_q_action = NULL;
1128 }
1129
1130 controller_get_interface()->set_ble_resolving_list_max_size(0);
1131 if (btm_cb.ble_ctr_cb.irk_list_mask) {
1132 osi_free(btm_cb.ble_ctr_cb.irk_list_mask);
1133 btm_cb.ble_ctr_cb.irk_list_mask = NULL;
1134 }
1135
1136 }
1137
btm_ble_add_default_entry_to_resolving_list(void)1138 void btm_ble_add_default_entry_to_resolving_list(void)
1139 {
1140 /*
1141 * Add local IRK entry with 00:00:00:00:00:00 address. This entry will
1142 * be used to generate RPA for non-directed advertising if own_addr_type
1143 * is set to rpa_pub since we use all-zero address as peer address in
1144 * such case. Peer IRK should be left all-zero since this is not for an
1145 * actual peer.
1146 */
1147 BD_ADDR peer_addr = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
1148 BT_OCTET16 peer_irk = {0x0};
1149
1150 // Remove the existing entry in resolving list When resetting the device identity
1151 btsnd_hcic_ble_rm_device_resolving_list(BLE_ADDR_PUBLIC, peer_addr);
1152
1153 btsnd_hcic_ble_add_device_resolving_list (BLE_ADDR_PUBLIC, peer_addr, peer_irk, btm_cb.devcb.id_keys.irk);
1154 }
1155 #endif
1156