mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
feat(ble_audio): Add CAP Handover (U2B & B2U) example
This commit is contained in:
@@ -571,7 +571,17 @@ esp_err_t esp_ble_iso_chan_send_ts(esp_ble_iso_chan_t *chan,
|
||||
#define ESP_BLE_ISO_GAP_EVENT_SECURITY_CHANGE BT_LE_GAP_APP_EVENT_SECURITY_CHANGE
|
||||
/*!< ISO GAP BIGInfo Adv Report event */
|
||||
#define ESP_BLE_ISO_GAP_EVENT_BIGINFO_RECV BT_LE_GAP_APP_EVENT_BIGINFO_RECV
|
||||
/** ISO GAP application event structure */
|
||||
/**
|
||||
* @brief ISO GAP application event structure
|
||||
*
|
||||
* @note Addresses carried by these events are in the **active host's own byte
|
||||
* order**: on-air/LSB-first under NimBLE, MSB-first under Bluedroid
|
||||
* (the order every `esp_ble_gap_*` API takes). Feeding one straight back
|
||||
* to a host API is therefore always correct; comparing one against an
|
||||
* address the audio layer holds, such as a Broadcast Receive State,
|
||||
* needs a reversal under Bluedroid. See `struct bt_le_addr` in
|
||||
* common/app/gap.h for the full convention.
|
||||
*/
|
||||
typedef struct bt_le_gap_app_event esp_ble_iso_gap_app_event_t;
|
||||
|
||||
/** ISO initialization information structure */
|
||||
|
||||
@@ -1881,7 +1881,7 @@ static void handle_gattc_notify_event(struct bt_le_gattc_notify_rx_event *event)
|
||||
* tearing down a core subscription like the ASCS control point
|
||||
* over one bad PDU would drop every later notification. Tolerate
|
||||
* the bad PDU and keep the subscription. */
|
||||
params->notify(conn, params, event->value, event->len);
|
||||
params->notify(conn, params, NOTIFY_VALUE(event), event->len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ static void handle_gattc_notify_rx_event_safe(struct bt_le_gattc_notify_rx_event
|
||||
* tearing down a core subscription like the ASCS control point
|
||||
* over one bad PDU would drop every later notification. Tolerate
|
||||
* the bad PDU and keep the subscription. */
|
||||
params->notify(conn, params, event->value, event->len);
|
||||
params->notify(conn, params, NOTIFY_VALUE(event), event->len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,7 @@ static struct bt_le_ext_adv *ext_adv_find(uint8_t adv_handle)
|
||||
struct bt_le_ext_adv *adv = NULL;
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(ext_adv_pool); i++) {
|
||||
if (atomic_test_bit(ext_adv_pool[i].flags,
|
||||
BT_PER_ADV_PARAMS_SET) &&
|
||||
if (atomic_test_bit(ext_adv_pool[i].flags, BT_PER_ADV_PARAMS_SET) &&
|
||||
ext_adv_pool[i].handle == adv_handle) {
|
||||
LOG_DBG("ExtAdvFound[%u][%u]", i, adv_handle);
|
||||
adv = &ext_adv_pool[i];
|
||||
@@ -44,8 +43,7 @@ static struct bt_le_ext_adv *ext_adv_new(void)
|
||||
struct bt_le_ext_adv *adv = NULL;
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(ext_adv_pool); i++) {
|
||||
if (atomic_test_bit(ext_adv_pool[i].flags,
|
||||
BT_PER_ADV_PARAMS_SET) == false) {
|
||||
if (atomic_test_bit(ext_adv_pool[i].flags, BT_PER_ADV_PARAMS_SET) == false) {
|
||||
adv = &ext_adv_pool[i];
|
||||
|
||||
memset(adv, 0, sizeof(*adv));
|
||||
@@ -160,3 +158,23 @@ int bt_le_ext_adv_get_info(const struct bt_le_ext_adv *adv,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_LIB_ONLY
|
||||
struct bt_le_ext_adv *bt_le_ext_adv_lookup_addr(const bt_addr_le_t *adv_addr, uint8_t sid)
|
||||
{
|
||||
struct bt_le_ext_adv *adv = NULL;
|
||||
|
||||
BT_LE_ASSERT(adv_addr);
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(ext_adv_pool); i++) {
|
||||
if (atomic_test_bit(ext_adv_pool[i].flags, BT_PER_ADV_PARAMS_SET) &&
|
||||
bt_addr_le_eq(&ext_adv_pool[i].addr, adv_addr) &&
|
||||
ext_adv_pool[i].sid == sid) {
|
||||
LOG_INF("ExtAdvLookupAddrFound[%u][%u]", i, sid);
|
||||
adv = &ext_adv_pool[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return adv;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,30 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Byte order of `val` is the active host's, NOT a single fixed convention:
|
||||
*
|
||||
* NimBLE on-air / LSB-first, val[0] is the least significant octet.
|
||||
* Bluedroid MSB-first, val[0] is the most significant octet - the order
|
||||
* esp_bd_addr_t uses and the order every esp_ble_gap_* API expects.
|
||||
*
|
||||
* That is deliberate: an address delivered by an event is normally handed
|
||||
* straight back to the same host's API (create sync, connect, disconnect), so
|
||||
* leaving it untouched keeps those paths correct on both hosts.
|
||||
*
|
||||
* The cost is that `bt_addr_le_t` in this port does not mean one thing either.
|
||||
* On Bluedroid its contents follow whichever path filled it:
|
||||
*
|
||||
* conn->le.dst MSB - stored verbatim from the connect event and
|
||||
* passed back to BTA_GATTC_* unchanged.
|
||||
* bt_bond_info.addr MSB - read from the Bluedroid bond store as is.
|
||||
* per_adv_sync->addr LSB - bt_le_per_adv_sync_new() reverses it, because
|
||||
* it is compared against addresses off the air.
|
||||
* BASS recv_state->addr LSB - arrives over ATT, where BASS defines LSB-first.
|
||||
*
|
||||
* So an application only has to convert where the two meet: comparing an event
|
||||
* address against one the audio layer holds (a Broadcast Receive State, say)
|
||||
* needs a reversal under CONFIG_BT_BLUEDROID_ENABLED and none under NimBLE.
|
||||
*/
|
||||
struct bt_le_addr {
|
||||
uint8_t type;
|
||||
uint8_t val[6];
|
||||
|
||||
@@ -72,6 +72,15 @@ struct bt_le_gattc_notify_rx_event {
|
||||
uint8_t *value;
|
||||
};
|
||||
|
||||
/* Neither adapter allocates a buffer for a zero-length notification, but NULL data is
|
||||
* how gatt.c completes an unsubscribe: a lib notify handler that sees it drops its
|
||||
* subscription. A zero-length notification is a real PDU (BASS sends one for an emptied
|
||||
* Broadcast Receive State), so keep the pointer non-NULL when handing it to the lib.
|
||||
*/
|
||||
#define NOTIFY_VALUE(_event) \
|
||||
((const void *)((_event)->value != NULL ? (const uint8_t *)(_event)->value \
|
||||
: (const uint8_t *)""))
|
||||
|
||||
struct bt_le_gatts_notify_tx_event {
|
||||
bool is_notify;
|
||||
uint16_t conn_handle;
|
||||
|
||||
@@ -406,6 +406,16 @@ int bt_le_per_adv_sync_get_info(struct bt_le_per_adv_sync *per_adv_sync,
|
||||
struct bt_le_per_adv_sync *bt_le_per_adv_sync_lookup_addr(const bt_addr_le_t *adv_addr,
|
||||
uint8_t sid);
|
||||
|
||||
/**
|
||||
* @brief Look up a local extended advertising set by advertiser address.
|
||||
*
|
||||
* @param adv_addr Advertiser address.
|
||||
* @param sid The advertising set ID.
|
||||
*
|
||||
* @return Extended advertising set object or NULL if not found.
|
||||
*/
|
||||
struct bt_le_ext_adv *bt_le_ext_adv_lookup_addr(const bt_addr_le_t *adv_addr, uint8_t sid);
|
||||
|
||||
/**
|
||||
* @brief Register periodic advertising sync callbacks.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user