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