| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012 |
- /******************************************************************************
- *
- * 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 "common/bt_target.h"
- #if (BLE_INCLUDED == TRUE && BLE_PRIVACY_SPT == TRUE)
- #include "stack/bt_types.h"
- #include "stack/hcimsgs.h"
- #include "stack/btu.h"
- //#include "vendor_hcidefs.h"
- #include "btm_int.h"
- #include "device/controller.h"
- #include "stack/hcidefs.h"
- #define HCI_VENDOR_BLE_RPA_VSC (0x0155 | HCI_GRP_VENDOR_SPECIFIC)
- /* 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;
- }
- }
- }
- /*******************************************************************************
- **
- ** 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);
- for (UINT8 i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; ++i) {
- btm_cb.sec_dev_rec[i].ble.in_controller_list &= ~BTM_RESOLVING_LIST_BIT;
- }
- }
- }
- /*******************************************************************************
- **
- ** 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_WARNING("%s Resolving list Full ", __func__);
- } else {
- BTM_TRACE_ERROR("%s Add resolving list error %d ", __func__, status);
- }
- }
- /*******************************************************************************
- **
- ** 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;
- #if (SMP_INCLUDED == TRUE)
- UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state;
- BTM_TRACE_DEBUG("%s btm_cb.ble_ctr_cb.privacy_mode = %d\n", __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\n",
- __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->sec_flags & BTM_SEC_IN_USE) != 0 &&
- ((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};
- 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;
- }
- /* It will cause that scanner doesn't send scan request to advertiser
- * which has sent IRK to us and we have stored the IRK in controller.
- * It is a hardware limitation. The preliminary solution is not to
- * send key to the controller, but to resolve the random address in host. */
- /*
- BTM_TRACE_DEBUG("%s:adding device to controller resolving list\n", __func__);
- UINT8 *peer_irk = p_dev_rec->ble.keys.irk;
- UINT8 *local_irk = btm_cb.devcb.id_keys.irk;
- //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_WARNING("%s Resolving list full ", __func__);
- }
- } else {
- BTM_TRACE_DEBUG("Device already in Resolving list\n");
- rt = TRUE;
- }
- } else {
- BTM_TRACE_DEBUG("Device not a RPA enabled device\n");
- }
- #endif ///SMP_INCLUDED == TRUE
- 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\n", __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\n");
- }
- /* 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();
- }
- }
- #if 0 //Unused
- /*******************************************************************************
- **
- ** 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);
- }
- #endif
- /*******************************************************************************
- **
- ** 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;
- }
- tBTM_SEC_DEV_REC *p_dev = &btm_cb.sec_dev_rec[0];
- for (UINT8 i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++, p_dev ++) {
- if ((p_dev->ble.in_controller_list & BTM_RESOLVING_LIST_BIT) &&
- (p_dev->ble.in_controller_list & BTM_WHITE_LIST_BIT)) {
- btm_ble_enable_resolving_list(rl_mask);
- return;
- }
- }
- 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;
- if (p_q->resolve_q_random_pseudo) {
- osi_free(p_q->resolve_q_random_pseudo);
- p_q->resolve_q_random_pseudo = NULL;
- }
- if (p_q->resolve_q_action) {
- osi_free(p_q->resolve_q_action);
- p_q->resolve_q_action = NULL;
- }
- controller_get_interface()->set_ble_resolving_list_max_size(0);
- if (btm_cb.ble_ctr_cb.irk_list_mask) {
- osi_free(btm_cb.ble_ctr_cb.irk_list_mask);
- btm_cb.ble_ctr_cb.irk_list_mask = NULL;
- }
- }
- #endif
|