diff --git a/include/zephyr/bluetooth/audio/bap.h b/include/zephyr/bluetooth/audio/bap.h index f034c946737..8ae5ecc01f2 100644 --- a/include/zephyr/bluetooth/audio/bap.h +++ b/include/zephyr/bluetooth/audio/bap.h @@ -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); }; /** diff --git a/samples/bluetooth/unicast_audio_client/src/main.c b/samples/bluetooth/unicast_audio_client/src/main.c index 949eb12eaf2..543b5c2b6d5 100644 --- a/samples/bluetooth/unicast_audio_client/src/main.c +++ b/samples/bluetooth/unicast_audio_client/src/main.c @@ -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) diff --git a/subsys/bluetooth/audio/bap_unicast_client.c b/subsys/bluetooth/audio/bap_unicast_client.c index c3e8a76b44e..f3ca1716ab3 100644 --- a/subsys/bluetooth/audio/bap_unicast_client.c +++ b/subsys/bluetooth/audio/bap_unicast_client.c @@ -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; diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index 70d49a801b4..8d35167e417 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -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[]) diff --git a/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c b/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c index ba6dbd0a0c0..fb89cb1e49b 100644 --- a/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_unicast_client_test.c @@ -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); } diff --git a/tests/bsim/bluetooth/audio/src/cap_initiator_test.c b/tests/bsim/bluetooth/audio/src/cap_initiator_test.c index b4f4368ab94..67c7f41d05e 100644 --- a/tests/bsim/bluetooth/audio/src/cap_initiator_test.c +++ b/tests/bsim/bluetooth/audio/src/cap_initiator_test.c @@ -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); }