fix(ble_audio): Miscellaneous fixes for running coordinated set

This commit is contained in:
Liu Linyan
2026-09-04 09:26:24 +08:00
parent cd0572bbb6
commit 1aa418d673
7 changed files with 178 additions and 71 deletions
@@ -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);