• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_PRIVACY_SPT == TRUE)
28 #include "bt_types.h"
29 #include "btm_int.h"
30 #include "btu.h"
31 #include "device/include/controller.h"
32 #include "hcimsgs.h"
33 #include "vendor_hcidefs.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_t op_code)65 void btm_ble_enq_resolving_list_pending(BD_ADDR pseudo_bda, uint8_t op_code) {
66   tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
67 
68   memcpy(p_q->resolve_q_random_pseudo[p_q->q_next], pseudo_bda, BD_ADDR_LEN);
69   p_q->resolve_q_action[p_q->q_next] = op_code;
70   p_q->q_next++;
71   p_q->q_next %= controller_get_interface()->get_ble_resolving_list_max_size();
72 }
73 
74 /*******************************************************************************
75  *
76  * Function         btm_ble_brcm_find_resolving_pending_entry
77  *
78  * Description      check to see if the action is in pending list
79  *
80  * Parameters       true: action pending;
81  *                  false: new action
82  *
83  * Returns          void
84  *
85  ******************************************************************************/
btm_ble_brcm_find_resolving_pending_entry(BD_ADDR pseudo_addr,uint8_t action)86 bool btm_ble_brcm_find_resolving_pending_entry(BD_ADDR pseudo_addr,
87                                                uint8_t action) {
88   tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
89 
90   for (uint8_t i = p_q->q_pending; i != p_q->q_next;) {
91     if (memcmp(p_q->resolve_q_random_pseudo[i], pseudo_addr, BD_ADDR_LEN) ==
92             0 &&
93         action == p_q->resolve_q_action[i])
94       return true;
95 
96     i++;
97     i %= controller_get_interface()->get_ble_resolving_list_max_size();
98   }
99   return false;
100 }
101 
102 /*******************************************************************************
103  *
104  * Function         btm_ble_deq_resolving_pending
105  *
106  * Description      dequeue target address from resolving pending operation
107  *                  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 bool btm_ble_deq_resolving_pending(BD_ADDR pseudo_addr) {
115   tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
116 
117   if (p_q->q_next != p_q->q_pending) {
118     memcpy(pseudo_addr, p_q->resolve_q_random_pseudo[p_q->q_pending],
119            BD_ADDR_LEN);
120     memset(p_q->resolve_q_random_pseudo[p_q->q_pending], 0, BD_ADDR_LEN);
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(BD_ADDR pseudo_bda,bool add)188 void btm_ble_update_resolving_list(BD_ADDR 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   BD_ADDR 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   BD_ADDR 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   BD_ADDR 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       BTM_TRACE_ERROR("%s peer_addr: %02x:%02x:%02x:%02x:%02x:%02x", __func__,
359                       rra[0], rra[1], rra[2], rra[3], rra[4], rra[5]);
360     } else {
361       STREAM_TO_BDADDR(rra, p);
362     }
363     btm_ble_refresh_peer_resolvable_private_addr(pseudo_bda, rra, rra_type);
364   }
365 }
366 /*******************************************************************************
367                 VSC that implement controller based privacy
368  ******************************************************************************/
369 /*******************************************************************************
370  *
371  * Function         btm_ble_resolving_list_vsc_op_cmpl
372  *
373  * Description      IRK operation VSC complete handler
374  *
375  * Parameters
376  *
377  * Returns          void
378  *
379  ******************************************************************************/
btm_ble_resolving_list_vsc_op_cmpl(tBTM_VSC_CMPL * p_params)380 void btm_ble_resolving_list_vsc_op_cmpl(tBTM_VSC_CMPL* p_params) {
381   uint8_t *p = p_params->p_param_buf, op_subcode;
382   uint16_t evt_len = p_params->param_len;
383 
384   op_subcode = *(p + 1);
385 
386   BTM_TRACE_DEBUG("%s op_subcode = %d", __func__, op_subcode);
387 
388   if (op_subcode == BTM_BLE_META_CLEAR_IRK_LIST) {
389     btm_ble_clear_resolving_list_complete(p, evt_len);
390   } else if (op_subcode == BTM_BLE_META_ADD_IRK_ENTRY) {
391     btm_ble_add_resolving_list_entry_complete(p, evt_len);
392   } else if (op_subcode == BTM_BLE_META_REMOVE_IRK_ENTRY) {
393     btm_ble_remove_resolving_list_entry_complete(p, evt_len);
394   } else if (op_subcode == BTM_BLE_META_READ_IRK_ENTRY) {
395     btm_ble_read_resolving_list_entry_complete(p, evt_len);
396   } else if (op_subcode == BTM_BLE_META_IRK_ENABLE) {
397     /* RPA offloading enable/disabled */
398   }
399 }
400 
401 /*******************************************************************************
402  *
403  * Function         btm_ble_remove_resolving_list_entry
404  *
405  * Description      This function to remove an IRK entry from the list
406  *
407  * Parameters       ble_addr_type: address type
408  *                  ble_addr: LE adddress
409  *
410  * Returns          status
411  *
412  ******************************************************************************/
btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC * p_dev_rec)413 tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC* p_dev_rec) {
414   /* if controller does not support RPA offloading or privacy 1.2, skip */
415   if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
416     return BTM_WRONG_MODE;
417 
418   if (controller_get_interface()->supports_ble_privacy()) {
419     btsnd_hcic_ble_rm_device_resolving_list(p_dev_rec->ble.static_addr_type,
420                                             p_dev_rec->ble.static_addr);
421   } else {
422     uint8_t param[20] = {0};
423     uint8_t* p = param;
424 
425     UINT8_TO_STREAM(p, BTM_BLE_META_REMOVE_IRK_ENTRY);
426     UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
427     BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);
428 
429     BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC,
430                               BTM_BLE_META_REMOVE_IRK_LEN, param,
431                               btm_ble_resolving_list_vsc_op_cmpl);
432   }
433 
434   btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
435                                      BTM_BLE_META_REMOVE_IRK_ENTRY);
436   return BTM_CMD_STARTED;
437 }
438 
439 /*******************************************************************************
440  *
441  * Function         btm_ble_clear_resolving_list
442  *
443  * Description      This function clears the resolving  list
444  *
445  * Parameters       None.
446  *
447  ******************************************************************************/
btm_ble_clear_resolving_list(void)448 void btm_ble_clear_resolving_list(void) {
449   if (controller_get_interface()->supports_ble_privacy()) {
450     btsnd_hcic_ble_clear_resolving_list();
451   } else {
452     uint8_t param[20] = {0};
453     uint8_t* p = param;
454 
455     UINT8_TO_STREAM(p, BTM_BLE_META_CLEAR_IRK_LIST);
456     BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC,
457                               BTM_BLE_META_CLEAR_IRK_LEN, param,
458                               btm_ble_resolving_list_vsc_op_cmpl);
459   }
460 }
461 
462 /*******************************************************************************
463  *
464  * Function         btm_ble_read_resolving_list_entry
465  *
466  * Description      This function read an IRK entry by index
467  *
468  * Parameters       entry index.
469  *
470  * Returns          status
471  *
472  ******************************************************************************/
btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC * p_dev_rec)473 tBTM_STATUS btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC* p_dev_rec) {
474   if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT))
475     return BTM_WRONG_MODE;
476 
477   if (controller_get_interface()->supports_ble_privacy()) {
478     btsnd_hcic_ble_read_resolvable_addr_peer(p_dev_rec->ble.static_addr_type,
479                                              p_dev_rec->ble.static_addr);
480   } else {
481     uint8_t param[20] = {0};
482     uint8_t* p = param;
483 
484     UINT8_TO_STREAM(p, BTM_BLE_META_READ_IRK_ENTRY);
485     UINT8_TO_STREAM(p, p_dev_rec->ble.resolving_list_index);
486 
487     BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_META_READ_IRK_LEN,
488                               param, btm_ble_resolving_list_vsc_op_cmpl);
489   }
490 
491   btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
492                                      BTM_BLE_META_READ_IRK_ENTRY);
493 
494   return BTM_CMD_STARTED;
495 }
496 
497 /*******************************************************************************
498  *
499  * Function         btm_ble_suspend_resolving_list_activity
500  *
501  * Description      This function suspends all resolving list activity,
502  *                  including scanning, initiating, and advertising, if
503  *                  resolving list is being enabled.
504  *
505  * Parameters
506  *
507  * Returns          true if suspended; false otherwise
508  *
509  ******************************************************************************/
btm_ble_suspend_resolving_list_activity(void)510 bool btm_ble_suspend_resolving_list_activity(void) {
511   tBTM_BLE_CB* p_ble_cb = &btm_cb.ble_ctr_cb;
512 
513   /* if resolving list is not enabled, do not need to terminate any activity */
514   /* if asking for stop all activity */
515   /* if already suspended */
516   if (p_ble_cb->suspended_rl_state != BTM_BLE_RL_IDLE) return true;
517 
518   /* direct connection active, wait until it completed */
519   if (btm_ble_get_conn_st() == BLE_DIR_CONN) {
520     BTM_TRACE_ERROR("resolving list can not be edited, EnQ now");
521     return false;
522   }
523 
524   p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
525 
526   if (p_ble_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE) {
527     btm_ble_stop_adv();
528     p_ble_cb->suspended_rl_state |= BTM_BLE_RL_ADV;
529   }
530 
531   if (BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) {
532     btm_ble_stop_scan();
533     p_ble_cb->suspended_rl_state |= BTM_BLE_RL_SCAN;
534   }
535 
536   if (btm_ble_suspend_bg_conn())
537     p_ble_cb->suspended_rl_state |= BTM_BLE_RL_INIT;
538 
539   return true;
540 }
541 
542 /*******************************************************************************
543  *
544  * Function         btm_ble_resume_resolving_list_activity
545  *
546  * Description      This function resumes the resolving list activity, including
547  *                  scanning, initiating, and advertising, if any of these
548  *                  activities has been suspended earlier.
549  *
550  * Returns          none
551  *
552  ******************************************************************************/
btm_ble_resume_resolving_list_activity(void)553 void btm_ble_resume_resolving_list_activity(void) {
554   tBTM_BLE_CB* p_ble_cb = &btm_cb.ble_ctr_cb;
555 
556   if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_ADV) btm_ble_start_adv();
557 
558   if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_SCAN) btm_ble_start_scan();
559 
560   if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_INIT) btm_ble_resume_bg_conn();
561 
562   p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
563 }
564 
565 /*******************************************************************************
566  *
567  * Function         btm_ble_vendor_enable_irk_feature
568  *
569  * Description      This function is called to enable or disable the RRA
570  *                  offloading feature.
571  *
572  * Parameters       enable: enable or disable the RRA offloading feature
573  *
574  ******************************************************************************/
btm_ble_vendor_enable_irk_feature(bool enable)575 void btm_ble_vendor_enable_irk_feature(bool enable) {
576   uint8_t param[20], *p;
577 
578   p = param;
579   memset(param, 0, 20);
580 
581   /* select feature based on control block settings */
582   UINT8_TO_STREAM(p, BTM_BLE_META_IRK_ENABLE);
583   UINT8_TO_STREAM(p, enable ? 0x01 : 0x00);
584 
585   BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_IRK_ENABLE_LEN,
586                             param, btm_ble_resolving_list_vsc_op_cmpl);
587 }
588 
589 /*******************************************************************************
590  *
591  * Function         btm_ble_exe_disable_resolving_list
592  *
593  * Description      execute resolving list disable
594  *
595  * Returns          none
596  *
597  ******************************************************************************/
btm_ble_exe_disable_resolving_list(void)598 bool btm_ble_exe_disable_resolving_list(void) {
599   if (!btm_ble_suspend_resolving_list_activity()) return false;
600 
601   if (!controller_get_interface()->supports_ble_privacy())
602     btm_ble_vendor_enable_irk_feature(false);
603   else
604     btsnd_hcic_ble_set_addr_resolution_enable(false);
605 
606   return true;
607 }
608 
609 /*******************************************************************************
610  *
611  * Function         btm_ble_exe_enable_resolving_list
612  *
613  * Description      enable LE resolve address list
614  *
615  * Returns          none
616  *
617  ******************************************************************************/
btm_ble_exe_enable_resolving_list(void)618 void btm_ble_exe_enable_resolving_list(void) {
619   if (!btm_ble_suspend_resolving_list_activity()) return;
620 
621   if (!controller_get_interface()->supports_ble_privacy())
622     btm_ble_vendor_enable_irk_feature(true);
623   else
624     btsnd_hcic_ble_set_addr_resolution_enable(true);
625 }
626 
627 /*******************************************************************************
628  *
629  * Function         btm_ble_disable_resolving_list
630  *
631  * Description      Disable LE Address resolution
632  *
633  * Returns          none
634  *
635  ******************************************************************************/
btm_ble_disable_resolving_list(uint8_t rl_mask,bool to_resume)636 bool btm_ble_disable_resolving_list(uint8_t rl_mask, bool to_resume) {
637   uint8_t rl_state = btm_cb.ble_ctr_cb.rl_state;
638 
639   /* if controller does not support RPA offloading or privacy 1.2, skip */
640   if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
641     return false;
642 
643   btm_cb.ble_ctr_cb.rl_state &= ~rl_mask;
644 
645   if (rl_state != BTM_BLE_RL_IDLE &&
646       btm_cb.ble_ctr_cb.rl_state == BTM_BLE_RL_IDLE) {
647     if (btm_ble_exe_disable_resolving_list()) {
648       if (to_resume) btm_ble_resume_resolving_list_activity();
649 
650       return true;
651     } else
652       return false;
653   }
654 
655   return true;
656 }
657 
658 /*******************************************************************************
659  *
660  * Function         btm_ble_resolving_list_load_dev
661  *
662  * Description      This function adds a device which is using RPA into the
663  *                  white list.
664  *
665  * Parameters       pointer to device security record
666  *
667  * Returns          true if device added, otherwise falase.
668  *
669  ******************************************************************************/
btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC * p_dev_rec)670 bool btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC* p_dev_rec) {
671   bool rt = false;
672   uint8_t rl_mask = btm_cb.ble_ctr_cb.rl_state;
673 
674   BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d", __func__,
675                   btm_cb.ble_ctr_cb.privacy_mode);
676 
677   /* if controller does not support RPA offloading or privacy 1.2, skip */
678   if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
679     return false;
680 
681   BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d", __func__,
682                   btm_cb.ble_ctr_cb.privacy_mode);
683 
684   /* only add RPA enabled device into resolving list */
685   if (p_dev_rec != NULL && /* RPA is being used and PID is known */
686       ((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0 ||
687        (p_dev_rec->ble.key_type & BTM_LE_KEY_LID) != 0)) {
688     if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
689         btm_ble_brcm_find_resolving_pending_entry(
690             p_dev_rec->bd_addr, BTM_BLE_META_ADD_IRK_ENTRY) == false) {
691       if (btm_cb.ble_ctr_cb.resolving_list_avail_size > 0) {
692         if (rl_mask) {
693           if (!btm_ble_disable_resolving_list(rl_mask, false)) return false;
694         }
695 
696         btm_ble_update_resolving_list(p_dev_rec->bd_addr, true);
697         if (controller_get_interface()->supports_ble_privacy()) {
698           BD_ADDR dummy_bda = {0};
699           uint8_t* peer_irk = p_dev_rec->ble.keys.irk;
700           uint8_t* local_irk = btm_cb.devcb.id_keys.irk;
701 
702           if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) == 0) {
703             memcpy(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
704             p_dev_rec->ble.static_addr_type = p_dev_rec->ble.ble_addr_type;
705           }
706 
707           BTM_TRACE_DEBUG("%s:adding device to controller resolving list",
708                           __func__);
709           // use identical IRK for now
710           btsnd_hcic_ble_add_device_resolving_list(
711               p_dev_rec->ble.static_addr_type, p_dev_rec->ble.static_addr,
712               peer_irk, local_irk);
713 
714           if (controller_get_interface()->supports_ble_privacy()) {
715             BTM_TRACE_DEBUG("%s: adding device privacy mode", __func__);
716             btsnd_hcic_ble_set_privacy_mode(p_dev_rec->ble.static_addr_type,
717                                             p_dev_rec->ble.static_addr, 0x01);
718           }
719         } else {
720           uint8_t param[40] = {0};
721           uint8_t* p = param;
722 
723           UINT8_TO_STREAM(p, BTM_BLE_META_ADD_IRK_ENTRY);
724           ARRAY_TO_STREAM(p, p_dev_rec->ble.keys.irk, BT_OCTET16_LEN);
725           UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
726           BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);
727 
728           BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC,
729                                     BTM_BLE_META_ADD_IRK_LEN, param,
730                                     btm_ble_resolving_list_vsc_op_cmpl);
731         }
732 
733         rt = true;
734         btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
735                                            BTM_BLE_META_ADD_IRK_ENTRY);
736 
737         /* if resolving list has been turned on, re-enable it */
738         if (rl_mask)
739           btm_ble_enable_resolving_list(rl_mask);
740         else
741           btm_ble_enable_resolving_list(BTM_BLE_RL_INIT);
742       }
743     } else {
744       BTM_TRACE_ERROR("Device already in Resolving list");
745       rt = true;
746     }
747   } else {
748     BTM_TRACE_DEBUG("Device not a RPA enabled device");
749   }
750   return rt;
751 }
752 
753 /*******************************************************************************
754  *
755  * Function         btm_ble_resolving_list_remove_dev
756  *
757  * Description      This function removes the device from resolving list
758  *
759  * Parameters
760  *
761  * Returns          status
762  *
763  ******************************************************************************/
btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC * p_dev_rec)764 void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC* p_dev_rec) {
765   uint8_t rl_mask = btm_cb.ble_ctr_cb.rl_state;
766 
767   BTM_TRACE_EVENT("%s", __func__);
768   if (rl_mask) {
769     if (!btm_ble_disable_resolving_list(rl_mask, false)) return;
770   }
771 
772   if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
773       btm_ble_brcm_find_resolving_pending_entry(
774           p_dev_rec->bd_addr, BTM_BLE_META_REMOVE_IRK_ENTRY) == false) {
775     btm_ble_update_resolving_list(p_dev_rec->bd_addr, false);
776     btm_ble_remove_resolving_list_entry(p_dev_rec);
777   } else {
778     BTM_TRACE_DEBUG("Device not in resolving list");
779   }
780 
781   /* if resolving list has been turned on, re-enable it */
782   if (rl_mask) btm_ble_enable_resolving_list(rl_mask);
783 }
784 
785 /*******************************************************************************
786  *
787  * Function         btm_ble_enable_resolving_list
788  *
789  * Description      enable LE resolve address list
790  *
791  * Returns          none
792  *
793  ******************************************************************************/
btm_ble_enable_resolving_list(uint8_t rl_mask)794 void btm_ble_enable_resolving_list(uint8_t rl_mask) {
795   uint8_t rl_state = btm_cb.ble_ctr_cb.rl_state;
796 
797   btm_cb.ble_ctr_cb.rl_state |= rl_mask;
798   if (rl_state == BTM_BLE_RL_IDLE &&
799       btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE &&
800       controller_get_interface()->get_ble_resolving_list_max_size() != 0) {
801     btm_ble_exe_enable_resolving_list();
802     btm_ble_resume_resolving_list_activity();
803   }
804 }
805 
806 /*******************************************************************************
807  *
808  * Function         btm_ble_resolving_list_empty
809  *
810  * Description      check to see if resoving list is empty or not
811  *
812  * Returns          true: empty; false non-empty
813  *
814  ******************************************************************************/
btm_ble_resolving_list_empty(void)815 bool btm_ble_resolving_list_empty(void) {
816   return (controller_get_interface()->get_ble_resolving_list_max_size() ==
817           btm_cb.ble_ctr_cb.resolving_list_avail_size);
818 }
819 
is_on_resolving_list(void * data,void * context)820 bool is_on_resolving_list(void* data, void* context) {
821   tBTM_SEC_DEV_REC* p_dev = static_cast<tBTM_SEC_DEV_REC*>(data);
822   if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
823       (p_dev->ble.in_controller_list & BTM_WHITE_LIST_BIT))
824     return false;
825 
826   return true;
827 }
828 
829 /*******************************************************************************
830  *
831  * Function         btm_ble_enable_resolving_list_for_platform
832  *
833  * Description      enable/disable resolving list feature depending on if any
834  *                  resolving list is empty and whitelist is involoved in the
835  *                  operation.
836  *
837  * Returns          none
838  *
839  ******************************************************************************/
btm_ble_enable_resolving_list_for_platform(uint8_t rl_mask)840 void btm_ble_enable_resolving_list_for_platform(uint8_t rl_mask) {
841   /* if controller does not support, skip */
842   if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
843     return;
844 
845   if (btm_cb.ble_ctr_cb.wl_state == BTM_BLE_WL_IDLE) {
846     if (controller_get_interface()->get_ble_resolving_list_max_size() >
847         btm_cb.ble_ctr_cb.resolving_list_avail_size)
848       btm_ble_enable_resolving_list(rl_mask);
849     else
850       btm_ble_disable_resolving_list(rl_mask, true);
851     return;
852   }
853 
854   list_node_t* n = list_foreach(btm_cb.sec_dev_rec, is_on_resolving_list, NULL);
855   if (n)
856     btm_ble_enable_resolving_list(rl_mask);
857   else
858     btm_ble_disable_resolving_list(rl_mask, true);
859 }
860 
861 /*******************************************************************************
862  *
863  * Function         btm_ble_resolving_list_init
864  *
865  * Description      Initialize resolving list in host stack
866  *
867  * Parameters       Max resolving list size
868  *
869  * Returns          void
870  *
871  ******************************************************************************/
btm_ble_resolving_list_init(uint8_t max_irk_list_sz)872 void btm_ble_resolving_list_init(uint8_t max_irk_list_sz) {
873   tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
874   uint8_t irk_mask_size =
875       (max_irk_list_sz % 8) ? (max_irk_list_sz / 8 + 1) : (max_irk_list_sz / 8);
876 
877   if (max_irk_list_sz > 0) {
878     p_q->resolve_q_random_pseudo =
879         (BD_ADDR*)osi_malloc(sizeof(BD_ADDR) * max_irk_list_sz);
880     p_q->resolve_q_action = (uint8_t*)osi_malloc(max_irk_list_sz);
881 
882     /* RPA offloading feature */
883     if (btm_cb.ble_ctr_cb.irk_list_mask == NULL)
884       btm_cb.ble_ctr_cb.irk_list_mask = (uint8_t*)osi_malloc(irk_mask_size);
885 
886     BTM_TRACE_DEBUG("%s max_irk_list_sz = %d", __func__, max_irk_list_sz);
887   }
888 
889   controller_get_interface()->set_ble_resolving_list_max_size(max_irk_list_sz);
890   btm_ble_clear_resolving_list();
891   btm_cb.ble_ctr_cb.resolving_list_avail_size = max_irk_list_sz;
892 }
893 
894 /*******************************************************************************
895  *
896  * Function         btm_ble_resolving_list_cleanup
897  *
898  * Description      Cleanup resolving list dynamic memory
899  *
900  * Parameters
901  *
902  * Returns          void
903  *
904  ******************************************************************************/
btm_ble_resolving_list_cleanup(void)905 void btm_ble_resolving_list_cleanup(void) {
906   tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
907 
908   osi_free_and_reset((void**)&p_q->resolve_q_random_pseudo);
909   osi_free_and_reset((void**)&p_q->resolve_q_action);
910 
911   controller_get_interface()->set_ble_resolving_list_max_size(0);
912 
913   osi_free_and_reset((void**)&btm_cb.ble_ctr_cb.irk_list_mask);
914 }
915 #endif
916