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