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 "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 ******************************************************************************/
66void 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 ******************************************************************************/
88bool 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 ******************************************************************************/
115bool 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 ******************************************************************************/
139void 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 ******************************************************************************/
159uint8_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 ******************************************************************************/
188void 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
206bool 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 ******************************************************************************/
222void 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 ******************************************************************************/
266void 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 ******************************************************************************/
304void 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 ******************************************************************************/
338void 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 ******************************************************************************/
379void 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 ******************************************************************************/
412tBTM_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 ******************************************************************************/
447void 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 ******************************************************************************/
472tBTM_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 ******************************************************************************/
509bool 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 ******************************************************************************/
559void 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 ******************************************************************************/
588void 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 ******************************************************************************/
611bool 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 ******************************************************************************/
631void 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 ******************************************************************************/
649bool 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 ******************************************************************************/
683bool btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC* p_dev_rec) {
684  bool rt = false;
685  uint8_t rl_mask = btm_cb.ble_ctr_cb.rl_state;
686
687  BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d", __func__,
688                  btm_cb.ble_ctr_cb.privacy_mode);
689
690  /* if controller does not support RPA offloading or privacy 1.2, skip */
691  if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
692    return false;
693
694  BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d", __func__,
695                  btm_cb.ble_ctr_cb.privacy_mode);
696
697  /* only add RPA enabled device into resolving list */
698  if (p_dev_rec != NULL && /* RPA is being used and PID is known */
699      ((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0 ||
700       (p_dev_rec->ble.key_type & BTM_LE_KEY_LID) != 0)) {
701    if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
702        btm_ble_brcm_find_resolving_pending_entry(
703            p_dev_rec->bd_addr, BTM_BLE_META_ADD_IRK_ENTRY) == false) {
704      if (btm_cb.ble_ctr_cb.resolving_list_avail_size > 0) {
705        if (rl_mask) {
706          if (!btm_ble_disable_resolving_list(rl_mask, false)) return false;
707        }
708
709        btm_ble_update_resolving_list(p_dev_rec->bd_addr, true);
710        if (controller_get_interface()->supports_ble_privacy()) {
711          uint8_t* peer_irk = p_dev_rec->ble.keys.irk;
712          uint8_t* local_irk = btm_cb.devcb.id_keys.irk;
713
714          if (p_dev_rec->ble.static_addr.IsEmpty()) {
715            p_dev_rec->ble.static_addr = p_dev_rec->bd_addr;
716            p_dev_rec->ble.static_addr_type = p_dev_rec->ble.ble_addr_type;
717          }
718
719          BTM_TRACE_DEBUG("%s:adding device to controller resolving list",
720                          __func__);
721          // use identical IRK for now
722          btsnd_hcic_ble_add_device_resolving_list(
723              p_dev_rec->ble.static_addr_type, p_dev_rec->ble.static_addr,
724              peer_irk, local_irk);
725
726          if (controller_get_interface()->supports_ble_set_privacy_mode()) {
727            BTM_TRACE_DEBUG("%s: adding device privacy mode", __func__);
728            btsnd_hcic_ble_set_privacy_mode(p_dev_rec->ble.static_addr_type,
729                                            p_dev_rec->ble.static_addr, 0x01);
730          }
731        } else {
732          uint8_t param[40] = {0};
733          uint8_t* p = param;
734
735          UINT8_TO_STREAM(p, BTM_BLE_META_ADD_IRK_ENTRY);
736          ARRAY_TO_STREAM(p, p_dev_rec->ble.keys.irk, BT_OCTET16_LEN);
737          UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
738          BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);
739
740          BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC,
741                                    BTM_BLE_META_ADD_IRK_LEN, param,
742                                    btm_ble_resolving_list_vsc_op_cmpl);
743        }
744
745        rt = true;
746        btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
747                                           BTM_BLE_META_ADD_IRK_ENTRY);
748
749        /* if resolving list has been turned on, re-enable it */
750        if (rl_mask)
751          btm_ble_enable_resolving_list(rl_mask);
752        else
753          btm_ble_enable_resolving_list(BTM_BLE_RL_INIT);
754      }
755    } else {
756      BTM_TRACE_ERROR("Device already in Resolving list");
757      rt = true;
758    }
759  } else {
760    BTM_TRACE_DEBUG("Device not a RPA enabled device");
761  }
762  return rt;
763}
764
765/*******************************************************************************
766 *
767 * Function         btm_ble_resolving_list_remove_dev
768 *
769 * Description      This function removes the device from resolving list
770 *
771 * Parameters
772 *
773 * Returns          status
774 *
775 ******************************************************************************/
776void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC* p_dev_rec) {
777  uint8_t rl_mask = btm_cb.ble_ctr_cb.rl_state;
778
779  BTM_TRACE_EVENT("%s", __func__);
780  if (rl_mask) {
781    if (!btm_ble_disable_resolving_list(rl_mask, false)) return;
782  }
783
784  if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
785      btm_ble_brcm_find_resolving_pending_entry(
786          p_dev_rec->bd_addr, BTM_BLE_META_REMOVE_IRK_ENTRY) == false) {
787    btm_ble_update_resolving_list(p_dev_rec->bd_addr, false);
788    btm_ble_remove_resolving_list_entry(p_dev_rec);
789  } else {
790    BTM_TRACE_DEBUG("Device not in resolving list");
791  }
792
793  /* if resolving list has been turned on, re-enable it */
794  if (rl_mask) btm_ble_enable_resolving_list(rl_mask);
795}
796
797/*******************************************************************************
798 *
799 * Function         btm_ble_enable_resolving_list
800 *
801 * Description      enable LE resolve address list
802 *
803 * Returns          none
804 *
805 ******************************************************************************/
806void btm_ble_enable_resolving_list(uint8_t rl_mask) {
807  uint8_t rl_state = btm_cb.ble_ctr_cb.rl_state;
808
809  btm_cb.ble_ctr_cb.rl_state |= rl_mask;
810  if (rl_state == BTM_BLE_RL_IDLE &&
811      btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE &&
812      controller_get_interface()->get_ble_resolving_list_max_size() != 0) {
813    btm_ble_exe_enable_resolving_list();
814    btm_ble_resume_resolving_list_activity();
815  }
816}
817
818/*******************************************************************************
819 *
820 * Function         btm_ble_resolving_list_empty
821 *
822 * Description      check to see if resoving list is empty or not
823 *
824 * Returns          true: empty; false non-empty
825 *
826 ******************************************************************************/
827bool btm_ble_resolving_list_empty(void) {
828  return (controller_get_interface()->get_ble_resolving_list_max_size() ==
829          btm_cb.ble_ctr_cb.resolving_list_avail_size);
830}
831
832bool is_on_resolving_list(void* data, void* context) {
833  tBTM_SEC_DEV_REC* p_dev = static_cast<tBTM_SEC_DEV_REC*>(data);
834  if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
835      (p_dev->ble.in_controller_list & BTM_WHITE_LIST_BIT))
836    return false;
837
838  return true;
839}
840
841/*******************************************************************************
842 *
843 * Function         btm_ble_enable_resolving_list_for_platform
844 *
845 * Description      enable/disable resolving list feature depending on if any
846 *                  resolving list is empty and whitelist is involoved in the
847 *                  operation.
848 *
849 * Returns          none
850 *
851 ******************************************************************************/
852void btm_ble_enable_resolving_list_for_platform(uint8_t rl_mask) {
853  /* if controller does not support, skip */
854  if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
855    return;
856
857  if (btm_cb.ble_ctr_cb.wl_state == BTM_BLE_WL_IDLE) {
858    if (controller_get_interface()->get_ble_resolving_list_max_size() >
859        btm_cb.ble_ctr_cb.resolving_list_avail_size)
860      btm_ble_enable_resolving_list(rl_mask);
861    else
862      btm_ble_disable_resolving_list(rl_mask, true);
863    return;
864  }
865
866  list_node_t* n = list_foreach(btm_cb.sec_dev_rec, is_on_resolving_list, NULL);
867  if (n)
868    btm_ble_enable_resolving_list(rl_mask);
869  else
870    btm_ble_disable_resolving_list(rl_mask, true);
871}
872
873/*******************************************************************************
874 *
875 * Function         btm_ble_resolving_list_init
876 *
877 * Description      Initialize resolving list in host stack
878 *
879 * Parameters       Max resolving list size
880 *
881 * Returns          void
882 *
883 ******************************************************************************/
884void btm_ble_resolving_list_init(uint8_t max_irk_list_sz) {
885  tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
886  uint8_t irk_mask_size =
887      (max_irk_list_sz % 8) ? (max_irk_list_sz / 8 + 1) : (max_irk_list_sz / 8);
888
889  if (max_irk_list_sz > 0) {
890    p_q->resolve_q_random_pseudo =
891        (RawAddress*)osi_malloc(sizeof(RawAddress) * max_irk_list_sz);
892    p_q->resolve_q_action = (uint8_t*)osi_malloc(max_irk_list_sz);
893
894    /* RPA offloading feature */
895    if (btm_cb.ble_ctr_cb.irk_list_mask == NULL)
896      btm_cb.ble_ctr_cb.irk_list_mask = (uint8_t*)osi_malloc(irk_mask_size);
897
898    BTM_TRACE_DEBUG("%s max_irk_list_sz = %d", __func__, max_irk_list_sz);
899  }
900
901  controller_get_interface()->set_ble_resolving_list_max_size(max_irk_list_sz);
902  btm_ble_clear_resolving_list();
903  btm_cb.ble_ctr_cb.resolving_list_avail_size = max_irk_list_sz;
904}
905
906/*******************************************************************************
907 *
908 * Function         btm_ble_resolving_list_cleanup
909 *
910 * Description      Cleanup resolving list dynamic memory
911 *
912 * Parameters
913 *
914 * Returns          void
915 *
916 ******************************************************************************/
917void btm_ble_resolving_list_cleanup(void) {
918  tBTM_BLE_RESOLVE_Q* p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
919
920  osi_free_and_reset((void**)&p_q->resolve_q_random_pseudo);
921  osi_free_and_reset((void**)&p_q->resolve_q_action);
922
923  controller_get_interface()->set_ble_resolving_list_max_size(0);
924
925  osi_free_and_reset((void**)&btm_cb.ble_ctr_cb.irk_list_mask);
926}
927#endif
928