From 0943c10ed5713a08659f08e39e13de4894aaba61 Mon Sep 17 00:00:00 2001 From: Satya Calloji Date: Mon, 12 May 2014 09:13:02 -0700 Subject: [PATCH] LE: Add RRA offloading and vendor specific PCF commands Change-Id: Iadca8e73ceaadcd0429421ea70f1b76644e88c42 --- bta/dm/bta_dm_api.c | 16 ++ bta/dm/bta_dm_int.h | 3 + btif/src/btif_dm.c | 3 + include/bt_target.h | 3 + stack/btm/btm_ble.c | 11 + stack/btm/btm_ble_addr.c | 146 ++++++++++ stack/btm/btm_ble_bgconn.c | 17 ++ stack/btm/btm_ble_gap.c | 32 ++- stack/btm/btm_ble_int.h | 9 +- stack/btm/btm_ble_multi_adv.c | 27 +- stack/btm/btm_int.h | 6 +- stack/l2cap/l2c_ble.c | 12 + vnd/ble/vendor_ble.c | 641 +++++++++++++++++++++++++++++++++++++++--- vnd/ble/vendor_hcidefs.h | 25 +- vnd/include/vendor_api.h | 17 +- vnd/include/vendor_ble.h | 45 ++- 16 files changed, 965 insertions(+), 48 deletions(-) diff --git a/bta/dm/bta_dm_api.c b/bta/dm/bta_dm_api.c index 288e1262b..ff762f990 100644 --- a/bta/dm/bta_dm_api.c +++ b/bta/dm/bta_dm_api.c @@ -1820,7 +1820,23 @@ void BTA_DmBleEnableRemotePrivacy(BD_ADDR bd_addr, BOOLEAN privacy_enable) *******************************************************************************/ void BTA_DmBleConfigLocalPrivacy(BOOLEAN privacy_enable) { +#if BLE_INCLUDED == TRUE +#if BLE_VND_INCLUDED == TRUE && BLE_PRIVACY_SPT == TRUE + tBTA_DM_API_LOCAL_PRIVACY *p_msg; + + if ((p_msg = (tBTA_DM_API_LOCAL_PRIVACY *) GKI_getbuf(sizeof(tBTA_DM_API_ENABLE_PRIVACY))) != NULL) + { + memset (p_msg, 0, sizeof(tBTA_DM_API_LOCAL_PRIVACY)); + + p_msg->hdr.event = BTA_DM_API_LOCAL_PRIVACY_EVT; + p_msg->privacy_enable = privacy_enable; + + bta_sys_sendmsg(p_msg); + } +#endif +#else UNUSED(privacy_enable); +#endif } #endif diff --git a/bta/dm/bta_dm_int.h b/bta/dm/bta_dm_int.h index 78eb83322..901450187 100644 --- a/bta/dm/bta_dm_int.h +++ b/bta/dm/bta_dm_int.h @@ -1101,6 +1101,9 @@ extern void bta_dm_ble_set_scan_params (tBTA_DM_MSG *p_data); extern void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data); extern void bta_dm_ble_observe (tBTA_DM_MSG *p_data); extern void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data); +#if BLE_PRIVACY_SPT == TRUE +extern void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data); +#endif extern void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data); diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c index 025fcb748..f72ed3245 100644 --- a/btif/src/btif_dm.c +++ b/btif/src/btif_dm.c @@ -1357,6 +1357,9 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param) btif_storage_load_autopair_device_list(); btif_enable_bluetooth_evt(p_data->enable.status, p_data->enable.bd_addr); + + /* Enable local privacy */ + BTA_DmBleConfigLocalPrivacy(TRUE); } break; diff --git a/include/bt_target.h b/include/bt_target.h index 01dd1929e..76a49fc2f 100644 --- a/include/bt_target.h +++ b/include/bt_target.h @@ -1307,6 +1307,9 @@ and USER_HW_DISABLE_API macros */ #define BLE_MULTI_ADV_INCLUDED TRUE #endif +#ifndef BLE_VND_INCLUDED +#define BLE_VND_INCLUDED TRUE +#endif /****************************************************************************** ** diff --git a/stack/btm/btm_ble.c b/stack/btm/btm_ble.c index 130aa1ccc..48c60e197 100644 --- a/stack/btm/btm_ble.c +++ b/stack/btm/btm_ble.c @@ -38,6 +38,10 @@ #include "gap_api.h" #include "bt_utils.h" +#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE) +#include "vendor_ble.h" +#endif + #if SMP_INCLUDED == TRUE extern BOOLEAN AES_CMAC ( BT_OCTET16 key, UINT8 *input, UINT16 length, UINT16 tlen, UINT8 *p_signature); extern void smp_link_encrypted(BD_ADDR bda, UINT8 encr_enable); @@ -1613,6 +1617,10 @@ void btm_ble_connected (UINT8 *bda, UINT16 handle, UINT8 enc_mode, UINT8 role, if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_RANDOM && !addr_matched) memcpy(p_dev_rec->ble.cur_rand_addr, bda, BD_ADDR_LEN); + +#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE) + btm_ble_vendor_disable_irk_list(); +#endif #endif if (role == HCI_ROLE_SLAVE) @@ -1649,6 +1657,9 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len) if (status == 0) { #if (BLE_PRIVACY_SPT == TRUE ) +#if (BLE_VND_INCLUDED == TRUE) + match = btm_public_addr_to_random_pseudo (bda, &bda_type); +#endif /* possiblly receive connection complete with resolvable random on slave role while the device has been paired */ if (!match && role == HCI_ROLE_SLAVE && BTM_BLE_IS_RESOLVE_BDA(bda)) diff --git a/stack/btm/btm_ble_addr.c b/stack/btm/btm_ble_addr.c index 378470ea5..79c0a5d2a 100644 --- a/stack/btm/btm_ble_addr.c +++ b/stack/btm/btm_ble_addr.c @@ -34,6 +34,10 @@ #include "btm_ble_int.h" #include "smp_api.h" +#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE) +#include "vendor_ble.h" +#endif + /******************************************************************************* ** ** Function btm_gen_resolve_paddr_cmpl @@ -378,6 +382,148 @@ tBLE_ADDR_TYPE btm_ble_map_bda_to_conn_bda(BD_ADDR bd_addr) return BLE_ADDR_PUBLIC; } +#if BLE_PRIVACY_SPT == TRUE +#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE) +/******************************************************************************* +** +** Function btm_find_dev_by_public_static_addr +** +** Description find the security record whose LE static address is matching +** +*******************************************************************************/ +tBTM_SEC_DEV_REC* btm_find_dev_by_public_static_addr(BD_ADDR bd_addr) +{ + UINT8 i; + tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; + + for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++, p_dev_rec ++) + { + if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_RANDOM && + BTM_BLE_IS_RESOLVE_BDA(p_dev_rec->bd_addr)) + { + if ( memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) == 0) + { + p_dev_rec->ble.active_addr_type = BTM_BLE_ADDR_RRA; + /* found the match */ + return p_dev_rec; + } + } + } + return NULL; +} + +/******************************************************************************* +** +** Function btm_public_addr_to_random_pseudo +** +** Description This function map a static BD address to a pseudo random address +** in security database. +** +*******************************************************************************/ +BOOLEAN btm_public_addr_to_random_pseudo(BD_ADDR bd_addr, UINT8 *p_addr_type) +{ + tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_public_static_addr(bd_addr); + + BTM_TRACE_EVENT0 ("btm_public_addr_to_random_pseudo"); + + /* evt reported on static address, map static address to random pseudo */ + if (p_dev_rec != NULL && + /* static address is not static address */ + memcmp(p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN) != 0) + /* update current random */ + btm_ble_read_irk_entry(p_dev_rec->ble.static_addr); + if (p_dev_rec != NULL) + { + /* assign the orginal random to be the current report address */ + memcpy(bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN); + /* always be a resolvable random if a match is found */ + *p_addr_type = BLE_ADDR_RANDOM; + + BTM_TRACE_ERROR0("matched a public/reconnect address and map to random pseudo"); + + return TRUE; + } + + return FALSE; +} + +/******************************************************************************* +** +** Function btm_random_pseudo_to_public +** +** Description This function map a random pseudo address to a public address +** random_pseudo is input and output parameter +** +*******************************************************************************/ +BOOLEAN btm_random_pseudo_to_public(BD_ADDR random_pseudo, UINT8 *p_static_addr_type) +{ + tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (random_pseudo); + + if (p_dev_rec != NULL) + { + if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_RANDOM && + BTM_BLE_IS_RESOLVE_BDA(p_dev_rec->bd_addr) && + (p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0) + { + BTM_TRACE_EVENT0 ("btm_random_pseudo_to_public found the puclic static address!"); + * p_static_addr_type = p_dev_rec->ble.static_addr_type; + memcpy(random_pseudo, p_dev_rec->ble.static_addr, BD_ADDR_LEN); + return TRUE; + } + } + + return FALSE; +} + +/******************************************************************************* +** +** Function btm_ble_refresh_rra +** +** Description This function refresh the currently used RRA into security +** database and set active connection address. +** +*******************************************************************************/ +void btm_ble_refresh_rra(BD_ADDR static_bda, BD_ADDR rra) +{ + tBTM_SEC_DEV_REC *p_sec_rec = btm_find_dev_by_public_static_addr(static_bda); + tACL_CONN *p_acl = btm_bda_to_acl (p_sec_rec->bd_addr, BT_TRANSPORT_LE); + UINT8 rra_dummy = FALSE; + BD_ADDR dummy_bda = {0}; + + BTM_TRACE_ERROR0("btm_ble_refresh_rra"); + + if (memcmp(dummy_bda, rra, BD_ADDR_LEN) == 0) + rra_dummy = TRUE; + + /* connection refresh RRA */ + if (p_acl != NULL /* && memcmp(p_acl->active_remote_addr, dummy_bda, BD_ADDR_LEN) == 0 */) + { + /* use static address, rra is empty */ + if (rra_dummy) + { + p_acl->active_remote_addr_type = p_sec_rec->ble.static_addr_type; + memcpy(p_acl->active_remote_addr, p_sec_rec->ble.static_addr, BD_ADDR_LEN); + } + else + { + p_acl->active_remote_addr_type = BLE_ADDR_RANDOM; + memcpy(p_acl->active_remote_addr, rra, BD_ADDR_LEN); + } + } + /* update security record here, in adv event or connection complete process */ + if (p_sec_rec != NULL) + { + memcpy(p_sec_rec->ble.cur_rand_addr, rra, BD_ADDR_LEN); + p_sec_rec->ble.active_addr_type = rra_dummy ? BTM_BLE_ADDR_STATIC: BTM_BLE_ADDR_RRA; + } + else + { + BTM_TRACE_ERROR0("No matching known device in record"); + } + +} +#endif /* CS support */ +#endif /* privacy support */ #endif diff --git a/stack/btm/btm_ble_bgconn.c b/stack/btm/btm_ble_bgconn.c index 7341cd25a..bcc51e8cf 100644 --- a/stack/btm/btm_ble_bgconn.c +++ b/stack/btm/btm_ble_bgconn.c @@ -30,6 +30,9 @@ #include "l2c_int.h" #include "hcimsgs.h" #include "bt_utils.h" +#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE) +#include "vendor_ble.h" +#endif #ifndef BTM_BLE_SCAN_PARAM_TOUT #define BTM_BLE_SCAN_PARAM_TOUT 50 /* 50 seconds */ @@ -83,6 +86,10 @@ BOOLEAN btm_add_dev_to_controller (BOOLEAN to_add, BD_ADDR bd_addr, UINT8 attr) { if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_PUBLIC || !BTM_BLE_IS_RESOLVE_BDA(bd_addr)) { +#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) + /* add device into IRK list */ + btm_ble_vendor_irk_list_load_dev(p_dev_rec); +#endif started = btsnd_hcic_ble_add_white_list (p_dev_rec->ble.ble_addr_type, bd_addr); } if (memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) != 0 && @@ -412,6 +419,11 @@ BOOLEAN btm_ble_start_auto_conn(BOOLEAN start) btsnd_hcic_ble_create_conn_cancel(); btm_ble_set_conn_st (BLE_CONN_CANCEL); +#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE) +#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) + btm_ble_vendor_disable_irk_list(); +#endif +#endif } else { @@ -493,6 +505,11 @@ BOOLEAN btm_ble_start_select_conn(BOOLEAN start,tBTM_BLE_SEL_CBACK *p_select_c p_cb->scan_activity &= ~BTM_LE_SELECT_CONN_ACTIVE; p_cb->p_select_cback = NULL; +#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) +#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE) + btm_ble_vendor_disable_irk_list(); +#endif +#endif /* stop scanning */ if (!BTM_BLE_IS_SCAN_ACTIVE(p_cb->scan_activity)) diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c index d70db7376..eb2ca061f 100644 --- a/stack/btm/btm_ble_gap.c +++ b/stack/btm/btm_ble_gap.c @@ -35,6 +35,9 @@ #include "gap_api.h" #endif #if (BLE_INCLUDED == TRUE) +#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE) +#include "vendor_ble.h" +#endif #include "gattdefs.h" #include "btm_ble_int.h" @@ -325,6 +328,11 @@ tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT8 duration, btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, BTM_BLE_DEFAULT_SFP); /* assume observe always not using white list */ +#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) + /* enable IRK list */ + btm_ble_vendor_irk_list_known_dev (TRUE); +#endif + status = btm_ble_start_scan(BTM_BLE_DUPLICATE_DISABLE); } if (status == BTM_CMD_STARTED) @@ -525,6 +533,7 @@ void BTM_BleConfigPrivacy(BOOLEAN enable) { p_cb->addr_mgnt_cb.own_addr_type = BLE_ADDR_PUBLIC; } + btm_ble_multi_adv_enb_privacy(p_cb->privacy); } } @@ -1591,6 +1600,13 @@ tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration) if (!BTM_BLE_IS_SCAN_ACTIVE(p_ble_cb->scan_activity)) { btm_update_scanner_filter_policy(SP_ADV_ALL); + +#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) +#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE) + /* enable IRK list */ + btm_ble_vendor_irk_list_known_dev (TRUE); +#endif +#endif status = btm_ble_start_scan(BTM_BLE_DUPLICATE_DISABLE); } @@ -2160,7 +2176,14 @@ void btm_ble_process_adv_pkt (UINT8 *p_data) } #endif - +#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) +#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE) + /* map address to security record */ + btm_public_addr_to_random_pseudo(bda, &addr_type); + BTM_TRACE_ERROR6("new address: %02x:%02x:%02x:%02x:%02x:%02x", + bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); +#endif +#endif /* Only process the results if the inquiry is still active */ if (!BTM_BLE_IS_SCAN_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) @@ -2676,7 +2699,7 @@ void btm_ble_timeout(TIMER_LIST_ENT *p_tle) else { #if BLE_MULTI_ADV_INCLUDED == TRUE - btm_ble_multi_adv_configure_rpa((tBTM_BLE_MULTI_ADV_INST*)&p_tle->param); + btm_ble_multi_adv_configure_rpa((tBTM_BLE_MULTI_ADV_INST*)p_tle->param); #endif } } @@ -2749,7 +2772,10 @@ void btm_ble_write_adv_enable_complete(UINT8 * p) p_cb->adv_mode = !p_cb->adv_mode; } - +#if (BLE_VND_INCLUDED == TRUE && BLE_PRIVACY_SPT == TRUE) + if (p_cb->adv_mode == BTM_BLE_ADV_DISABLE) + btm_ble_vendor_disable_irk_list(); +#endif } /******************************************************************************* diff --git a/stack/btm/btm_ble_int.h b/stack/btm/btm_ble_int.h index 4553f4a90..52be674c6 100644 --- a/stack/btm/btm_ble_int.h +++ b/stack/btm/btm_ble_int.h @@ -397,11 +397,18 @@ extern void btm_gen_resolve_paddr_low(tBTM_RAND_ENC *p); extern void btm_ble_multi_adv_configure_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst); extern void btm_ble_multi_adv_init(void); extern void btm_ble_multi_adv_reenable(UINT8 inst_id); - +extern void btm_ble_multi_adv_enb_privacy(BOOLEAN enable); extern BOOLEAN btm_ble_topology_check(tBTM_BLE_STATE_MASK request); extern BOOLEAN btm_ble_clear_topology_mask(tBTM_BLE_STATE_MASK request_state); extern BOOLEAN btm_ble_set_topology_mask(tBTM_BLE_STATE_MASK request_state); +#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE) +/* BLE address mapping with CS feature */ +extern BOOLEAN btm_public_addr_to_random_pseudo(BD_ADDR bd_addr, UINT8 *p_addr_type); +extern BOOLEAN btm_random_pseudo_to_public(BD_ADDR random_pseudo, UINT8 *p_static_addr_type); +extern void btm_ble_refresh_rra(BD_ADDR pseudo_bda, BD_ADDR rra); +#endif + #if BTM_BLE_CONFORMANCE_TESTING == TRUE BT_API extern void btm_ble_set_no_disc_if_pair_fail (BOOLEAN disble_disc); BT_API extern void btm_ble_set_test_mac_value (BOOLEAN enable, UINT8 *p_test_mac_val); diff --git a/stack/btm/btm_ble_multi_adv.c b/stack/btm/btm_ble_multi_adv.c index 24394dacd..0dc0e9ead 100644 --- a/stack/btm/btm_ble_multi_adv.c +++ b/stack/btm/btm_ble_multi_adv.c @@ -31,7 +31,7 @@ /* length of each multi adv sub command */ #define BTM_BLE_MULTI_ADV_ENB_LEN 3 -#define BTM_BLE_MULTI_ADV_SET_PARAM_LEN 33 +#define BTM_BLE_MULTI_ADV_SET_PARAM_LEN 24 #define BTM_BLE_MULTI_ADV_WRITE_DATA_LEN (BTM_BLE_AD_DATA_LEN + 3) #define BTM_BLE_MULTI_ADV_SET_RANDOM_ADDR_LEN 8 @@ -498,6 +498,31 @@ void btm_ble_multi_adv_reenable(UINT8 inst_id) /******************************************************************************* ** +** Function btm_ble_multi_adv_enb_privacy +** +** Description This function enable/disable privacy setting in multi adv +** +** Parameters enable: enable or disable the adv instance. +** +** Returns none. +** +*******************************************************************************/ +void btm_ble_multi_adv_enb_privacy(BOOLEAN enable) +{ + UINT8 i; + tBTM_BLE_MULTI_ADV_INST *p_inst = &btm_multi_adv_cb.adv_inst[0]; + + for (i = 0; i < BTM_BLE_MULTI_ADV_MAX; i ++, p_inst++) + { + if (enable) + btm_ble_multi_adv_configure_rpa (p_inst); + else + btu_stop_timer(&p_inst->raddr_timer_ent); + } +} + +/******************************************************************************* +** ** Function BTM_BleEnableAdvInstance ** ** Description This function enable a Multi-ADV instance with the specified diff --git a/stack/btm/btm_int.h b/stack/btm/btm_int.h index 9504766d1..2d4e10714 100644 --- a/stack/btm/btm_int.h +++ b/stack/btm/btm_int.h @@ -516,9 +516,11 @@ typedef struct #define BTM_BLE_ADDR_PSEUDO 0 /* address index device record */ #define BTM_BLE_ADDR_RRA 1 /* cur_rand_addr */ -#define BTM_BLE_ADDR_STATIC 2 /* static_addr */ - +#define BTM_BLE_ADDR_RECONN 2 /* reconnection address */ +#define BTM_BLE_ADDR_STATIC 3 /* static_addr */ UINT8 active_addr_type; + + BOOLEAN privacy_enabled; /* remote device privacy enabled or not */ #endif #if SMP_INCLUDED == TRUE diff --git a/stack/l2cap/l2c_ble.c b/stack/l2cap/l2c_ble.c index 0e6c73a69..b1af83754 100644 --- a/stack/l2cap/l2c_ble.c +++ b/stack/l2cap/l2c_ble.c @@ -36,6 +36,9 @@ #define L2CA_SET_UPD_ST(x, y) x = (((x) & ~UPD_ST_MASK) | (y)) +#if (defined BLE_VND_INCLUDED && BLE_VND_INCLUDED == TRUE) +#include "vendor_ble.h" +#endif /******************************************************************************* ** ** Function L2CA_CancelBleConnectReq @@ -640,6 +643,15 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) L2CAP_TRACE_ERROR0("initate direct connection fail, topology limitation"); return FALSE; } +#if BLE_PRIVACY_SPT == TRUE +#if (defined BLE_VND_INCLUDED || BLE_VND_INCLUDED == TRUE) + extern tBTM_STATUS BTM_BleEnableIRKFeature(BOOLEAN enable); + if (btm_ble_vendor_irk_list_load_dev(p_dev_rec)) + BTM_BleEnableIRKFeature(TRUE); + + btm_random_pseudo_to_public(init_addr, &init_addr_type); +#endif +#endif if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int */ scan_win, /* UINT16 scan_win */ FALSE, /* UINT8 white_list */ diff --git a/vnd/ble/vendor_ble.c b/vnd/ble/vendor_ble.c index 8f846ef5e..db1dadfb4 100644 --- a/vnd/ble/vendor_ble.c +++ b/vnd/ble/vendor_ble.c @@ -346,6 +346,9 @@ tBTM_STATUS btm_ble_update_pf_manu_data(tBTM_BLE_SCAN_COND_OP action, } UINT8_TO_STREAM(p, action); + /* Filter index */ + UINT8_TO_STREAM(p, 0); + if (action == BTM_BLE_SCAN_COND_ADD || action == BTM_BLE_SCAN_COND_DELETE) { @@ -429,6 +432,9 @@ tBTM_STATUS btm_ble_update_pf_local_name(tBTM_BLE_SCAN_COND_OP action, UINT8_TO_STREAM(p, BTM_BLE_META_PF_LOCAL_NAME); UINT8_TO_STREAM(p, action); + /* Filter index */ + UINT8_TO_STREAM(p, 0); + if (action == BTM_BLE_SCAN_COND_ADD || action == BTM_BLE_SCAN_COND_DELETE) { @@ -481,6 +487,9 @@ tBTM_STATUS btm_ble_update_addr_filter(tBTM_BLE_SCAN_COND_OP action, UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR); UINT8_TO_STREAM(p, action); + /* Filter index */ + UINT8_TO_STREAM(p, 0); + if (action == BTM_BLE_SCAN_COND_ADD || action == BTM_BLE_SCAN_COND_DELETE) { @@ -553,6 +562,9 @@ tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action, UINT8_TO_STREAM(p, BTM_BLE_META_PF_ADDR); UINT8_TO_STREAM(p, action); + /* Filter index */ + UINT8_TO_STREAM(p, 0); + BDADDR_TO_STREAM(p, p_uuid_cond->p_target_addr->bda); UINT8_TO_STREAM(p, p_uuid_cond->p_target_addr->type); @@ -571,24 +583,12 @@ tBTM_STATUS btm_ble_update_uuid_filter(tBTM_BLE_SCAN_COND_OP action, UINT8_TO_STREAM(p, evt_type); UINT8_TO_STREAM(p, action); - /* per BD ADDR UUID filter */ - if (p_uuid_cond && p_uuid_cond->p_target_addr) - { - BDADDR_TO_STREAM(p, p_uuid_cond->p_target_addr->bda); - UINT8_TO_STREAM(p, p_uuid_cond->p_target_addr->type); - } - else /* generic UUID filter */ - { - BDADDR_TO_STREAM(p, na_bda); - UINT8_TO_STREAM(p, 0x02); - } + /* Filter index */ + UINT8_TO_STREAM(p, 0); if (action == BTM_BLE_SCAN_COND_ADD || action == BTM_BLE_SCAN_COND_DELETE) { - UINT8_TO_STREAM(p, p_uuid_cond->cond_logic); - len ++; - if (p_uuid_cond->uuid.len == LEN_UUID_16) { UINT16_TO_STREAM(p, p_uuid_cond->uuid.uu.uuid16); @@ -737,16 +737,8 @@ tBTM_STATUS btm_ble_clear_scan_pf_filter(tBTM_BLE_SCAN_COND_OP action, UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_CLEAR); - if (p_target != NULL) - { - BDADDR_TO_STREAM(p, p_target->bda); - UINT8_TO_STREAM(p, p_target->type); - } - else - { - BDADDR_TO_STREAM(p, na_bda); - UINT8_TO_STREAM(p, 0x02); - } + /* Filter index */ + UINT8_TO_STREAM(p, 0); /* set PCF selection */ UINT32_TO_STREAM(p, BTM_BLE_PF_SELECT_NONE); @@ -815,16 +807,8 @@ tBTM_STATUS BTM_BleEnableFilterCondition(BOOLEAN enable, tBLE_BD_ADDR *p_target, UINT8_TO_STREAM(p, BTM_BLE_META_PF_FEAT_SEL); UINT8_TO_STREAM(p, BTM_BLE_SCAN_COND_ADD); - if (p_target != NULL) - { - BDADDR_TO_STREAM(p, p_target->bda); - UINT8_TO_STREAM(p, p_target->type); - } - else - { - BDADDR_TO_STREAM(p, na_bda); - UINT8_TO_STREAM(p, 0x02); - } + /* Filter index */ + UINT8_TO_STREAM(p, 0); /* set PCF selection */ UINT32_TO_STREAM(p, p_bda_filter->feat_mask); @@ -936,6 +920,595 @@ tBTM_STATUS BTM_BleCfgFilterCondition(tBTM_BLE_SCAN_COND_OP action, return st; } +/******************************************************************************* +** Resolve Address Using IRK List functions +*******************************************************************************/ + +#if BLE_PRIVACY_SPT == TRUE +/* Forward declaration */ +tBTM_STATUS BTM_BleEnableIRKFeature(BOOLEAN enable); + +/******************************************************************************* +** +** Function btm_ble_vendor_enq_irk_pending +** +** Description add target address into IRK pending operation queue +** +** Parameters target_bda: target device address +** add_entry: TRUE for add entry, FALSE for remove entry +** +** Returns void +** +*******************************************************************************/ +void btm_ble_vendor_enq_irk_pending(BD_ADDR target_bda, BD_ADDR psuedo_bda, UINT8 to_add) +{ + tBTM_BLE_IRK_Q *p_q = &btm_ble_vendor_cb.irk_pend_q; + + memcpy(p_q->irk_q[p_q->q_next], target_bda, BD_ADDR_LEN); + memcpy(p_q->irk_q_random_pseudo[p_q->q_next], psuedo_bda, BD_ADDR_LEN); + p_q->irk_q_action[p_q->q_next] = to_add; + + p_q->q_next ++; + p_q->q_next %= BTM_CS_IRK_LIST_MAX; + + return ; +} +/******************************************************************************* +** +** Function btm_ble_vendor_find_irk_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_vendor_find_irk_pending_entry(BD_ADDR psuedo_addr, UINT8 action) +{ + tBTM_BLE_IRK_Q *p_q = &btm_ble_vendor_cb.irk_pend_q; + UINT8 i; + + for (i = p_q->q_pending; i != p_q->q_next; ) + { + if (memcmp(p_q->irk_q_random_pseudo[i], psuedo_addr, BD_ADDR_LEN) == 0 && + action == p_q->irk_q_action[i]) + return TRUE; + + i ++; + i %= BTM_CS_IRK_LIST_MAX; + } + return FALSE; +} +/******************************************************************************* +** +** Function btm_ble_vendor_deq_irk_pending +** +** Description add target address into IRK pending operation queue +** +** Parameters target_bda: target device address +** add_entry: TRUE for add entry, FALSE for remove entry +** +** Returns void +** +*******************************************************************************/ +BOOLEAN btm_ble_vendor_deq_irk_pending(BD_ADDR target_bda, BD_ADDR psuedo_addr) +{ + tBTM_BLE_IRK_Q *p_q = &btm_ble_vendor_cb.irk_pend_q; + + if (p_q->q_next != p_q->q_pending) + { + memcpy(target_bda, p_q->irk_q[p_q->q_pending], BD_ADDR_LEN); + memcpy(psuedo_addr, p_q->irk_q_random_pseudo[p_q->q_pending], BD_ADDR_LEN); + + p_q->q_pending ++; + p_q->q_pending %= BTM_CS_IRK_LIST_MAX; + + return TRUE; + } + + return FALSE; + +} +/******************************************************************************* +** +** Function btm_ble_vendor_find_irk_entry +** +** Description find IRK entry in local host IRK list by static address +** +** Returns IRK list entry pointer +** +*******************************************************************************/ +tBTM_BLE_IRK_ENTRY * btm_ble_vendor_find_irk_entry(BD_ADDR target_bda) +{ + tBTM_BLE_IRK_ENTRY *p_irk_entry = &btm_ble_vendor_cb.irk_list[0]; + UINT8 i; + + for (i = 0; i < BTM_CS_IRK_LIST_MAX; i ++, p_irk_entry++) + { + if (p_irk_entry->in_use && memcmp(p_irk_entry->bd_addr, target_bda, BD_ADDR_LEN) == 0) + { + return p_irk_entry ; + } + } + return NULL; +} +/******************************************************************************* +** +** Function btm_ble_vendor_find_irk_entry_by_psuedo_addr +** +** Description find IRK entry in local host IRK list by psuedo address +** +** Returns IRK list entry pointer +** +*******************************************************************************/ +tBTM_BLE_IRK_ENTRY * btm_ble_vendor_find_irk_entry_by_psuedo_addr (BD_ADDR psuedo_bda) +{ + tBTM_BLE_IRK_ENTRY *p_irk_entry = &btm_ble_vendor_cb.irk_list[0]; + UINT8 i; + + for (i = 0; i < BTM_CS_IRK_LIST_MAX; i ++, p_irk_entry++) + { + if (p_irk_entry->in_use && memcmp(p_irk_entry->psuedo_bda, psuedo_bda, BD_ADDR_LEN) == 0) + { + return p_irk_entry ; + } + } + return NULL; +} +/******************************************************************************* +** +** Function btm_ble_vendor_alloc_irk_entry +** +** Description allocate IRK entry in local host IRK list +** +** Returns IRK list index +** +*******************************************************************************/ +UINT8 btm_ble_vendor_alloc_irk_entry(BD_ADDR target_bda, BD_ADDR pseudo_bda) +{ + tBTM_BLE_IRK_ENTRY *p_irk_entry = &btm_ble_vendor_cb.irk_list[0]; + UINT8 i; + + for (i = 0; i < BTM_CS_IRK_LIST_MAX; i ++, p_irk_entry++) + { + if (!p_irk_entry->in_use) + { + memcpy(p_irk_entry->bd_addr, target_bda, BD_ADDR_LEN); + memcpy(p_irk_entry->psuedo_bda, pseudo_bda, BD_ADDR_LEN); + + p_irk_entry->index = i; + p_irk_entry->in_use = TRUE; + + return i; + } + } + return BTM_CS_IRK_LIST_INVALID; +} + +/******************************************************************************* +** +** Function btm_ble_vendor_update_irk_list +** +** Description update IRK entry in local host IRK list +** +** Returns void +** +*******************************************************************************/ +void btm_ble_vendor_update_irk_list(BD_ADDR target_bda, BD_ADDR pseudo_bda, BOOLEAN add) +{ + tBTM_BLE_IRK_ENTRY *p_irk_entry = btm_ble_vendor_find_irk_entry(target_bda); + UINT8 i; + + if (add) + { + if (p_irk_entry == NULL) + { + if ((i = btm_ble_vendor_alloc_irk_entry(target_bda, pseudo_bda)) == BTM_CS_IRK_LIST_INVALID) + { + BTM_TRACE_ERROR0("max IRK capacity reached"); + } + } + else + { + BTM_TRACE_WARNING0(" IRK already in queue"); + } + } + else + { + if (p_irk_entry != NULL) + { + memset(p_irk_entry, 0, sizeof(tBTM_BLE_IRK_ENTRY)); + } + else + { + BTM_TRACE_ERROR0("No IRK exist in list, can not remove"); + } + } + return ; +} +/******************************************************************************* +** +** Function btm_ble_vendor_irk_vsc_op_cmpl +** +** Description IRK operation VSC complete handler +** +** Parameters +** +** Returns void +** +*******************************************************************************/ +void btm_ble_vendor_irk_vsc_op_cmpl (tBTM_VSC_CMPL *p_params) +{ + UINT8 status; + UINT8 *p = p_params->p_param_buf, op_subcode; + UINT16 evt_len = p_params->param_len; + UINT8 i; + tBTM_BLE_VENDOR_CB *p_cb = &btm_ble_vendor_cb; + BD_ADDR target_bda, pseudo_bda, rra; + + + STREAM_TO_UINT8(status, p); + + evt_len--; + + if (evt_len < 2 ) + { + BTM_TRACE_ERROR0("can not interpret IRK VSC cmpl callback"); + return; + } + op_subcode = *p ++; + + BTM_TRACE_DEBUG1("btm_ble_vendor_irk_vsc_op_cmpl op_subcode = %d", op_subcode); + + if (op_subcode == BTM_BLE_META_CLEAR_IRK_LIST) + { + if (status == HCI_SUCCESS) + { + STREAM_TO_UINT8(p_cb->irk_avail_size, p); + p_cb->irk_list_size = 0; + + BTM_TRACE_DEBUG1("p_cb->irk_list_size = %d", p_cb->irk_avail_size); + + for (i = 0; i < BTM_CS_IRK_LIST_MAX; i ++) + memset(&p_cb->irk_list[i], 0, sizeof(tBTM_BLE_IRK_ENTRY)); + } + } + else if (op_subcode == BTM_BLE_META_ADD_IRK_ENTRY) + { + if (!btm_ble_vendor_deq_irk_pending(target_bda, pseudo_bda)) + { + BTM_TRACE_ERROR0("no pending IRK operation"); + return; + } + + if (status == HCI_SUCCESS) + { + STREAM_TO_UINT8(p_cb->irk_avail_size, p); + btm_ble_vendor_update_irk_list(target_bda, pseudo_bda, TRUE); + } + else if (status == 0x07) /* BT_ERROR_CODE_MEMORY_CAPACITY_EXCEEDED */ + { + p_cb->irk_avail_size = 0; + BTM_TRACE_ERROR0("IRK Full "); + } + else + { + /* give the credit back if invalid parameter failed the operation */ + p_cb->irk_list_size ++; + } + } + else if (op_subcode == BTM_BLE_META_REMOVE_IRK_ENTRY) + { + if (!btm_ble_vendor_deq_irk_pending(target_bda, pseudo_bda)) + { + BTM_TRACE_ERROR0("no pending IRK operation"); + return; + } + if (status == HCI_SUCCESS) + { + STREAM_TO_UINT8(p_cb->irk_avail_size, p); + btm_ble_vendor_update_irk_list(target_bda, pseudo_bda, FALSE); + } + else + { + /* give the credit back if invalid parameter failed the operation */ + if (p_cb->irk_avail_size > 0) + p_cb->irk_list_size --; + } + + } + else if (op_subcode == BTM_BLE_META_READ_IRK_ENTRY) + { + if (status == HCI_SUCCESS) + { + //STREAM_TO_UINT8(index, p); + p += (1 + 16 + 1); /* skip index, IRK value, address type */ + STREAM_TO_BDADDR(target_bda, p); + STREAM_TO_BDADDR(rra, p); + + btm_ble_refresh_rra(target_bda, rra); + } + } + +} +/******************************************************************************* +** +** Function btm_ble_remove_irk_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_irk_entry(tBTM_SEC_DEV_REC *p_dev_rec) +{ + UINT8 param[20], *p; + tBTM_STATUS st; + tBTM_BLE_VENDOR_CB *p_cb = &btm_ble_vendor_cb; + + p = param; + memset(param, 0, 20); + + 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); + + if ((st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC, + BTM_BLE_META_REMOVE_IRK_LEN, + param, + btm_ble_vendor_irk_vsc_op_cmpl)) + != BTM_NO_RESOURCES) + { + btm_ble_vendor_enq_irk_pending(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, FALSE); + p_cb->irk_list_size --; + } + + return st; + +} +/******************************************************************************* +** +** Function btm_ble_vendor_clear_irk_list +** +** Description This function clears the IRK entry list +** +** Parameters None. +** +** Returns status +** +*******************************************************************************/ +tBTM_STATUS btm_ble_vendor_clear_irk_list(void) +{ + UINT8 param[20], *p; + tBTM_STATUS st; + + p = param; + memset(param, 0, 20); + + 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_vendor_irk_vsc_op_cmpl); + + return st; + +} +/******************************************************************************* +** +** Function btm_ble_read_irk_entry +** +** Description This function read an IRK entry by index +** +** Parameters entry index. +** +** Returns status +** +*******************************************************************************/ +tBTM_STATUS btm_ble_read_irk_entry(BD_ADDR target_bda) +{ + UINT8 param[20], *p; + tBTM_STATUS st = BTM_UNKNOWN_ADDR; + tBTM_BLE_IRK_ENTRY *p_entry = btm_ble_vendor_find_irk_entry(target_bda); + + if (p_entry == NULL) + return st; + + p = param; + memset(param, 0, 20); + + UINT8_TO_STREAM(p, BTM_BLE_META_READ_IRK_ENTRY); + UINT8_TO_STREAM(p, p_entry->index); + + st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC, + BTM_BLE_META_READ_IRK_LEN, + param, + btm_ble_vendor_irk_vsc_op_cmpl); + + return st; + +} + + +/******************************************************************************* +** +** Function btm_ble_vendor_enable_irk_list_known_dev +** +** Description This function add all known device with random address into +** IRK list. +** +** Parameters enable: enable IRK list with known device, or disable it +** +** Returns status +** +*******************************************************************************/ +void btm_ble_vendor_irk_list_known_dev(BOOLEAN enable) +{ + UINT8 i; + UINT8 count = 0; + tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; + + /* add all known device with random address into IRK list */ + for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++, p_dev_rec ++) + { + if (p_dev_rec->sec_flags & BTM_SEC_IN_USE) + { + if (btm_ble_vendor_irk_list_load_dev(p_dev_rec)) + count ++; + } + } + + if ((count > 0 && enable) || !enable) + BTM_BleEnableIRKFeature(enable); + + return ; +} +/******************************************************************************* +** +** Function btm_ble_vendor_irk_list_load_dev +** +** Description This function add a device which is using RPA into white list +** +** Parameters +** +** Returns status +** +*******************************************************************************/ +BOOLEAN btm_ble_vendor_irk_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec) +{ + UINT8 param[40], *p; + tBTM_BLE_VENDOR_CB *p_cb = &btm_ble_vendor_cb; + BOOLEAN rt = FALSE; + tBTM_BLE_IRK_ENTRY *p_irk_entry = NULL; + + memset(param, 0, 40); + + if (p_dev_rec != NULL && /* RPA is being used and PID is known */ + (p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0) + { + + if ((p_irk_entry = btm_ble_vendor_find_irk_entry_by_psuedo_addr(p_dev_rec->bd_addr)) == NULL && + btm_ble_vendor_find_irk_pending_entry(p_dev_rec->bd_addr, TRUE) == FALSE) + { + + if (p_cb->irk_avail_size > 0) + { + 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_vendor_irk_vsc_op_cmpl) + != BTM_NO_RESOURCES) + { + btm_ble_vendor_enq_irk_pending(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, TRUE); + p_cb->irk_list_size ++; + rt = TRUE; + } + } + } + else + { + BTM_TRACE_ERROR0("Device already in IRK list"); + rt = TRUE; + } + } + else + { + BTM_TRACE_DEBUG0("Device not a RPA enabled device"); + } + return rt; +} +/******************************************************************************* +** +** Function btm_ble_vendor_irk_list_remove_dev +** +** Description This function remove the device from IRK list +** +** Parameters +** +** Returns status +** +*******************************************************************************/ +void btm_ble_vendor_irk_list_remove_dev(tBTM_SEC_DEV_REC *p_dev_rec) +{ + tBTM_BLE_VENDOR_CB *p_cs_cb = &btm_ble_vendor_cb; + tBTM_BLE_IRK_ENTRY *p_irk_entry; + + if ((p_irk_entry = btm_ble_vendor_find_irk_entry_by_psuedo_addr(p_dev_rec->bd_addr)) != NULL && + btm_ble_vendor_find_irk_pending_entry(p_dev_rec->bd_addr, FALSE) == FALSE) + { + btm_ble_remove_irk_entry(p_dev_rec); + } + else + { + BTM_TRACE_ERROR0("Device not in IRK list"); + } + + if (p_cs_cb->irk_list_size == 0) + BTM_BleEnableIRKFeature(FALSE); +} +/******************************************************************************* +** +** Function btm_ble_vendor_disable_irk_list +** +** Description disable LE resolve address feature +** +** Parameters +** +** Returns status +** +*******************************************************************************/ +void btm_ble_vendor_disable_irk_list(void) +{ + BTM_BleEnableIRKFeature(FALSE); + +} + +/******************************************************************************* +** +** Function BTM_BleEnableIRKFeature +** +** 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_BleEnableIRKFeature(BOOLEAN enable) +{ + UINT8 param[20], *p; + tBTM_STATUS st = BTM_WRONG_MODE; + tBTM_BLE_PF_COUNT *p_bda_filter; + + 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_vendor_irk_vsc_op_cmpl); + + return st; +} + +#endif + /******************************************************************************* ** diff --git a/vnd/ble/vendor_hcidefs.h b/vnd/ble/vendor_hcidefs.h index dd2a1ca2a..f85e7fdff 100644 --- a/vnd/ble/vendor_hcidefs.h +++ b/vnd/ble/vendor_hcidefs.h @@ -28,10 +28,29 @@ #ifndef VENDOR_HCIDEFS_H #define VENDOR_HCIDEFS_H -/* advertising data payload filter VSC */ -#define HCI_VENDOR_BLE_PCF_VSC (0x0138 | HCI_GRP_VENDOR_SPECIFIC) +/***************************************************************************** +** Private address resolution VSC +******************************************************************************/ + +/* VSC */ +#define HCI_VENDOR_BLE_RPA_VSC (0x0155 | HCI_GRP_VENDOR_SPECIFIC) + +/* Sub codes */ +#define HCI_VENDOR_BLE_RPA_ENABLE 0x01 +#define HCI_VENDOR_BLE_RPA_ADD_IRK 0x02 +#define HCI_VENDOR_BLE_RPA_REMOVE_IRK 0x03 +#define HCI_VENDOR_BLE_RPA_CLEAR_IRK 0x04 +#define HCI_VENDOR_BLE_RPA_READ_IRK 0x05 + + +/***************************************************************************** +** Advertising data payload filter VSC +******************************************************************************/ + +/* VSC */ +#define HCI_VENDOR_BLE_PCF_VSC (0x0157 | HCI_GRP_VENDOR_SPECIFIC) -/* BLE PCF VSC sub code */ +/* Sub codes */ #define BTM_BLE_META_PF_ENABLE 0x00 #define BTM_BLE_META_PF_FEAT_SEL 0x01 #define BTM_BLE_META_PF_ADDR 0x02 diff --git a/vnd/include/vendor_api.h b/vnd/include/vendor_api.h index 3c65a351d..c69c42012 100644 --- a/vnd/include/vendor_api.h +++ b/vnd/include/vendor_api.h @@ -14,10 +14,21 @@ #include "bt_types.h" #include "btm_api.h" +/**************************************************************************** +** Resolvable private address offload VSC specific definitions +******************************************************************************/ + +enum +{ + BTM_BLE_PRIVACY_ENABLE, + BTM_BLE_PRIVACY_DISABLE +}; + + +/**************************************************************************** +** Advertising packet filter VSC specific definitions +******************************************************************************/ -/************************************* -** VENDOR BLE specific definitions -**************************************/ enum { BTM_BLE_SCAN_COND_ADD, diff --git a/vnd/include/vendor_ble.h b/vnd/include/vendor_ble.h index 432b55ea9..6cd587de8 100644 --- a/vnd/include/vendor_ble.h +++ b/vnd/include/vendor_ble.h @@ -30,9 +30,18 @@ #include "btm_ble_api.h" #include "vendor_api.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 + /* BLE meta vsc header: 1 bytes of sub_code, 1 byte of PCF action */ #define BTM_BLE_META_HDR_LENGTH 2 -#define BTM_BLE_PF_FEAT_SEL_LEN 12 +#define BTM_BLE_PF_FEAT_SEL_LEN 18 #define BTM_BLE_PCF_ENABLE_LEN 2 #define BTM_BLE_META_ADDR_LEN 7 #define BTM_BLE_META_UUID_LEN 40 @@ -64,6 +73,29 @@ typedef struct UINT8 pf_counter[BTM_BLE_PF_TYPE_MAX]; /* number of filter indexed by tBTM_BLE_PF_COND_TYPE */ }tBTM_BLE_PF_COUNT; +#ifndef BTM_CS_IRK_LIST_MAX +#define BTM_CS_IRK_LIST_MAX 0x20 +#endif + +#define BTM_CS_IRK_LIST_INVALID 0xff + +typedef struct +{ + BOOLEAN in_use; + BD_ADDR bd_addr; /* must be the address used in controller */ + BD_ADDR psuedo_bda; /* the random pseudo address */ + UINT8 index; +}tBTM_BLE_IRK_ENTRY; + + +typedef struct +{ + BD_ADDR irk_q[BTM_CS_IRK_LIST_MAX]; + BD_ADDR irk_q_random_pseudo[BTM_CS_IRK_LIST_MAX]; + UINT8 irk_q_action[BTM_CS_IRK_LIST_MAX]; + UINT8 q_next; + UINT8 q_pending; +} tBTM_BLE_IRK_Q; /* control block for BLE customer specific feature */ typedef struct @@ -74,6 +106,11 @@ typedef struct tBTM_BLE_PF_COUNT addr_filter_count[BTM_BLE_MAX_FILTER_COUNTER]; /* per BDA filter indexed by tBTM_BLE_PF_COND_TYPE */ tBLE_BD_ADDR cur_filter_target; + UINT8 irk_list_size; + UINT8 irk_avail_size; + tBTM_BLE_IRK_ENTRY irk_list[BTM_CS_IRK_LIST_MAX]; + tBTM_BLE_IRK_Q irk_pend_q; + tBTM_BLE_PF_CMPL_CBACK *p_scan_pf_cback; }tBTM_BLE_VENDOR_CB; @@ -89,6 +126,12 @@ BTM_API extern tBTM_BLE_VENDOR_CB *btm_ble_vendor_ptr; #define btm_ble_vendor_cb (*btm_ble_vendor_ptr) #endif +extern void btm_ble_vendor_irk_list_known_dev(BOOLEAN enable); +extern tBTM_STATUS btm_ble_read_irk_entry(BD_ADDR target_bda); +extern void btm_ble_vendor_disable_irk_list(void); +extern BOOLEAN btm_ble_vendor_irk_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec); +extern void btm_ble_vendor_irk_list_remove_dev(tBTM_SEC_DEV_REC *p_dev_rec); +extern tBTM_STATUS btm_ble_enable_vendor_feature (BOOLEAN enable, UINT32 feature_bit); extern void btm_ble_vendor_init(void); extern BOOLEAN btm_ble_vendor_write_device_wl_attribute (tBLE_ADDR_TYPE addr_type, BD_ADDR bd_addr, UINT8 attribute); -- 2.11.0