mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
Merge branch 'idf/ble_audio_cap_handover' into 'master'
feat(ble_audio): Add CAP Handover (U2B & B2U) example See merge request espressif/esp-idf!52061
This commit is contained in:
@@ -102,7 +102,17 @@ esp_err_t esp_ble_audio_gattc_disc_start(uint16_t conn_handle);
|
||||
#define ESP_BLE_AUDIO_GAP_EVENT_ACL_DISCONNECT BT_LE_GAP_APP_EVENT_ACL_DISCONNECT
|
||||
/*!< Audio GAP Security Change event */
|
||||
#define ESP_BLE_AUDIO_GAP_EVENT_SECURITY_CHANGE BT_LE_GAP_APP_EVENT_SECURITY_CHANGE
|
||||
/** Audio GAP application event structure */
|
||||
/**
|
||||
* @brief Audio 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_audio_gap_app_event_t;
|
||||
|
||||
/*!< Audio GATT MTU exchange complete event */
|
||||
|
||||
@@ -185,7 +185,7 @@ static const uint16_t ext_structs[] = {
|
||||
sizeof(struct bt_bond_info),
|
||||
};
|
||||
|
||||
#define LEA_VERSION (0x20260824)
|
||||
#define LEA_VERSION (0x20260828)
|
||||
|
||||
struct lib_ext_cfgs {
|
||||
/* BLE */
|
||||
|
||||
@@ -1976,7 +1976,8 @@ struct bt_bap_unicast_client_cb {
|
||||
* @param dir The type of remote endpoints and capabilities discovered.
|
||||
* @param codec_cap Remote capabilities.
|
||||
*
|
||||
* If discovery procedure has complete both @p codec and @p ep are set to NULL.
|
||||
* Called once per record; the end of the procedure is reported by the
|
||||
* discover callback below, not by a NULL @p codec_cap.
|
||||
*/
|
||||
void (*pac_record)(struct bt_conn *conn, enum bt_audio_dir dir,
|
||||
const struct bt_audio_codec_cap *codec_cap);
|
||||
@@ -1990,21 +1991,21 @@ struct bt_bap_unicast_client_cb {
|
||||
* @param dir The type of remote endpoints and capabilities discovered.
|
||||
* @param ep Remote endpoint.
|
||||
*
|
||||
* If discovery procedure has complete both @p codec and @p ep are set to NULL.
|
||||
* Called once per endpoint; the end of the procedure is reported by the
|
||||
* discover callback below, not by a NULL @p ep.
|
||||
*/
|
||||
void (*endpoint)(struct bt_conn *conn, enum bt_audio_dir dir, struct bt_bap_ep *ep);
|
||||
|
||||
/**
|
||||
* @brief BAP discovery callback function.
|
||||
*
|
||||
* If discovery procedure has completed @p ep is set to NULL and @p err is 0.
|
||||
* Called once the discovery procedure has completed, for the direction it
|
||||
* covered.
|
||||
*
|
||||
* @param conn Connection to the remote unicast server.
|
||||
* @param err Error value. 0 on success, GATT error on positive value or errno on
|
||||
* negative value.
|
||||
* @param dir The type of remote endpoints and capabilities discovered.
|
||||
*
|
||||
* If discovery procedure has complete both @p codec and @p ep are set to NULL.
|
||||
*/
|
||||
void (*discover)(struct bt_conn *conn, int err, enum bt_audio_dir dir);
|
||||
|
||||
|
||||
@@ -996,19 +996,21 @@ struct bt_cap_handover_broadcast_to_unicast_param {
|
||||
|
||||
/** @brief Broadcast ID of the @p broadcast_source
|
||||
*
|
||||
* Ignored if @p reception_stop_param is not NULL.
|
||||
* Always required: receive state notifications are matched against the
|
||||
* {broadcast_id, adv_sid, adv_type} triple to decide that reception stopped,
|
||||
* whether or not @p reception_stop_param is given.
|
||||
*/
|
||||
uint32_t broadcast_id;
|
||||
|
||||
/** @brief Advertising set ID of the @p broadcast_source
|
||||
*
|
||||
* Ignored if @p reception_stop_param is not NULL.
|
||||
* Always required, see @p broadcast_id.
|
||||
*/
|
||||
uint8_t adv_sid;
|
||||
|
||||
/** @brief Advertising type of the advertising address of @p broadcast_source
|
||||
*
|
||||
* Ignored if @p reception_stop_param is not NULL.
|
||||
* Always required, see @p broadcast_id.
|
||||
*/
|
||||
uint8_t adv_type;
|
||||
|
||||
|
||||
Submodule components/bt/esp_ble_audio/lib/lib updated: 3565467bac...f53091ee14
@@ -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