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