Bluetooth: BAP: Remove bt_bap_unicast_client_discover_params

Remove the BAP unicast client specific discover parameter struct.
This make the BAP discover work more similar to the other
profiles.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2023-03-23 15:21:10 +01:00 committed by Carles Cufí
commit 5d498d78ad
6 changed files with 215 additions and 270 deletions

View file

@ -1076,8 +1076,6 @@ int bt_bap_unicast_group_add_streams(struct bt_bap_unicast_group *unicast_group,
*/ */
int bt_bap_unicast_group_delete(struct bt_bap_unicast_group *unicast_group); int bt_bap_unicast_group_delete(struct bt_bap_unicast_group *unicast_group);
struct bt_bap_unicast_client_discover_params;
/** Unicast Client callback structure */ /** Unicast Client callback structure */
struct bt_bap_unicast_client_cb { struct bt_bap_unicast_client_cb {
/** /**
@ -1225,13 +1223,11 @@ struct bt_bap_unicast_client_cb {
* @param dir The type of remote endpoints and capabilities discovered. * @param dir The type of remote endpoints and capabilities discovered.
* @param codec Remote capabilities. * @param codec Remote capabilities.
* @param ep Remote endpoint. * @param ep Remote endpoint.
* @param params Pointer to the discover parameters.
* *
* If discovery procedure has complete both @p codec and @p ep are set to NULL. * 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, void (*discover)(struct bt_conn *conn, int err, enum bt_audio_dir dir,
struct bt_codec *codec, struct bt_bap_ep *ep, struct bt_codec *codec, struct bt_bap_ep *ep);
struct bt_bap_unicast_client_discover_params *params);
}; };
/** /**
@ -1246,29 +1242,16 @@ struct bt_bap_unicast_client_cb {
*/ */
int bt_bap_unicast_client_register_cb(const struct bt_bap_unicast_client_cb *cb); int bt_bap_unicast_client_register_cb(const struct bt_bap_unicast_client_cb *cb);
struct bt_bap_unicast_client_discover_params {
/** Read parameters used interally for discovery */
struct bt_gatt_read_params read;
/** Discover parameters used interally for discovery */
struct bt_gatt_discover_params discover;
};
/** /**
* @brief Discover remote capabilities and endpoints * @brief Discover remote capabilities and endpoints
* *
* This procedure is used by a client to discover remote capabilities and * This procedure is used by a client to discover remote capabilities and
* endpoints and notifies via params callback. * endpoints and notifies via params callback.
* *
* @note This procedure is asynchronous therefore the parameters need to
* remains valid while it is active.
*
* @param conn Connection object * @param conn Connection object
* @param dir The type of remote endpoints and capabilities to discover. * @param dir The type of remote endpoints and capabilities to discover.
* @param params Discover parameters
*/ */
int bt_bap_unicast_client_discover(struct bt_conn *conn, enum bt_audio_dir dir, int bt_bap_unicast_client_discover(struct bt_conn *conn, enum bt_audio_dir dir);
struct bt_bap_unicast_client_discover_params *params);
/** @} */ /* End of group bt_bap_unicast_client */ /** @} */ /* End of group bt_bap_unicast_client */
/** /**

View file

@ -584,8 +584,7 @@ static void print_remote_codec(struct bt_codec *codec_capabilities, enum bt_audi
} }
static void discover_sinks_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir, static void discover_sinks_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir,
struct bt_codec *codec, struct bt_bap_ep *ep, struct bt_codec *codec, struct bt_bap_ep *ep)
struct bt_bap_unicast_client_discover_params *params)
{ {
if (err != 0 && err != BT_ATT_ERR_ATTRIBUTE_NOT_FOUND) { if (err != 0 && err != BT_ATT_ERR_ATTRIBUTE_NOT_FOUND) {
printk("Discovery failed: %d\n", err); printk("Discovery failed: %d\n", err);
@ -609,14 +608,11 @@ static void discover_sinks_cb(struct bt_conn *conn, int err, enum bt_audio_dir d
printk("Discover sinks complete: err %d\n", err); printk("Discover sinks complete: err %d\n", err);
} }
(void)memset(params, 0, sizeof(*params));
k_sem_give(&sem_sinks_discovered); k_sem_give(&sem_sinks_discovered);
} }
static void discover_sources_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir, static void discover_sources_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir,
struct bt_codec *codec, struct bt_bap_ep *ep, struct bt_codec *codec, struct bt_bap_ep *ep)
struct bt_bap_unicast_client_discover_params *params)
{ {
if (err != 0 && err != BT_ATT_ERR_ATTRIBUTE_NOT_FOUND) { if (err != 0 && err != BT_ATT_ERR_ATTRIBUTE_NOT_FOUND) {
printk("Discovery failed: %d\n", err); printk("Discovery failed: %d\n", err);
@ -640,8 +636,6 @@ static void discover_sources_cb(struct bt_conn *conn, int err, enum bt_audio_dir
printk("Discover sources complete: err %d\n", err); printk("Discover sources complete: err %d\n", err);
} }
(void)memset(params, 0, sizeof(*params));
k_sem_give(&sem_sources_discovered); k_sem_give(&sem_sources_discovered);
} }
@ -792,12 +786,11 @@ static int scan_and_connect(void)
static int discover_sinks(void) static int discover_sinks(void)
{ {
static struct bt_bap_unicast_client_discover_params params;
int err; int err;
unicast_client_cbs.discover = discover_sinks_cb; unicast_client_cbs.discover = discover_sinks_cb;
err = bt_bap_unicast_client_discover(default_conn, BT_AUDIO_DIR_SINK, &params); err = bt_bap_unicast_client_discover(default_conn, BT_AUDIO_DIR_SINK);
if (err != 0) { if (err != 0) {
printk("Failed to discover sinks: %d\n", err); printk("Failed to discover sinks: %d\n", err);
return err; return err;
@ -814,12 +807,11 @@ static int discover_sinks(void)
static int discover_sources(void) static int discover_sources(void)
{ {
static struct bt_bap_unicast_client_discover_params params;
int err; int err;
unicast_client_cbs.discover = discover_sources_cb; unicast_client_cbs.discover = discover_sources_cb;
err = bt_bap_unicast_client_discover(default_conn, BT_AUDIO_DIR_SOURCE, &params); err = bt_bap_unicast_client_discover(default_conn, BT_AUDIO_DIR_SOURCE);
if (err != 0) { if (err != 0) {
printk("Failed to discover sources: %d\n", err); printk("Failed to discover sources: %d\n", err);
return err; return err;

View file

@ -89,6 +89,10 @@ static struct unicast_client {
/* Discovery parameters */ /* Discovery parameters */
enum bt_audio_dir dir; enum bt_audio_dir dir;
bool busy; bool busy;
union {
struct bt_gatt_read_params read_params;
struct bt_gatt_discover_params disc_params;
};
/* The read_buf needs to use the maximum ATT attribute size as a single /* The read_buf needs to use the maximum ATT attribute size as a single
* PAC record may use the full size * PAC record may use the full size
@ -108,9 +112,7 @@ static int unicast_client_ep_set_codec(struct bt_bap_ep *ep, uint8_t id, uint16_
static int unicast_client_ep_start(struct bt_bap_ep *ep, static int unicast_client_ep_start(struct bt_bap_ep *ep,
struct net_buf_simple *buf); struct net_buf_simple *buf);
static int unicast_client_ase_discover(struct bt_conn *conn, static int unicast_client_ase_discover(struct bt_conn *conn, uint16_t start_handle);
struct bt_bap_unicast_client_discover_params *params,
uint16_t start_handle);
static void unicast_client_reset(struct bt_bap_ep *ep); static void unicast_client_reset(struct bt_bap_ep *ep);
@ -1448,8 +1450,7 @@ static int unicast_client_ep_subscribe(struct bt_conn *conn, struct bt_bap_ep *e
return bt_gatt_subscribe(conn, &client_ep->subscribe); return bt_gatt_subscribe(conn, &client_ep->subscribe);
} }
static void discover_cb(struct bt_conn *conn, int err, struct bt_codec *codec, struct bt_bap_ep *ep, static void discover_cb(struct bt_conn *conn, int err, struct bt_codec *codec, struct bt_bap_ep *ep)
struct bt_bap_unicast_client_discover_params *params)
{ {
struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)]; struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
const enum bt_audio_dir dir = client->dir; const enum bt_audio_dir dir = client->dir;
@ -1458,39 +1459,33 @@ static void discover_cb(struct bt_conn *conn, int err, struct bt_codec *codec, s
/* Discover complete - Reset discovery values */ /* Discover complete - Reset discovery values */
client->dir = 0U; client->dir = 0U;
client->busy = false; client->busy = false;
memset(&client->disc_params, 0, sizeof(client->disc_params));
} }
if (unicast_client_cbs != NULL && unicast_client_cbs->discover != NULL) { if (unicast_client_cbs != NULL && unicast_client_cbs->discover != NULL) {
unicast_client_cbs->discover(conn, err, dir, codec, ep, params); unicast_client_cbs->discover(conn, err, dir, codec, ep);
} }
} }
static void unicast_client_cp_sub_cb(struct bt_conn *conn, uint8_t err, static void unicast_client_cp_sub_cb(struct bt_conn *conn, uint8_t err,
struct bt_gatt_subscribe_params *sub_params) struct bt_gatt_subscribe_params *sub_params)
{ {
struct bt_bap_unicast_client_discover_params *params;
LOG_DBG("conn %p err %u", conn, err); LOG_DBG("conn %p err %u", conn, err);
params = CONTAINER_OF(sub_params->disc_params, struct bt_bap_unicast_client_discover_params, discover_cb(conn, err, NULL, NULL);
discover);
discover_cb(conn, err, NULL, NULL, params);
} }
static void unicast_client_ep_set_cp(struct bt_conn *conn, static void unicast_client_ep_set_cp(struct bt_conn *conn, uint16_t handle)
struct bt_bap_unicast_client_discover_params *params,
uint16_t handle)
{ {
uint8_t index; struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
LOG_DBG("conn %p 0x%04x", conn, handle); LOG_DBG("conn %p 0x%04x", conn, handle);
index = bt_conn_index(conn);
#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0
for (size_t i = 0U; i < ARRAY_SIZE(uni_cli_insts[index].snks); i++) { for (size_t i = 0U; i < ARRAY_SIZE(client->snks); i++) {
struct bt_bap_unicast_client_ep *client_ep = &uni_cli_insts[index].snks[i]; struct bt_bap_unicast_client_ep *client_ep = &client->snks[i];
if (client_ep->handle) { if (client_ep->handle) {
client_ep->cp_handle = handle; client_ep->cp_handle = handle;
@ -1499,8 +1494,8 @@ static void unicast_client_ep_set_cp(struct bt_conn *conn,
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */ #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0 */
#if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 #if CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0
for (size_t i = 0U; i < ARRAY_SIZE(uni_cli_insts[index].srcs); i++) { for (size_t i = 0U; i < ARRAY_SIZE(client->srcs); i++) {
struct bt_bap_unicast_client_ep *client_ep = &uni_cli_insts[index].srcs[i]; struct bt_bap_unicast_client_ep *client_ep = &client->srcs[i];
if (client_ep->handle) { if (client_ep->handle) {
client_ep->cp_handle = handle; client_ep->cp_handle = handle;
@ -1508,29 +1503,28 @@ static void unicast_client_ep_set_cp(struct bt_conn *conn,
} }
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */ #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */
if (!uni_cli_insts[index].cp_subscribe.value_handle) { if (!client->cp_subscribe.value_handle) {
int err; int err;
uni_cli_insts[index].cp_subscribe.value_handle = handle; client->cp_subscribe.value_handle = handle;
uni_cli_insts[index].cp_subscribe.ccc_handle = 0x0000; client->cp_subscribe.ccc_handle = 0x0000;
uni_cli_insts[index].cp_subscribe.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; client->cp_subscribe.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
uni_cli_insts[index].cp_subscribe.disc_params = &params->discover; client->cp_subscribe.disc_params = &client->disc_params;
uni_cli_insts[index].cp_subscribe.notify = unicast_client_cp_notify; client->cp_subscribe.notify = unicast_client_cp_notify;
uni_cli_insts[index].cp_subscribe.value = BT_GATT_CCC_NOTIFY; client->cp_subscribe.value = BT_GATT_CCC_NOTIFY;
uni_cli_insts[index].cp_subscribe.subscribe = unicast_client_cp_sub_cb; client->cp_subscribe.subscribe = unicast_client_cp_sub_cb;
atomic_set_bit(uni_cli_insts[index].cp_subscribe.flags, atomic_set_bit(client->cp_subscribe.flags, BT_GATT_SUBSCRIBE_FLAG_VOLATILE);
BT_GATT_SUBSCRIBE_FLAG_VOLATILE);
err = bt_gatt_subscribe(conn, &uni_cli_insts[index].cp_subscribe); err = bt_gatt_subscribe(conn, &client->cp_subscribe);
if (err != 0) { if (err != 0) {
LOG_DBG("Failed to subscribe: %d", err); LOG_DBG("Failed to subscribe: %d", err);
discover_cb(conn, BT_ATT_ERR_UNLIKELY, NULL, NULL, params); discover_cb(conn, BT_ATT_ERR_UNLIKELY, NULL, NULL);
return; return;
} }
} else { /* already subscribed */ } else { /* already subscribed */
discover_cb(conn, 0, NULL, NULL, params); discover_cb(conn, 0, NULL, NULL);
} }
} }
@ -2836,53 +2830,51 @@ static uint8_t unicast_client_cp_discover_func(struct bt_conn *conn,
const struct bt_gatt_attr *attr, const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *discover) struct bt_gatt_discover_params *discover)
{ {
struct bt_bap_unicast_client_discover_params *params;
struct bt_gatt_chrc *chrc; struct bt_gatt_chrc *chrc;
uint16_t value_handle;
params = CONTAINER_OF(discover, struct bt_bap_unicast_client_discover_params, discover);
if (!attr) { if (!attr) {
LOG_ERR("Unable to find ASE Control Point"); LOG_ERR("Unable to find ASE Control Point");
discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND, NULL, NULL, params); discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND, NULL, NULL);
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
chrc = attr->user_data; chrc = attr->user_data;
value_handle = chrc->value_handle;
memset(discover, 0, sizeof(*discover));
LOG_DBG("conn %p attr %p handle 0x%04x", conn, attr, chrc->value_handle); LOG_DBG("conn %p attr %p handle 0x%04x", conn, attr, value_handle);
unicast_client_ep_set_cp(conn, params, chrc->value_handle); unicast_client_ep_set_cp(conn, value_handle);
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
static int unicast_client_ase_cp_discover(struct bt_conn *conn, static int unicast_client_ase_cp_discover(struct bt_conn *conn)
struct bt_bap_unicast_client_discover_params *params)
{ {
LOG_DBG("conn %p params %p", conn, params); struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
params->discover.uuid = cp_uuid; LOG_DBG("conn %p", conn);
params->discover.func = unicast_client_cp_discover_func;
params->discover.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
params->discover.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
params->discover.type = BT_GATT_DISCOVER_CHARACTERISTIC;
return bt_gatt_discover(conn, &params->discover); client->disc_params.uuid = cp_uuid;
client->disc_params.func = unicast_client_cp_discover_func;
client->disc_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
client->disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
client->disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
return bt_gatt_discover(conn, &client->disc_params);
} }
static uint8_t unicast_client_ase_read_func(struct bt_conn *conn, uint8_t err, static uint8_t unicast_client_ase_read_func(struct bt_conn *conn, uint8_t err,
struct bt_gatt_read_params *read, const void *data, struct bt_gatt_read_params *read, const void *data,
uint16_t length) uint16_t length)
{ {
struct bt_bap_unicast_client_discover_params *params;
uint16_t handle = read->single.handle; uint16_t handle = read->single.handle;
struct unicast_client *client; struct unicast_client *client;
struct net_buf_simple *buf; struct net_buf_simple *buf;
struct bt_bap_ep *ep; struct bt_bap_ep *ep;
params = CONTAINER_OF(read, struct bt_bap_unicast_client_discover_params, read);
LOG_DBG("conn %p err 0x%02x len %u", conn, err, length); LOG_DBG("conn %p err 0x%02x len %u", conn, err, length);
if (err) { if (err) {
@ -2910,6 +2902,8 @@ static uint8_t unicast_client_ase_read_func(struct bt_conn *conn, uint8_t err,
return BT_GATT_ITER_CONTINUE; return BT_GATT_ITER_CONTINUE;
} }
memset(read, 0, sizeof(*read));
if (buf->len < sizeof(struct bt_ascs_ase_status)) { if (buf->len < sizeof(struct bt_ascs_ase_status)) {
LOG_DBG("Read response too small (%u)", buf->len); LOG_DBG("Read response too small (%u)", buf->len);
@ -2933,19 +2927,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_set_status(ep, buf);
unicast_client_ep_subscribe(conn, ep); unicast_client_ep_subscribe(conn, ep);
discover_cb(conn, 0, NULL, ep, params); discover_cb(conn, 0, NULL, ep);
err = unicast_client_ase_discover(conn, params, handle); err = unicast_client_ase_discover(conn, handle);
if (err != 0) { if (err != 0) {
LOG_DBG("Failed to read ASE: %d", err); LOG_DBG("Failed to read ASE: %d", err);
discover_cb(conn, err, NULL, NULL, params); discover_cb(conn, err, NULL, NULL);
} }
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
fail: fail:
discover_cb(conn, err, NULL, NULL, params); discover_cb(conn, err, NULL, NULL);
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
@ -2953,85 +2947,80 @@ static uint8_t unicast_client_ase_discover_cb(struct bt_conn *conn,
const struct bt_gatt_attr *attr, const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *discover) struct bt_gatt_discover_params *discover)
{ {
struct bt_bap_unicast_client_discover_params *params;
struct unicast_client *client; struct unicast_client *client;
struct bt_gatt_chrc *chrc; struct bt_gatt_chrc *chrc;
uint16_t value_handle;
int err; int err;
params = CONTAINER_OF(discover, struct bt_bap_unicast_client_discover_params,
discover);
if (attr == NULL) { if (attr == NULL) {
err = unicast_client_ase_cp_discover(conn, params); err = unicast_client_ase_cp_discover(conn);
if (err != 0) { if (err != 0) {
LOG_ERR("Unable to discover ASE Control Point"); LOG_ERR("Unable to discover ASE Control Point");
discover_cb(conn, BT_ATT_ERR_UNLIKELY, NULL, NULL, params); discover_cb(conn, BT_ATT_ERR_UNLIKELY, NULL, NULL);
} }
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
chrc = attr->user_data; chrc = attr->user_data;
value_handle = chrc->value_handle;
memset(discover, 0, sizeof(*discover));
client = &uni_cli_insts[bt_conn_index(conn)]; client = &uni_cli_insts[bt_conn_index(conn)];
LOG_DBG("conn %p attr %p handle 0x%04x dir %s", conn, attr, chrc->value_handle, LOG_DBG("conn %p attr %p handle 0x%04x dir %s", conn, attr, value_handle,
bt_audio_dir_str(client->dir)); bt_audio_dir_str(client->dir));
/* Reset to use for long read */ /* Reset to use for long read */
reset_read_buf(client); reset_read_buf(client);
params->read.func = unicast_client_ase_read_func; client->read_params.func = unicast_client_ase_read_func;
params->read.handle_count = 1U; client->read_params.handle_count = 1U;
params->read.single.handle = chrc->value_handle; client->read_params.single.handle = value_handle;
params->read.single.offset = 0U; client->read_params.single.offset = 0U;
err = bt_gatt_read(conn, &params->read); err = bt_gatt_read(conn, &client->read_params);
if (err != 0) { if (err != 0) {
LOG_DBG("Failed to read PAC records: %d", err); LOG_DBG("Failed to read PAC records: %d", err);
discover_cb(conn, err, NULL, NULL, params); discover_cb(conn, err, NULL, NULL);
} }
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
static int unicast_client_ase_discover(struct bt_conn *conn, static int unicast_client_ase_discover(struct bt_conn *conn, uint16_t start_handle)
struct bt_bap_unicast_client_discover_params *params,
uint16_t start_handle)
{ {
struct unicast_client *client; struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
LOG_DBG("conn %p params %p", conn, params); LOG_DBG("conn %p ", conn);
client = &uni_cli_insts[bt_conn_index(conn)];
if (client->dir == BT_AUDIO_DIR_SINK) { if (client->dir == BT_AUDIO_DIR_SINK) {
params->discover.uuid = ase_snk_uuid; client->disc_params.uuid = ase_snk_uuid;
} else if (client->dir == BT_AUDIO_DIR_SOURCE) { } else if (client->dir == BT_AUDIO_DIR_SOURCE) {
params->discover.uuid = ase_src_uuid; client->disc_params.uuid = ase_src_uuid;
} else { } else {
return -EINVAL; return -EINVAL;
} }
params->discover.func = unicast_client_ase_discover_cb; client->disc_params.func = unicast_client_ase_discover_cb;
params->discover.type = BT_GATT_DISCOVER_CHARACTERISTIC; client->disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
params->discover.start_handle = start_handle; client->disc_params.start_handle = start_handle;
params->discover.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; client->disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
return bt_gatt_discover(conn, &params->discover); return bt_gatt_discover(conn, &client->disc_params);
} }
static uint8_t unicast_client_pacs_avail_ctx_read_func(struct bt_conn *conn, uint8_t err, static uint8_t unicast_client_pacs_avail_ctx_read_func(struct bt_conn *conn, uint8_t err,
struct bt_gatt_read_params *read, struct bt_gatt_read_params *read,
const void *data, uint16_t length) const void *data, uint16_t length)
{ {
struct bt_bap_unicast_client_discover_params *params;
struct bt_pacs_context context; struct bt_pacs_context context;
struct net_buf_simple buf; struct net_buf_simple buf;
int cb_err; int cb_err;
params = CONTAINER_OF(read, struct bt_bap_unicast_client_discover_params, read); memset(read, 0, sizeof(*read));
LOG_DBG("conn %p err 0x%02x len %u", conn, err, length); LOG_DBG("conn %p err 0x%02x len %u", conn, err, length);
@ -3042,7 +3031,7 @@ static uint8_t unicast_client_pacs_avail_ctx_read_func(struct bt_conn *conn, uin
err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN; err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
} }
discover_cb(conn, err, NULL, NULL, params); discover_cb(conn, err, NULL, NULL);
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
@ -3058,11 +3047,11 @@ static uint8_t unicast_client_pacs_avail_ctx_read_func(struct bt_conn *conn, uin
} }
/* Read ASE instances */ /* Read ASE instances */
cb_err = unicast_client_ase_discover(conn, params, BT_ATT_FIRST_ATTRIBUTE_HANDLE); cb_err = unicast_client_ase_discover(conn, BT_ATT_FIRST_ATTRIBUTE_HANDLE);
if (cb_err != 0) { if (cb_err != 0) {
LOG_ERR("Unable to read ASE: %d", cb_err); LOG_ERR("Unable to read ASE: %d", cb_err);
discover_cb(conn, err, NULL, NULL, params); discover_cb(conn, err, NULL, NULL);
} }
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
@ -3108,53 +3097,55 @@ static uint8_t unicast_client_pacs_avail_ctx_notify_cb(struct bt_conn *conn,
return BT_GATT_ITER_CONTINUE; return BT_GATT_ITER_CONTINUE;
} }
static int unicast_client_pacs_avail_ctx_read(struct bt_conn *conn, static int unicast_client_pacs_avail_ctx_read(struct bt_conn *conn, uint16_t handle)
struct bt_bap_unicast_client_discover_params *params,
uint16_t handle)
{ {
LOG_DBG("conn %p params %p", conn, params); struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
params->read.func = unicast_client_pacs_avail_ctx_read_func; LOG_DBG("conn %p", conn);
params->read.handle_count = 1U;
params->read.single.handle = handle;
params->read.single.offset = 0U;
return bt_gatt_read(conn, &params->read); client->read_params.func = unicast_client_pacs_avail_ctx_read_func;
client->read_params.handle_count = 1U;
client->read_params.single.handle = handle;
client->read_params.single.offset = 0U;
return bt_gatt_read(conn, &client->read_params);
} }
static uint8_t unicast_client_pacs_avail_ctx_discover_cb(struct bt_conn *conn, static uint8_t unicast_client_pacs_avail_ctx_discover_cb(struct bt_conn *conn,
const struct bt_gatt_attr *attr, const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *discover) struct bt_gatt_discover_params *discover)
{ {
struct bt_bap_unicast_client_discover_params *params;
uint8_t index = bt_conn_index(conn); uint8_t index = bt_conn_index(conn);
const struct bt_gatt_chrc *chrc; const struct bt_gatt_chrc *chrc;
uint8_t chrc_properties;
uint16_t value_handle;
int err; int err;
params = CONTAINER_OF(discover, struct bt_bap_unicast_client_discover_params, discover);
if (!attr) { if (!attr) {
/* If available_ctx is not found, we terminate the discovery as /* If available_ctx is not found, we terminate the discovery as
* the characteristic is mandatory * the characteristic is mandatory
*/ */
discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND, NULL, NULL, params); discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND, NULL, NULL);
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
chrc = attr->user_data; chrc = attr->user_data;
chrc_properties = chrc->properties;
value_handle = chrc->value_handle;
memset(discover, 0, sizeof(*discover));
LOG_DBG("conn %p attr %p handle 0x%04x", conn, attr, chrc->value_handle); LOG_DBG("conn %p attr %p handle 0x%04x", conn, attr, value_handle);
if (chrc->properties & BT_GATT_CHRC_NOTIFY) { if (chrc_properties & BT_GATT_CHRC_NOTIFY) {
struct bt_gatt_subscribe_params *sub_params; struct bt_gatt_subscribe_params *sub_params;
sub_params = &uni_cli_insts[index].avail_ctx_subscribe; sub_params = &uni_cli_insts[index].avail_ctx_subscribe;
if (sub_params->value_handle == 0) { if (sub_params->value_handle == 0) {
LOG_DBG("Subscribing to handle %u", chrc->value_handle); LOG_DBG("Subscribing to handle %u", value_handle);
sub_params->value_handle = chrc->value_handle; sub_params->value_handle = value_handle;
sub_params->ccc_handle = 0x0000; /* auto discover ccc */ sub_params->ccc_handle = 0x0000; /* auto discover ccc */
sub_params->end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; sub_params->end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
sub_params->disc_params = &uni_cli_insts[index].avail_ctx_cc_disc; sub_params->disc_params = &uni_cli_insts[index].avail_ctx_cc_disc;
@ -3167,51 +3158,51 @@ static uint8_t unicast_client_pacs_avail_ctx_discover_cb(struct bt_conn *conn,
} }
} /* else already subscribed */ } /* else already subscribed */
} else { } else {
LOG_DBG("Invalid chrc->properties: %u", chrc->properties); LOG_DBG("Invalid chrc->properties: %u", chrc_properties);
/* If the characteristic is not subscribable we terminate the /* If the characteristic is not subscribable we terminate the
* discovery as BT_GATT_CHRC_NOTIFY is mandatory * discovery as BT_GATT_CHRC_NOTIFY is mandatory
*/ */
discover_cb(conn, BT_ATT_ERR_NOT_SUPPORTED, NULL, NULL, params); discover_cb(conn, BT_ATT_ERR_NOT_SUPPORTED, NULL, NULL);
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
err = unicast_client_pacs_avail_ctx_read(conn, params, chrc->value_handle); err = unicast_client_pacs_avail_ctx_read(conn, value_handle);
if (err != 0) { if (err != 0) {
LOG_DBG("Failed to read PACS avail_ctx: %d", err); LOG_DBG("Failed to read PACS avail_ctx: %d", err);
discover_cb(conn, err, NULL, NULL, params); discover_cb(conn, err, NULL, NULL);
} }
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
static int static int unicast_client_pacs_avail_ctx_discover(struct bt_conn *conn)
unicast_client_pacs_avail_ctx_discover(struct bt_conn *conn,
struct bt_bap_unicast_client_discover_params *params)
{ {
LOG_DBG("conn %p params %p", conn, params); struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
params->discover.uuid = pacs_avail_ctx_uuid; LOG_DBG("conn %p", conn);
params->discover.func = unicast_client_pacs_avail_ctx_discover_cb;
params->discover.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
params->discover.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
params->discover.type = BT_GATT_DISCOVER_CHARACTERISTIC;
return bt_gatt_discover(conn, &params->discover); client->disc_params.uuid = pacs_avail_ctx_uuid;
client->disc_params.func = unicast_client_pacs_avail_ctx_discover_cb;
client->disc_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
client->disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
client->disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
return bt_gatt_discover(conn, &client->disc_params);
} }
static uint8_t unicast_client_pacs_location_read_func(struct bt_conn *conn, uint8_t err, static uint8_t unicast_client_pacs_location_read_func(struct bt_conn *conn, uint8_t err,
struct bt_gatt_read_params *read, struct bt_gatt_read_params *read,
const void *data, uint16_t length) const void *data, uint16_t length)
{ {
struct bt_bap_unicast_client_discover_params *params;
struct unicast_client *client; struct unicast_client *client;
struct net_buf_simple buf; struct net_buf_simple buf;
uint32_t location; uint32_t location;
int cb_err; int cb_err;
params = CONTAINER_OF(read, struct bt_bap_unicast_client_discover_params, read); memset(read, 0, sizeof(*read));
client = &uni_cli_insts[bt_conn_index(conn)]; client = &uni_cli_insts[bt_conn_index(conn)];
LOG_DBG("conn %p err 0x%02x len %u", conn, err, length); LOG_DBG("conn %p err 0x%02x len %u", conn, err, length);
@ -3224,7 +3215,7 @@ static uint8_t unicast_client_pacs_location_read_func(struct bt_conn *conn, uint
err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN; err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
} }
discover_cb(conn, err, NULL, NULL, params); discover_cb(conn, err, NULL, NULL);
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
@ -3239,11 +3230,11 @@ static uint8_t unicast_client_pacs_location_read_func(struct bt_conn *conn, uint
} }
/* Read available contexts */ /* Read available contexts */
cb_err = unicast_client_pacs_avail_ctx_discover(conn, params); cb_err = unicast_client_pacs_avail_ctx_discover(conn);
if (cb_err != 0) { if (cb_err != 0) {
LOG_ERR("Unable to read available contexts: %d", cb_err); LOG_ERR("Unable to read available contexts: %d", cb_err);
discover_cb(conn, cb_err, NULL, NULL, params); discover_cb(conn, cb_err, NULL, NULL);
} }
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
@ -3299,48 +3290,48 @@ static uint8_t unicast_client_pacs_location_notify_cb(struct bt_conn *conn,
return BT_GATT_ITER_CONTINUE; return BT_GATT_ITER_CONTINUE;
} }
static int unicast_client_pacs_location_read(struct bt_conn *conn, static int unicast_client_pacs_location_read(struct bt_conn *conn, uint16_t handle)
struct bt_bap_unicast_client_discover_params *params,
uint16_t handle)
{ {
LOG_DBG("conn %p params %p", conn, params); struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
params->read.func = unicast_client_pacs_location_read_func; LOG_DBG("conn %p", conn);
params->read.handle_count = 1U;
params->read.single.handle = handle;
params->read.single.offset = 0U;
return bt_gatt_read(conn, &params->read); client->read_params.func = unicast_client_pacs_location_read_func;
client->read_params.handle_count = 1U;
client->read_params.single.handle = handle;
client->read_params.single.offset = 0U;
return bt_gatt_read(conn, &client->read_params);
} }
static uint8_t unicast_client_pacs_location_discover_cb(struct bt_conn *conn, static uint8_t unicast_client_pacs_location_discover_cb(struct bt_conn *conn,
const struct bt_gatt_attr *attr, const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *discover) struct bt_gatt_discover_params *discover)
{ {
struct bt_bap_unicast_client_discover_params *params;
uint8_t index = bt_conn_index(conn); uint8_t index = bt_conn_index(conn);
const struct bt_gatt_chrc *chrc; const struct bt_gatt_chrc *chrc;
uint16_t value_handle;
int err; int err;
params = CONTAINER_OF(discover, struct bt_bap_unicast_client_discover_params, discover);
if (!attr) { if (!attr) {
/* If location is not found, we just continue reading the /* If location is not found, we just continue reading the
* available contexts, as location is optional. * available contexts, as location is optional.
*/ */
err = unicast_client_pacs_avail_ctx_discover(conn, params); err = unicast_client_pacs_avail_ctx_discover(conn);
if (err != 0) { if (err != 0) {
LOG_ERR("Unable to read available contexts: %d", err); LOG_ERR("Unable to read available contexts: %d", err);
discover_cb(conn, err, NULL, NULL, params); discover_cb(conn, err, NULL, NULL);
} }
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
chrc = attr->user_data; chrc = attr->user_data;
value_handle = chrc->value_handle;
memset(discover, 0, sizeof(*discover));
LOG_DBG("conn %p attr %p handle 0x%04x", conn, attr, chrc->value_handle); LOG_DBG("conn %p attr %p handle 0x%04x", conn, attr, value_handle);
if (chrc->properties & BT_GATT_CHRC_NOTIFY) { if (chrc->properties & BT_GATT_CHRC_NOTIFY) {
const struct unicast_client *client = &uni_cli_insts[index]; const struct unicast_client *client = &uni_cli_insts[index];
@ -3352,7 +3343,7 @@ static uint8_t unicast_client_pacs_location_discover_cb(struct bt_conn *conn,
sub_params = &uni_cli_insts[index].src_loc_subscribe; sub_params = &uni_cli_insts[index].src_loc_subscribe;
} }
sub_params->value_handle = chrc->value_handle; sub_params->value_handle = value_handle;
sub_params->ccc_handle = 0x0000; /* auto discover ccc */ sub_params->ccc_handle = 0x0000; /* auto discover ccc */
sub_params->end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; sub_params->end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
sub_params->disc_params = &uni_cli_insts[index].loc_cc_disc; sub_params->disc_params = &uni_cli_insts[index].loc_cc_disc;
@ -3365,51 +3356,48 @@ static uint8_t unicast_client_pacs_location_discover_cb(struct bt_conn *conn,
} }
} }
err = unicast_client_pacs_location_read(conn, params, chrc->value_handle); err = unicast_client_pacs_location_read(conn, value_handle);
if (err != 0) { if (err != 0) {
LOG_DBG("Failed to read PACS location: %d", err); LOG_DBG("Failed to read PACS location: %d", err);
discover_cb(conn, err, NULL, NULL, params); discover_cb(conn, err, NULL, NULL);
} }
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
static int static int unicast_client_pacs_location_discover(struct bt_conn *conn)
unicast_client_pacs_location_discover(struct bt_conn *conn,
struct bt_bap_unicast_client_discover_params *params)
{ {
const struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)]; struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
LOG_DBG("conn %p params %p dir %s", conn, params, bt_audio_dir_str(client->dir)); LOG_DBG("conn %p dir %s", conn, bt_audio_dir_str(client->dir));
if (client->dir == BT_AUDIO_DIR_SINK) { if (client->dir == BT_AUDIO_DIR_SINK) {
params->discover.uuid = pacs_snk_loc_uuid; client->disc_params.uuid = pacs_snk_loc_uuid;
} else if (client->dir == BT_AUDIO_DIR_SOURCE) { } else if (client->dir == BT_AUDIO_DIR_SOURCE) {
params->discover.uuid = pacs_src_loc_uuid; client->disc_params.uuid = pacs_src_loc_uuid;
} else { } else {
return -EINVAL; return -EINVAL;
} }
params->discover.func = unicast_client_pacs_location_discover_cb; client->disc_params.func = unicast_client_pacs_location_discover_cb;
params->discover.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; client->disc_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
params->discover.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; client->disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
params->discover.type = BT_GATT_DISCOVER_CHARACTERISTIC; client->disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
return bt_gatt_discover(conn, &params->discover); return bt_gatt_discover(conn, &client->disc_params);
} }
static uint8_t unicast_client_pacs_context_read_func(struct bt_conn *conn, uint8_t err, static uint8_t unicast_client_pacs_context_read_func(struct bt_conn *conn, uint8_t err,
struct bt_gatt_read_params *read, struct bt_gatt_read_params *read,
const void *data, uint16_t length) const void *data, uint16_t length)
{ {
struct bt_bap_unicast_client_discover_params *params;
struct net_buf_simple buf; struct net_buf_simple buf;
struct bt_pacs_context *context; struct bt_pacs_context *context;
int cb_err; int cb_err;
int index; int index;
params = CONTAINER_OF(read, struct bt_bap_unicast_client_discover_params, read); memset(read, 0, sizeof(*read));
LOG_DBG("conn %p err 0x%02x len %u", conn, err, length); LOG_DBG("conn %p err 0x%02x len %u", conn, err, length);
@ -3424,11 +3412,11 @@ static uint8_t unicast_client_pacs_context_read_func(struct bt_conn *conn, uint8
discover_loc: discover_loc:
/* Read ASE instances */ /* Read ASE instances */
cb_err = unicast_client_pacs_location_discover(conn, params); cb_err = unicast_client_pacs_location_discover(conn);
if (cb_err != 0) { if (cb_err != 0) {
LOG_ERR("Unable to read PACS location: %d", cb_err); LOG_ERR("Unable to read PACS location: %d", cb_err);
discover_cb(conn, cb_err, NULL, NULL, params); discover_cb(conn, cb_err, NULL, NULL);
} }
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
@ -3438,79 +3426,76 @@ static uint8_t unicast_client_pacs_context_discover_cb(struct bt_conn *conn,
const struct bt_gatt_attr *attr, const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *discover) struct bt_gatt_discover_params *discover)
{ {
const struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)]; struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
struct bt_bap_unicast_client_discover_params *params;
struct bt_gatt_chrc *chrc; struct bt_gatt_chrc *chrc;
uint16_t value_handle;
int err; int err;
params = CONTAINER_OF(discover, struct bt_bap_unicast_client_discover_params,
discover);
if (attr == NULL) { if (attr == NULL) {
LOG_ERR("Unable to find %s PAC context", bt_audio_dir_str(client->dir)); LOG_ERR("Unable to find %s PAC context", bt_audio_dir_str(client->dir));
discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND, NULL, NULL, params); discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND, NULL, NULL);
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
chrc = attr->user_data; chrc = attr->user_data;
value_handle = chrc->value_handle;
memset(discover, 0, sizeof(*discover));
LOG_DBG("conn %p attr %p handle 0x%04x dir %s", conn, attr, chrc->value_handle, LOG_DBG("conn %p attr %p handle 0x%04x dir %s", conn, attr, value_handle,
bt_audio_dir_str(client->dir)); bt_audio_dir_str(client->dir));
/* TODO: Subscribe to PAC context */ /* TODO: Subscribe to PAC context */
params->read.func = unicast_client_pacs_context_read_func; client->read_params.func = unicast_client_pacs_context_read_func;
params->read.handle_count = 1U; client->read_params.handle_count = 1U;
params->read.single.handle = chrc->value_handle; client->read_params.single.handle = value_handle;
params->read.single.offset = 0U; client->read_params.single.offset = 0U;
err = bt_gatt_read(conn, &params->read); err = bt_gatt_read(conn, &client->read_params);
if (err != 0) { if (err != 0) {
LOG_DBG("Failed to read PAC records: %d", err); LOG_DBG("Failed to read PAC records: %d", err);
discover_cb(conn, err, NULL, NULL, params); discover_cb(conn, err, NULL, NULL);
} }
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
static int static int unicast_client_pacs_context_discover(struct bt_conn *conn)
unicast_client_pacs_context_discover(struct bt_conn *conn,
struct bt_bap_unicast_client_discover_params *params)
{ {
LOG_DBG("conn %p params %p", conn, params); struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
params->discover.uuid = pacs_context_uuid; LOG_DBG("conn %p", conn);
params->discover.func = unicast_client_pacs_context_discover_cb;
params->discover.type = BT_GATT_DISCOVER_CHARACTERISTIC;
params->discover.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
params->discover.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
return bt_gatt_discover(conn, &params->discover); client->disc_params.uuid = pacs_context_uuid;
client->disc_params.func = unicast_client_pacs_context_discover_cb;
client->disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
client->disc_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
client->disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
return bt_gatt_discover(conn, &client->disc_params);
} }
static uint8_t unicast_client_read_func(struct bt_conn *conn, uint8_t err, static uint8_t unicast_client_read_func(struct bt_conn *conn, uint8_t err,
struct bt_gatt_read_params *read, const void *data, struct bt_gatt_read_params *read, const void *data,
uint16_t length) uint16_t length)
{ {
struct bt_bap_unicast_client_discover_params *params; uint16_t handle = read->single.handle;
struct unicast_client *client; struct unicast_client *client;
struct bt_pacs_read_rsp *rsp; struct bt_pacs_read_rsp *rsp;
struct net_buf_simple *buf; struct net_buf_simple *buf;
int cb_err = err; int cb_err = err;
uint8_t i; uint8_t i;
params = CONTAINER_OF(read, struct bt_bap_unicast_client_discover_params, read);
LOG_DBG("conn %p err 0x%02x len %u", conn, err, length); LOG_DBG("conn %p err 0x%02x len %u", conn, err, length);
if (cb_err != BT_ATT_ERR_SUCCESS) { if (cb_err != BT_ATT_ERR_SUCCESS) {
goto fail; goto fail;
} }
LOG_DBG("handle 0x%04x", read->single.handle); LOG_DBG("handle 0x%04x", handle);
client = &uni_cli_insts[bt_conn_index(conn)]; client = &uni_cli_insts[bt_conn_index(conn)];
buf = &client->net_buf; buf = &client->net_buf;
@ -3531,6 +3516,8 @@ static uint8_t unicast_client_read_func(struct bt_conn *conn, uint8_t err,
return BT_GATT_ITER_CONTINUE; return BT_GATT_ITER_CONTINUE;
} }
memset(read, 0, sizeof(*read));
if (buf->len < sizeof(*rsp)) { if (buf->len < sizeof(*rsp)) {
LOG_DBG("Read response too small (%u)", buf->len); LOG_DBG("Read response too small (%u)", buf->len);
@ -3607,7 +3594,7 @@ static uint8_t unicast_client_read_func(struct bt_conn *conn, uint8_t err,
LOG_DBG("codec 0x%02x config count %u meta count %u ", codec.id, codec.data_count, LOG_DBG("codec 0x%02x config count %u meta count %u ", codec.id, codec.data_count,
codec.meta_count); codec.meta_count);
discover_cb(conn, 0, &codec, NULL, params); discover_cb(conn, 0, &codec, NULL);
} }
if (i != rsp->num_pac) { if (i != rsp->num_pac) {
@ -3617,7 +3604,7 @@ static uint8_t unicast_client_read_func(struct bt_conn *conn, uint8_t err,
} }
/* Read PACS contexts */ /* Read PACS contexts */
cb_err = unicast_client_pacs_context_discover(conn, params); cb_err = unicast_client_pacs_context_discover(conn);
if (cb_err != 0) { if (cb_err != 0) {
LOG_ERR("Unable to read PACS context: %d", cb_err); LOG_ERR("Unable to read PACS context: %d", cb_err);
goto fail; goto fail;
@ -3626,7 +3613,7 @@ static uint8_t unicast_client_read_func(struct bt_conn *conn, uint8_t err,
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
fail: fail:
discover_cb(conn, cb_err, NULL, NULL, params); discover_cb(conn, cb_err, NULL, NULL);
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
@ -3634,41 +3621,41 @@ static uint8_t unicast_client_pac_discover_cb(struct bt_conn *conn,
const struct bt_gatt_attr *attr, const struct bt_gatt_attr *attr,
struct bt_gatt_discover_params *discover) struct bt_gatt_discover_params *discover)
{ {
const struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)]; struct unicast_client *client = &uni_cli_insts[bt_conn_index(conn)];
struct bt_bap_unicast_client_discover_params *params;
struct bt_gatt_chrc *chrc; struct bt_gatt_chrc *chrc;
uint16_t value_handle;
int err; int err;
params = CONTAINER_OF(discover, struct bt_bap_unicast_client_discover_params, discover);
if (attr == NULL) { if (attr == NULL) {
LOG_ERR("Unable to find %s PAC", bt_audio_dir_str(client->dir)); LOG_ERR("Unable to find %s PAC", bt_audio_dir_str(client->dir));
discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND, NULL, NULL, params); discover_cb(conn, BT_ATT_ERR_ATTRIBUTE_NOT_FOUND, NULL, NULL);
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
} }
chrc = attr->user_data; chrc = attr->user_data;
value_handle = chrc->value_handle;
memset(discover, 0, sizeof(*discover));
LOG_DBG("conn %p attr %p handle 0x%04x dir %s", conn, attr, chrc->value_handle, LOG_DBG("conn %p attr %p handle 0x%04x dir %s", conn, attr, value_handle,
bt_audio_dir_str(client->dir)); bt_audio_dir_str(client->dir));
/* TODO: Subscribe to PAC */ /* TODO: Subscribe to PAC */
/* Reset to use for long read */ /* Reset to use for long read */
reset_read_buf(&uni_cli_insts[bt_conn_index(conn)]); reset_read_buf(client);
params->read.func = unicast_client_read_func; client->read_params.func = unicast_client_read_func;
params->read.handle_count = 1U; client->read_params.handle_count = 1U;
params->read.single.handle = chrc->value_handle; client->read_params.single.handle = value_handle;
params->read.single.offset = 0U; client->read_params.single.offset = 0U;
err = bt_gatt_read(conn, &params->read); err = bt_gatt_read(conn, &client->read_params);
if (err != 0) { if (err != 0) {
LOG_DBG("Failed to read PAC records: %d", err); LOG_DBG("Failed to read PAC records: %d", err);
discover_cb(conn, err, NULL, NULL, params); discover_cb(conn, err, NULL, NULL);
} }
return BT_GATT_ITER_STOP; return BT_GATT_ITER_STOP;
@ -3685,8 +3672,7 @@ static struct bt_conn_cb conn_cbs = {
.disconnected = unicast_client_disconnected, .disconnected = unicast_client_disconnected,
}; };
int bt_bap_unicast_client_discover(struct bt_conn *conn, enum bt_audio_dir dir, int bt_bap_unicast_client_discover(struct bt_conn *conn, enum bt_audio_dir dir)
struct bt_bap_unicast_client_discover_params *params)
{ {
struct unicast_client *client; struct unicast_client *client;
static bool conn_cb_registered; static bool conn_cb_registered;
@ -3710,24 +3696,24 @@ int bt_bap_unicast_client_discover(struct bt_conn *conn, enum bt_audio_dir dir,
} }
if (dir == BT_AUDIO_DIR_SINK) { if (dir == BT_AUDIO_DIR_SINK) {
params->discover.uuid = snk_uuid; client->disc_params.uuid = snk_uuid;
} else if (dir == BT_AUDIO_DIR_SOURCE) { } else if (dir == BT_AUDIO_DIR_SOURCE) {
params->discover.uuid = src_uuid; client->disc_params.uuid = src_uuid;
} else { } else {
return -EINVAL; return -EINVAL;
} }
params->discover.func = unicast_client_pac_discover_cb; client->disc_params.func = unicast_client_pac_discover_cb;
params->discover.type = BT_GATT_DISCOVER_CHARACTERISTIC; client->disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
params->discover.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; client->disc_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
params->discover.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; client->disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
if (!conn_cb_registered) { if (!conn_cb_registered) {
bt_conn_cb_register(&conn_cbs); bt_conn_cb_register(&conn_cbs);
conn_cb_registered = true; conn_cb_registered = true;
} }
err = bt_gatt_discover(conn, &params->discover); err = bt_gatt_discover(conn, &client->disc_params);
if (err != 0) { if (err != 0) {
return err; return err;
} }

View file

@ -748,8 +748,7 @@ static void add_source(const struct bt_conn *conn, struct bt_bap_ep *ep)
#endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */ #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, static void discover_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir,
struct bt_codec *codec, struct bt_bap_ep *ep, struct bt_codec *codec, struct bt_bap_ep *ep)
struct bt_bap_unicast_client_discover_params *params)
{ {
if (codec != NULL) { if (codec != NULL) {
print_remote_codec(conn, codec, dir); print_remote_codec(conn, codec, dir);
@ -773,13 +772,10 @@ static void discover_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir,
} }
shell_print(ctx_shell, "Discover complete: err %d", err); shell_print(ctx_shell, "Discover complete: err %d", err);
memset(params, 0, sizeof(*params));
} }
static void discover_all(struct bt_conn *conn, int err, enum bt_audio_dir dir, static void discover_all(struct bt_conn *conn, int err, enum bt_audio_dir dir,
struct bt_codec *codec, struct bt_bap_ep *ep, struct bt_codec *codec, struct bt_bap_ep *ep)
struct bt_bap_unicast_client_discover_params *params)
{ {
if (codec != NULL) { if (codec != NULL) {
print_remote_codec(conn, codec, dir); print_remote_codec(conn, codec, dir);
@ -807,10 +803,10 @@ static void discover_all(struct bt_conn *conn, int err, enum bt_audio_dir dir,
dir = BT_AUDIO_DIR_SOURCE; dir = BT_AUDIO_DIR_SOURCE;
unicast_client_cbs.discover = discover_cb; unicast_client_cbs.discover = discover_cb;
err = bt_bap_unicast_client_discover(default_conn, dir, params); err = bt_bap_unicast_client_discover(default_conn, dir);
if (err) { if (err) {
shell_error(ctx_shell, "bt_bap_unicast_client_discover err %d", err); shell_error(ctx_shell, "bt_bap_unicast_client_discover err %d", err);
discover_cb(conn, err, dir, NULL, NULL, params); discover_cb(conn, err, dir, NULL, NULL);
} }
} }
} }
@ -900,7 +896,6 @@ static struct bt_bap_unicast_client_cb unicast_client_cbs = {
static int cmd_discover(const struct shell *sh, size_t argc, char *argv[]) static int cmd_discover(const struct shell *sh, size_t argc, char *argv[])
{ {
static struct bt_bap_unicast_client_discover_params params;
static bool cbs_registered; static bool cbs_registered;
enum bt_audio_dir dir; enum bt_audio_dir dir;
uint8_t conn_index; uint8_t conn_index;
@ -942,7 +937,7 @@ static int cmd_discover(const struct shell *sh, size_t argc, char *argv[])
} }
} }
err = bt_bap_unicast_client_discover(default_conn, dir, &params); err = bt_bap_unicast_client_discover(default_conn, dir);
if (err != 0) { if (err != 0) {
return -ENOEXEC; return -ENOEXEC;
} }

View file

@ -232,8 +232,7 @@ static void print_remote_codec(struct bt_codec *codec, enum bt_audio_dir dir)
} }
static void discover_sinks_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir, static void discover_sinks_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir,
struct bt_codec *codec, struct bt_bap_ep *ep, struct bt_codec *codec, struct bt_bap_ep *ep)
struct bt_bap_unicast_client_discover_params *params)
{ {
static bool codec_found; static bool codec_found;
static bool endpoint_found; static bool endpoint_found;
@ -262,8 +261,6 @@ static void discover_sinks_cb(struct bt_conn *conn, int err, enum bt_audio_dir d
printk("Sinks discover complete\n"); printk("Sinks discover complete\n");
(void)memset(params, 0, sizeof(*params));
if (endpoint_found && codec_found) { if (endpoint_found && codec_found) {
SET_FLAG(flag_sink_discovered); SET_FLAG(flag_sink_discovered);
} else { } else {
@ -272,8 +269,7 @@ static void discover_sinks_cb(struct bt_conn *conn, int err, enum bt_audio_dir d
} }
static void discover_sources_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir, static void discover_sources_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir,
struct bt_codec *codec, struct bt_bap_ep *ep, struct bt_codec *codec, struct bt_bap_ep *ep)
struct bt_bap_unicast_client_discover_params *params)
{ {
static bool codec_found; static bool codec_found;
static bool endpoint_found; static bool endpoint_found;
@ -302,8 +298,6 @@ static void discover_sources_cb(struct bt_conn *conn, int err, enum bt_audio_dir
printk("Sources discover complete\n"); printk("Sources discover complete\n");
(void)memset(params, 0, sizeof(*params));
if (endpoint_found && codec_found) { if (endpoint_found && codec_found) {
SET_FLAG(flag_source_discovered); SET_FLAG(flag_source_discovered);
} else { } else {
@ -378,15 +372,13 @@ static void exchange_mtu(void)
static void discover_sinks(void) static void discover_sinks(void)
{ {
static struct bt_bap_unicast_client_discover_params params;
int err; int err;
unicast_client_cbs.discover = discover_sinks_cb; unicast_client_cbs.discover = discover_sinks_cb;
UNSET_FLAG(flag_sink_discovered); UNSET_FLAG(flag_sink_discovered);
err = bt_bap_unicast_client_discover(default_conn, BT_AUDIO_DIR_SINK, &params); err = bt_bap_unicast_client_discover(default_conn, BT_AUDIO_DIR_SINK);
if (err != 0) { if (err != 0) {
printk("Failed to discover sink: %d\n", err); printk("Failed to discover sink: %d\n", err);
return; return;
@ -399,19 +391,20 @@ static void discover_sinks(void)
static void discover_sources(void) static void discover_sources(void)
{ {
static struct bt_bap_unicast_client_discover_params params;
int err; int err;
unicast_client_cbs.discover = discover_sources_cb; unicast_client_cbs.discover = discover_sources_cb;
UNSET_FLAG(flag_source_discovered); UNSET_FLAG(flag_source_discovered);
err = bt_bap_unicast_client_discover(default_conn, BT_AUDIO_DIR_SOURCE, &params); err = bt_bap_unicast_client_discover(default_conn, BT_AUDIO_DIR_SOURCE);
if (err != 0) { if (err != 0) {
printk("Failed to discover sink: %d\n", err); printk("Failed to discover sink: %d\n", err);
return; return;
} }
memset(g_sources, 0, sizeof(g_sources));
WAIT_FOR_FLAG(flag_source_discovered); WAIT_FOR_FLAG(flag_source_discovered);
} }

View file

@ -263,8 +263,7 @@ static void print_remote_codec(struct bt_codec *codec, enum bt_audio_dir dir)
} }
static void discover_sink_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir, static void discover_sink_cb(struct bt_conn *conn, int err, enum bt_audio_dir dir,
struct bt_codec *codec, struct bt_bap_ep *ep, struct bt_codec *codec, struct bt_bap_ep *ep)
struct bt_bap_unicast_client_discover_params *params)
{ {
static bool codec_found; static bool codec_found;
static bool endpoint_found; static bool endpoint_found;
@ -294,8 +293,6 @@ static void discover_sink_cb(struct bt_conn *conn, int err, enum bt_audio_dir di
printk("Sink discover complete\n"); printk("Sink discover complete\n");
(void)memset(params, 0, sizeof(*params));
if (endpoint_found && codec_found) { if (endpoint_found && codec_found) {
SET_FLAG(flag_sink_discovered); SET_FLAG(flag_sink_discovered);
} else { } else {
@ -376,10 +373,9 @@ static void scan_and_connect(void)
static void discover_sink(void) static void discover_sink(void)
{ {
static struct bt_bap_unicast_client_discover_params params;
int err; int err;
err = bt_bap_unicast_client_discover(default_conn, BT_AUDIO_DIR_SINK, &params); err = bt_bap_unicast_client_discover(default_conn, BT_AUDIO_DIR_SINK);
if (err != 0) { if (err != 0) {
printk("Failed to discover sink: %d\n", err); printk("Failed to discover sink: %d\n", err);
return; return;