mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-06 22:24:33 +02:00
Merge branch 'bugfix/btdm_cherry_pick_api_manage_pair_info_#13119' into 'master'
component/bt: cherry-pick the bugfix/btdm_api_manage_pair_info_#13119 to this branch. See merge request !1095
This commit is contained in:
@@ -351,6 +351,41 @@ esp_err_t esp_ble_confirm_reply(esp_bd_addr_t bd_addr, bool accept)
|
|||||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_remove_bond_device(esp_bd_addr_t bd_addr)
|
||||||
|
{
|
||||||
|
btc_msg_t msg;
|
||||||
|
btc_ble_gap_args_t arg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
|
msg.act = BTC_GAP_BLE_REMOVE_BOND_DEV_EVT;
|
||||||
|
memcpy(arg.remove_bond_device.bd_addr, bd_addr, ESP_BD_ADDR_LEN);
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_clear_bond_device_list(void)
|
||||||
|
{
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
|
msg.act = BTC_GAP_BLE_CLEAR_BOND_DEV_EVT;
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, NULL, 0, NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_ble_get_bond_device_list(void)
|
||||||
|
{
|
||||||
|
btc_msg_t msg;
|
||||||
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
|
msg.act = BTC_GAP_BLE_GET_BOND_DEV_EVT;
|
||||||
|
|
||||||
|
return (btc_transfer_context(&msg, NULL, 0, NULL)
|
||||||
|
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t esp_ble_gap_disconnect(esp_bd_addr_t remote_device)
|
esp_err_t esp_ble_gap_disconnect(esp_bd_addr_t remote_device)
|
||||||
{
|
{
|
||||||
btc_msg_t msg;
|
btc_msg_t msg;
|
||||||
|
@@ -113,6 +113,7 @@ typedef enum {
|
|||||||
#define ESP_BLE_CSR_KEY_MASK (1 << 2) /* relate to BTM_BLE_CSR_KEY_MASK in btm_api.h */
|
#define ESP_BLE_CSR_KEY_MASK (1 << 2) /* relate to BTM_BLE_CSR_KEY_MASK in btm_api.h */
|
||||||
/// Used to exchange the link key(this key just used in the BLE & BR/EDR coexist mode) in the init key & response key
|
/// Used to exchange the link key(this key just used in the BLE & BR/EDR coexist mode) in the init key & response key
|
||||||
#define ESP_BLE_LINK_KEY_MASK (1 << 3) /* relate to BTM_BLE_LINK_KEY_MASK in btm_api.h */
|
#define ESP_BLE_LINK_KEY_MASK (1 << 3) /* relate to BTM_BLE_LINK_KEY_MASK in btm_api.h */
|
||||||
|
typedef uint8_t esp_ble_key_mask_t; /* the key mask type */
|
||||||
|
|
||||||
/// Minimum of the application id
|
/// Minimum of the application id
|
||||||
#define ESP_APP_ID_MIN 0x0000
|
#define ESP_APP_ID_MIN 0x0000
|
||||||
|
@@ -94,6 +94,10 @@ typedef enum {
|
|||||||
ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT, /*!< When update connection parameters complete, the event comes */
|
ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT, /*!< When update connection parameters complete, the event comes */
|
||||||
ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT, /*!< When set pkt lenght complete, the event comes */
|
ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT, /*!< When set pkt lenght complete, the event comes */
|
||||||
ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT, /*!< When Enable/disable privacy on the local device complete, the event comes */
|
ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT, /*!< When Enable/disable privacy on the local device complete, the event comes */
|
||||||
|
ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT, /*!< When remove the bond device complete, the event comes */
|
||||||
|
ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT, /*!< When clear the bond device clear complete, the event comes */
|
||||||
|
ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT, /*!< When get the bond device list complete, the event comes */
|
||||||
|
ESP_GAP_BLE_EVT_MAX,
|
||||||
} esp_gap_ble_cb_event_t;
|
} esp_gap_ble_cb_event_t;
|
||||||
|
|
||||||
/// Advertising data maximum length
|
/// Advertising data maximum length
|
||||||
@@ -367,6 +371,26 @@ typedef union
|
|||||||
esp_ble_lcsrk_keys lcsrk_key; /*!< local device CSRK = d1(ER,DIV,1)*/
|
esp_ble_lcsrk_keys lcsrk_key; /*!< local device CSRK = d1(ER,DIV,1)*/
|
||||||
} esp_ble_key_value_t; /*!< ble key value type*/
|
} esp_ble_key_value_t; /*!< ble key value type*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief struct type of the bond key informatuon value
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
esp_ble_key_mask_t key_mask; /*!< the key mask to indicate witch key is present */
|
||||||
|
esp_ble_penc_keys_t penc_key; /*!< received peer encryption key */
|
||||||
|
esp_ble_pcsrk_keys_t pcsrk_key; /*!< received peer device SRK */
|
||||||
|
esp_ble_pid_keys_t pid_key; /*!< peer device ID key */
|
||||||
|
} esp_ble_bond_key_info_t; /*!< ble bond key information value type */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief struct type of the bond device value
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
esp_bd_addr_t bd_addr; /*!< peer address */
|
||||||
|
esp_ble_bond_key_info_t bond_key; /*!< the bond key information */
|
||||||
|
} esp_ble_bond_dev_t; /*!< the ble bond device type */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief union type of the security key value
|
* @brief union type of the security key value
|
||||||
@@ -546,6 +570,27 @@ typedef union {
|
|||||||
struct ble_local_privacy_cmpl_evt_param {
|
struct ble_local_privacy_cmpl_evt_param {
|
||||||
esp_bt_status_t status; /*!< Indicate the set local privacy operation success status */
|
esp_bt_status_t status; /*!< Indicate the set local privacy operation success status */
|
||||||
} local_privacy_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT */
|
} local_privacy_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT */
|
||||||
|
/**
|
||||||
|
* @brief ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT
|
||||||
|
*/
|
||||||
|
struct ble_remove_bond_dev_cmpl_evt_param {
|
||||||
|
esp_bt_status_t status; /*!< Indicate the remove bond device operation success status */
|
||||||
|
esp_bd_addr_t bd_addr; /*!< The device address which has been remove from the bond list */
|
||||||
|
}remove_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT */
|
||||||
|
/**
|
||||||
|
* @brief ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT
|
||||||
|
*/
|
||||||
|
struct ble_clear_bond_dev_cmpl_evt_param {
|
||||||
|
esp_bt_status_t status; /*!< Indicate the clear bond device operation success status */
|
||||||
|
}clear_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT */
|
||||||
|
/**
|
||||||
|
* @brief ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT
|
||||||
|
*/
|
||||||
|
struct ble_get_bond_dev_cmpl_evt_param {
|
||||||
|
esp_bt_status_t status; /*!< Indicate the get bond device operation success status */
|
||||||
|
uint8_t dev_num; /*!< Indicate the get number device in the bond list */
|
||||||
|
esp_ble_bond_dev_t *bond_dev; /*!< the pointer to the bond device Structure */
|
||||||
|
}get_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT */
|
||||||
} esp_ble_gap_cb_param_t;
|
} esp_ble_gap_cb_param_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -821,6 +866,38 @@ esp_err_t esp_ble_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t pas
|
|||||||
*/
|
*/
|
||||||
esp_err_t esp_ble_confirm_reply(esp_bd_addr_t bd_addr, bool accept);
|
esp_err_t esp_ble_confirm_reply(esp_bd_addr_t bd_addr, bool accept);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Removes a device from the security database list of
|
||||||
|
* peer device. It manages unpairing event while connected.
|
||||||
|
*
|
||||||
|
* @param[in] bd_addr : BD address of the peer device
|
||||||
|
*
|
||||||
|
* @return - ESP_OK : success
|
||||||
|
* - other : failed
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_remove_bond_device(esp_bd_addr_t bd_addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Removes all of the device from the security database list of
|
||||||
|
* peer device. It manages unpairing event while connected.
|
||||||
|
*
|
||||||
|
* @return - ESP_OK : success
|
||||||
|
* - other : failed
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_clear_bond_device_list(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the device from the security database list of peer device.
|
||||||
|
* It will return the device bonded information from the ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT event.
|
||||||
|
*
|
||||||
|
* @return - ESP_OK : success
|
||||||
|
* - other : failed
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
esp_err_t esp_ble_get_bond_device_list(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function is to disconnect the physical connection of the peer device
|
* @brief This function is to disconnect the physical connection of the peer device
|
||||||
*
|
*
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
btc_dm_pairing_cb_t pairing_cb;
|
btc_dm_pairing_cb_t pairing_cb;
|
||||||
btc_dm_local_key_cb_t ble_local_key_cb;
|
btc_dm_local_key_cb_t ble_local_key_cb;
|
||||||
|
btc_bonded_devices_t bonded_devices;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
@@ -48,17 +50,63 @@ bt_status_t btc_storage_load_bonded_ble_devices(void)
|
|||||||
|
|
||||||
bt_status_t btc_in_fetch_bonded_ble_devices(int add)
|
bt_status_t btc_in_fetch_bonded_ble_devices(int add)
|
||||||
{
|
{
|
||||||
btc_bonded_devices_t bonded_devices;
|
bt_status_t status = BT_STATUS_FAIL;
|
||||||
|
int device_type = 0;
|
||||||
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
|
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
|
||||||
iter = btc_config_section_next(iter)) {
|
iter = btc_config_section_next(iter)) {
|
||||||
const char *name = btc_config_section_name(iter);
|
const char *name = btc_config_section_name(iter);
|
||||||
if (!string_is_bdaddr(name)) {
|
if (!string_is_bdaddr(name) ||
|
||||||
|
!btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) ||
|
||||||
|
((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
LOG_DEBUG("%s, name = %s", __func__, name);
|
||||||
|
if (btc_in_fetch_bonded_ble_device(name, add, &bonded_devices) != BT_STATUS_SUCCESS) {
|
||||||
|
LOG_DEBUG("Remote device:%s, no link key or ble key found", name);
|
||||||
|
} else {
|
||||||
|
status = BT_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
bt_status_t btc_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev)
|
||||||
|
{
|
||||||
|
bt_bdaddr_t bd_addr;
|
||||||
|
int device_type = 0;
|
||||||
|
char buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0};
|
||||||
|
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
|
||||||
|
iter = btc_config_section_next(iter)) {
|
||||||
|
const char *name = btc_config_section_name(iter);
|
||||||
|
if (!string_is_bdaddr(name) ||
|
||||||
|
!btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) ||
|
||||||
|
((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (btc_in_fetch_bonded_ble_device(name, add, &bonded_devices) != BT_STATUS_SUCCESS) {
|
string_to_bdaddr(name, &bd_addr);
|
||||||
LOG_DEBUG("Remote device:%s, no link key or ble key found", name);
|
memcpy(bond_dev->bd_addr, bd_addr.address, sizeof(bt_bdaddr_t));
|
||||||
|
//resolve the peer device long term key
|
||||||
|
if (btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PENC, buffer, sizeof(tBTM_LE_PENC_KEYS))
|
||||||
|
== BT_STATUS_SUCCESS) {
|
||||||
|
bond_dev->bond_key.key_mask |= ESP_BLE_ENC_KEY_MASK;
|
||||||
|
memcpy(&bond_dev->bond_key.penc_key, buffer, sizeof(tBTM_LE_PENC_KEYS));
|
||||||
}
|
}
|
||||||
|
//resolve the peer device csrk
|
||||||
|
if (btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PCSRK, buffer, sizeof(tBTM_LE_PCSRK_KEYS))
|
||||||
|
== BT_STATUS_SUCCESS) {
|
||||||
|
bond_dev->bond_key.key_mask |= ESP_BLE_CSR_KEY_MASK;
|
||||||
|
memcpy(&bond_dev->bond_key.pcsrk_key, buffer, sizeof(tBTM_LE_PCSRK_KEYS));
|
||||||
|
}
|
||||||
|
//resolve the peer device irk
|
||||||
|
if (btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PID, buffer, sizeof(tBTM_LE_PID_KEYS))
|
||||||
|
== BT_STATUS_SUCCESS) {
|
||||||
|
bond_dev->bond_key.key_mask |= ESP_BLE_ID_KEY_MASK;
|
||||||
|
memcpy(&bond_dev->bond_key.pid_key, buffer, sizeof(tBTM_LE_PID_KEYS));
|
||||||
|
}
|
||||||
|
//serch for the next bond device
|
||||||
|
bond_dev++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return BT_STATUS_SUCCESS;
|
return BT_STATUS_SUCCESS;
|
||||||
@@ -80,7 +128,8 @@ void btc_save_ble_bonding_keys(void)
|
|||||||
bdcpy(bd_addr.address, pairing_cb.bd_addr);
|
bdcpy(bd_addr.address, pairing_cb.bd_addr);
|
||||||
bdstr_t bdstr;
|
bdstr_t bdstr;
|
||||||
bdaddr_to_string(&bd_addr, bdstr, sizeof(bdstr));
|
bdaddr_to_string(&bd_addr, bdstr, sizeof(bdstr));
|
||||||
btc_config_set_int(bdstr, "DevType", BT_DEVICE_TYPE_BLE);
|
btc_config_set_int(bdstr, BTC_LE_DEV_TYPE, BT_DEVICE_TYPE_BLE);
|
||||||
|
LOG_DEBUG("%s, penc = %d, pid = %d", __func__, pairing_cb.ble.is_penc_key_rcvd, pairing_cb.ble.is_pid_key_rcvd);
|
||||||
if (pairing_cb.ble.is_penc_key_rcvd) {
|
if (pairing_cb.ble.is_penc_key_rcvd) {
|
||||||
btc_storage_add_ble_bonding_key(&bd_addr,
|
btc_storage_add_ble_bonding_key(&bd_addr,
|
||||||
(char *) &pairing_cb.ble.penc_key,
|
(char *) &pairing_cb.ble.penc_key,
|
||||||
@@ -236,8 +285,11 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool btc_storage_compare_address_key_value(uint8_t key_type, void *key_value, int key_length)
|
bool btc_storage_compare_address_key_value(bt_bdaddr_t *remote_bd_addr,
|
||||||
|
uint8_t key_type, void *key_value, int key_length)
|
||||||
{
|
{
|
||||||
|
bdstr_t bdstr;
|
||||||
|
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
||||||
char *key_type_str;
|
char *key_type_str;
|
||||||
switch (key_type) {
|
switch (key_type) {
|
||||||
case BTM_LE_KEY_PENC:
|
case BTM_LE_KEY_PENC:
|
||||||
@@ -261,7 +313,7 @@ bool btc_storage_compare_address_key_value(uint8_t key_type, void *key_value, in
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return btc_compare_address_key_value(key_type_str, key_value, key_length);
|
return btc_compare_address_key_value(bdstr, key_type_str, key_value, key_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -281,6 +333,9 @@ bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr)
|
|||||||
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr));
|
||||||
BTIF_TRACE_DEBUG(" %s in bd addr:%s",__FUNCTION__, bdstr);
|
BTIF_TRACE_DEBUG(" %s in bd addr:%s",__FUNCTION__, bdstr);
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
if (btc_config_exist(bdstr, BTC_LE_DEV_TYPE)) {
|
||||||
|
ret &= btc_config_remove(bdstr, BTC_LE_DEV_TYPE);
|
||||||
|
}
|
||||||
if (btc_config_exist(bdstr, "LE_KEY_PENC")) {
|
if (btc_config_exist(bdstr, "LE_KEY_PENC")) {
|
||||||
ret &= btc_config_remove(bdstr, "LE_KEY_PENC");
|
ret &= btc_config_remove(bdstr, "LE_KEY_PENC");
|
||||||
}
|
}
|
||||||
@@ -296,10 +351,48 @@ bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr)
|
|||||||
if (btc_config_exist(bdstr, "LE_KEY_LCSRK")) {
|
if (btc_config_exist(bdstr, "LE_KEY_LCSRK")) {
|
||||||
ret &= btc_config_remove(bdstr, "LE_KEY_LCSRK");
|
ret &= btc_config_remove(bdstr, "LE_KEY_LCSRK");
|
||||||
}
|
}
|
||||||
|
//remove the address information after delete the ble key.
|
||||||
|
ret = btc_config_remove_section(bdstr);
|
||||||
btc_config_save();
|
btc_config_save();
|
||||||
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
|
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bt_status_t btc_storage_clear_bond_devices(void)
|
||||||
|
{
|
||||||
|
bt_bdaddr_t bd_addr;
|
||||||
|
int device_type = 0;
|
||||||
|
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
|
||||||
|
iter = btc_config_section_next(iter)) {
|
||||||
|
const char *name = btc_config_section_name(iter);
|
||||||
|
if (!string_is_bdaddr(name) &&
|
||||||
|
!btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) &&
|
||||||
|
((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
string_to_bdaddr(name, &bd_addr);
|
||||||
|
//remove the ble bonding keys from the config and then save the config to the flash
|
||||||
|
if (btc_storage_remove_ble_bonding_keys(&bd_addr) != BT_STATUS_SUCCESS) {
|
||||||
|
LOG_ERROR("%s, remove bonding key faild", __func__);
|
||||||
|
return BT_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
// the bonded_devices Structure record the devices which has been added to the BTM layer global variable
|
||||||
|
for (int i = 0; i < bonded_devices.num_devices; i++) {
|
||||||
|
//if the address is equal to the record device address, remove it from the BTM layer global variable
|
||||||
|
if (!memcmp(bd_addr.address, bonded_devices.devices[i].address, sizeof(bt_bdaddr_t))) {
|
||||||
|
BD_ADDR bta_addr;
|
||||||
|
memcpy(bta_addr, bd_addr.address, sizeof(BD_ADDR));
|
||||||
|
if(BTA_DmRemoveDevice(bta_addr) != BTA_SUCCESS) {
|
||||||
|
LOG_ERROR("%s, remove device faild", __func__);
|
||||||
|
return BT_STATUS_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return BT_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
** Function btc_storage_add_ble_local_key
|
** Function btc_storage_add_ble_local_key
|
||||||
@@ -412,7 +505,7 @@ bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add,
|
|||||||
bool device_added = false;
|
bool device_added = false;
|
||||||
bool key_found = false;
|
bool key_found = false;
|
||||||
|
|
||||||
if (!btc_config_get_int(remote_bd_addr, "DevType", &device_type)) {
|
if (!btc_config_get_int(remote_bd_addr, BTC_LE_DEV_TYPE, &device_type)) {
|
||||||
LOG_ERROR("%s, device_type = %x", __func__, device_type);
|
LOG_ERROR("%s, device_type = %x", __func__, device_type);
|
||||||
return BT_STATUS_FAIL;
|
return BT_STATUS_FAIL;
|
||||||
}
|
}
|
||||||
@@ -443,6 +536,13 @@ bt_status_t btc_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add,
|
|||||||
btc_read_le_key(BTM_LE_KEY_LCSRK, sizeof(tBTM_LE_LCSRK_KEYS),
|
btc_read_le_key(BTM_LE_KEY_LCSRK, sizeof(tBTM_LE_LCSRK_KEYS),
|
||||||
bd_addr, addr_type, add, &device_added, &key_found);
|
bd_addr, addr_type, add, &device_added, &key_found);
|
||||||
|
|
||||||
|
// Fill in the bonded devices
|
||||||
|
if (device_added)
|
||||||
|
{
|
||||||
|
memcpy(&p_bonded_devices->devices[p_bonded_devices->num_devices++],
|
||||||
|
&bd_addr, sizeof(bt_bdaddr_t));
|
||||||
|
}
|
||||||
|
|
||||||
if (key_found) {
|
if (key_found) {
|
||||||
return BT_STATUS_SUCCESS;
|
return BT_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -479,6 +579,24 @@ bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
|
|||||||
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
|
return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int btc_storage_get_num_ble_bond_devices(void)
|
||||||
|
{
|
||||||
|
int num_dev = 0;
|
||||||
|
int device_type = 0;
|
||||||
|
for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end();
|
||||||
|
iter = btc_config_section_next(iter)) {
|
||||||
|
const char *name = btc_config_section_name(iter);
|
||||||
|
if (!string_is_bdaddr(name) &&
|
||||||
|
!btc_config_get_int(name, BTC_LE_DEV_TYPE, &device_type) &&
|
||||||
|
device_type != BT_DEVICE_TYPE_BLE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_dev++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_dev;
|
||||||
|
}
|
||||||
|
|
||||||
void btc_dm_load_ble_local_keys(void)
|
void btc_dm_load_ble_local_keys(void)
|
||||||
{
|
{
|
||||||
|
@@ -47,7 +47,7 @@ bool btc_get_device_type(const BD_ADDR bd_addr, int *p_device_type)
|
|||||||
bdstr_t bd_addr_str;
|
bdstr_t bd_addr_str;
|
||||||
bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str));
|
bdaddr_to_string(&bda, bd_addr_str, sizeof(bd_addr_str));
|
||||||
|
|
||||||
if (!btc_config_get_int(bd_addr_str, "DevType", p_device_type)) {
|
if (!btc_config_get_int(bd_addr_str, BTC_LE_DEV_TYPE, p_device_type)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type)
|
|||||||
static pthread_mutex_t lock; // protects operations on |config|.
|
static pthread_mutex_t lock; // protects operations on |config|.
|
||||||
static config_t *config;
|
static config_t *config;
|
||||||
|
|
||||||
bool btc_compare_address_key_value(char *key_type, void *key_value, int key_length)
|
bool btc_compare_address_key_value(const char *section, char *key_type, void *key_value, int key_length)
|
||||||
{
|
{
|
||||||
assert(key_value != NULL);
|
assert(key_value != NULL);
|
||||||
bool status = false;
|
bool status = false;
|
||||||
@@ -88,7 +88,9 @@ bool btc_compare_address_key_value(char *key_type, void *key_value, int key_leng
|
|||||||
}
|
}
|
||||||
btc_key_value_to_string((uint8_t *)key_value, value_str, key_length);
|
btc_key_value_to_string((uint8_t *)key_value, value_str, key_length);
|
||||||
pthread_mutex_lock(&lock);
|
pthread_mutex_lock(&lock);
|
||||||
status = config_has_key_in_section(config, key_type, value_str);
|
if ((status = config_has_key_in_section(config, key_type, value_str)) == true) {
|
||||||
|
config_remove_section(config, section);
|
||||||
|
}
|
||||||
pthread_mutex_unlock(&lock);
|
pthread_mutex_unlock(&lock);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -365,6 +367,18 @@ bool btc_config_remove(const char *section, const char *key)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool btc_config_remove_section(const char *section)
|
||||||
|
{
|
||||||
|
assert(config != NULL);
|
||||||
|
assert(section != NULL);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&lock);
|
||||||
|
bool ret = config_remove_section(config, section);
|
||||||
|
pthread_mutex_unlock(&lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void btc_config_save(void)
|
void btc_config_save(void)
|
||||||
{
|
{
|
||||||
assert(config != NULL);
|
assert(config != NULL);
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include "btc_storage.h"
|
#include "btc_storage.h"
|
||||||
#include "btc_ble_storage.h"
|
#include "btc_ble_storage.h"
|
||||||
#include "esp_gap_ble_api.h"
|
#include "esp_gap_ble_api.h"
|
||||||
|
#include "btm_int.h"
|
||||||
#include "bta_api.h"
|
#include "bta_api.h"
|
||||||
#include "bta_gatt_api.h"
|
#include "bta_gatt_api.h"
|
||||||
|
|
||||||
@@ -118,13 +119,15 @@ static void btc_disable_bluetooth_evt(void)
|
|||||||
static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
|
static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
|
||||||
{
|
{
|
||||||
/* Save link key, if not temporary */
|
/* Save link key, if not temporary */
|
||||||
|
LOG_DEBUG("%s, status = %d", __func__, p_auth_cmpl->success);
|
||||||
bt_status_t status = BT_STATUS_FAIL;
|
bt_status_t status = BT_STATUS_FAIL;
|
||||||
if (p_auth_cmpl->success) {
|
|
||||||
status = BT_STATUS_SUCCESS;
|
|
||||||
int addr_type;
|
int addr_type;
|
||||||
bt_bdaddr_t bdaddr;
|
bt_bdaddr_t bdaddr;
|
||||||
bdcpy(bdaddr.address, p_auth_cmpl->bd_addr);
|
bdcpy(bdaddr.address, p_auth_cmpl->bd_addr);
|
||||||
bdcpy(pairing_cb.bd_addr, p_auth_cmpl->bd_addr);
|
bdcpy(pairing_cb.bd_addr, p_auth_cmpl->bd_addr);
|
||||||
|
|
||||||
|
if (p_auth_cmpl->success) {
|
||||||
|
status = BT_STATUS_SUCCESS;
|
||||||
LOG_DEBUG ("%s, - p_auth_cmpl->bd_addr: %08x%04x", __func__,
|
LOG_DEBUG ("%s, - p_auth_cmpl->bd_addr: %08x%04x", __func__,
|
||||||
(p_auth_cmpl->bd_addr[0] << 24) + (p_auth_cmpl->bd_addr[1] << 16) + (p_auth_cmpl->bd_addr[2] << 8) + p_auth_cmpl->bd_addr[3],
|
(p_auth_cmpl->bd_addr[0] << 24) + (p_auth_cmpl->bd_addr[1] << 16) + (p_auth_cmpl->bd_addr[2] << 8) + p_auth_cmpl->bd_addr[3],
|
||||||
(p_auth_cmpl->bd_addr[4] << 8) + p_auth_cmpl->bd_addr[5]);
|
(p_auth_cmpl->bd_addr[4] << 8) + p_auth_cmpl->bd_addr[5]);
|
||||||
@@ -137,7 +140,7 @@ static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl)
|
|||||||
/* check the irk has been save in the flash or not, if the irk has already save, means that the peer device has bonding
|
/* check the irk has been save in the flash or not, if the irk has already save, means that the peer device has bonding
|
||||||
before. */
|
before. */
|
||||||
if(pairing_cb.ble.is_pid_key_rcvd) {
|
if(pairing_cb.ble.is_pid_key_rcvd) {
|
||||||
btc_storage_compare_address_key_value(BTM_LE_KEY_PID,
|
btc_storage_compare_address_key_value(&bdaddr, BTM_LE_KEY_PID,
|
||||||
(void *)&pairing_cb.ble.pid_key, sizeof(tBTM_LE_PID_KEYS));
|
(void *)&pairing_cb.ble.pid_key, sizeof(tBTM_LE_PID_KEYS));
|
||||||
}
|
}
|
||||||
btc_save_ble_bonding_keys();
|
btc_save_ble_bonding_keys();
|
||||||
@@ -321,8 +324,6 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
|
|||||||
btc_clear_services_mask();
|
btc_clear_services_mask();
|
||||||
btc_storage_load_bonded_devices();
|
btc_storage_load_bonded_devices();
|
||||||
#if (SMP_INCLUDED == TRUE)
|
#if (SMP_INCLUDED == TRUE)
|
||||||
//load the ble local key whitch has been store in the flash
|
|
||||||
btc_dm_load_ble_local_keys();
|
|
||||||
//load the bonding device to the btm layer
|
//load the bonding device to the btm layer
|
||||||
btc_storage_load_bonded_ble_devices();
|
btc_storage_load_bonded_ble_devices();
|
||||||
#endif ///SMP_INCLUDED == TRUE
|
#endif ///SMP_INCLUDED == TRUE
|
||||||
@@ -348,8 +349,20 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
|
|||||||
case BTA_DM_BOND_CANCEL_CMPL_EVT:
|
case BTA_DM_BOND_CANCEL_CMPL_EVT:
|
||||||
case BTA_DM_SP_CFM_REQ_EVT:
|
case BTA_DM_SP_CFM_REQ_EVT:
|
||||||
case BTA_DM_SP_KEY_NOTIF_EVT:
|
case BTA_DM_SP_KEY_NOTIF_EVT:
|
||||||
|
break;
|
||||||
case BTA_DM_DEV_UNPAIRED_EVT:
|
case BTA_DM_DEV_UNPAIRED_EVT: {
|
||||||
|
bt_bdaddr_t bd_addr;
|
||||||
|
rsp_app = true;
|
||||||
|
LOG_ERROR("BTA_DM_DEV_UNPAIRED_EVT");
|
||||||
|
memcpy(bd_addr.address, p_data->link_down.bd_addr, sizeof(BD_ADDR));
|
||||||
|
btm_set_bond_type_dev(p_data->link_down.bd_addr, BOND_TYPE_UNKNOWN);
|
||||||
|
//remove the bonded key in the config and nvs flash.
|
||||||
|
//btc_storage_remove_ble_bonding_keys(&bd_addr);
|
||||||
|
ble_msg.act = ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT;
|
||||||
|
param.remove_bond_dev_cmpl.status = (p_data->link_down.status == HCI_SUCCESS) ? ESP_BT_STATUS_SUCCESS : ESP_BT_STATUS_FAIL;
|
||||||
|
memcpy(param.remove_bond_dev_cmpl.bd_addr, p_data->link_down.bd_addr, sizeof(BD_ADDR));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case BTA_DM_BUSY_LEVEL_EVT:
|
case BTA_DM_BUSY_LEVEL_EVT:
|
||||||
case BTA_DM_LINK_UP_EVT:
|
case BTA_DM_LINK_UP_EVT:
|
||||||
case BTA_DM_LINK_DOWN_EVT:
|
case BTA_DM_LINK_DOWN_EVT:
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "btc_config.h"
|
#include "btc_config.h"
|
||||||
#include "alarm.h"
|
#include "alarm.h"
|
||||||
|
#include "btc_ble_storage.h"
|
||||||
|
|
||||||
static future_t *main_future[BTC_MAIN_FUTURE_NUM];
|
static future_t *main_future[BTC_MAIN_FUTURE_NUM];
|
||||||
|
|
||||||
@@ -56,6 +57,8 @@ static void btc_init_bluetooth(void)
|
|||||||
osi_alarm_init();
|
osi_alarm_init();
|
||||||
bte_main_boot_entry(btc_init_callback);
|
bte_main_boot_entry(btc_init_callback);
|
||||||
btc_config_init();
|
btc_config_init();
|
||||||
|
//load the ble local key whitch has been store in the flash
|
||||||
|
btc_dm_load_ble_local_keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -11,9 +11,11 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
#ifndef __BTC_BLE_STORAGE_H__
|
||||||
|
#define __BTC_BLE_STORAGE_H__
|
||||||
#include "bt_types.h"
|
#include "bt_types.h"
|
||||||
#include "bt_target.h"
|
#include "bt_target.h"
|
||||||
|
#include "esp_gap_ble_api.h"
|
||||||
|
|
||||||
#if (SMP_INCLUDED == TRUE)
|
#if (SMP_INCLUDED == TRUE)
|
||||||
#define BTC_LE_LOCAL_KEY_IR (1<<0)
|
#define BTC_LE_LOCAL_KEY_IR (1<<0)
|
||||||
@@ -77,9 +79,12 @@ typedef struct
|
|||||||
|
|
||||||
extern btc_dm_pairing_cb_t pairing_cb;
|
extern btc_dm_pairing_cb_t pairing_cb;
|
||||||
extern btc_dm_local_key_cb_t ble_local_key_cb;
|
extern btc_dm_local_key_cb_t ble_local_key_cb;
|
||||||
|
extern btc_bonded_devices_t bonded_devices;
|
||||||
|
|
||||||
bt_status_t btc_storage_load_bonded_ble_devices(void);
|
bt_status_t btc_storage_load_bonded_ble_devices(void);
|
||||||
|
|
||||||
|
bt_status_t btc_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev);
|
||||||
|
|
||||||
bt_status_t btc_in_fetch_bonded_ble_devices(int add);
|
bt_status_t btc_in_fetch_bonded_ble_devices(int add);
|
||||||
|
|
||||||
void btc_dm_remove_ble_bonding_keys(void);
|
void btc_dm_remove_ble_bonding_keys(void);
|
||||||
@@ -102,14 +107,16 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr,
|
|||||||
char *key_value,
|
char *key_value,
|
||||||
int key_length);
|
int key_length);
|
||||||
|
|
||||||
bool btc_storage_compare_address_key_value(uint8_t key_type, void *key_value, int key_length);
|
bool btc_storage_compare_address_key_value(bt_bdaddr_t *remote_bd_addr,
|
||||||
|
uint8_t key_type, void *key_value, int key_length);
|
||||||
bt_status_t btc_storage_add_ble_local_key(char *key,
|
bt_status_t btc_storage_add_ble_local_key(char *key,
|
||||||
uint8_t key_type,
|
uint8_t key_type,
|
||||||
uint8_t key_length);
|
uint8_t key_length);
|
||||||
|
|
||||||
bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr);
|
bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr);
|
||||||
|
|
||||||
|
bt_status_t btc_storage_clear_bond_devices(void);
|
||||||
|
|
||||||
bt_status_t btc_storage_remove_ble_local_keys(void);
|
bt_status_t btc_storage_remove_ble_local_keys(void);
|
||||||
|
|
||||||
bt_status_t btc_storage_get_ble_local_key(uint8_t key_type,
|
bt_status_t btc_storage_get_ble_local_key(uint8_t key_type,
|
||||||
@@ -119,6 +126,8 @@ bt_status_t btc_storage_get_ble_local_key(uint8_t key_type,
|
|||||||
bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
|
bt_status_t btc_storage_get_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
|
||||||
int *addr_type);
|
int *addr_type);
|
||||||
|
|
||||||
|
int btc_storage_get_num_ble_bond_devices(void);
|
||||||
|
|
||||||
bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
|
bt_status_t btc_storage_set_remote_addr_type(bt_bdaddr_t *remote_bd_addr,
|
||||||
uint8_t addr_type);
|
uint8_t addr_type);
|
||||||
|
|
||||||
@@ -127,3 +136,4 @@ void btc_dm_load_ble_local_keys(void);
|
|||||||
void btc_dm_get_ble_local_keys(tBTA_DM_BLE_LOCAL_KEY_MASK *p_key_mask, BT_OCTET16 er,
|
void btc_dm_get_ble_local_keys(tBTA_DM_BLE_LOCAL_KEY_MASK *p_key_mask, BT_OCTET16 er,
|
||||||
tBTA_BLE_LOCAL_ID_KEYS *p_id_keys);
|
tBTA_BLE_LOCAL_ID_KEYS *p_id_keys);
|
||||||
#endif ///SMP_INCLUDED == TRUE
|
#endif ///SMP_INCLUDED == TRUE
|
||||||
|
#endif ///__BTC_BLE_STORAGE_H__
|
@@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include "bt_types.h"
|
#include "bt_types.h"
|
||||||
|
|
||||||
|
#define BTC_LE_DEV_TYPE "DevType"
|
||||||
|
|
||||||
typedef struct btc_config_section_iter_t btc_config_section_iter_t;
|
typedef struct btc_config_section_iter_t btc_config_section_iter_t;
|
||||||
|
|
||||||
bool btc_config_init(void);
|
bool btc_config_init(void);
|
||||||
@@ -35,6 +37,7 @@ bool btc_config_set_str(const char *section, const char *key, const char *value)
|
|||||||
bool btc_config_get_bin(const char *section, const char *key, uint8_t *value, size_t *length);
|
bool btc_config_get_bin(const char *section, const char *key, uint8_t *value, size_t *length);
|
||||||
bool btc_config_set_bin(const char *section, const char *key, const uint8_t *value, size_t length);
|
bool btc_config_set_bin(const char *section, const char *key, const uint8_t *value, size_t length);
|
||||||
bool btc_config_remove(const char *section, const char *key);
|
bool btc_config_remove(const char *section, const char *key);
|
||||||
|
bool btc_config_remove_section(const char *section);
|
||||||
|
|
||||||
size_t btc_config_get_bin_length(const char *section, const char *key);
|
size_t btc_config_get_bin_length(const char *section, const char *key);
|
||||||
|
|
||||||
@@ -49,7 +52,7 @@ int btc_config_clear(void);
|
|||||||
|
|
||||||
// TODO(zachoverflow): Eww...we need to move these out. These are peer specific, not config general.
|
// TODO(zachoverflow): Eww...we need to move these out. These are peer specific, not config general.
|
||||||
bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type);
|
bool btc_get_address_type(const BD_ADDR bd_addr, int *p_addr_type);
|
||||||
bool btc_compare_address_key_value(char *key_type, void *key_value, int key_length);
|
bool btc_compare_address_key_value(const char *section, char *key_type, void *key_value, int key_length);
|
||||||
bool btc_get_device_type(const BD_ADDR bd_addr, int *p_device_type);
|
bool btc_get_device_type(const BD_ADDR bd_addr, int *p_device_type);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -24,10 +24,15 @@
|
|||||||
#include "btc_gatt_util.h"
|
#include "btc_gatt_util.h"
|
||||||
#include "esp_bt_defs.h"
|
#include "esp_bt_defs.h"
|
||||||
#include "esp_gap_ble_api.h"
|
#include "esp_gap_ble_api.h"
|
||||||
|
#include "btc_ble_storage.h"
|
||||||
|
|
||||||
static tBTA_BLE_ADV_DATA gl_bta_adv_data;
|
static tBTA_BLE_ADV_DATA gl_bta_adv_data;
|
||||||
static tBTA_BLE_ADV_DATA gl_bta_scan_rsp_data;
|
static tBTA_BLE_ADV_DATA gl_bta_scan_rsp_data;
|
||||||
|
|
||||||
|
static void btc_gap_ble_arg_deep_free(btc_msg_t *msg);
|
||||||
|
static void btc_gap_ble_cb_deep_free(btc_msg_t *msg);
|
||||||
|
static void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
|
||||||
|
|
||||||
static inline void btc_gap_ble_cb_to_app(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
|
static inline void btc_gap_ble_cb_to_app(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
|
||||||
{
|
{
|
||||||
esp_gap_ble_cb_t btc_gap_ble_cb = (esp_gap_ble_cb_t)btc_profile_cb_get(BTC_PID_GAP_BLE);
|
esp_gap_ble_cb_t btc_gap_ble_cb = (esp_gap_ble_cb_t)btc_profile_cb_get(BTC_PID_GAP_BLE);
|
||||||
@@ -779,6 +784,68 @@ static void btc_ble_set_rand_addr (BD_ADDR rand_addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void btc_ble_remove_bond_device(esp_bt_status_t status)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
esp_ble_gap_cb_param_t param;
|
||||||
|
btc_msg_t msg;
|
||||||
|
param.remove_bond_dev_cmpl.status = status;
|
||||||
|
msg.sig = BTC_SIG_API_CB;
|
||||||
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
|
msg.act = ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT;
|
||||||
|
|
||||||
|
ret = btc_transfer_context(&msg, ¶m,
|
||||||
|
sizeof(esp_ble_gap_cb_param_t), NULL);
|
||||||
|
|
||||||
|
if (ret != BT_STATUS_SUCCESS) {
|
||||||
|
LOG_ERROR("%s btc_transfer_context failed", __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void btc_ble_clear_bond_device(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
esp_ble_gap_cb_param_t param;
|
||||||
|
btc_msg_t msg;
|
||||||
|
ret = btc_storage_clear_bond_devices();
|
||||||
|
param.clear_bond_dev_cmpl.status = ret;
|
||||||
|
msg.sig = BTC_SIG_API_CB;
|
||||||
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
|
msg.act = ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT;
|
||||||
|
|
||||||
|
ret = btc_transfer_context(&msg, ¶m,
|
||||||
|
sizeof(esp_ble_gap_cb_param_t), NULL);
|
||||||
|
|
||||||
|
if (ret != BT_STATUS_SUCCESS) {
|
||||||
|
LOG_ERROR("%s btc_transfer_context failed", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void btc_ble_get_bond_device_list(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
esp_ble_gap_cb_param_t param;
|
||||||
|
esp_ble_bond_dev_t *bond_dev;
|
||||||
|
btc_msg_t msg;
|
||||||
|
int num_dev = btc_storage_get_num_ble_bond_devices();
|
||||||
|
bond_dev = GKI_getbuf(sizeof(esp_ble_bond_dev_t)*num_dev);
|
||||||
|
|
||||||
|
param.get_bond_dev_cmpl.status = btc_get_bonded_ble_devices_list(bond_dev);
|
||||||
|
param.get_bond_dev_cmpl.dev_num = num_dev;
|
||||||
|
param.get_bond_dev_cmpl.bond_dev = bond_dev;
|
||||||
|
msg.sig = BTC_SIG_API_CB;
|
||||||
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
|
msg.act = ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT;
|
||||||
|
|
||||||
|
ret = btc_transfer_context(&msg, ¶m, sizeof(esp_ble_gap_cb_param_t), btc_gap_ble_cb_deep_copy);
|
||||||
|
|
||||||
|
if (ret != BT_STATUS_SUCCESS) {
|
||||||
|
LOG_ERROR("%s btc_transfer_context failed", __func__);
|
||||||
|
}
|
||||||
|
// release the buffer after used.
|
||||||
|
GKI_freebuf((void *)bond_dev);
|
||||||
|
}
|
||||||
static void btc_ble_config_local_privacy(bool privacy_enable, tBTA_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cback)
|
static void btc_ble_config_local_privacy(bool privacy_enable, tBTA_SET_LOCAL_PRIVACY_CBACK *set_local_privacy_cback)
|
||||||
{
|
{
|
||||||
BTA_DmBleConfigLocalPrivacy(privacy_enable, set_local_privacy_cback);
|
BTA_DmBleConfigLocalPrivacy(privacy_enable, set_local_privacy_cback);
|
||||||
@@ -793,81 +860,14 @@ void btc_gap_ble_cb_handler(btc_msg_t *msg)
|
|||||||
{
|
{
|
||||||
esp_ble_gap_cb_param_t *param = (esp_ble_gap_cb_param_t *)msg->arg;
|
esp_ble_gap_cb_param_t *param = (esp_ble_gap_cb_param_t *)msg->arg;
|
||||||
|
|
||||||
switch (msg->act) {
|
if (msg->act < ESP_GAP_BLE_EVT_MAX) {
|
||||||
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:
|
btc_gap_ble_cb_to_app(msg->act, param);
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT, param);
|
} else {
|
||||||
break;
|
LOG_ERROR("%s, unknow msg->act = %d", __func__, msg->act);
|
||||||
case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT :
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_SCAN_RESULT_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_RESULT_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_START_COMPLETE_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_START_COMPLETE_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_AUTH_CMPL_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_AUTH_CMPL_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_KEY_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_KEY_EVT, param);
|
|
||||||
break;
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_KEY_EVT, param);
|
|
||||||
case ESP_GAP_BLE_SEC_REQ_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SEC_REQ_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_PASSKEY_NOTIF_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_PASSKEY_NOTIF_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_PASSKEY_REQ_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_PASSKEY_REQ_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_OOB_REQ_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_OOB_REQ_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_LOCAL_IR_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_LOCAL_IR_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_LOCAL_ER_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_LOCAL_ER_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_NC_REQ_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_NC_REQ_EVT, param);
|
|
||||||
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT, param);
|
|
||||||
break;
|
|
||||||
case ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT:
|
|
||||||
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT, param);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
btc_gap_ble_cb_deep_free(msg);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
|
void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
|
||||||
@@ -939,6 +939,30 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
|
||||||
|
{
|
||||||
|
switch (msg->act) {
|
||||||
|
case ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT: {
|
||||||
|
esp_ble_gap_cb_param_t *src = (esp_ble_gap_cb_param_t *)p_src;
|
||||||
|
esp_ble_gap_cb_param_t *dst = (esp_ble_gap_cb_param_t *)p_dest;
|
||||||
|
uint16_t length = 0;
|
||||||
|
if (src->get_bond_dev_cmpl.bond_dev) {
|
||||||
|
length = (src->get_bond_dev_cmpl.dev_num)*sizeof(esp_ble_bond_dev_t);
|
||||||
|
dst->get_bond_dev_cmpl.bond_dev = GKI_getbuf(length);
|
||||||
|
if (dst->get_bond_dev_cmpl.bond_dev != NULL) {
|
||||||
|
memcpy(dst->get_bond_dev_cmpl.bond_dev, src->get_bond_dev_cmpl.bond_dev, length);
|
||||||
|
} else {
|
||||||
|
LOG_ERROR("%s %d no mem", __func__, msg->act);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
LOG_ERROR("%s, Unhandled deep copy %d\n", __func__, msg->act);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
|
static void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("%s \n", __func__);
|
LOG_DEBUG("%s \n", __func__);
|
||||||
@@ -978,6 +1002,23 @@ static void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void btc_gap_ble_cb_deep_free(btc_msg_t *msg)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("%s", __func__);
|
||||||
|
switch (msg->act) {
|
||||||
|
case ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT: {
|
||||||
|
esp_ble_bond_dev_t *bond_dev = ((esp_ble_gap_cb_param_t *)msg->arg)->get_bond_dev_cmpl.bond_dev;
|
||||||
|
if (bond_dev) {
|
||||||
|
GKI_freebuf((void *)bond_dev);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
LOG_DEBUG("Unhandled deep free %d", msg->act);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void btc_gap_ble_call_handler(btc_msg_t *msg)
|
void btc_gap_ble_call_handler(btc_msg_t *msg)
|
||||||
{
|
{
|
||||||
btc_ble_gap_args_t *arg = (btc_ble_gap_args_t *)msg->arg;
|
btc_ble_gap_args_t *arg = (btc_ble_gap_args_t *)msg->arg;
|
||||||
@@ -1104,6 +1145,26 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
|
|||||||
BTA_DmBleConfirmReply(bd_addr, arg->enc_comfirm_replay.accept);
|
BTA_DmBleConfirmReply(bd_addr, arg->enc_comfirm_replay.accept);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case BTC_GAP_BLE_REMOVE_BOND_DEV_EVT: {
|
||||||
|
BD_ADDR bd_addr;
|
||||||
|
bt_bdaddr_t bt_addr;
|
||||||
|
memcpy(bd_addr, arg->remove_bond_device.bd_addr, sizeof(BD_ADDR));
|
||||||
|
memcpy(bt_addr.address, arg->remove_bond_device.bd_addr, sizeof(bt_bdaddr_t));
|
||||||
|
LOG_DEBUG("BTC_GAP_BLE_REMOVE_BOND_DEV_EVT");
|
||||||
|
if (btc_storage_remove_ble_bonding_keys(&bt_addr) == BT_STATUS_SUCCESS) {
|
||||||
|
BTA_DmRemoveDevice(bd_addr);
|
||||||
|
} else {
|
||||||
|
LOG_ERROR("remove device failed: the address[%x:%x:%x:%x:%x:%x] didn't in the bonding list", bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
|
||||||
|
btc_ble_remove_bond_device(ESP_BT_STATUS_FAIL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BTC_GAP_BLE_CLEAR_BOND_DEV_EVT:
|
||||||
|
btc_ble_clear_bond_device();
|
||||||
|
break;
|
||||||
|
case BTC_GAP_BLE_GET_BOND_DEV_EVT:
|
||||||
|
btc_ble_get_bond_device_list();
|
||||||
|
break;
|
||||||
#endif ///SMP_INCLUDED == TRUE
|
#endif ///SMP_INCLUDED == TRUE
|
||||||
case BTC_GAP_BLE_DISCONNECT_EVT:
|
case BTC_GAP_BLE_DISCONNECT_EVT:
|
||||||
btc_ble_disconnect(arg->disconnect.remote_device);
|
btc_ble_disconnect(arg->disconnect.remote_device);
|
||||||
|
@@ -40,6 +40,9 @@ typedef enum {
|
|||||||
BTC_GAP_BLE_PASSKEY_REPLY_EVT,
|
BTC_GAP_BLE_PASSKEY_REPLY_EVT,
|
||||||
BTC_GAP_BLE_CONFIRM_REPLY_EVT,
|
BTC_GAP_BLE_CONFIRM_REPLY_EVT,
|
||||||
BTC_GAP_BLE_DISCONNECT_EVT,
|
BTC_GAP_BLE_DISCONNECT_EVT,
|
||||||
|
BTC_GAP_BLE_REMOVE_BOND_DEV_EVT,
|
||||||
|
BTC_GAP_BLE_CLEAR_BOND_DEV_EVT,
|
||||||
|
BTC_GAP_BLE_GET_BOND_DEV_EVT,
|
||||||
} btc_gap_ble_act_t;
|
} btc_gap_ble_act_t;
|
||||||
|
|
||||||
/* btc_ble_gap_args_t */
|
/* btc_ble_gap_args_t */
|
||||||
@@ -89,39 +92,41 @@ typedef union {
|
|||||||
uint8_t *raw_scan_rsp;
|
uint8_t *raw_scan_rsp;
|
||||||
uint32_t raw_scan_rsp_len;
|
uint32_t raw_scan_rsp_len;
|
||||||
} cfg_scan_rsp_data_raw;
|
} cfg_scan_rsp_data_raw;
|
||||||
|
//BTC_GAP_BLE_SET_ENCRYPTION_EVT
|
||||||
struct set_encryption_args {
|
struct set_encryption_args {
|
||||||
esp_bd_addr_t bd_addr;
|
esp_bd_addr_t bd_addr;
|
||||||
esp_ble_sec_act_t sec_act;
|
esp_ble_sec_act_t sec_act;
|
||||||
} set_encryption;
|
} set_encryption;
|
||||||
|
//BTC_GAP_BLE_SET_SECURITY_PARAM_EVT
|
||||||
struct set_security_param_args {
|
struct set_security_param_args {
|
||||||
esp_ble_sm_param_t param_type;
|
esp_ble_sm_param_t param_type;
|
||||||
uint8_t len;
|
uint8_t len;
|
||||||
uint8_t *value;
|
uint8_t *value;
|
||||||
} set_security_param;
|
} set_security_param;
|
||||||
|
//BTC_GAP_BLE_SECURITY_RSP_EVT
|
||||||
struct enc_rsp_args {
|
struct enc_rsp_args {
|
||||||
esp_bd_addr_t bd_addr;
|
esp_bd_addr_t bd_addr;
|
||||||
bool accept;
|
bool accept;
|
||||||
} sec_rsp;
|
} sec_rsp;
|
||||||
|
//BTC_GAP_BLE_PASSKEY_REPLY_EVT
|
||||||
struct enc_passkey_reply_args {
|
struct enc_passkey_reply_args {
|
||||||
esp_bd_addr_t bd_addr;
|
esp_bd_addr_t bd_addr;
|
||||||
bool accept;
|
bool accept;
|
||||||
uint32_t passkey;
|
uint32_t passkey;
|
||||||
} enc_passkey_replay;
|
} enc_passkey_replay;
|
||||||
|
//BTC_GAP_BLE_CONFIRM_REPLY_EVT
|
||||||
struct enc_comfirm_reply_args {
|
struct enc_comfirm_reply_args {
|
||||||
esp_bd_addr_t bd_addr;
|
esp_bd_addr_t bd_addr;
|
||||||
bool accept;
|
bool accept;
|
||||||
} enc_comfirm_replay;
|
} enc_comfirm_replay;
|
||||||
|
|
||||||
//BTC_GAP_BLE_DISCONNECT_EVT
|
//BTC_GAP_BLE_DISCONNECT_EVT
|
||||||
struct disconnect_args {
|
struct disconnect_args {
|
||||||
esp_bd_addr_t remote_device;
|
esp_bd_addr_t remote_device;
|
||||||
} disconnect;
|
} disconnect;
|
||||||
|
//BTC_GAP_BLE_REMOVE_BOND_DEV_EVT
|
||||||
|
struct remove_bond_device_args {
|
||||||
|
esp_bd_addr_t bd_addr;
|
||||||
|
} remove_bond_device;
|
||||||
} btc_ble_gap_args_t;
|
} btc_ble_gap_args_t;
|
||||||
|
|
||||||
void btc_gap_ble_call_handler(btc_msg_t *msg);
|
void btc_gap_ble_call_handler(btc_msg_t *msg);
|
||||||
|
@@ -261,6 +261,23 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param
|
|||||||
ESP_LOGI(GATTS_TABLE_TAG, "pair status = %s",param->ble_security.auth_cmpl.success ? "success" : "fail");
|
ESP_LOGI(GATTS_TABLE_TAG, "pair status = %s",param->ble_security.auth_cmpl.success ? "success" : "fail");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT: {
|
||||||
|
ESP_LOGD(GATTS_TABLE_TAG, "ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT status = %d", param->remove_bond_dev_cmpl.status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT: {
|
||||||
|
ESP_LOGD(GATTS_TABLE_TAG, "ESP_GAP_BLE_CLEAR_BOND_DEV_COMPLETE_EVT status = %d", param->clear_bond_dev_cmpl.status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT: {
|
||||||
|
ESP_LOGD(GATTS_TABLE_TAG, "ESP_GAP_BLE_GET_BOND_DEV_COMPLETE_EVT status = %d, num = %d", param->get_bond_dev_cmpl.status, param->get_bond_dev_cmpl.dev_num);
|
||||||
|
esp_ble_bond_dev_t *bond_dev = param->get_bond_dev_cmpl.bond_dev;
|
||||||
|
for(int i = 0; i < param->get_bond_dev_cmpl.dev_num; i++) {
|
||||||
|
ESP_LOGD(GATTS_TABLE_TAG, "mask = %x", bond_dev[i].bond_key.key_mask);
|
||||||
|
esp_log_buffer_hex(GATTS_TABLE_TAG, (void *)bond_dev[i].bd_addr, sizeof(esp_bd_addr_t));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user