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