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