/******************************************************************************
 *
 *  Copyright (C) 1999-2012 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  This file contains functions for BLE controller based privacy.
 *
 ******************************************************************************/
#include <string.h>
#include "bt_target.h"

#if (BLE_INCLUDED == TRUE && BLE_PRIVACY_SPT == TRUE)
#include "bt_types.h"
#include "hcimsgs.h"
#include "btu.h"
#include "vendor_hcidefs.h"
#include "btm_int.h"
#include "device/include/controller.h"

/* RPA offload VSC specifics */
#define BTM_BLE_META_IRK_ENABLE         0x01
#define BTM_BLE_META_ADD_IRK_ENTRY      0x02
#define BTM_BLE_META_REMOVE_IRK_ENTRY   0x03
#define BTM_BLE_META_CLEAR_IRK_LIST     0x04
#define BTM_BLE_META_READ_IRK_ENTRY     0x05
#define BTM_BLE_META_CS_RESOLVE_ADDR    0x00000001
#define BTM_BLE_IRK_ENABLE_LEN          2

#define BTM_BLE_META_ADD_IRK_LEN        24
#define BTM_BLE_META_REMOVE_IRK_LEN     8
#define BTM_BLE_META_CLEAR_IRK_LEN      1
#define BTM_BLE_META_READ_IRK_LEN       2
#define BTM_BLE_META_ADD_WL_ATTR_LEN    9

/*******************************************************************************
**         Functions implemented controller based privacy using Resolving List
*******************************************************************************/
/*******************************************************************************
**
** Function         btm_ble_enq_resolving_list_pending
**
** Description      add target address into resolving pending operation queue
**
** Parameters       target_bda: target device address
**                  add_entry: TRUE for add entry, FALSE for remove entry
**
** Returns          void
**
*******************************************************************************/
void btm_ble_enq_resolving_list_pending(BD_ADDR pseudo_bda, UINT8 op_code)
{
    tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;

    memcpy(p_q->resolve_q_random_pseudo[p_q->q_next], pseudo_bda, BD_ADDR_LEN);
    p_q->resolve_q_action[p_q->q_next] = op_code;
    p_q->q_next ++;
    p_q->q_next %= controller_get_interface()->get_ble_resolving_list_max_size();
}

/*******************************************************************************
**
** Function         btm_ble_brcm_find_resolving_pending_entry
**
** Description      check to see if the action is in pending list
**
** Parameters       TRUE: action pending;
**                  FALSE: new action
**
** Returns          void
**
*******************************************************************************/
BOOLEAN btm_ble_brcm_find_resolving_pending_entry(BD_ADDR pseudo_addr, UINT8 action)
{
    tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;

    for (UINT8 i = p_q->q_pending; i != p_q->q_next;)
    {
        if (memcmp(p_q->resolve_q_random_pseudo[i], pseudo_addr, BD_ADDR_LEN) == 0 &&
            action == p_q->resolve_q_action[i])
            return TRUE;

        i ++;
        i %= controller_get_interface()->get_ble_resolving_list_max_size();
    }
    return FALSE;
}

/*******************************************************************************
**
** Function         btm_ble_deq_resolving_pending
**
** Description      dequeue target address from resolving pending operation queue
**
** Parameters       pseudo_addr: pseudo_addr device address
**
** Returns          void
**
*******************************************************************************/
BOOLEAN btm_ble_deq_resolving_pending(BD_ADDR pseudo_addr)
{
    tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;

    if (p_q->q_next != p_q->q_pending)
    {
        memcpy(pseudo_addr, p_q->resolve_q_random_pseudo[p_q->q_pending], BD_ADDR_LEN);
        memset(p_q->resolve_q_random_pseudo[p_q->q_pending], 0, BD_ADDR_LEN);
        p_q->q_pending ++;
        p_q->q_pending %= controller_get_interface()->get_ble_resolving_list_max_size();
        return TRUE;
    }

    return FALSE;
}

/*******************************************************************************
**
** Function         btm_ble_clear_irk_index
**
** Description      clear IRK list index mask for availability
**
** Returns          none
**
*******************************************************************************/
void btm_ble_clear_irk_index(UINT8 index)
{
    UINT8 byte;
    UINT8 bit;

    if (index < controller_get_interface()->get_ble_resolving_list_max_size())
    {
         byte = index / 8;
         bit = index % 8;
         btm_cb.ble_ctr_cb.irk_list_mask[byte] &= (~(1 << bit));
    }
}

/*******************************************************************************
**
** Function         btm_ble_find_irk_index
**
** Description      find the first available IRK list index
**
** Returns          index from 0 ~ max (127 default)
**
*******************************************************************************/
UINT8 btm_ble_find_irk_index(void)
{
    UINT8 i = 0;
    UINT8 byte;
    UINT8 bit;

    while (i < controller_get_interface()->get_ble_resolving_list_max_size())
    {
        byte = i / 8;
        bit = i % 8;

        if ((btm_cb.ble_ctr_cb.irk_list_mask[byte] & (1 << bit)) == 0)
        {
            btm_cb.ble_ctr_cb.irk_list_mask[byte] |= (1 << bit);
            return i;
        }
        i++;
    }

    BTM_TRACE_ERROR ("%s failed, list full", __func__);
    return i;
}

/*******************************************************************************
**
** Function         btm_ble_update_resolving_list
**
** Description      update resolving list entry in host maintained record
**
** Returns          void
**
*******************************************************************************/
void btm_ble_update_resolving_list(BD_ADDR pseudo_bda, BOOLEAN add)
{
    tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(pseudo_bda);
    if (p_dev_rec == NULL)
        return;

    if (add)
    {
        p_dev_rec->ble.in_controller_list |= BTM_RESOLVING_LIST_BIT;
        if (!controller_get_interface()->supports_ble_privacy())
            p_dev_rec->ble.resolving_list_index = btm_ble_find_irk_index();
    }
    else
    {
        p_dev_rec->ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT;
        if (!controller_get_interface()->supports_ble_privacy())
        {
           /* clear IRK list index mask */
           btm_ble_clear_irk_index(p_dev_rec->ble.resolving_list_index);
           p_dev_rec->ble.resolving_list_index = 0;
        }
    }
}

bool clear_resolving_list_bit(void *data, void *context)
{
    tBTM_SEC_DEV_REC *p_dev_rec = data;
    p_dev_rec->ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT;
    return true;
}

/*******************************************************************************
**
** Function         btm_ble_clear_resolving_list_complete
**
** Description      This function is called when command complete for
**                  clear resolving list
**
** Returns          void
**
*******************************************************************************/
void btm_ble_clear_resolving_list_complete(UINT8 *p, UINT16 evt_len)
{
    UINT8 status = 0;
    STREAM_TO_UINT8(status, p);

    BTM_TRACE_DEBUG("%s status=%d", __func__, status);

    if (status == HCI_SUCCESS)
    {
        if (evt_len >= 3)
        {
            /* VSC complete has one extra byte for op code and list size, skip it here */
            p ++;

            /* updated the available list size, and current list size */
            uint8_t irk_list_sz_max = 0;
            STREAM_TO_UINT8(irk_list_sz_max, p);

            if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
                btm_ble_resolving_list_init(irk_list_sz_max);

            uint8_t irk_mask_size = (irk_list_sz_max % 8) ?
                            (irk_list_sz_max / 8 + 1) : (irk_list_sz_max / 8);
            memset(btm_cb.ble_ctr_cb.irk_list_mask, 0, irk_mask_size);
        }

        btm_cb.ble_ctr_cb.resolving_list_avail_size =
            controller_get_interface()->get_ble_resolving_list_max_size();

        BTM_TRACE_DEBUG("%s resolving_list_avail_size=%d",
                        __func__, btm_cb.ble_ctr_cb.resolving_list_avail_size);

        list_foreach(btm_cb.sec_dev_rec, clear_resolving_list_bit, NULL);
    }
}

/*******************************************************************************
**
** Function         btm_ble_add_resolving_list_entry_complete
**
** Description      This function is called when command complete for
**                  add resolving list entry
**
** Returns          void
**
*******************************************************************************/
void btm_ble_add_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
{
    UINT8 status;
    STREAM_TO_UINT8(status, p);

    BTM_TRACE_DEBUG("%s status = %d", __func__, status);

    BD_ADDR pseudo_bda;
    if (!btm_ble_deq_resolving_pending(pseudo_bda))
    {
        BTM_TRACE_DEBUG("no pending resolving list operation");
        return;
    }

    if (status == HCI_SUCCESS)
    {
        /* privacy 1.2 command complete does not have these extra byte */
        if (evt_len > 2)
        {
            /* VSC complete has one extra byte for op code, skip it here */
            p ++;
            STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
        }
        else
            btm_cb.ble_ctr_cb.resolving_list_avail_size --;
    }
    else if (status == HCI_ERR_MEMORY_FULL) /* BT_ERROR_CODE_MEMORY_CAPACITY_EXCEEDED  */
    {
        btm_cb.ble_ctr_cb.resolving_list_avail_size = 0;
        BTM_TRACE_DEBUG("%s Resolving list Full ", __func__);
    }
}

/*******************************************************************************
**
** Function         btm_ble_remove_resolving_list_entry_complete
**
** Description      This function is called when command complete for
**                  remove resolving list entry
**
** Returns          void
**
*******************************************************************************/
void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
{
    BD_ADDR pseudo_bda;
    UINT8 status;

    STREAM_TO_UINT8(status, p);

    BTM_TRACE_DEBUG("%s status = %d", __func__, status);

    if (!btm_ble_deq_resolving_pending(pseudo_bda))
    {
        BTM_TRACE_ERROR("%s no pending resolving list operation", __func__);
        return;
    }

    if (status == HCI_SUCCESS)
    {
        /* proprietary: spec does not have these extra bytes */
        if (evt_len > 2)
        {
            p ++; /* skip opcode */
            STREAM_TO_UINT8(btm_cb.ble_ctr_cb.resolving_list_avail_size, p);
        }
        else
            btm_cb.ble_ctr_cb.resolving_list_avail_size++;
    }
}

/*******************************************************************************
**
** Function         btm_ble_read_resolving_list_entry_complete
**
** Description      This function is called when command complete for
**                  remove resolving list entry
**
** Returns          void
**
*******************************************************************************/
void btm_ble_read_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
{
    UINT8           status, rra_type = BTM_BLE_ADDR_PSEUDO;
    BD_ADDR         rra, pseudo_bda;

    STREAM_TO_UINT8  (status, p);

    BTM_TRACE_DEBUG("%s status = %d", __func__, status);

    if (!btm_ble_deq_resolving_pending(pseudo_bda))
    {
        BTM_TRACE_ERROR("no pending resolving list operation");
        return;
    }

    if (status == HCI_SUCCESS)
    {
        /* proprietary spec has extra bytes */
        if (evt_len > 8)
        {
            p += (2 + 16 + 1 + 6); /* skip subcode, index, IRK value, address type, identity addr type */
            STREAM_TO_BDADDR(rra, p);

            BTM_TRACE_ERROR("%s peer_addr: %02x:%02x:%02x:%02x:%02x:%02x",
                            __func__, rra[0], rra[1], rra[2], rra[3], rra[4], rra[5]);
        }
        else
        {
           STREAM_TO_BDADDR(rra, p);
        }
        btm_ble_refresh_peer_resolvable_private_addr(pseudo_bda, rra, rra_type);
   }
}
/*******************************************************************************
                VSC that implement controller based privacy
********************************************************************************/
/*******************************************************************************
**
** Function         btm_ble_resolving_list_vsc_op_cmpl
**
** Description      IRK operation VSC complete handler
**
** Parameters
**
** Returns          void
**
*******************************************************************************/
void btm_ble_resolving_list_vsc_op_cmpl (tBTM_VSC_CMPL *p_params)
{
    UINT8  *p = p_params->p_param_buf, op_subcode;
    UINT16  evt_len = p_params->param_len;

    op_subcode   = *(p + 1);

    BTM_TRACE_DEBUG("%s op_subcode = %d", __func__, op_subcode);

    if (op_subcode == BTM_BLE_META_CLEAR_IRK_LIST)
    {
        btm_ble_clear_resolving_list_complete(p, evt_len);
    }
    else if (op_subcode == BTM_BLE_META_ADD_IRK_ENTRY)
    {
       btm_ble_add_resolving_list_entry_complete(p, evt_len);
    }
    else if (op_subcode == BTM_BLE_META_REMOVE_IRK_ENTRY)
    {
        btm_ble_remove_resolving_list_entry_complete(p, evt_len);
    }
    else if (op_subcode == BTM_BLE_META_READ_IRK_ENTRY)
    {
         btm_ble_read_resolving_list_entry_complete(p, evt_len);
    }
    else if (op_subcode == BTM_BLE_META_IRK_ENABLE)
    {
        /* RPA offloading enable/disabled */
    }
}

/*******************************************************************************
**
** Function         btm_ble_remove_resolving_list_entry
**
** Description      This function to remove an IRK entry from the list
**
** Parameters       ble_addr_type: address type
**                  ble_addr: LE adddress
**
** Returns          status
**
*******************************************************************************/
tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
{
    /* if controller does not support RPA offloading or privacy 1.2, skip */
    if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
        return BTM_WRONG_MODE;

    tBTM_STATUS st = BTM_NO_RESOURCES;
    if (controller_get_interface()->supports_ble_privacy())
    {
        if (btsnd_hcic_ble_rm_device_resolving_list(p_dev_rec->ble.static_addr_type,
                                                    p_dev_rec->ble.static_addr))
            st =  BTM_CMD_STARTED;
    }
    else
    {
        UINT8 param[20]= {0};
        UINT8 *p = param;

        UINT8_TO_STREAM(p, BTM_BLE_META_REMOVE_IRK_ENTRY);
        UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
        BDADDR_TO_STREAM(p, p_dev_rec->ble.static_addr);

        st = BTM_VendorSpecificCommand(HCI_VENDOR_BLE_RPA_VSC,
                                       BTM_BLE_META_REMOVE_IRK_LEN,
                                       param,
                                       btm_ble_resolving_list_vsc_op_cmpl);
    }

    if (st == BTM_CMD_STARTED)
        btm_ble_enq_resolving_list_pending( p_dev_rec->bd_addr, BTM_BLE_META_REMOVE_IRK_ENTRY);

    return st;
}

/*******************************************************************************
**
** Function         btm_ble_clear_resolving_list
**
** Description      This function clears the resolving  list
**
** Parameters       None.
**
** Returns          status
**
*******************************************************************************/
tBTM_STATUS btm_ble_clear_resolving_list(void)
{
    tBTM_STATUS st = BTM_NO_RESOURCES;

    if (controller_get_interface()->supports_ble_privacy())
    {
        if (btsnd_hcic_ble_clear_resolving_list())
            st =  BTM_SUCCESS;
    }
    else
    {
        UINT8 param[20] = {0};
        UINT8 *p = param;

        UINT8_TO_STREAM(p, BTM_BLE_META_CLEAR_IRK_LIST);
        st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
                                        BTM_BLE_META_CLEAR_IRK_LEN,
                                        param,
                                        btm_ble_resolving_list_vsc_op_cmpl);
    }

    return st;
}

/*******************************************************************************
**
** Function         btm_ble_read_resolving_list_entry
**
** Description      This function read an IRK entry by index
**
** Parameters       entry index.
**
** Returns          status
**
*******************************************************************************/
tBTM_STATUS btm_ble_read_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec)
{
    tBTM_STATUS st = BTM_NO_RESOURCES;

    if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT))
        return BTM_WRONG_MODE;

    if (controller_get_interface()->supports_ble_privacy())
    {
        if (btsnd_hcic_ble_read_resolvable_addr_peer(p_dev_rec->ble.static_addr_type,
                                                     p_dev_rec->ble.static_addr))
            st =  BTM_CMD_STARTED;
    }
    else
    {
        UINT8 param[20] = {0};
        UINT8 *p = param;

        UINT8_TO_STREAM(p, BTM_BLE_META_READ_IRK_ENTRY);
        UINT8_TO_STREAM(p, p_dev_rec->ble.resolving_list_index);

        st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
                                        BTM_BLE_META_READ_IRK_LEN,
                                        param,
                                        btm_ble_resolving_list_vsc_op_cmpl);
    }

    if (st == BTM_CMD_STARTED)
        btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
                                           BTM_BLE_META_READ_IRK_ENTRY);

    return st;
}


/*******************************************************************************
**
** Function         btm_ble_suspend_resolving_list_activity
**
** Description      This function suspends all resolving list activity, including
**                  scan, initiating, and advertising, if resolving list is being
**                  enabled.
**
** Parameters
**
** Returns          TRUE if suspended; FALSE otherwise
**
*******************************************************************************/
BOOLEAN btm_ble_suspend_resolving_list_activity(void)
{
    tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;

    /* if resolving list is not enabled, do not need to terminate any activity */
    /* if asking for stop all activity */
    /* if already suspended */
    if (p_ble_cb->suspended_rl_state != BTM_BLE_RL_IDLE)
        return TRUE;

    /* direct connection active, wait until it completed */
    if (btm_ble_get_conn_st() == BLE_DIR_CONN)
    {
        BTM_TRACE_ERROR("resolving list can not be edited, EnQ now");
        return FALSE;
    }

    p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;

    if (p_ble_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE)
    {
        btm_ble_stop_adv();
        p_ble_cb->suspended_rl_state |= BTM_BLE_RL_ADV;
    }

    if (BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity))
    {
        btm_ble_stop_scan();
        p_ble_cb->suspended_rl_state |= BTM_BLE_RL_SCAN;
    }

    if (btm_ble_suspend_bg_conn())
        p_ble_cb->suspended_rl_state |= BTM_BLE_RL_INIT;

    return TRUE;
}

/*******************************************************************************
**
** Function         btm_ble_resume_resolving_list_activity
**
** Description      This function resumes the resolving list activity, including
**                  scanning, initiating, and advertising, if any of these
**                  activities has been suspended earlier.
**
** Returns          none
**
*******************************************************************************/
void btm_ble_resume_resolving_list_activity(void)
{
    tBTM_BLE_CB *p_ble_cb = &btm_cb.ble_ctr_cb;

    if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_ADV)
        btm_ble_start_adv();

    if (p_ble_cb->suspended_rl_state & BTM_BLE_RL_SCAN)
        btm_ble_start_scan();

    if  (p_ble_cb->suspended_rl_state & BTM_BLE_RL_INIT)
        btm_ble_resume_bg_conn();

    p_ble_cb->suspended_rl_state = BTM_BLE_RL_IDLE;
}

/*******************************************************************************
**
** Function         btm_ble_vendor_enable_irk_feature
**
** Description      This function is called to enable or disable the RRA
**                  offloading feature.
**
** Parameters       enable: enable or disable the RRA offloading feature
**
** Returns          BTM_SUCCESS if successful
**
*******************************************************************************/
tBTM_STATUS btm_ble_vendor_enable_irk_feature(BOOLEAN enable)
{
    UINT8           param[20], *p;
    tBTM_STATUS     st = BTM_MODE_UNSUPPORTED;

    p = param;
    memset(param, 0, 20);

    /* select feature based on control block settings */
    UINT8_TO_STREAM(p, BTM_BLE_META_IRK_ENABLE);
    UINT8_TO_STREAM(p, enable ? 0x01 : 0x00);

    st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_IRK_ENABLE_LEN,
                                    param, btm_ble_resolving_list_vsc_op_cmpl);

    return st;
}

/*******************************************************************************
**
** Function         btm_ble_exe_disable_resolving_list
**
** Description      execute resolving list disable
**
** Returns          none
**
*******************************************************************************/
BOOLEAN btm_ble_exe_disable_resolving_list(void)
{
    if (!btm_ble_suspend_resolving_list_activity())
        return FALSE;

    if (!controller_get_interface()->supports_ble_privacy())
        btm_ble_vendor_enable_irk_feature(FALSE);
    else
        btsnd_hcic_ble_set_addr_resolution_enable(FALSE);

    return TRUE;
}

/*******************************************************************************
**
** Function         btm_ble_exe_enable_resolving_list
**
** Description      enable LE resolve address list
**
** Returns          none
**
*******************************************************************************/
void btm_ble_exe_enable_resolving_list(void)
{
    if (!btm_ble_suspend_resolving_list_activity())
        return;

    if (!controller_get_interface()->supports_ble_privacy())
        btm_ble_vendor_enable_irk_feature(TRUE);
    else
        btsnd_hcic_ble_set_addr_resolution_enable(TRUE);
}

/*******************************************************************************
**
** Function         btm_ble_disable_resolving_list
**
** Description      Disable LE Address resolution
**
** Returns          none
**
*******************************************************************************/
BOOLEAN btm_ble_disable_resolving_list(UINT8 rl_mask, BOOLEAN to_resume )
{
    UINT8 rl_state = btm_cb.ble_ctr_cb.rl_state;

    /* if controller does not support RPA offloading or privacy 1.2, skip */
    if (controller_get_interface()->get_ble_resolving_list_max_size()== 0)
        return FALSE;

    btm_cb.ble_ctr_cb.rl_state &= ~rl_mask;

    if (rl_state != BTM_BLE_RL_IDLE && btm_cb.ble_ctr_cb.rl_state == BTM_BLE_RL_IDLE)
    {
        if (btm_ble_exe_disable_resolving_list())
        {
            if (to_resume)
                btm_ble_resume_resolving_list_activity();

            return TRUE;
        }
        else
            return FALSE;
    }

    return TRUE;
}

/*******************************************************************************
**
** Function         btm_ble_resolving_list_load_dev
**
** Description      This function add a device which is using RPA into white list
**
** Parameters       pointer to device security record
**
** Returns          TRUE if device added, otherwise falase.
**
*******************************************************************************/
BOOLEAN btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec)
{
    BOOLEAN rt = FALSE;
    UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;

    BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d", __func__,
                                btm_cb.ble_ctr_cb.privacy_mode);

    /* if controller does not support RPA offloading or privacy 1.2, skip */
    if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
        return FALSE;

    BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d",
                    __func__, btm_cb.ble_ctr_cb.privacy_mode);

    /* only add RPA enabled device into resolving list */
    if (p_dev_rec != NULL && /* RPA is being used and PID is known */
       ((p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0 ||
       (p_dev_rec->ble.key_type & BTM_LE_KEY_LID) != 0))
    {
        if (!(p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
            btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
                                                      BTM_BLE_META_ADD_IRK_ENTRY) == FALSE)
        {
            if (btm_cb.ble_ctr_cb.resolving_list_avail_size > 0)
            {
                if (rl_mask)
                {
                    if (!btm_ble_disable_resolving_list (rl_mask, FALSE))
                        return FALSE;
                }

                btm_ble_update_resolving_list(p_dev_rec->bd_addr, TRUE);
                if (controller_get_interface()->supports_ble_privacy())
                {
                    BD_ADDR dummy_bda = {0};
                    UINT8 *peer_irk = p_dev_rec->ble.keys.irk;
                    UINT8 *local_irk = btm_cb.devcb.id_keys.irk;

                    if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) == 0)
                    {
                        memcpy(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
                        p_dev_rec->ble.static_addr_type = p_dev_rec->ble.ble_addr_type;
                    }

                    BTM_TRACE_DEBUG("%s:adding device to controller resolving list", __func__);
                    // use identical IRK for now
                    rt = btsnd_hcic_ble_add_device_resolving_list(p_dev_rec->ble.static_addr_type,
                              p_dev_rec->ble.static_addr, peer_irk, local_irk);
                }
                else
                {
                    UINT8 param[40] = {0};
                    UINT8 *p = param;

                    UINT8_TO_STREAM(p, BTM_BLE_META_ADD_IRK_ENTRY);
                    ARRAY_TO_STREAM(p, p_dev_rec->ble.keys.irk, BT_OCTET16_LEN);
                    UINT8_TO_STREAM(p, p_dev_rec->ble.static_addr_type);
                    BDADDR_TO_STREAM(p,p_dev_rec->ble.static_addr);

                    if (BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC,
                                                   BTM_BLE_META_ADD_IRK_LEN,
                                                   param,
                                                   btm_ble_resolving_list_vsc_op_cmpl)
                                                   == BTM_CMD_STARTED)
                        rt = TRUE;
                }

               if (rt)
                   btm_ble_enq_resolving_list_pending(p_dev_rec->bd_addr,
                                                      BTM_BLE_META_ADD_IRK_ENTRY);

                /* if resolving list has been turned on, re-enable it */
                if (rl_mask)
                    btm_ble_enable_resolving_list(rl_mask);
                else
                    btm_ble_enable_resolving_list(BTM_BLE_RL_INIT);
            }
        }
        else
        {
            BTM_TRACE_ERROR("Device already in Resolving list");
            rt = TRUE;
        }
    }
    else
    {
        BTM_TRACE_DEBUG("Device not a RPA enabled device");
    }
    return rt;
}

/*******************************************************************************
**
** Function         btm_ble_resolving_list_remove_dev
**
** Description      This function removes the device from resolving list
**
** Parameters
**
** Returns          status
**
*******************************************************************************/
void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC *p_dev_rec)
{
    UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;

    BTM_TRACE_EVENT ("%s", __func__);
    if (rl_mask)
    {
        if (!btm_ble_disable_resolving_list (rl_mask, FALSE))
             return;
    }

    if ((p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
        btm_ble_brcm_find_resolving_pending_entry(p_dev_rec->bd_addr,
                                                  BTM_BLE_META_REMOVE_IRK_ENTRY) == FALSE)
    {
        btm_ble_update_resolving_list( p_dev_rec->bd_addr, FALSE);
        btm_ble_remove_resolving_list_entry(p_dev_rec);
    }
    else
    {
        BTM_TRACE_DEBUG("Device not in resolving list");
    }

    /* if resolving list has been turned on, re-enable it */
    if (rl_mask)
        btm_ble_enable_resolving_list(rl_mask);
}

/*******************************************************************************
**
** Function         btm_ble_enable_resolving_list
**
** Description      enable LE resolve address list
**
** Returns          none
**
*******************************************************************************/
void btm_ble_enable_resolving_list(UINT8 rl_mask)
{
    UINT8 rl_state = btm_cb.ble_ctr_cb.rl_state;

    btm_cb.ble_ctr_cb.rl_state |= rl_mask;
    if (rl_state == BTM_BLE_RL_IDLE &&
        btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE &&
        controller_get_interface()->get_ble_resolving_list_max_size() != 0)
    {
        btm_ble_exe_enable_resolving_list();
        btm_ble_resume_resolving_list_activity();
    }
}

/*******************************************************************************
**
** Function         btm_ble_resolving_list_empty
**
** Description      check to see if resoving list is empty or not
**
** Returns          TRUE: empty; FALSE non-empty
**
*******************************************************************************/
BOOLEAN btm_ble_resolving_list_empty(void)
{
    return (controller_get_interface()->get_ble_resolving_list_max_size() ==
            btm_cb.ble_ctr_cb.resolving_list_avail_size);
}


bool is_on_resolving_list(void *data, void *context)
{
    tBTM_SEC_DEV_REC *p_dev = data;
    if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
        (p_dev->ble.in_controller_list & BTM_WHITE_LIST_BIT))
        return false;

    return true;
}


/*******************************************************************************
**
** Function         btm_ble_enable_resolving_list_for_platform
**
** Description      enable/disable resolving list feature depending on if any
**                  resolving list is empty and whitelist is involoved in the
**                  operation.
**
** Returns          none
**
*******************************************************************************/
void btm_ble_enable_resolving_list_for_platform (UINT8 rl_mask)
{
    /* if controller does not support, skip */
    if (controller_get_interface()->get_ble_resolving_list_max_size() == 0)
        return;

    if (btm_cb.ble_ctr_cb.wl_state == BTM_BLE_WL_IDLE)
    {
        if (controller_get_interface()->get_ble_resolving_list_max_size() >
                                        btm_cb.ble_ctr_cb.resolving_list_avail_size)
            btm_ble_enable_resolving_list(rl_mask);
        else
            btm_ble_disable_resolving_list(rl_mask, TRUE);
        return;
    }

    list_node_t *n = list_foreach(btm_cb.sec_dev_rec, is_on_resolving_list, NULL);
    if (n)
        btm_ble_enable_resolving_list(rl_mask);
    else
        btm_ble_disable_resolving_list(rl_mask, TRUE);
}

/*******************************************************************************
**
** Function         btm_ble_resolving_list_init
**
** Description      Initialize resolving list in host stack
**
** Parameters       Max resolving list size
**
** Returns          void
**
*******************************************************************************/
void btm_ble_resolving_list_init(UINT8 max_irk_list_sz)
{
    tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;
    UINT8 irk_mask_size =  (max_irk_list_sz % 8) ?
                           (max_irk_list_sz/8 + 1) : (max_irk_list_sz/8);

    if (max_irk_list_sz > 0)
    {
        p_q->resolve_q_random_pseudo = (BD_ADDR *)osi_malloc(sizeof(BD_ADDR) * max_irk_list_sz);
        p_q->resolve_q_action = (UINT8 *)osi_malloc(max_irk_list_sz);

        /* RPA offloading feature */
        if (btm_cb.ble_ctr_cb.irk_list_mask == NULL)
            btm_cb.ble_ctr_cb.irk_list_mask = (UINT8 *)osi_malloc(irk_mask_size);

        BTM_TRACE_DEBUG ("%s max_irk_list_sz = %d", __func__, max_irk_list_sz);
    }

    controller_get_interface()->set_ble_resolving_list_max_size(max_irk_list_sz);
    btm_ble_clear_resolving_list();
    btm_cb.ble_ctr_cb.resolving_list_avail_size = max_irk_list_sz;
}

/*******************************************************************************
**
** Function         btm_ble_resolving_list_cleanup
**
** Description      Cleanup resolving list dynamic memory
**
** Parameters
**
** Returns          void
**
*******************************************************************************/
void btm_ble_resolving_list_cleanup(void)
{
    tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q;

    osi_free_and_reset((void **)&p_q->resolve_q_random_pseudo);
    osi_free_and_reset((void **)&p_q->resolve_q_action);

    controller_get_interface()->set_ble_resolving_list_max_size(0);

    osi_free_and_reset((void **)&btm_cb.ble_ctr_cb.irk_list_mask);
}
#endif
