mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
fix(ble_audio): Miscellaneous fixes for running coordinated set
This commit is contained in:
@@ -28,11 +28,6 @@ static esp_bt_status_t scan_op_status;
|
||||
|
||||
#define WAIT_API(_call) EXAMPLE_WAIT_API_CHECK(_call, scan_sem, portMAX_DELAY, scan_op_status)
|
||||
|
||||
/* Cached peer address. Bluedroid's pairing and disconnect APIs key off
|
||||
* bd_addr rather than conn_handle, so we stash the addr at conn_create
|
||||
* time and reuse it in pairing_start / security_failed_recover. */
|
||||
static esp_bd_addr_t peer_bda;
|
||||
|
||||
static esp_ble_ext_scan_params_t ext_scan_params = {
|
||||
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
|
||||
.filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
|
||||
@@ -138,6 +133,9 @@ int conn_create(uint8_t addr_type, const uint8_t addr[6])
|
||||
esp_gatt_if_t gattc_if;
|
||||
esp_err_t err;
|
||||
|
||||
esp_bd_addr_t peer_bda;
|
||||
|
||||
/* Local copy: the Bluedroid APIs below take a non-const esp_bd_addr_t. */
|
||||
memcpy(peer_bda, addr, sizeof(peer_bda));
|
||||
|
||||
err = esp_ble_gap_prefer_ext_connect_params_set(
|
||||
@@ -165,8 +163,14 @@ int conn_create(uint8_t addr_type, const uint8_t addr[6])
|
||||
|
||||
int pairing_start(uint16_t conn_handle)
|
||||
{
|
||||
(void)conn_handle;
|
||||
return esp_ble_set_encryption(peer_bda, ESP_BLE_SEC_ENCRYPT_NO_MITM);
|
||||
const uint8_t *addr = set_member_addr(conn_handle);
|
||||
|
||||
if (addr == NULL) {
|
||||
ESP_LOGE(TAG, "No address for handle %u; not starting security", conn_handle);
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
return esp_ble_set_encryption((uint8_t *)addr, ESP_BLE_SEC_ENCRYPT_NO_MITM);
|
||||
}
|
||||
|
||||
int exchange_mtu(uint16_t conn_handle)
|
||||
@@ -181,13 +185,20 @@ int exchange_mtu(uint16_t conn_handle)
|
||||
|
||||
void security_failed_recover(uint16_t conn_handle, uint8_t status)
|
||||
{
|
||||
(void)conn_handle;
|
||||
const uint8_t *addr = set_member_addr(conn_handle);
|
||||
|
||||
if (addr == NULL) {
|
||||
ESP_LOGE(TAG, "Security change failed on handle %u, status %u; member already gone",
|
||||
conn_handle, status);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Asymmetric bond state: we still hold an LTK for this peer but it
|
||||
* cleared its side, so encrypt-with-cached-key times out. Drop the bond
|
||||
* and tear down the link; the next reconnect runs fresh pairing. */
|
||||
ESP_LOGE(TAG, "Security change failed, status %u, clearing local bond and reconnecting", status);
|
||||
ESP_LOGE(TAG, "Security change failed on handle %u, status %u, clearing local bond and reconnecting",
|
||||
conn_handle, status);
|
||||
|
||||
esp_ble_remove_bond_device(peer_bda);
|
||||
esp_ble_gap_disconnect(peer_bda);
|
||||
esp_ble_remove_bond_device((uint8_t *)addr);
|
||||
esp_ble_gap_disconnect((uint8_t *)addr);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,12 @@ struct set_member {
|
||||
static struct set_member members[TMAP_CEN_PEER_COUNT];
|
||||
static size_t member_count;
|
||||
|
||||
/* One connect at a time. members[] only learns a peer at acl_connect, and
|
||||
* ext_scan_stop() does not discard reports already queued for us, so without
|
||||
* this a second report starts an overlapping conn_create that the stack
|
||||
* rejects ("L2CAP - LE - cannot start new connection at conn st: 1"). */
|
||||
static bool conn_pending;
|
||||
|
||||
/* Lock state: pending until the callback, held until stream setup completes. */
|
||||
static bool lock_pending;
|
||||
static bool set_locked;
|
||||
@@ -41,6 +47,17 @@ uint16_t set_member_handle(size_t index)
|
||||
return (index < member_count) ? members[index].handle : CONN_HANDLE_INIT;
|
||||
}
|
||||
|
||||
const uint8_t *set_member_addr(uint16_t conn_handle)
|
||||
{
|
||||
for (size_t i = 0; i < member_count; i++) {
|
||||
if (members[i].handle == conn_handle) {
|
||||
return members[i].dst;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct set_member *member_by_handle(uint16_t handle)
|
||||
{
|
||||
for (size_t i = 0; i < member_count; i++) {
|
||||
@@ -196,7 +213,7 @@ static void ext_scan_recv(esp_ble_audio_gap_app_event_t *event)
|
||||
struct adv_match match = {0};
|
||||
int err;
|
||||
|
||||
if (member_count >= ARRAY_SIZE(members)) {
|
||||
if (member_count >= ARRAY_SIZE(members) || conn_pending) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -235,15 +252,21 @@ static void ext_scan_recv(esp_ble_audio_gap_app_event_t *event)
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "Failed to create conn, err %d", err);
|
||||
ext_scan_start();
|
||||
return;
|
||||
}
|
||||
|
||||
conn_pending = true;
|
||||
}
|
||||
|
||||
static void acl_connect(esp_ble_audio_gap_app_event_t *event)
|
||||
{
|
||||
int err;
|
||||
|
||||
conn_pending = false;
|
||||
|
||||
if (event->acl_connect.status) {
|
||||
ESP_LOGE(TAG, "Connection failed, status %d", event->acl_connect.status);
|
||||
ext_scan_start();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,6 +93,8 @@ size_t set_member_count(void);
|
||||
|
||||
uint16_t set_member_handle(size_t index);
|
||||
|
||||
const uint8_t *set_member_addr(uint16_t conn_handle);
|
||||
|
||||
void set_member_discovered(uint16_t conn_handle, int err);
|
||||
|
||||
void set_lock_complete(int err);
|
||||
|
||||
Reference in New Issue
Block a user