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_INCLUDED == TRUE && BLE_PRIVACY_SPT == TRUE)
     28 #include "bt_types.h"
     29 #include "hcimsgs.h"
     30 #include "btu.h"
     31 #include "vendor_hcidefs.h"
     32 #include "btm_int.h"
     33 #include "device/include/controller.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 op_code)
     66 {
     67     tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
     68 
     69     memcpy(p_q->resolve_q_random_pseudo[p_q->q_next], pseudo_bda, BD_ADDR_LEN);
     70     p_q->resolve_q_action[p_q->q_next] = op_code;
     71     p_q->q_next ++;
     72     p_q->q_next %= controller_get_interface()->get_ble_resolving_list_max_size();
     73 }
     74 
     75 /*******************************************************************************
     76 **
     77 ** Function         btm_ble_brcm_find_resolving_pending_entry
     78 **
     79 ** Description      check to see if the action is in pending list
     80 **
     81 ** Parameters       TRUE: action pending;
     82 **                  FALSE: new action
     83 **
     84 ** Returns          void
     85 **
     86 *******************************************************************************/
     87 BOOLEAN btm_ble_brcm_find_resolving_pending_entry(BD_ADDR pseudo_addr, UINT8 action)
     88 {
     89     tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
     90 
     91     for (UINT8 i = p_q->q_pending; i != p_q->q_next;)
     92     {
     93         if (memcmp(p_q->resolve_q_random_pseudo[i], pseudo_addr, BD_ADDR_LEN) == 0 &&
     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 queue
    108 **
    109 ** Parameters       pseudo_addr: pseudo_addr device address
    110 **
    111 ** Returns          void
    112 **
    113 *******************************************************************************/
    114 BOOLEAN btm_ble_deq_resolving_pending(BD_ADDR pseudo_addr)
    115 {
    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     {
    120         memcpy(pseudo_addr, p_q->resolve_q_random_pseudo[p_q->q_pending], BD_ADDR_LEN);
    121         memset(p_q->resolve_q_random_pseudo[p_q->q_pending], 0, BD_ADDR_LEN);
    122         p_q->q_pending ++;
    123         p_q->q_pending %= 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 index)
    140 {
    141     UINT8 byte;
    142     UINT8 bit;
    143 
    144     if (index < controller_get_interface()->get_ble_resolving_list_max_size())
    145     {
    146          byte = index / 8;
    147          bit = index % 8;
    148          btm_cb.ble_ctr_cb.irk_list_mask[byte] &= (~(1 << bit));
    149     }
    150 }
    151 
    152 /*******************************************************************************
    153 **
    154 ** Function         btm_ble_find_irk_index
    155 **
    156 ** Description      find the first available IRK list index
    157 **
    158 ** Returns          index from 0 ~ max (127 default)
    159 **
    160 *******************************************************************************/
    161 UINT8 btm_ble_find_irk_index(void)
    162 {
    163     UINT8 i = 0;
    164     UINT8 byte;
    165     UINT8 bit;
    166 
    167     while (i < controller_get_interface()->get_ble_resolving_list_max_size())
    168     {
    169         byte = i / 8;
    170         bit = i % 8;
    171 
    172         if ((btm_cb.ble_ctr_cb.irk_list_mask[byte] & (1 << bit)) == 0)
    173         {
    174             btm_cb.ble_ctr_cb.irk_list_mask[byte] |= (1 << bit);
    175             return i;
    176         }
    177         i++;
    178     }
    179 
    180     BTM_TRACE_ERROR ("%s failed, list full", __func__);
    181     return i;
    182 }
    183 
    184 /*******************************************************************************
    185 **
    186 ** Function         btm_ble_update_resolving_list
    187 **
    188 ** Description      update resolving list entry in host maintained record
    189 **
    190 ** Returns          void
    191 **
    192 *******************************************************************************/
    193 void btm_ble_update_resolving_list(BD_ADDR pseudo_bda, BOOLEAN add)
    194 {
    195     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_bda);
    196     if (p_dev_rec == NULL)
    197         return;
    198 
    199     if (add)
    200     {
    201         p_dev_rec->ble.in_controller_list |= BTM_RESOLVING_LIST_BIT;
    202         if (!controller_get_interface()->supports_ble_privacy())
    203             p_dev_rec->ble.resolving_list_index = btm_ble_find_irk_index();
    204     }
    205     else
    206     {
    207         p_dev_rec->ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT;
    208         if (!controller_get_interface()->supports_ble_privacy())
    209         {
    210            /* clear IRK list index mask */
    211            btm_ble_clear_irk_index(p_dev_rec->ble.resolving_list_index);
    212            p_dev_rec->ble.resolving_list_index = 0;
    213         }
    214     }
    215 }
    216 
    217 bool clear_resolving_list_bit(void *data, void *context)
    218 {
    219     tBTM_SEC_DEV_REC *p_dev_rec = data;
    220     p_dev_rec->ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT;
    221     return true;
    222 }
    223 
    224 /*******************************************************************************
    225 **
    226 ** Function         btm_ble_clear_resolving_list_complete
    227 **
    228 ** Description      This function is called when command complete for
    229 **                  clear resolving list
    230 **
    231 ** Returns          void
    232 **
    233 *******************************************************************************/
    234 void btm_ble_clear_resolving_list_complete(UINT8 *p, UINT16 evt_len)
    235 {
    236     UINT8 status = 0;
    237     STREAM_TO_UINT8(status, p);
    238 
    239     BTM_TRACE_DEBUG("%s status=%d", __func__, status);
    240 
    241     if (status == HCI_SUCCESS)
    242     {
    243         if (evt_len >= 3)
    244         {
    245             /* VSC complete has one extra byte for op code and list size, skip it here */
    246             p ++;
    247 
    248             /* updated the available list size, and current list size */
    249             uint8_t irk_list_sz_max = 0;
    250             STREAM_TO_UINT8(irk_list_sz_max, p);
    251 
    252             if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
    253                 btm_ble_resolving_list_init(irk_list_sz_max);
    254 
    255             uint8_t irk_mask_size = (irk_list_sz_max % 8) ?
    256                             (irk_list_sz_max / 8 + 1) : (irk_list_sz_max / 8);
    257             memset(btm_cb.ble_ctr_cb.irk_list_mask, 0, irk_mask_size);
    258         }
    259 
    260         btm_cb.ble_ctr_cb.resolving_list_avail_size =
    261             controller_get_interface()->get_ble_resolving_list_max_size();
    262 
    263         BTM_TRACE_DEBUG("%s resolving_list_avail_size=%d",
    264                         __func__, btm_cb.ble_ctr_cb.resolving_list_avail_size);
    265 
    266         list_foreach(btm_cb.sec_dev_rec, clear_resolving_list_bit, NULL);
    267     }
    268 }
    269 
    270 /*******************************************************************************
    271 **
    272 ** Function         btm_ble_add_resolving_list_entry_complete
    273 **
    274 ** Description      This function is called when command complete for
    275 **                  add resolving list entry
    276 **
    277 ** Returns          void
    278 **
    279 *******************************************************************************/
    280 void btm_ble_add_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
    281 {
    282     UINT8 status;
    283     STREAM_TO_UINT8(status, p);
    284 
    285     BTM_TRACE_DEBUG("%s status = %d", __func__, status);
    286 
    287     BD_ADDR pseudo_bda;
    288     if (!btm_ble_deq_resolving_pending(pseudo_bda))
    289     {
    290         BTM_TRACE_DEBUG("no pending resolving list operation");
    291         return;
    292     }
    293 
    294     if (status == HCI_SUCCESS)
    295     {
    296         /* privacy 1.2 command complete does not have these extra byte */
    297         if (evt_len > 2)
    298         {
    299             /* VSC complete has one extra byte for op code, skip it here */
    300             p ++;
    301             STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
    302         }
    303         else
    304             btm_cb.ble_ctr_cb.resolving_list_avail_size --;
    305     }
    306     else if (status == HCI_ERR_MEMORY_FULL) /* BT_ERROR_CODE_MEMORY_CAPACITY_EXCEEDED  */
    307     {
    308         btm_cb.ble_ctr_cb.resolving_list_avail_size = 0;
    309         BTM_TRACE_DEBUG("%s Resolving list Full ", __func__);
    310     }
    311 }
    312 
    313 /*******************************************************************************
    314 **
    315 ** Function         btm_ble_remove_resolving_list_entry_complete
    316 **
    317 ** Description      This function is called when command complete for
    318 **                  remove resolving list entry
    319 **
    320 ** Returns          void
    321 **
    322 *******************************************************************************/
    323 void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
    324 {
    325     BD_ADDR pseudo_bda;
    326     UINT8 status;
    327 
    328     STREAM_TO_UINT8(status, p);
    329 
    330     BTM_TRACE_DEBUG("%s status = %d", __func__, status);
    331 
    332     if (!btm_ble_deq_resolving_pending(pseudo_bda))
    333     {
    334         BTM_TRACE_ERROR("%s no pending resolving list operation", __func__);
    335         return;
    336     }
    337 
    338     if (status == HCI_SUCCESS)
    339     {
    340         /* proprietary: spec does not have these extra bytes */
    341         if (evt_len > 2)
    342         {
    343             p ++; /* skip opcode */
    344             STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
    345         }
    346         else
    347             btm_cb.ble_ctr_cb.resolving_list_avail_size++;
    348     }
    349 }
    350 
    351 /*******************************************************************************
    352 **
    353 ** Function         btm_ble_read_resolving_list_entry_complete
    354 **
    355 ** Description      This function is called when command complete for
    356 **                  remove resolving list entry
    357 **
    358 ** Returns          void
    359 **
    360 *******************************************************************************/
    361 void btm_ble_read_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
    362 {
    363     UINT8           status, rra_type = BTM_BLE_ADDR_PSEUDO;
    364     BD_ADDR         rra, pseudo_bda;
    365 
    366     STREAM_TO_UINT8  (status, p);
    367 
    368     BTM_TRACE_DEBUG("%s status = %d", __func__, status);
    369 
    370     if (!btm_ble_deq_resolving_pending(pseudo_bda))
    371     {
    372         BTM_TRACE_ERROR("no pending resolving list operation");
    373         return;
    374     }
    375 
    376     if (status == HCI_SUCCESS)
    377     {
    378         /* proprietary spec has extra bytes */
    379         if (evt_len > 8)
    380         {
    381             p += (2 + 16 + 1 + 6); /* skip subcode, index, IRK value, address type, identity addr type */
    382             STREAM_TO_BDADDR(rra, p);
    383 
    384             BTM_TRACE_ERROR("%s peer_addr: %02x:%02x:%02x:%02x:%02x:%02x",
    385                             __func__, rra[0], rra[1], rra[2], rra[3], rra[4], rra[5]);
    386         }
    387         else
    388         {
    389            STREAM_TO_BDADDR(rra, p);
    390         }
    391         btm_ble_refresh_peer_resolvable_private_addr(pseudo_bda, rra, rra_type);
    392    }
    393 }
    394 /*******************************************************************************
    395                 VSC that implement controller based privacy
    396 ********************************************************************************/
    397 /*******************************************************************************
    398 **
    399 ** Function         btm_ble_resolving_list_vsc_op_cmpl
    400 **
    401 ** Description      IRK operation VSC complete handler
    402 **
    403 ** Parameters
    404 **
    405 ** Returns          void
    406 **
    407 *******************************************************************************/
    408 void btm_ble_resolving_list_vsc_op_cmpl (tBTM_VSC_CMPL *p_params)
    409 {
    410     UINT8  *p = p_params->p_param_buf, op_subcode;
    411     UINT16  evt_len = p_params->param_len;
    412 
    413     op_subcode   = *(p + 1);
    414 
    415     BTM_TRACE_DEBUG("%s op_subcode = %d", __func__, op_subcode);
    416 
    417     if (op_subcode == BTM_BLE_META_CLEAR_IRK_LIST)
    418     {
    419         btm_ble_clear_resolving_list_complete(p, evt_len);
    420     }
    421     else if (op_subcode == BTM_BLE_META_ADD_IRK_ENTRY)
    422     {
    423        btm_ble_add_resolving_list_entry_complete(p, evt_len);
    424     }
    425     else if (op_subcode == BTM_BLE_META_REMOVE_IRK_ENTRY)
    426     {
    427         btm_ble_remove_resolving_list_entry_complete(p, evt_len);
    428     }
    429     else if (op_subcode == BTM_BLE_META_READ_IRK_ENTRY)
    430     {
    431          btm_ble_read_resolving_list_entry_complete(p, evt_len);
    432     }
    433     else if (op_subcode == BTM_BLE_META_IRK_ENABLE)
    434     {
    435         /* RPA offloading enable/disabled */
    436     }
    437 }
    438 
    439 /*******************************************************************************
    440 **
    441 ** Function         btm_ble_remove_resolving_list_entry
    442 **
    443 ** Description      This function to remove an IRK entry from the list
    444 **
    445 ** Parameters       ble_addr_type: address type
    446 **                  ble_addr: LE adddress
    447 **
    448 ** Returns          status
    449 **
    450 *******************************************************************************/
    451 tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
    452 {
    453     /* if controller does not support RPA offloading or privacy 1.2, skip */
    454     if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
    455         return BTM_WRONG_MODE;
    456 
    457     tBTM_STATUS st = BTM_NO_RESOURCES;
    458     if (controller_get_interface()->supports_ble_privacy())
    459     {
    460         if (btsnd_hcic_ble_rm_device_resolving_list(p_dev_rec->ble.static_addr_type,
    461                                                     p_dev_rec->ble.static_addr))
    462             st =  BTM_CMD_STARTED;
    463     }
    464     else
    465     {
    466         UINT8 param[20]= {0};
    467         UINT8 *p = param;
    468 
    469         UINT8_TO_STREAM(p, BTM_BLE_META_REMOVE_IRK_ENTRY);
    470         UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
    471         BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);
    472 
    473         st = BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC,
    474                                        BTM_BLE_META_REMOVE_IRK_LEN,
    475                                        param,
    476                                        btm_ble_resolving_list_vsc_op_cmpl);
    477     }
    478 
    479     if (st == BTM_CMD_STARTED)
    480         btm_ble_enq_resolving_list_pending( p_dev_rec->bd_addr, BTM_BLE_META_REMOVE_IRK_ENTRY);
    481 
    482     return st;
    483 }
    484 
    485 /*******************************************************************************
    486 **
    487 ** Function         btm_ble_clear_resolving_list
    488 **
    489 ** Description      This function clears the resolving  list
    490 **
    491 ** Parameters       None.
    492 **
    493 ** Returns          status
    494 **
    495 *******************************************************************************/
    496 tBTM_STATUS btm_ble_clear_resolving_list(void)
    497 {
    498     tBTM_STATUS st = BTM_NO_RESOURCES;
    499 
    500     if (controller_get_interface()->supports_ble_privacy())
    501     {
    502         if (btsnd_hcic_ble_clear_resolving_list())
    503             st =  BTM_SUCCESS;
    504     }
    505     else
    506     {
    507         UINT8 param[20] = {0};
    508         UINT8 *p = param;
    509 
    510         UINT8_TO_STREAM(p, BTM_BLE_META_CLEAR_IRK_LIST);
    511         st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
    512                                         BTM_BLE_META_CLEAR_IRK_LEN,
    513                                         param,
    514                                         btm_ble_resolving_list_vsc_op_cmpl);
    515     }
    516 
    517     return st;
    518 }
    519 
    520 /*******************************************************************************
    521 **
    522 ** Function         btm_ble_read_resolving_list_entry
    523 **
    524 ** Description      This function read an IRK entry by index
    525 **
    526 ** Parameters       entry index.
    527 **
    528 ** Returns          status
    529 **
    530 *******************************************************************************/
    531 tBTM_STATUS btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
    532 {
    533     tBTM_STATUS st = BTM_NO_RESOURCES;
    534 
    535     if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT))
    536         return BTM_WRONG_MODE;
    537 
    538     if (controller_get_interface()->supports_ble_privacy())
    539     {
    540         if (btsnd_hcic_ble_read_resolvable_addr_peer(p_dev_rec->ble.static_addr_type,
    541                                                      p_dev_rec->ble.static_addr))
    542             st =  BTM_CMD_STARTED;
    543     }
    544     else
    545     {
    546         UINT8 param[20] = {0};
    547         UINT8 *p = param;
    548 
    549         UINT8_TO_STREAM(p, BTM_BLE_META_READ_IRK_ENTRY);
    550         UINT8_TO_STREAM(p, p_dev_rec->ble.resolving_list_index);
    551 
    552         st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
    553                                         BTM_BLE_META_READ_IRK_LEN,
    554                                         param,
    555                                         btm_ble_resolving_list_vsc_op_cmpl);
    556     }
    557 
    558     if (st == BTM_CMD_STARTED)
    559         btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
    560                                            BTM_BLE_META_READ_IRK_ENTRY);
    561 
    562     return st;
    563 }
    564 
    565 
    566 /*******************************************************************************
    567 **
    568 ** Function         btm_ble_suspend_resolving_list_activity
    569 **
    570 ** Description      This function suspends all resolving list activity, including
    571 **                  scan, initiating, and advertising, if resolving list is being
    572 **                  enabled.
    573 **
    574 ** Parameters
    575 **
    576 ** Returns          TRUE if suspended; FALSE otherwise
    577 **
    578 *******************************************************************************/
    579 BOOLEAN btm_ble_suspend_resolving_list_activity(void)
    580 {
    581     tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
    582 
    583     /* if resolving list is not enabled, do not need to terminate any activity */
    584     /* if asking for stop all activity */
    585     /* if already suspended */
    586     if (p_ble_cb->suspended_rl_state != BTM_BLE_RL_IDLE)
    587         return TRUE;
    588 
    589     /* direct connection active, wait until it completed */
    590     if (btm_ble_get_conn_st() == BLE_DIR_CONN)
    591     {
    592         BTM_TRACE_ERROR("resolving list can not be edited, EnQ now");
    593         return FALSE;
    594     }
    595 
    596     p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
    597 
    598     if (p_ble_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE)
    599     {
    600         btm_ble_stop_adv();
    601         p_ble_cb->suspended_rl_state |= BTM_BLE_RL_ADV;
    602     }
    603 
    604     if (BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity))
    605     {
    606         btm_ble_stop_scan();
    607         p_ble_cb->suspended_rl_state |= BTM_BLE_RL_SCAN;
    608     }
    609 
    610     if (btm_ble_suspend_bg_conn())
    611         p_ble_cb->suspended_rl_state |= BTM_BLE_RL_INIT;
    612 
    613     return TRUE;
    614 }
    615 
    616 /*******************************************************************************
    617 **
    618 ** Function         btm_ble_resume_resolving_list_activity
    619 **
    620 ** Description      This function resumes the resolving list activity, including
    621 **                  scanning, initiating, and advertising, if any of these
    622 **                  activities has been suspended earlier.
    623 **
    624 ** Returns          none
    625 **
    626 *******************************************************************************/
    627 void btm_ble_resume_resolving_list_activity(void)
    628 {
    629     tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;
    630 
    631     if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_ADV)
    632         btm_ble_start_adv();
    633 
    634     if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_SCAN)
    635         btm_ble_start_scan();
    636 
    637     if  (p_ble_cb->suspended_rl_state & BTM_BLE_RL_INIT)
    638         btm_ble_resume_bg_conn();
    639 
    640     p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
    641 }
    642 
    643 /*******************************************************************************
    644 **
    645 ** Function         btm_ble_vendor_enable_irk_feature
    646 **
    647 ** Description      This function is called to enable or disable the RRA
    648 **                  offloading feature.
    649 **
    650 ** Parameters       enable: enable or disable the RRA offloading feature
    651 **
    652 ** Returns          BTM_SUCCESS if successful
    653 **
    654 *******************************************************************************/
    655 tBTM_STATUS btm_ble_vendor_enable_irk_feature(BOOLEAN enable)
    656 {
    657     UINT8           param[20], *p;
    658     tBTM_STATUS     st = BTM_MODE_UNSUPPORTED;
    659 
    660     p = param;
    661     memset(param, 0, 20);
    662 
    663     /* select feature based on control block settings */
    664     UINT8_TO_STREAM(p, BTM_BLE_META_IRK_ENABLE);
    665     UINT8_TO_STREAM(p, enable ? 0x01 : 0x00);
    666 
    667     st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_IRK_ENABLE_LEN,
    668                                     param, btm_ble_resolving_list_vsc_op_cmpl);
    669 
    670     return st;
    671 }
    672 
    673 /*******************************************************************************
    674 **
    675 ** Function         btm_ble_exe_disable_resolving_list
    676 **
    677 ** Description      execute resolving list disable
    678 **
    679 ** Returns          none
    680 **
    681 *******************************************************************************/
    682 BOOLEAN btm_ble_exe_disable_resolving_list(void)
    683 {
    684     if (!btm_ble_suspend_resolving_list_activity())
    685         return FALSE;
    686 
    687     if (!controller_get_interface()->supports_ble_privacy())
    688         btm_ble_vendor_enable_irk_feature(FALSE);
    689     else
    690         btsnd_hcic_ble_set_addr_resolution_enable(FALSE);
    691 
    692     return TRUE;
    693 }
    694 
    695 /*******************************************************************************
    696 **
    697 ** Function         btm_ble_exe_enable_resolving_list
    698 **
    699 ** Description      enable LE resolve address list
    700 **
    701 ** Returns          none
    702 **
    703 *******************************************************************************/
    704 void btm_ble_exe_enable_resolving_list(void)
    705 {
    706     if (!btm_ble_suspend_resolving_list_activity())
    707         return;
    708 
    709     if (!controller_get_interface()->supports_ble_privacy())
    710         btm_ble_vendor_enable_irk_feature(TRUE);
    711     else
    712         btsnd_hcic_ble_set_addr_resolution_enable(TRUE);
    713 }
    714 
    715 /*******************************************************************************
    716 **
    717 ** Function         btm_ble_disable_resolving_list
    718 **
    719 ** Description      Disable LE Address resolution
    720 **
    721 ** Returns          none
    722 **
    723 *******************************************************************************/
    724 BOOLEAN btm_ble_disable_resolving_list(UINT8 rl_mask, BOOLEAN to_resume )
    725 {
    726     UINT8 rl_state = btm_cb.ble_ctr_cb.rl_state;
    727 
    728     /* if controller does not support RPA offloading or privacy 1.2, skip */
    729     if (controller_get_interface()->get_ble_resolving_list_max_size()== 0)
    730         return FALSE;
    731 
    732     btm_cb.ble_ctr_cb.rl_state &= ~rl_mask;
    733 
    734     if (rl_state != BTM_BLE_RL_IDLE && btm_cb.ble_ctr_cb.rl_state == BTM_BLE_RL_IDLE)
    735     {
    736         if (btm_ble_exe_disable_resolving_list())
    737         {
    738             if (to_resume)
    739                 btm_ble_resume_resolving_list_activity();
    740 
    741             return TRUE;
    742         }
    743         else
    744             return FALSE;
    745     }
    746 
    747     return TRUE;
    748 }
    749 
    750 /*******************************************************************************
    751 **
    752 ** Function         btm_ble_resolving_list_load_dev
    753 **
    754 ** Description      This function add a device which is using RPA into white list
    755 **
    756 ** Parameters       pointer to device security record
    757 **
    758 ** Returns          TRUE if device added, otherwise falase.
    759 **
    760 *******************************************************************************/
    761 BOOLEAN btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec)
    762 {
    763     BOOLEAN rt = FALSE;
    764     UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;
    765 
    766     BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d", __func__,
    767                                 btm_cb.ble_ctr_cb.privacy_mode);
    768 
    769     /* if controller does not support RPA offloading or privacy 1.2, skip */
    770     if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
    771         return FALSE;
    772 
    773     BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d",
    774                     __func__, btm_cb.ble_ctr_cb.privacy_mode);
    775 
    776     /* only add RPA enabled device into resolving list */
    777     if (p_dev_rec != NULL && /* RPA is being used and PID is known */
    778        ((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0 ||
    779        (p_dev_rec->ble.key_type & BTM_LE_KEY_LID) != 0))
    780     {
    781         if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
    782             btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
    783                                                       BTM_BLE_META_ADD_IRK_ENTRY) == FALSE)
    784         {
    785             if (btm_cb.ble_ctr_cb.resolving_list_avail_size > 0)
    786             {
    787                 if (rl_mask)
    788                 {
    789                     if (!btm_ble_disable_resolving_list (rl_mask, FALSE))
    790                         return FALSE;
    791                 }
    792 
    793                 btm_ble_update_resolving_list(p_dev_rec->bd_addr, TRUE);
    794                 if (controller_get_interface()->supports_ble_privacy())
    795                 {
    796                     BD_ADDR dummy_bda = {0};
    797                     UINT8 *peer_irk = p_dev_rec->ble.keys.irk;
    798                     UINT8 *local_irk = btm_cb.devcb.id_keys.irk;
    799 
    800                     if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) == 0)
    801                     {
    802                         memcpy(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
    803                         p_dev_rec->ble.static_addr_type = p_dev_rec->ble.ble_addr_type;
    804                     }
    805 
    806                     BTM_TRACE_DEBUG("%s:adding device to controller resolving list", __func__);
    807                     // use identical IRK for now
    808                     rt = btsnd_hcic_ble_add_device_resolving_list(p_dev_rec->ble.static_addr_type,
    809                               p_dev_rec->ble.static_addr, peer_irk, local_irk);
    810                 }
    811                 else
    812                 {
    813                     UINT8 param[40] = {0};
    814                     UINT8 *p = param;
    815 
    816                     UINT8_TO_STREAM(p, BTM_BLE_META_ADD_IRK_ENTRY);
    817                     ARRAY_TO_STREAM(p, p_dev_rec->ble.keys.irk, BT_OCTET16_LEN);
    818                     UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
    819                     BDADDR_TO_STREAM(p,p_dev_rec->ble.static_addr);
    820 
    821                     if (BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
    822                                                    BTM_BLE_META_ADD_IRK_LEN,
    823                                                    param,
    824                                                    btm_ble_resolving_list_vsc_op_cmpl)
    825                                                    == BTM_CMD_STARTED)
    826                         rt = TRUE;
    827                 }
    828 
    829                if (rt)
    830                    btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
    831                                                       BTM_BLE_META_ADD_IRK_ENTRY);
    832 
    833                 /* if resolving list has been turned on, re-enable it */
    834                 if (rl_mask)
    835                     btm_ble_enable_resolving_list(rl_mask);
    836                 else
    837                     btm_ble_enable_resolving_list(BTM_BLE_RL_INIT);
    838             }
    839         }
    840         else
    841         {
    842             BTM_TRACE_ERROR("Device already in Resolving list");
    843             rt = TRUE;
    844         }
    845     }
    846     else
    847     {
    848         BTM_TRACE_DEBUG("Device not a RPA enabled device");
    849     }
    850     return rt;
    851 }
    852 
    853 /*******************************************************************************
    854 **
    855 ** Function         btm_ble_resolving_list_remove_dev
    856 **
    857 ** Description      This function removes the device from resolving list
    858 **
    859 ** Parameters
    860 **
    861 ** Returns          status
    862 **
    863 *******************************************************************************/
    864 void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC *p_dev_rec)
    865 {
    866     UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;
    867 
    868     BTM_TRACE_EVENT ("%s", __func__);
    869     if (rl_mask)
    870     {
    871         if (!btm_ble_disable_resolving_list (rl_mask, FALSE))
    872              return;
    873     }
    874 
    875     if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
    876         btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
    877                                                   BTM_BLE_META_REMOVE_IRK_ENTRY) == FALSE)
    878     {
    879         btm_ble_update_resolving_list( p_dev_rec->bd_addr, FALSE);
    880         btm_ble_remove_resolving_list_entry(p_dev_rec);
    881     }
    882     else
    883     {
    884         BTM_TRACE_DEBUG("Device not in resolving list");
    885     }
    886 
    887     /* if resolving list has been turned on, re-enable it */
    888     if (rl_mask)
    889         btm_ble_enable_resolving_list(rl_mask);
    890 }
    891 
    892 /*******************************************************************************
    893 **
    894 ** Function         btm_ble_enable_resolving_list
    895 **
    896 ** Description      enable LE resolve address list
    897 **
    898 ** Returns          none
    899 **
    900 *******************************************************************************/
    901 void btm_ble_enable_resolving_list(UINT8 rl_mask)
    902 {
    903     UINT8 rl_state = btm_cb.ble_ctr_cb.rl_state;
    904 
    905     btm_cb.ble_ctr_cb.rl_state |= rl_mask;
    906     if (rl_state == BTM_BLE_RL_IDLE &&
    907         btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE &&
    908         controller_get_interface()->get_ble_resolving_list_max_size() != 0)
    909     {
    910         btm_ble_exe_enable_resolving_list();
    911         btm_ble_resume_resolving_list_activity();
    912     }
    913 }
    914 
    915 /*******************************************************************************
    916 **
    917 ** Function         btm_ble_resolving_list_empty
    918 **
    919 ** Description      check to see if resoving list is empty or not
    920 **
    921 ** Returns          TRUE: empty; FALSE non-empty
    922 **
    923 *******************************************************************************/
    924 BOOLEAN btm_ble_resolving_list_empty(void)
    925 {
    926     return (controller_get_interface()->get_ble_resolving_list_max_size() ==
    927             btm_cb.ble_ctr_cb.resolving_list_avail_size);
    928 }
    929 
    930 
    931 bool is_on_resolving_list(void *data, void *context)
    932 {
    933     tBTM_SEC_DEV_REC *p_dev = data;
    934     if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
    935         (p_dev->ble.in_controller_list & BTM_WHITE_LIST_BIT))
    936         return false;
    937 
    938     return true;
    939 }
    940 
    941 
    942 /*******************************************************************************
    943 **
    944 ** Function         btm_ble_enable_resolving_list_for_platform
    945 **
    946 ** Description      enable/disable resolving list feature depending on if any
    947 **                  resolving list is empty and whitelist is involoved in the
    948 **                  operation.
    949 **
    950 ** Returns          none
    951 **
    952 *******************************************************************************/
    953 void btm_ble_enable_resolving_list_for_platform (UINT8 rl_mask)
    954 {
    955     /* if controller does not support, skip */
    956     if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
    957         return;
    958 
    959     if (btm_cb.ble_ctr_cb.wl_state == BTM_BLE_WL_IDLE)
    960     {
    961         if (controller_get_interface()->get_ble_resolving_list_max_size() >
    962                                         btm_cb.ble_ctr_cb.resolving_list_avail_size)
    963             btm_ble_enable_resolving_list(rl_mask);
    964         else
    965             btm_ble_disable_resolving_list(rl_mask, TRUE);
    966         return;
    967     }
    968 
    969     list_node_t *n = list_foreach(btm_cb.sec_dev_rec, is_on_resolving_list, NULL);
    970     if (n)
    971         btm_ble_enable_resolving_list(rl_mask);
    972     else
    973         btm_ble_disable_resolving_list(rl_mask, TRUE);
    974 }
    975 
    976 /*******************************************************************************
    977 **
    978 ** Function         btm_ble_resolving_list_init
    979 **
    980 ** Description      Initialize resolving list in host stack
    981 **
    982 ** Parameters       Max resolving list size
    983 **
    984 ** Returns          void
    985 **
    986 *******************************************************************************/
    987 void btm_ble_resolving_list_init(UINT8 max_irk_list_sz)
    988 {
    989     tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
    990     UINT8 irk_mask_size =  (max_irk_list_sz % 8) ?
    991                            (max_irk_list_sz/8 + 1) : (max_irk_list_sz/8);
    992 
    993     if (max_irk_list_sz > 0)
    994     {
    995         p_q->resolve_q_random_pseudo = (BD_ADDR *)osi_malloc(sizeof(BD_ADDR) * max_irk_list_sz);
    996         p_q->resolve_q_action = (UINT8 *)osi_malloc(max_irk_list_sz);
    997 
    998         /* RPA offloading feature */
    999         if (btm_cb.ble_ctr_cb.irk_list_mask == NULL)
   1000             btm_cb.ble_ctr_cb.irk_list_mask = (UINT8 *)osi_malloc(irk_mask_size);
   1001 
   1002         BTM_TRACE_DEBUG ("%s max_irk_list_sz = %d", __func__, max_irk_list_sz);
   1003     }
   1004 
   1005     controller_get_interface()->set_ble_resolving_list_max_size(max_irk_list_sz);
   1006     btm_ble_clear_resolving_list();
   1007     btm_cb.ble_ctr_cb.resolving_list_avail_size = max_irk_list_sz;
   1008 }
   1009 
   1010 /*******************************************************************************
   1011 **
   1012 ** Function         btm_ble_resolving_list_cleanup
   1013 **
   1014 ** Description      Cleanup resolving list dynamic memory
   1015 **
   1016 ** Parameters
   1017 **
   1018 ** Returns          void
   1019 **
   1020 *******************************************************************************/
   1021 void btm_ble_resolving_list_cleanup(void)
   1022 {
   1023     tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
   1024 
   1025     osi_free_and_reset((void **)&p_q->resolve_q_random_pseudo);
   1026     osi_free_and_reset((void **)&p_q->resolve_q_action);
   1027 
   1028     controller_get_interface()->set_ble_resolving_list_max_size(0);
   1029 
   1030     osi_free_and_reset((void **)&btm_cb.ble_ctr_cb.irk_list_mask);
   1031 }
   1032 #endif
   1033