Skip to content

Commit

Permalink
Merge branch 'bugfix/fix_some_ble_bugs_cjh_v5.2' into 'release/v5.2'
Browse files Browse the repository at this point in the history
Fixed some BLE bugs 240620 (backport v5.2)

See merge request espressif/esp-idf!31647
  • Loading branch information
Isl2017 committed Jun 26, 2024
2 parents 293f868 + ba4a43e commit 1491b57
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 107 deletions.
92 changes: 54 additions & 38 deletions components/bt/controller/esp32c3/bt.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ do{\
} while(0)

#define OSI_FUNCS_TIME_BLOCKING 0xffffffff
#define OSI_VERSION 0x00010008
#define OSI_VERSION 0x00010009
#define OSI_MAGIC_VALUE 0xFADEBEAD

/* Types definition
Expand All @@ -138,15 +138,24 @@ typedef struct {

typedef void (* osi_intr_handler)(void);

typedef struct {
int source; /*!< ISR source */
int flags; /*!< ISR alloc flag */
void (*fn)(void *); /*!< ISR function */
void *arg; /*!< ISR function args*/
intr_handle_t *handle; /*!< ISR handle */
esp_err_t ret;
} btdm_isr_alloc_t;

/* OSI function */
struct osi_funcs_t {
uint32_t _magic;
uint32_t _version;
void (*_interrupt_set)(int cpu_no, int intr_source, int interrupt_no, int interrpt_prio);
void (*_interrupt_clear)(int interrupt_source, int interrupt_no);
void (*_interrupt_handler_set)(int interrupt_no, intr_handler_t fn, void *arg);
void (*_interrupt_disable)(void);
void (*_interrupt_restore)(void);
int (* _interrupt_alloc)(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle);
int (* _interrupt_free)(void *handle);
void (*_interrupt_handler_set_rsv)(int interrupt_no, intr_handler_t fn, void *arg);
void (*_global_intr_disable)(void);
void (*_global_intr_restore)(void);
void (*_task_yield)(void);
void (*_task_yield_from_isr)(void);
void *(*_semphr_create)(uint32_t max, uint32_t init);
Expand Down Expand Up @@ -191,8 +200,8 @@ struct osi_funcs_t {
uint32_t (* _coex_schm_interval_get)(void);
uint8_t (* _coex_schm_curr_period_get)(void);
void *(* _coex_schm_curr_phase_get)(void);
void (* _interrupt_on)(int intr_num);
void (* _interrupt_off)(int intr_num);
int (* _interrupt_enable)(void *handle);
int (* _interrupt_disable)(void *handle);
void (* _esp_hw_power_down)(void);
void (* _esp_hw_power_up)(void);
void (* _ets_backup_dma_copy)(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_rem);
Expand Down Expand Up @@ -273,11 +282,10 @@ extern uint32_t _bt_controller_data_end;
/* Local Function Declare
*********************************************************************
*/
static void interrupt_set_wrapper(int cpu_no, int intr_source, int intr_num, int intr_prio);
static void interrupt_clear_wrapper(int intr_source, int intr_num);
static void interrupt_handler_set_wrapper(int n, intr_handler_t fn, void *arg);
static void interrupt_disable(void);
static void interrupt_restore(void);
static int interrupt_alloc_wrapper(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle);
static int interrupt_free_wrapper(void *handle);
static void global_interrupt_disable(void);
static void global_interrupt_restore(void);
static void task_yield_from_isr(void);
static void *semphr_create_wrapper(uint32_t max, uint32_t init);
static void semphr_delete_wrapper(void *semphr);
Expand Down Expand Up @@ -315,8 +323,8 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status);
static uint32_t coex_schm_interval_get_wrapper(void);
static uint8_t coex_schm_curr_period_get_wrapper(void);
static void * coex_schm_curr_phase_get_wrapper(void);
static void interrupt_on_wrapper(int intr_num);
static void interrupt_off_wrapper(int intr_num);
static int interrupt_enable_wrapper(void *handle);
static int interrupt_disable_wrapper(void *handle);
static void btdm_hw_mac_power_up_wrapper(void);
static void btdm_hw_mac_power_down_wrapper(void);
static void btdm_backup_dma_copy_wrapper(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem);
Expand All @@ -337,11 +345,11 @@ static void bt_controller_deinit_internal(void);
static const struct osi_funcs_t osi_funcs_ro = {
._magic = OSI_MAGIC_VALUE,
._version = OSI_VERSION,
._interrupt_set = interrupt_set_wrapper,
._interrupt_clear = interrupt_clear_wrapper,
._interrupt_handler_set = interrupt_handler_set_wrapper,
._interrupt_disable = interrupt_disable,
._interrupt_restore = interrupt_restore,
._interrupt_alloc = interrupt_alloc_wrapper,
._interrupt_free = interrupt_free_wrapper,
._interrupt_handler_set_rsv = NULL,
._global_intr_disable = global_interrupt_disable,
._global_intr_restore = global_interrupt_restore,
._task_yield = vPortYield,
._task_yield_from_isr = task_yield_from_isr,
._semphr_create = semphr_create_wrapper,
Expand Down Expand Up @@ -386,8 +394,8 @@ static const struct osi_funcs_t osi_funcs_ro = {
._coex_schm_interval_get = coex_schm_interval_get_wrapper,
._coex_schm_curr_period_get = coex_schm_curr_period_get_wrapper,
._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper,
._interrupt_on = interrupt_on_wrapper,
._interrupt_off = interrupt_off_wrapper,
._interrupt_enable = interrupt_enable_wrapper,
._interrupt_disable = interrupt_disable_wrapper,
._esp_hw_power_down = btdm_hw_mac_power_down_wrapper,
._esp_hw_power_up = btdm_hw_mac_power_up_wrapper,
._ets_backup_dma_copy = btdm_backup_dma_copy_wrapper,
Expand Down Expand Up @@ -474,36 +482,44 @@ static inline void esp_bt_power_domain_off(void)
esp_wifi_bt_power_domain_off();
}

static void interrupt_set_wrapper(int cpu_no, int intr_source, int intr_num, int intr_prio)
static void btdm_intr_alloc(void *arg)
{
esp_rom_route_intr_matrix(cpu_no, intr_source, intr_num);
#if __riscv
esprv_intc_int_set_priority(intr_num, intr_prio);
//esprv_intc_int_enable_level(1 << intr_num);
esprv_intc_int_set_type(intr_num, 0);
#endif
btdm_isr_alloc_t *p = arg;
p->ret = esp_intr_alloc(p->source, p->flags, p->fn, p->arg, p->handle);
}

static void interrupt_clear_wrapper(int intr_source, int intr_num)
static int interrupt_alloc_wrapper(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle)
{
btdm_isr_alloc_t p;
p.source = source;
p.flags = ESP_INTR_FLAG_LEVEL3 | ESP_INTR_FLAG_IRAM;
p.fn = handler;
p.arg = arg;
p.handle = (intr_handle_t *)ret_handle;
#if CONFIG_FREERTOS_UNICORE
btdm_intr_alloc(&p);
#else
esp_ipc_call_blocking(cpu_id, btdm_intr_alloc, &p);
#endif
return p.ret;
}

static void interrupt_handler_set_wrapper(int n, intr_handler_t fn, void *arg)
static int interrupt_free_wrapper(void *handle)
{
esp_cpu_intr_set_handler(n, fn, arg);
return esp_intr_free((intr_handle_t)handle);
}

static void interrupt_on_wrapper(int intr_num)
static int interrupt_enable_wrapper(void *handle)
{
esp_cpu_intr_enable(1 << intr_num);
return esp_intr_enable((intr_handle_t)handle);
}

static void interrupt_off_wrapper(int intr_num)
static int interrupt_disable_wrapper(void *handle)
{
esp_cpu_intr_disable(1<<intr_num);
return esp_intr_disable((intr_handle_t)handle);
}

static void IRAM_ATTR interrupt_disable(void)
static void IRAM_ATTR global_interrupt_disable(void)
{
if (xPortInIsrContext()) {
portENTER_CRITICAL_ISR(&global_int_mux);
Expand All @@ -512,7 +528,7 @@ static void IRAM_ATTR interrupt_disable(void)
}
}

static void IRAM_ATTR interrupt_restore(void)
static void IRAM_ATTR global_interrupt_restore(void)
{
if (xPortInIsrContext()) {
portEXIT_CRITICAL_ISR(&global_int_mux);
Expand Down
2 changes: 1 addition & 1 deletion components/bt/controller/lib_esp32c3_family
11 changes: 11 additions & 0 deletions components/bt/host/bluedroid/Kconfig.in
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,17 @@ config BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE
In order to reduce the pairing time, slave actively initiates connection parameters
update during pairing.

config BT_BLE_SMP_ID_RESET_ENABLE
bool "Reset device identity when all bonding records are deleted"
depends on BT_BLE_SMP_ENABLE
default n
help
There are tracking risks associated with using a fixed or static IRK.
If enabled this option, Bluedroid will assign a new randomly-generated IRK
when all pairing and bonding records are deleted. This would decrease the ability
of a previously paired peer to be used to determine whether a device
with which it previously shared an IRK is within range.

config BT_STACK_NO_LOG
bool "Disable BT debug logs (minimize bin size)"
depends on BT_BLUEDROID_ENABLED
Expand Down
54 changes: 44 additions & 10 deletions components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -661,21 +661,55 @@ typedef struct {
esp_bt_octet16_t oob_r; /*!< the 128 bits of randomizer value */
} esp_ble_local_oob_data_t;

/**
* @brief Definition of the authentication failed reason
*/
typedef enum {
// Failure reason defined in Bluetooth Core Spec 5.0 Vol3, Part H, 3.5.5
ESP_AUTH_SMP_PASSKEY_FAIL = 78, /*!< The user input of passkey failed */
ESP_AUTH_SMP_OOB_FAIL, /*!< The OOB data is not available */
ESP_AUTH_SMP_PAIR_AUTH_FAIL, /*!< The authentication requirements cannot be met */
ESP_AUTH_SMP_CONFIRM_VALUE_FAIL, /*!< The confirm value does not match the calculated comparison value */
ESP_AUTH_SMP_PAIR_NOT_SUPPORT, /*!< Pairing is not supported by the device */
ESP_AUTH_SMP_ENC_KEY_SIZE, /*!< The resultant encryption key size is not long enough */
ESP_AUTH_SMP_INVALID_CMD, /*!< The SMP command received is not supported by this device */
ESP_AUTH_SMP_UNKNOWN_ERR, /*!< Pairing failed due to an unspecified reason */
ESP_AUTH_SMP_REPEATED_ATTEMPT, /*!< Pairing or authentication procedure is disallowed */
ESP_AUTH_SMP_INVALID_PARAMETERS, /*!< The command length is invalid or that a parameter is outside the specified range */
ESP_AUTH_SMP_DHKEY_CHK_FAIL, /*!< The DHKey Check value received doesn’t match the one calculated by the local device */
ESP_AUTH_SMP_NUM_COMP_FAIL, /*!< The confirm values in the numeric comparison protocol do not match */
ESP_AUTH_SMP_BR_PARING_IN_PROGR, /*!< Pairing Request sent over the BR/EDR transport is in progress */
ESP_AUTH_SMP_XTRANS_DERIVE_NOT_ALLOW, /*!< The BR/EDR Link Key or BLE LTK cannot be used to derive */

// Failure reason defined in Bluedroid Host
ESP_AUTH_SMP_INTERNAL_ERR, /*!< Internal error in pairing procedure */
ESP_AUTH_SMP_UNKNOWN_IO, /*!< Unknown IO capability, unable to decide association model */
ESP_AUTH_SMP_INIT_FAIL, /*!< SMP pairing initiation failed */
ESP_AUTH_SMP_CONFIRM_FAIL, /*!< The confirm value does not match */
ESP_AUTH_SMP_BUSY, /*!< Pending security request on going */
ESP_AUTH_SMP_ENC_FAIL, /*!< The Controller failed to start encryption */
ESP_AUTH_SMP_STARTED, /*!< SMP pairing process started */
ESP_AUTH_SMP_RSP_TIMEOUT, /*!< Security Manager timeout due to no SMP command being received */
ESP_AUTH_SMP_DIV_NOT_AVAIL, /*!< Encrypted Diversifier value not available */
ESP_AUTH_SMP_UNSPEC_ERR, /*!< Unspecified failed reason */
ESP_AUTH_SMP_CONN_TOUT, /*!< Pairing process failed due to connection timeout */
} esp_ble_auth_fail_rsn_t;

/**
* @brief Structure associated with ESP_AUTH_CMPL_EVT
*/
typedef struct
{
esp_bd_addr_t bd_addr; /*!< BD address peer device. */
bool key_present; /*!< Valid link key value in key element */
esp_link_key key; /*!< Link key associated with peer device. */
uint8_t key_type; /*!< The type of Link Key */
bool success; /*!< TRUE of authentication succeeded, FALSE if failed. */
uint8_t fail_reason; /*!< The HCI reason/error code for when success=FALSE */
esp_ble_addr_type_t addr_type; /*!< Peer device address type */
esp_bt_dev_type_t dev_type; /*!< Device type */
esp_ble_auth_req_t auth_mode; /*!< authentication mode */
} esp_ble_auth_cmpl_t; /*!< The ble authentication complete cb type */
esp_bd_addr_t bd_addr; /*!< BD address of peer device */
bool key_present; /*!< True if the link key value is valid; false otherwise */
esp_link_key key; /*!< Link key associated with peer device */
uint8_t key_type; /*!< The type of link key */
bool success; /*!< True if authentication succeeded; false otherwise */
esp_ble_auth_fail_rsn_t fail_reason; /*!< The HCI reason/error code for failure when success is false */
esp_ble_addr_type_t addr_type; /*!< Peer device address type */
esp_bt_dev_type_t dev_type; /*!< Device type */
esp_ble_auth_req_t auth_mode; /*!< Authentication mode */
} esp_ble_auth_cmpl_t; /*!< The ble authentication complete cb type */

/**
* @brief union associated with ble security
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,13 @@
#define UC_BT_SMP_MAX_BONDS 8
#endif

//Device Nane Maximum Length
#ifdef CONFIG_BT_BLE_SMP_ID_RESET_ENABLE
#define UC_BT_BLE_SMP_ID_RESET_ENABLE CONFIG_BT_BLE_SMP_ID_RESET_ENABLE
#else
#define UC_BT_BLE_SMP_ID_RESET_ENABLE FALSE
#endif

//Device Name Maximum Length
#ifdef CONFIG_BT_MAX_DEVICE_NAME_LEN
#define UC_MAX_LOC_BD_NAME_LEN CONFIG_BT_MAX_DEVICE_NAME_LEN
#else
Expand Down
10 changes: 8 additions & 2 deletions components/bt/host/bluedroid/common/include/common/bt_target.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,12 @@
#define SMP_SLAVE_CON_PARAMS_UPD_ENABLE FALSE
#endif /* UC_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE */

#if (UC_BT_BLE_SMP_ID_RESET_ENABLE)
#define BLE_SMP_ID_RESET_ENABLE TRUE
#else
#define BLE_SMP_ID_RESET_ENABLE FALSE
#endif

#ifdef UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP
#define BLE_ADV_REPORT_FLOW_CONTROL (UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP && BLE_INCLUDED)
#endif /* UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP */
Expand Down Expand Up @@ -564,7 +570,7 @@
#define BT_CLASSIC_BQB_INCLUDED FALSE
#endif

/* This feature is used to eanble interleaved scan*/
/* This feature is used to enable interleaved scan*/
#ifndef BTA_HOST_INTERLEAVE_SEARCH
#define BTA_HOST_INTERLEAVE_SEARCH FALSE
#endif
Expand Down Expand Up @@ -1380,7 +1386,7 @@
#define GATT_CONFORMANCE_TESTING FALSE
#endif

/* number of background connection device allowence, ideally to be the same as WL size
/* number of background connection device allowance, ideally to be the same as WL size
*/
#ifndef GATT_MAX_BG_CONN_DEV
#define GATT_MAX_BG_CONN_DEV 8 /*MAX is 32*/
Expand Down
5 changes: 4 additions & 1 deletion components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len)
BTM_TRACE_DEBUG("%s status = %d", __func__, status);

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

Expand Down Expand Up @@ -1147,6 +1147,9 @@ void btm_ble_add_default_entry_to_resolving_list(void)
BD_ADDR peer_addr = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
BT_OCTET16 peer_irk = {0x0};

// Remove the existing entry in resolving list When resetting the device identity
btsnd_hcic_ble_rm_device_resolving_list(BLE_ADDR_PUBLIC, peer_addr);

btsnd_hcic_ble_add_device_resolving_list (BLE_ADDR_PUBLIC, peer_addr, peer_irk, btm_cb.devcb.id_keys.irk);
}
#endif
27 changes: 19 additions & 8 deletions components/bt/host/bluedroid/stack/btm/btm_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,20 +179,31 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
*******************************************************************************/
BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr, tBT_TRANSPORT transport)
{

tBTM_SEC_DEV_REC *p_dev_rec;

if (BTM_IsAclConnectionUp(bd_addr, transport)) {
BTM_TRACE_WARNING("%s FAILED: Cannot Delete when connection is active\n", __func__);
return FALSE;
}

if ((p_dev_rec = btm_find_dev(bd_addr)) != NULL) {
/* Tell controller to get rid of the link key, if it has one stored */
BTM_DeleteStoredLinkKey (p_dev_rec->bd_addr, NULL);

btm_sec_free_dev(p_dev_rec, transport);
btm_sec_free_dev(p_dev_rec, transport);
}

#if (BLE_SMP_ID_RESET_ENABLE == TRUE)
/*
* There are tracking risks associated with using a fixed or static IRK.
* A best-practices approach, when all pairing and bonding records are deleted,
* assign a new randomly-generated IRK.
*/
if (list_is_empty(btm_cb.p_sec_dev_rec_list)) {
btm_ble_reset_id();
}
#endif

return TRUE;
}

Expand Down Expand Up @@ -640,7 +651,7 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void)
tBTM_SEC_DEV_REC *p_dev_rec = NULL;
tBTM_SEC_DEV_REC *p_oldest = NULL;
list_node_t *p_node = NULL;
UINT32 ot = 0xFFFFFFFF;
UINT32 old_ts = 0xFFFFFFFF;

/* First look for the non-paired devices for the oldest entry */
for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) {
Expand All @@ -650,13 +661,13 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void)
continue; /* Device is paired so skip it */
}

if (p_dev_rec->timestamp < ot) {
if (p_dev_rec->timestamp < old_ts) {
p_oldest = p_dev_rec;
ot = p_dev_rec->timestamp;
old_ts = p_dev_rec->timestamp;
}
}

if (ot != 0xFFFFFFFF) {
if (old_ts != 0xFFFFFFFF) {
return (p_oldest);
}

Expand All @@ -666,9 +677,9 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void)
continue;
}

if (p_dev_rec->timestamp < ot) {
if (p_dev_rec->timestamp < old_ts) {
p_oldest = p_dev_rec;
ot = p_dev_rec->timestamp;
old_ts = p_dev_rec->timestamp;
}
}
return (p_oldest);
Expand Down
Loading

0 comments on commit 1491b57

Please sign in to comment.