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