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
279 BTM_TRACE_DEBUG("%s status = %d", __func__, status);
280
281 BD_ADDR pseudo_bda;
282 if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
283 BTM_TRACE_DEBUG("no pending resolving list operation");
284 return;
285 }
286
287 if (status == HCI_SUCCESS) {
288 /* privacy 1.2 command complete does not have these extra byte */
289 if (evt_len > 2) {
290 /* VSC complete has one extra byte for op code, skip it here */
291 p ++;
292 STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
293 } else {
294 btm_cb.ble_ctr_cb.resolving_list_avail_size --;
295 }
296 } else if (status == HCI_ERR_MEMORY_FULL) { /* BT_ERROR_CODE_MEMORY_CAPACITY_EXCEEDED */
297 btm_cb.ble_ctr_cb.resolving_list_avail_size = 0;
298 BTM_TRACE_ERROR("%s Resolving list Full ", __func__);
299 } else {
300 BTM_TRACE_ERROR("%s Add resolving list error %d ", __func__, status);
301 }
302
303 }
304
305 /*******************************************************************************
306 **
307 ** Function btm_ble_remove_resolving_list_entry_complete
308 **
309 ** Description This function is called when command complete for
310 ** remove resolving list entry
311 **
312 ** Returns void
313 **
314 *******************************************************************************/
btm_ble_remove_resolving_list_entry_complete(UINT8 * p,UINT16 evt_len)315 void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
316 {
317 BD_ADDR pseudo_bda;
318 UINT8 status;
319
320 STREAM_TO_UINT8(status, p);
321
322 BTM_TRACE_DEBUG("%s status = %d", __func__, status);
323
324 if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
325 BTM_TRACE_ERROR("%s no pending resolving list operation", __func__);
326 return;
327 }
328
329 if (status == HCI_SUCCESS) {
330 /* proprietary: spec does not have these extra bytes */
331 if (evt_len > 2) {
332 p ++; /* skip opcode */
333 STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
334 } else {
335 btm_cb.ble_ctr_cb.resolving_list_avail_size++;
336 }
337 } else {
338 BTM_TRACE_ERROR("%s remove resolving list error 0x%x", __func__, status);
339 }
340 }
341
342 /*******************************************************************************
343 **
344 ** Function btm_ble_read_resolving_list_entry_complete
345 **
346 ** Description This function is called when command complete for
347 ** remove resolving list entry
348 **
349 ** Returns void
350 **
351 *******************************************************************************/
btm_ble_read_resolving_list_entry_complete(UINT8 * p,UINT16 evt_len)352 void btm_ble_read_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
353 {
354 UINT8 status, rra_type = BTM_BLE_ADDR_PSEUDO;
355 BD_ADDR rra, pseudo_bda;
356
357 STREAM_TO_UINT8 (status, p);
358
359 BTM_TRACE_DEBUG("%s status = %d", __func__, status);
360
361 if (!btm_ble_deq_resolving_pending(pseudo_bda)) {
362 BTM_TRACE_ERROR("no pending resolving list operation");
363 return;
364 }
365
366 if (status == HCI_SUCCESS) {
367 /* proprietary spec has extra bytes */
368 if (evt_len > 8) {
369 p += (2 + 16 + 1 + 6); /* skip subcode, index, IRK value, address type, identity addr type */
370 STREAM_TO_BDADDR(rra, p);
371
372 BTM_TRACE_ERROR("%s peer_addr: %02x:%02x:%02x:%02x:%02x:%02x",
373 __func__, rra[0], rra[1], rra[2], rra[3], rra[4], rra[5]);
374 } else {
375 STREAM_TO_BDADDR(rra, p);
376 }
377 btm_ble_refresh_peer_resolvable_private_addr(pseudo_bda, rra, rra_type);
378 }
379 }
380 /*******************************************************************************
381 VSC that implement controller based privacy
382 ********************************************************************************/
383 /*******************************************************************************
384 **
385 ** Function btm_ble_resolving_list_vsc_op_cmpl
386 **
387 ** Description IRK operation VSC complete handler
388 **
389 ** Parameters
390 **
391 ** Returns void
392 **
393 *******************************************************************************/
btm_ble_resolving_list_vsc_op_cmpl(tBTM_VSC_CMPL * p_params)394 void btm_ble_resolving_list_vsc_op_cmpl (tBTM_VSC_CMPL *p_params)
395 {
396 UINT8 *p = p_params->p_param_buf, op_subcode;
397 UINT16 evt_len = p_params->param_len;
398
399 op_subcode = *(p + 1);
400
401 BTM_TRACE_DEBUG("%s op_subcode = %d", __func__, op_subcode);
402
403 if (op_subcode == BTM_BLE_META_CLEAR_IRK_LIST) {
404 btm_ble_clear_resolving_list_complete(p, evt_len);
405 } else if (op_subcode == BTM_BLE_META_ADD_IRK_ENTRY) {
406 btm_ble_add_resolving_list_entry_complete(p, evt_len);
407 } else if (op_subcode == BTM_BLE_META_REMOVE_IRK_ENTRY) {
408 btm_ble_remove_resolving_list_entry_complete(p, evt_len);
409 } else if (op_subcode == BTM_BLE_META_READ_IRK_ENTRY) {
410 btm_ble_read_resolving_list_entry_complete(p, evt_len);
411 } else if (op_subcode == BTM_BLE_META_IRK_ENABLE) {
412 /* RPA offloading enable/disabled */
413 }
414 }
415
416 /*******************************************************************************
417 **
418 ** Function btm_ble_remove_resolving_list_entry
419 **
420 ** Description This function to remove an IRK entry from the list
421 **
422 ** Parameters ble_addr_type: address type
423 ** ble_addr: LE adddress
424 **
425 ** Returns status
426 **
427 *******************************************************************************/
btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC * p_dev_rec)428 tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
429 {
430 /* if controller does not support RPA offloading or privacy 1.2, skip */
431 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
432 return BTM_WRONG_MODE;
433 }
434
435 tBTM_STATUS st = BTM_NO_RESOURCES;
436 if (controller_get_interface()->supports_ble_privacy()) {
437 if (btsnd_hcic_ble_rm_device_resolving_list(p_dev_rec->ble.static_addr_type,
438 p_dev_rec->ble.static_addr)) {
439 st = BTM_CMD_STARTED;
440 }
441 } else {
442 UINT8 param[20] = {0};
443 UINT8 *p = param;
444
445 UINT8_TO_STREAM(p, BTM_BLE_META_REMOVE_IRK_ENTRY);
446 UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
447 BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);
448
449 st = BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC,
450 BTM_BLE_META_REMOVE_IRK_LEN,
451 param,
452 btm_ble_resolving_list_vsc_op_cmpl);
453 }
454
455 if (st == BTM_CMD_STARTED) {
456 btm_ble_enq_resolving_list_pending( p_dev_rec->bd_addr, BTM_BLE_META_REMOVE_IRK_ENTRY);
457 }
458
459 return st;
460 }
461
462 /*******************************************************************************
463 **
464 ** Function btm_ble_clear_resolving_list
465 **
466 ** Description This function clears the resolving list
467 **
468 ** Parameters None.
469 **
470 ** Returns status
471 **
472 *******************************************************************************/
btm_ble_clear_resolving_list(void)473 tBTM_STATUS btm_ble_clear_resolving_list(void)
474 {
475 tBTM_STATUS st = BTM_NO_RESOURCES;
476
477 if (controller_get_interface()->supports_ble_privacy()) {
478 if (btsnd_hcic_ble_clear_resolving_list()) {
479 st = BTM_SUCCESS;
480 }
481 } else {
482 UINT8 param[20] = {0};
483 UINT8 *p = param;
484
485 UINT8_TO_STREAM(p, BTM_BLE_META_CLEAR_IRK_LIST);
486 st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
487 BTM_BLE_META_CLEAR_IRK_LEN,
488 param,
489 btm_ble_resolving_list_vsc_op_cmpl);
490 }
491
492 return st;
493 }
494
495 /*******************************************************************************
496 **
497 ** Function btm_ble_read_resolving_list_entry
498 **
499 ** Description This function read an IRK entry by index
500 **
501 ** Parameters entry index.
502 **
503 ** Returns status
504 **
505 *******************************************************************************/
btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC * p_dev_rec)506 tBTM_STATUS btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
507 {
508 tBTM_STATUS st = BTM_NO_RESOURCES;
509
510 if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT)) {
511 return BTM_WRONG_MODE;
512 }
513
514 if (controller_get_interface()->supports_ble_privacy()) {
515 if (btsnd_hcic_ble_read_resolvable_addr_peer(p_dev_rec->ble.static_addr_type,
516 p_dev_rec->ble.static_addr)) {
517 st = BTM_CMD_STARTED;
518 }
519 } else {
520 UINT8 param[20] = {0};
521 UINT8 *p = param;
522
523 UINT8_TO_STREAM(p, BTM_BLE_META_READ_IRK_ENTRY);
524 UINT8_TO_STREAM(p, p_dev_rec->ble.resolving_list_index);
525
526 st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
527 BTM_BLE_META_READ_IRK_LEN,
528 param,
529 btm_ble_resolving_list_vsc_op_cmpl);
530 }
531
532 if (st == BTM_CMD_STARTED) {
533 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
534 BTM_BLE_META_READ_IRK_ENTRY);
535 }
536
537 return st;
538 }
539
540
541 /*******************************************************************************
542 **
543 ** Function btm_ble_suspend_resolving_list_activity
544 **
545 ** Description This function suspends all resolving list activity, including
546 ** scan, initiating, and advertising, if resolving list is being
547 ** enabled.
548 **
549 ** Parameters
550 **
551 ** Returns TRUE if suspended; FALSE otherwise
552 **
553 *******************************************************************************/
btm_ble_suspend_resolving_list_activity(void)554 BOOLEAN btm_ble_suspend_resolving_list_activity(void)
555 {
556 tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
557
558 /* if resolving list is not enabled, do not need to terminate any activity */
559 /* if asking for stop all activity */
560 /* if already suspended */
561 if (p_ble_cb->suspended_rl_state != BTM_BLE_RL_IDLE) {
562 return TRUE;
563 }
564
565 /* direct connection active, wait until it completed */
566 if (btm_ble_get_conn_st() == BLE_DIR_CONN) {
567 BTM_TRACE_ERROR("resolving list can not be edited, EnQ now");
568 return FALSE;
569 }
570
571 p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
572
573 if (p_ble_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE) {
574 btm_ble_stop_adv();
575 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_ADV;
576 }
577
578 if (BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) {
579 btm_ble_stop_scan();
580 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_SCAN;
581 }
582
583 if (btm_ble_suspend_bg_conn()) {
584 p_ble_cb->suspended_rl_state |= BTM_BLE_RL_INIT;
585 }
586
587 return TRUE;
588 }
589
590 /*******************************************************************************
591 **
592 ** Function btm_ble_resume_resolving_list_activity
593 **
594 ** Description This function resumes the resolving list activity, including
595 ** scanning, initiating, and advertising, if any of these
596 ** activities has been suspended earlier.
597 **
598 ** Returns none
599 **
600 *******************************************************************************/
btm_ble_resume_resolving_list_activity(void)601 void btm_ble_resume_resolving_list_activity(void)
602 {
603 tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
604
605 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_ADV) {
606 btm_ble_start_adv();
607 }
608
609 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_SCAN) {
610 btm_ble_start_scan();
611 }
612
613 if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_INIT) {
614 btm_ble_resume_bg_conn();
615 }
616
617 p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
618 }
619
620 /*******************************************************************************
621 **
622 ** Function btm_ble_vendor_enable_irk_feature
623 **
624 ** Description This function is called to enable or disable the RRA
625 ** offloading feature.
626 **
627 ** Parameters enable: enable or disable the RRA offloading feature
628 **
629 ** Returns BTM_SUCCESS if successful
630 **
631 *******************************************************************************/
btm_ble_vendor_enable_irk_feature(BOOLEAN enable)632 tBTM_STATUS btm_ble_vendor_enable_irk_feature(BOOLEAN enable)
633 {
634 UINT8 param[20], *p;
635 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
636
637 p = param;
638 memset(param, 0, 20);
639
640 /* select feature based on control block settings */
641 UINT8_TO_STREAM(p, BTM_BLE_META_IRK_ENABLE);
642 UINT8_TO_STREAM(p, enable ? 0x01 : 0x00);
643
644 st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_IRK_ENABLE_LEN,
645 param, btm_ble_resolving_list_vsc_op_cmpl);
646
647 return st;
648 }
649
650 /*******************************************************************************
651 **
652 ** Function btm_ble_exe_disable_resolving_list
653 **
654 ** Description execute resolving list disable
655 **
656 ** Returns none
657 **
658 *******************************************************************************/
btm_ble_exe_disable_resolving_list(void)659 BOOLEAN btm_ble_exe_disable_resolving_list(void)
660 {
661 if (!btm_ble_suspend_resolving_list_activity()) {
662 return FALSE;
663 }
664
665 if (!controller_get_interface()->supports_ble_privacy()) {
666 btm_ble_vendor_enable_irk_feature(FALSE);
667 } else {
668 //btsnd_hcic_ble_set_addr_resolution_enable(FALSE);
669 }
670
671 return TRUE;
672 }
673
674 /*******************************************************************************
675 **
676 ** Function btm_ble_exe_enable_resolving_list
677 **
678 ** Description enable LE resolve address list
679 **
680 ** Returns none
681 **
682 *******************************************************************************/
btm_ble_exe_enable_resolving_list(void)683 void btm_ble_exe_enable_resolving_list(void)
684 {
685 if (!btm_ble_suspend_resolving_list_activity()) {
686 return;
687 }
688
689 if (!controller_get_interface()->supports_ble_privacy()) {
690 btm_ble_vendor_enable_irk_feature(TRUE);
691 } else {
692 //btsnd_hcic_ble_set_addr_resolution_enable(TRUE);
693 }
694 }
695
696 /*******************************************************************************
697 **
698 ** Function btm_ble_disable_resolving_list
699 **
700 ** Description Disable LE Address resolution
701 **
702 ** Returns none
703 **
704 *******************************************************************************/
btm_ble_disable_resolving_list(UINT8 rl_mask,BOOLEAN to_resume)705 BOOLEAN btm_ble_disable_resolving_list(UINT8 rl_mask, BOOLEAN to_resume )
706 {
707 UINT8 rl_state = btm_cb.ble_ctr_cb.rl_state;
708
709 /* if controller does not support RPA offloading or privacy 1.2, skip */
710 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
711 return FALSE;
712 }
713
714 btm_cb.ble_ctr_cb.rl_state &= ~rl_mask;
715
716 if (rl_state != BTM_BLE_RL_IDLE && btm_cb.ble_ctr_cb.rl_state == BTM_BLE_RL_IDLE) {
717 if (btm_ble_exe_disable_resolving_list()) {
718 if (to_resume) {
719 btm_ble_resume_resolving_list_activity();
720 }
721
722 return TRUE;
723 } else {
724 return FALSE;
725 }
726 }
727
728 return TRUE;
729 }
730
731 /*******************************************************************************
732 **
733 ** Function btm_ble_resolving_list_load_dev
734 **
735 ** Description This function add a device which is using RPA into white list
736 **
737 ** Parameters pointer to device security record
738 **
739 ** Returns TRUE if device added, otherwise falase.
740 **
741 *******************************************************************************/
btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC * p_dev_rec)742 BOOLEAN btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec)
743 {
744 BOOLEAN rt = FALSE;
745 #if (SMP_INCLUDED == TRUE)
746 UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;
747
748 BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d\n", __func__,
749 btm_cb.ble_ctr_cb.privacy_mode);
750
751 /* if controller does not support RPA offloading or privacy 1.2, skip */
752 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
753 return FALSE;
754 }
755
756 BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d\n",
757 __func__, btm_cb.ble_ctr_cb.privacy_mode);
758
759 /* only add RPA enabled device into resolving list */
760 if (p_dev_rec != NULL && /* RPA is being used and PID is known */
761 (p_dev_rec->sec_flags & BTM_SEC_IN_USE) != 0 &&
762 ((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0 ||
763 (p_dev_rec->ble.key_type & BTM_LE_KEY_LID) != 0)) {
764 if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
765 btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
766 BTM_BLE_META_ADD_IRK_ENTRY) == FALSE) {
767 if (btm_cb.ble_ctr_cb.resolving_list_avail_size > 0) {
768 if (rl_mask) {
769 if (!btm_ble_disable_resolving_list (rl_mask, FALSE)) {
770 return FALSE;
771 }
772 }
773
774 btm_ble_update_resolving_list(p_dev_rec->bd_addr, TRUE);
775 if (controller_get_interface()->supports_ble_privacy()) {
776 BD_ADDR dummy_bda = {0};
777 if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) == 0) {
778 memcpy(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
779 p_dev_rec->ble.static_addr_type = p_dev_rec->ble.ble_addr_type;
780 }
781
782 #if CONTROLLER_RPA_LIST_ENABLE
783 BTM_TRACE_DEBUG("%s:adding device to controller resolving list\n", __func__);
784 UINT8 *peer_irk = p_dev_rec->ble.keys.irk;
785 UINT8 *local_irk = btm_cb.devcb.id_keys.irk;
786 //use identical IRK for now
787 rt = btsnd_hcic_ble_add_device_resolving_list(p_dev_rec->ble.static_addr_type,
788 p_dev_rec->ble.static_addr, peer_irk, local_irk);
789 #else
790 // do nothing
791 /* It will cause that scanner doesn't send scan request to advertiser
792 * which has sent IRK to us and we have stored the IRK in controller.
793 * It is a hardware limitation. The preliminary solution is not to
794 * send key to the controller, but to resolve the random address in host. */
795
796 #endif
797
798 } else {
799 UINT8 param[40] = {0};
800 UINT8 *p = param;
801
802 UINT8_TO_STREAM(p, BTM_BLE_META_ADD_IRK_ENTRY);
803 ARRAY_TO_STREAM(p, p_dev_rec->ble.keys.irk, BT_OCTET16_LEN);
804 UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
805 BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);
806
807 if (BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
808 BTM_BLE_META_ADD_IRK_LEN,
809 param,
810 btm_ble_resolving_list_vsc_op_cmpl)
811 == BTM_CMD_STARTED) {
812 rt = TRUE;
813 }
814 }
815
816 if (rt) {
817 btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
818 BTM_BLE_META_ADD_IRK_ENTRY);
819 }
820
821 /* if resolving list has been turned on, re-enable it */
822 // if (rl_mask) {
823 // btm_ble_enable_resolving_list(rl_mask);
824 // } else {
825 // btm_ble_enable_resolving_list(BTM_BLE_RL_INIT);
826 // }
827 } else {
828 BTM_TRACE_WARNING("%s Resolving list full ", __func__);
829 }
830 } else {
831 BTM_TRACE_DEBUG("Device already in Resolving list\n");
832 rt = TRUE;
833 }
834 } else {
835 BTM_TRACE_DEBUG("Device not a RPA enabled device\n");
836 }
837 #endif ///SMP_INCLUDED == TRUE
838 return rt;
839 }
840
841 /*******************************************************************************
842 **
843 ** Function btm_ble_resolving_list_remove_dev
844 **
845 ** Description This function removes the device from resolving list
846 **
847 ** Parameters
848 **
849 ** Returns status
850 **
851 *******************************************************************************/
btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC * p_dev_rec)852 void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC *p_dev_rec)
853 {
854 UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;
855
856 BTM_TRACE_EVENT ("%s\n", __func__);
857 if (rl_mask) {
858 if (!btm_ble_disable_resolving_list (rl_mask, FALSE)) {
859 return;
860 }
861 }
862
863 if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
864 btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
865 BTM_BLE_META_REMOVE_IRK_ENTRY) == FALSE) {
866 btm_ble_update_resolving_list( p_dev_rec->bd_addr, FALSE);
867 btm_ble_remove_resolving_list_entry(p_dev_rec);
868 } else {
869 BTM_TRACE_DEBUG("Device not in resolving list\n");
870 }
871
872 /* if resolving list has been turned on, re-enable it */
873 // if (rl_mask) {
874 // btm_ble_enable_resolving_list(rl_mask);
875 // }
876 }
877
878 /*******************************************************************************
879 **
880 ** Function btm_ble_enable_resolving_list
881 **
882 ** Description enable LE resolve address list
883 **
884 ** Returns none
885 **
886 *******************************************************************************/
btm_ble_enable_resolving_list(UINT8 rl_mask)887 void btm_ble_enable_resolving_list(UINT8 rl_mask)
888 {
889 UINT8 rl_state = btm_cb.ble_ctr_cb.rl_state;
890
891 btm_cb.ble_ctr_cb.rl_state |= rl_mask;
892 if (rl_state == BTM_BLE_RL_IDLE &&
893 btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE &&
894 controller_get_interface()->get_ble_resolving_list_max_size() != 0) {
895 btm_ble_exe_enable_resolving_list();
896 btm_ble_resume_resolving_list_activity();
897 }
898 }
899
900 #if 0 //Unused
901 /*******************************************************************************
902 **
903 ** Function btm_ble_resolving_list_empty
904 **
905 ** Description check to see if resoving list is empty or not
906 **
907 ** Returns TRUE: empty; FALSE non-empty
908 **
909 *******************************************************************************/
910 BOOLEAN btm_ble_resolving_list_empty(void)
911 {
912 return (controller_get_interface()->get_ble_resolving_list_max_size() ==
913 btm_cb.ble_ctr_cb.resolving_list_avail_size);
914 }
915 #endif
916
917 /*******************************************************************************
918 **
919 ** Function btm_ble_enable_resolving_list_for_platform
920 **
921 ** Description enable/disable resolving list feature depending on if any
922 ** resolving list is empty and whitelist is involoved in the
923 ** operation.
924 **
925 ** Returns none
926 **
927 *******************************************************************************/
btm_ble_enable_resolving_list_for_platform(UINT8 rl_mask)928 void btm_ble_enable_resolving_list_for_platform (UINT8 rl_mask)
929 {
930 /* if controller does not support, skip */
931 if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) {
932 return;
933 }
934
935 if (btm_cb.ble_ctr_cb.wl_state == BTM_BLE_WL_IDLE) {
936 if (controller_get_interface()->get_ble_resolving_list_max_size() >
937 btm_cb.ble_ctr_cb.resolving_list_avail_size) {
938 btm_ble_enable_resolving_list(rl_mask);
939 } else {
940 btm_ble_disable_resolving_list(rl_mask, TRUE);
941 }
942 return;
943 }
944
945 tBTM_SEC_DEV_REC *p_dev = NULL;
946 list_node_t *p_node = NULL;
947 for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) {
948 p_dev = list_node(p_node);
949 if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
950 (p_dev->ble.in_controller_list & BTM_WHITE_LIST_BIT)) {
951 btm_ble_enable_resolving_list(rl_mask);
952 return;
953 }
954 }
955 btm_ble_disable_resolving_list(rl_mask, TRUE);
956 }
957
958 /*******************************************************************************
959 **
960 ** Function btm_ble_resolving_list_init
961 **
962 ** Description Initialize resolving list in host stack
963 **
964 ** Parameters Max resolving list size
965 **
966 ** Returns void
967 **
968 *******************************************************************************/
btm_ble_resolving_list_init(UINT8 max_irk_list_sz)969 void btm_ble_resolving_list_init(UINT8 max_irk_list_sz)
970 {
971 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
972 UINT8 irk_mask_size = (max_irk_list_sz % 8) ?
973 (max_irk_list_sz / 8 + 1) : (max_irk_list_sz / 8);
974
975 if (max_irk_list_sz > 0) {
976 p_q->resolve_q_random_pseudo = (BD_ADDR *)osi_malloc(sizeof(BD_ADDR) * max_irk_list_sz);
977 p_q->resolve_q_action = (UINT8 *)osi_malloc(max_irk_list_sz);
978
979 /* RPA offloading feature */
980 if (btm_cb.ble_ctr_cb.irk_list_mask == NULL) {
981 btm_cb.ble_ctr_cb.irk_list_mask = (UINT8 *)osi_malloc(irk_mask_size);
982 }
983
984 BTM_TRACE_DEBUG ("%s max_irk_list_sz = %d", __func__, max_irk_list_sz);
985 }
986
987 controller_get_interface()->set_ble_resolving_list_max_size(max_irk_list_sz);
988 btm_ble_clear_resolving_list();
989 btm_cb.ble_ctr_cb.resolving_list_avail_size = max_irk_list_sz;
990 }
991
992 /*******************************************************************************
993 **
994 ** Function btm_ble_resolving_list_cleanup
995 **
996 ** Description Cleanup resolving list dynamic memory
997 **
998 ** Parameters
999 **
1000 ** Returns void
1001 **
1002 *******************************************************************************/
btm_ble_resolving_list_cleanup(void)1003 void btm_ble_resolving_list_cleanup(void)
1004 {
1005 tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
1006
1007 if (p_q->resolve_q_random_pseudo) {
1008 osi_free(p_q->resolve_q_random_pseudo);
1009 p_q->resolve_q_random_pseudo = NULL;
1010 }
1011
1012 if (p_q->resolve_q_action) {
1013 osi_free(p_q->resolve_q_action);
1014 p_q->resolve_q_action = NULL;
1015 }
1016
1017 controller_get_interface()->set_ble_resolving_list_max_size(0);
1018 if (btm_cb.ble_ctr_cb.irk_list_mask) {
1019 osi_free(btm_cb.ble_ctr_cb.irk_list_mask);
1020 btm_cb.ble_ctr_cb.irk_list_mask = NULL;
1021 }
1022
1023 }
1024 #endif
1025