Bluetooth: BAP: Move endpoint discovery to new callback

Add a new endpoint callback that is used to report the found
ASEs during BAP discovery, rather than calling
the discovery callback with optional values.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2023-03-24 11:48:14 +01:00 committed by Carles Cufí
commit 3074c72d79
6 changed files with 112 additions and 142 deletions

View file

@ -1226,6 +1226,19 @@ struct bt_bap_unicast_client_cb {
void (*pac_record)(struct bt_conn *conn, enum bt_audio_dir dir,
const struct bt_codec *codec);
/**
* @brief Remote Audio Stream Endoint (ASE) discovered
*
* Called when an ASE has been discovered as part of the discovery procedure.
*
* @param conn Connection to the remote unicast server.
* @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.
*/
void (*endpoint)(struct bt_conn *conn, enum bt_audio_dir dir, struct bt_bap_ep *ep);
/**
* @brief BAP discovery callback function.
*
@ -1235,12 +1248,10 @@ struct bt_bap_unicast_client_cb {
* @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.
* @param ep Remote endpoint.
*
* 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,
struct bt_bap_ep *ep);
void (*discover)(struct bt_conn *conn, int err, enum bt_audio_dir dir);
};
/**

View file

@ -583,20 +583,13 @@ static void print_remote_codec(const struct bt_codec *codec_capabilities, enum b
print_codec_capabilities(codec_capabilities);
}
static void discover_sinks_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir,
struct bt_bap_ep *ep)
static void discover_sinks_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir)
{
if (err != 0 && err != BT_ATT_ERR_ATTRIBUTE_NOT_FOUND) {
printk("Discovery failed: %d\n", err);
return;
}
if (ep != NULL) {
add_remote_sink(ep);
return;
}
if (err == BT_ATT_ERR_ATTRIBUTE_NOT_FOUND) {
printk("Discover sinks completed without finding any sink ASEs\n");
} else {
@ -606,20 +599,13 @@ static void discover_sinks_cb(struct bt_conn *conn, int err, enum bt_audio_dir d
k_sem_give(&sem_sinks_discovered);
}
static void discover_sources_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir,
struct bt_bap_ep *ep)
static void discover_sources_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir)
{
if (err != 0 && err != BT_ATT_ERR_ATTRIBUTE_NOT_FOUND) {
printk("Discovery failed: %d\n", err);
return;
}
if (ep != NULL) {
add_remote_source(ep);
return;
}
if (err == BT_ATT_ERR_ATTRIBUTE_NOT_FOUND) {
printk("Discover sinks completed without finding any source ASEs\n");
} else {
@ -716,10 +702,20 @@ static void pac_record_cb(struct bt_conn *conn, enum bt_audio_dir dir, const str
print_remote_codec(codec, dir);
}
static void endpoint_cb(struct bt_conn *conn, enum bt_audio_dir dir, struct bt_bap_ep *ep)
{
if (dir == BT_AUDIO_DIR_SOURCE) {
add_remote_source(ep);
} else if (dir == BT_AUDIO_DIR_SINK) {
add_remote_sink(ep);
}
}
static struct bt_bap_unicast_client_cb unicast_client_cbs = {
.location = unicast_client_location_cb,
.available_contexts = available_contexts_cb,
.pac_record = pac_record_cb,
.endpoint = endpoint_cb,
};
static int init(void)

View file

@ -1464,21 +1464,27 @@ static void pac_record_cb(struct bt_conn *conn, const struct bt_codec *codec)
}
}
static void discover_cb(struct bt_conn *conn, int err, struct bt_bap_ep *ep)
static void endpoint_cb(struct bt_conn *conn, struct bt_bap_ep *ep)
{
if (unicast_client_cbs != NULL && unicast_client_cbs->endpoint != NULL) {
struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
const enum bt_audio_dir dir = client->dir;
unicast_client_cbs->endpoint(conn, dir, ep);
}
}
static void discover_cb(struct bt_conn *conn, int err)
{
struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
const enum bt_audio_dir dir = client->dir;
if (err != 0 || ep == NULL) {
/* Discover complete - Reset discovery values */
client->dir = 0U;
client->busy = false;
memset(&client->disc_params, 0, sizeof(client->disc_params));
}
/* Discover complete - Reset discovery values */
client->dir = 0U;
client->busy = false;
if (unicast_client_cbs != NULL && unicast_client_cbs->discover != NULL) {
unicast_client_cbs->discover(conn, err, dir, ep);
unicast_client_cbs->discover(conn, err, dir);
}
}
@ -1488,7 +1494,7 @@ static void unicast_client_cp_sub_cb(struct bt_conn *conn, uint8_t err,
LOG_DBG("conn %p err %u", conn, err);
discover_cb(conn, err, NULL);
discover_cb(conn, err);
}
static void unicast_client_ep_set_cp(struct bt_conn *conn, uint16_t handle)
@ -1533,12 +1539,12 @@ static void unicast_client_ep_set_cp(struct bt_conn *conn, uint16_t handle)
if (err != 0) {
LOG_DBG("Failed to subscribe: %d", err);
discover_cb(conn, BT_ATT_ERR_UNLIKELY, NULL);
discover_cb(conn, BT_ATT_ERR_UNLIKELY);
return;
}
} else { /* already subscribed */
discover_cb(conn, 0, NULL);
discover_cb(conn, 0);
}
}
@ -2850,7 +2856,7 @@ static uint8_t unicast_client_cp_discover_func(struct bt_conn *conn,
if (!attr) {
LOG_ERR("Unable to find ASE Control Point");
discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND, NULL);
discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
return BT_GATT_ITER_STOP;
}
@ -2941,19 +2947,19 @@ static uint8_t unicast_client_ase_read_func(struct bt_conn *conn, uint8_t err,
unicast_client_ep_set_status(ep, buf);
unicast_client_ep_subscribe(conn, ep);
discover_cb(conn, 0, ep);
endpoint_cb(conn, ep);
err = unicast_client_ase_discover(conn, handle);
if (err != 0) {
LOG_DBG("Failed to read ASE: %d", err);
discover_cb(conn, err, NULL);
discover_cb(conn, err);
}
return BT_GATT_ITER_STOP;
fail:
discover_cb(conn, err, NULL);
discover_cb(conn, err);
return BT_GATT_ITER_STOP;
}
@ -2971,7 +2977,7 @@ static uint8_t unicast_client_ase_discover_cb(struct bt_conn *conn,
if (err != 0) {
LOG_ERR("Unable to discover ASE Control Point");
discover_cb(conn, BT_ATT_ERR_UNLIKELY, NULL);
discover_cb(conn, BT_ATT_ERR_UNLIKELY);
}
return BT_GATT_ITER_STOP;
@ -2998,7 +3004,7 @@ static uint8_t unicast_client_ase_discover_cb(struct bt_conn *conn,
if (err != 0) {
LOG_DBG("Failed to read PAC records: %d", err);
discover_cb(conn, err, NULL);
discover_cb(conn, err);
}
return BT_GATT_ITER_STOP;
@ -3045,7 +3051,7 @@ static uint8_t unicast_client_pacs_avail_ctx_read_func(struct bt_conn *conn, uin
err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
}
discover_cb(conn, err, NULL);
discover_cb(conn, err);
return BT_GATT_ITER_STOP;
}
@ -3065,7 +3071,7 @@ static uint8_t unicast_client_pacs_avail_ctx_read_func(struct bt_conn *conn, uin
if (cb_err != 0) {
LOG_ERR("Unable to read ASE: %d", cb_err);
discover_cb(conn, err, NULL);
discover_cb(conn, err);
}
return BT_GATT_ITER_STOP;
@ -3140,7 +3146,7 @@ static uint8_t unicast_client_pacs_avail_ctx_discover_cb(struct bt_conn *conn,
* the characteristic is mandatory
*/
discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND, NULL);
discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
return BT_GATT_ITER_STOP;
}
@ -3176,7 +3182,7 @@ static uint8_t unicast_client_pacs_avail_ctx_discover_cb(struct bt_conn *conn,
/* If the characteristic is not subscribable we terminate the
* discovery as BT_GATT_CHRC_NOTIFY is mandatory
*/
discover_cb(conn, BT_ATT_ERR_NOT_SUPPORTED, NULL);
discover_cb(conn, BT_ATT_ERR_NOT_SUPPORTED);
return BT_GATT_ITER_STOP;
}
@ -3185,7 +3191,7 @@ static uint8_t unicast_client_pacs_avail_ctx_discover_cb(struct bt_conn *conn,
if (err != 0) {
LOG_DBG("Failed to read PACS avail_ctx: %d", err);
discover_cb(conn, err, NULL);
discover_cb(conn, err);
}
return BT_GATT_ITER_STOP;
@ -3229,7 +3235,7 @@ static uint8_t unicast_client_pacs_location_read_func(struct bt_conn *conn, uint
err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
}
discover_cb(conn, err, NULL);
discover_cb(conn, err);
return BT_GATT_ITER_STOP;
}
@ -3248,7 +3254,7 @@ static uint8_t unicast_client_pacs_location_read_func(struct bt_conn *conn, uint
if (cb_err != 0) {
LOG_ERR("Unable to read available contexts: %d", cb_err);
discover_cb(conn, cb_err, NULL);
discover_cb(conn, cb_err);
}
return BT_GATT_ITER_STOP;
@ -3335,7 +3341,7 @@ static uint8_t unicast_client_pacs_location_discover_cb(struct bt_conn *conn,
if (err != 0) {
LOG_ERR("Unable to read available contexts: %d", err);
discover_cb(conn, err, NULL);
discover_cb(conn, err);
}
return BT_GATT_ITER_STOP;
@ -3374,7 +3380,7 @@ static uint8_t unicast_client_pacs_location_discover_cb(struct bt_conn *conn,
if (err != 0) {
LOG_DBG("Failed to read PACS location: %d", err);
discover_cb(conn, err, NULL);
discover_cb(conn, err);
}
return BT_GATT_ITER_STOP;
@ -3430,7 +3436,7 @@ discover_loc:
if (cb_err != 0) {
LOG_ERR("Unable to read PACS location: %d", cb_err);
discover_cb(conn, cb_err, NULL);
discover_cb(conn, cb_err);
}
return BT_GATT_ITER_STOP;
@ -3448,7 +3454,7 @@ static uint8_t unicast_client_pacs_context_discover_cb(struct bt_conn *conn,
if (attr == NULL) {
LOG_ERR("Unable to find %s PAC context", bt_audio_dir_str(client->dir));
discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND, NULL);
discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
return BT_GATT_ITER_STOP;
}
@ -3471,7 +3477,7 @@ static uint8_t unicast_client_pacs_context_discover_cb(struct bt_conn *conn,
if (err != 0) {
LOG_DBG("Failed to read PAC records: %d", err);
discover_cb(conn, err, NULL);
discover_cb(conn, err);
}
return BT_GATT_ITER_STOP;
@ -3627,7 +3633,7 @@ static uint8_t unicast_client_read_func(struct bt_conn *conn, uint8_t err,
return BT_GATT_ITER_STOP;
fail:
discover_cb(conn, cb_err, NULL);
discover_cb(conn, cb_err);
return BT_GATT_ITER_STOP;
}
@ -3643,7 +3649,7 @@ static uint8_t unicast_client_pac_discover_cb(struct bt_conn *conn,
if (attr == NULL) {
LOG_ERR("Unable to find %s PAC", bt_audio_dir_str(client->dir));
discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND, NULL);
discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
return BT_GATT_ITER_STOP;
}
@ -3669,7 +3675,7 @@ static uint8_t unicast_client_pac_discover_cb(struct bt_conn *conn,
if (err != 0) {
LOG_DBG("Failed to read PAC records: %d", err);
discover_cb(conn, err, NULL);
discover_cb(conn, err);
}
return BT_GATT_ITER_STOP;

View file

@ -752,47 +752,28 @@ static void pac_record_cb(struct bt_conn *conn, enum bt_audio_dir dir, const str
print_remote_codec(conn, codec, dir);
}
static void discover_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir, struct bt_bap_ep *ep)
static void endpoint_cb(struct bt_conn *conn, enum bt_audio_dir dir, struct bt_bap_ep *ep)
{
if (ep) {
#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
if (dir == BT_AUDIO_DIR_SINK) {
add_sink(conn, ep);
}
if (dir == BT_AUDIO_DIR_SINK) {
add_sink(conn, ep);
}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */
#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
if (dir == BT_AUDIO_DIR_SOURCE) {
add_source(conn, ep);
}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0*/
return;
if (dir == BT_AUDIO_DIR_SOURCE) {
add_source(conn, ep);
}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0*/
}
static void discover_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir)
{
shell_print(ctx_shell, "Discover complete: err %d", err);
}
static void discover_all(struct bt_conn *conn, int err, enum bt_audio_dir dir, struct bt_bap_ep *ep)
static void discover_all(struct bt_conn *conn, int err, enum bt_audio_dir dir)
{
if (ep) {
#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
if (dir == BT_AUDIO_DIR_SINK) {
add_sink(conn, ep);
}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */
#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
if (dir == BT_AUDIO_DIR_SOURCE) {
add_source(conn, ep);
}
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0*/
return;
}
/* Sinks discovery complete, now discover sources */
if (dir == BT_AUDIO_DIR_SINK) {
dir = BT_AUDIO_DIR_SOURCE;
@ -801,7 +782,7 @@ static void discover_all(struct bt_conn *conn, int err, enum bt_audio_dir dir, s
err = bt_bap_unicast_client_discover(default_conn, dir);
if (err) {
shell_error(ctx_shell, "bt_bap_unicast_client_discover err %d", err);
discover_cb(conn, err, dir, NULL);
discover_cb(conn, err, dir);
}
}
}
@ -888,6 +869,7 @@ static struct bt_bap_unicast_client_cb unicast_client_cbs = {
.metadata = metadata_cb,
.release = release_cb,
.pac_record = pac_record_cb,
.endpoint = endpoint_cb,
};
static int cmd_discover(const struct shell *sh, size_t argc, char *argv[])

View file

@ -31,6 +31,7 @@ CREATE_FLAG(flag_mtu_exchanged);
CREATE_FLAG(flag_sink_discovered);
CREATE_FLAG(flag_source_discovered);
CREATE_FLAG(flag_codec_found);
CREATE_FLAG(flag_endpoint_found);
CREATE_FLAG(flag_stream_codec_configured);
static atomic_t flag_stream_qos_configured;
CREATE_FLAG(flag_stream_enabled);
@ -232,64 +233,28 @@ static void print_remote_codec(const struct bt_codec *codec, enum bt_audio_dir d
print_codec(codec);
}
static void discover_sinks_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir,
struct bt_bap_ep *ep)
static void discover_sinks_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir)
{
static bool endpoint_found;
if (err != 0) {
FAIL("Discovery failed: %d\n", err);
return;
}
if (ep != NULL) {
if (dir == BT_AUDIO_DIR_SINK) {
add_remote_sink(ep);
endpoint_found = true;
} else {
FAIL("Invalid param dir: %u\n", dir);
}
printk("Discover complete\n");
return;
}
printk("Sinks discover complete\n");
if (endpoint_found) {
SET_FLAG(flag_sink_discovered);
} else {
FAIL("Did not discover endpoint and codec\n");
}
SET_FLAG(flag_sink_discovered);
}
static void discover_sources_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir,
struct bt_bap_ep *ep)
static void discover_sources_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir)
{
static bool endpoint_found;
if (err != 0) {
FAIL("Discovery failed: %d\n", err);
return;
}
if (ep != NULL) {
if (dir == BT_AUDIO_DIR_SOURCE) {
add_remote_source(ep);
endpoint_found = true;
} else {
FAIL("Invalid param dir: %u\n", dir);
}
return;
}
printk("Sources discover complete\n");
if (endpoint_found) {
SET_FLAG(flag_source_discovered);
} else {
FAIL("Did not discover endpoint and codec\n");
}
SET_FLAG(flag_source_discovered);
}
static void pac_record_cb(struct bt_conn *conn, enum bt_audio_dir dir, const struct bt_codec *codec)
@ -298,6 +263,17 @@ static void pac_record_cb(struct bt_conn *conn, enum bt_audio_dir dir, const str
SET_FLAG(flag_codec_found);
}
static void endpoint_cb(struct bt_conn *conn, enum bt_audio_dir dir, struct bt_bap_ep *ep)
{
if (dir == BT_AUDIO_DIR_SINK) {
add_remote_sink(ep);
} else {
add_remote_source(ep);
}
SET_FLAG(flag_endpoint_found);
}
static struct bt_bap_unicast_client_cb unicast_client_cbs = {
.location = unicast_client_location_cb,
.available_contexts = available_contexts_cb,
@ -310,6 +286,7 @@ static struct bt_bap_unicast_client_cb unicast_client_cbs = {
.metadata = metadata_cb,
.release = release_cb,
.pac_record = pac_record_cb,
.endpoint = endpoint_cb,
};
static void att_mtu_updated(struct bt_conn *conn, uint16_t tx, uint16_t rx)
@ -372,6 +349,7 @@ static void discover_sinks(void)
UNSET_FLAG(flag_codec_found);
UNSET_FLAG(flag_sink_discovered);
UNSET_FLAG(flag_endpoint_found);
err = bt_bap_unicast_client_discover(default_conn, BT_AUDIO_DIR_SINK);
if (err != 0) {
@ -382,6 +360,7 @@ static void discover_sinks(void)
memset(g_sinks, 0, sizeof(g_sinks));
WAIT_FOR_FLAG(flag_codec_found);
WAIT_FOR_FLAG(flag_endpoint_found);
WAIT_FOR_FLAG(flag_sink_discovered);
}

View file

@ -53,6 +53,7 @@ static K_SEM_DEFINE(sem_broadcast_stopped, 0U, ARRAY_SIZE(broadcast_streams));
CREATE_FLAG(flag_discovered);
CREATE_FLAG(flag_codec_found);
CREATE_FLAG(flag_endpoint_found);
CREATE_FLAG(flag_started);
CREATE_FLAG(flag_updated);
CREATE_FLAG(flag_stopped);
@ -269,39 +270,32 @@ static void pac_record_cb(struct bt_conn *conn, enum bt_audio_dir dir, const str
SET_FLAG(flag_codec_found);
}
static void discover_sink_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir,
struct bt_bap_ep *ep)
static void discover_sink_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir)
{
static bool endpoint_found;
if (err != 0) {
FAIL("Discovery failed: %d\n", err);
return;
}
if (ep != NULL) {
if (dir == BT_AUDIO_DIR_SINK) {
add_remote_sink(ep);
endpoint_found = true;
} else {
FAIL("Invalid param dir: %u\n", dir);
}
return;
}
printk("Sink discover complete\n");
if (endpoint_found) {
SET_FLAG(flag_sink_discovered);
SET_FLAG(flag_sink_discovered);
}
static void endpoint_cb(struct bt_conn *conn, enum bt_audio_dir dir, struct bt_bap_ep *ep)
{
if (dir == BT_AUDIO_DIR_SINK) {
add_remote_sink(ep);
SET_FLAG(flag_endpoint_found);
} else {
FAIL("Did not discover endpoint and codec\n");
FAIL("Invalid param dir: %u\n", dir);
}
}
static const struct bt_bap_unicast_client_cb unicast_client_cbs = {
.discover = discover_sink_cb,
.pac_record = pac_record_cb,
.endpoint = endpoint_cb,
};
static void att_mtu_updated(struct bt_conn *conn, uint16_t tx, uint16_t rx)
@ -377,6 +371,7 @@ static void discover_sink(void)
UNSET_FLAG(flag_sink_discovered);
UNSET_FLAG(flag_codec_found);
UNSET_FLAG(flag_endpoint_found);
err = bt_bap_unicast_client_discover(default_conn, BT_AUDIO_DIR_SINK);
if (err != 0) {
@ -387,6 +382,7 @@ static void discover_sink(void)
memset(unicast_sink_eps, 0, sizeof(unicast_sink_eps));
WAIT_FOR_FLAG(flag_sink_discovered);
WAIT_FOR_FLAG(flag_endpoint_found);
WAIT_FOR_FLAG(flag_codec_found);
}