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