Bluetooth: Audio: Fix audio_iso handling for unicast client

For the unicast client, the direction for the endpoint
is reversed in terms of RX/TX, i.e. a sink endpoint is
RX for the unicast server and broadcast sink, but TX
for the unicast client, and similar for the source endpoint.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2022-12-14 13:09:52 +01:00 committed by Carles Cufí
commit f239df0ca7
6 changed files with 77 additions and 19 deletions

View file

@ -1514,7 +1514,7 @@ static int ase_stream_qos(struct bt_audio_stream *stream,
return -ENOMEM; return -ENOMEM;
} }
if (bt_audio_iso_get_ep(iso, ep->dir) != NULL) { if (bt_audio_iso_get_ep(false, iso, ep->dir) != NULL) {
LOG_ERR("iso %p already in use in dir %u", LOG_ERR("iso %p already in use in dir %u",
&iso->chan, ep->dir); &iso->chan, ep->dir);
bt_audio_iso_unref(iso); bt_audio_iso_unref(iso);

View file

@ -151,14 +151,28 @@ void bt_audio_iso_bind_ep(struct bt_audio_iso *iso, struct bt_audio_ep *ep)
qos = iso->chan.qos; qos = iso->chan.qos;
if (ep->dir == BT_AUDIO_DIR_SINK) { if (IS_ENABLED(CONFIG_BT_AUDIO_UNICAST_CLIENT) &&
__ASSERT(iso->rx.ep == NULL, bt_audio_ep_is_unicast_client(ep)) {
"iso %p bound with ep %p", iso, iso->rx.ep); /* For the unicast client, the direction and tx/rx is reversed */
iso->rx.ep = ep; if (ep->dir == BT_AUDIO_DIR_SOURCE) {
__ASSERT(iso->rx.ep == NULL,
"iso %p bound with ep %p", iso, iso->rx.ep);
iso->rx.ep = ep;
} else {
__ASSERT(iso->tx.ep == NULL,
"iso %p bound with ep %p", iso, iso->tx.ep);
iso->tx.ep = ep;
}
} else { } else {
__ASSERT(iso->tx.ep == NULL, if (ep->dir == BT_AUDIO_DIR_SINK) {
"iso %p bound with ep %p", iso, iso->tx.ep); __ASSERT(iso->rx.ep == NULL,
iso->tx.ep = ep; "iso %p bound with ep %p", iso, iso->rx.ep);
iso->rx.ep = ep;
} else {
__ASSERT(iso->tx.ep == NULL,
"iso %p bound with ep %p", iso, iso->tx.ep);
iso->tx.ep = ep;
}
} }
ep->iso = bt_audio_iso_ref(iso); ep->iso = bt_audio_iso_ref(iso);
@ -176,26 +190,51 @@ void bt_audio_iso_unbind_ep(struct bt_audio_iso *iso, struct bt_audio_ep *ep)
qos = iso->chan.qos; qos = iso->chan.qos;
if (ep->dir == BT_AUDIO_DIR_SINK) { if (IS_ENABLED(CONFIG_BT_AUDIO_UNICAST_CLIENT) &&
__ASSERT(iso->rx.ep == ep, bt_audio_ep_is_unicast_client(ep)) {
"iso %p not bound with ep %p", iso, ep); /* For the unicast client, the direction and tx/rx is reversed */
iso->rx.ep = NULL; if (ep->dir == BT_AUDIO_DIR_SOURCE) {
} else { __ASSERT(iso->rx.ep == NULL,
__ASSERT(iso->tx.ep == ep, "iso %p not bound with ep %p", iso, iso->rx.ep);
"iso %p not bound with ep %p", iso, ep); iso->rx.ep = NULL;
iso->tx.ep = NULL; } else {
__ASSERT(iso->tx.ep == NULL,
"iso %p not bound with ep %p", iso, iso->tx.ep);
iso->tx.ep = NULL;
}
} else {
if (ep->dir == BT_AUDIO_DIR_SINK) {
__ASSERT(iso->rx.ep == ep,
"iso %p not bound with ep %p", iso, ep);
iso->rx.ep = NULL;
} else {
__ASSERT(iso->tx.ep == ep,
"iso %p not bound with ep %p", iso, ep);
iso->tx.ep = NULL;
}
} }
bt_audio_iso_unref(ep->iso); bt_audio_iso_unref(ep->iso);
ep->iso = NULL; ep->iso = NULL;
} }
struct bt_audio_ep *bt_audio_iso_get_ep(struct bt_audio_iso *iso, struct bt_audio_ep *bt_audio_iso_get_ep(bool unicast_client,
struct bt_audio_iso *iso,
enum bt_audio_dir dir) enum bt_audio_dir dir)
{ {
__ASSERT(dir == BT_AUDIO_DIR_SINK || dir == BT_AUDIO_DIR_SOURCE, __ASSERT(dir == BT_AUDIO_DIR_SINK || dir == BT_AUDIO_DIR_SOURCE,
"invalid dir: %u", dir); "invalid dir: %u", dir);
/* TODO FIX FOR CLIENT */
if (IS_ENABLED(CONFIG_BT_AUDIO_UNICAST_CLIENT) && unicast_client) {
/* For the unicast client, the direction and tx/rx is reversed */
if (dir == BT_AUDIO_DIR_SOURCE) {
return iso->rx.ep;
} else {
return iso->tx.ep;
}
}
if (dir == BT_AUDIO_DIR_SINK) { if (dir == BT_AUDIO_DIR_SINK) {
return iso->rx.ep; return iso->rx.ep;
} else { } else {

View file

@ -40,5 +40,6 @@ struct bt_audio_iso *bt_audio_iso_find(bt_audio_iso_func_t func,
void bt_audio_iso_init(struct bt_audio_iso *iso, struct bt_iso_chan_ops *ops); void bt_audio_iso_init(struct bt_audio_iso *iso, struct bt_iso_chan_ops *ops);
void bt_audio_iso_bind_ep(struct bt_audio_iso *iso, struct bt_audio_ep *ep); void bt_audio_iso_bind_ep(struct bt_audio_iso *iso, struct bt_audio_ep *ep);
void bt_audio_iso_unbind_ep(struct bt_audio_iso *iso, struct bt_audio_ep *ep); void bt_audio_iso_unbind_ep(struct bt_audio_iso *iso, struct bt_audio_ep *ep);
struct bt_audio_ep *bt_audio_iso_get_ep(struct bt_audio_iso *iso, struct bt_audio_ep *bt_audio_iso_get_ep(bool unicast_client,
struct bt_audio_iso *iso,
enum bt_audio_dir dir); enum bt_audio_dir dir);

View file

@ -131,3 +131,4 @@ static inline const char *bt_audio_ep_state_str(uint8_t state)
bool bt_audio_ep_is_broadcast_snk(const struct bt_audio_ep *ep); bool bt_audio_ep_is_broadcast_snk(const struct bt_audio_ep *ep);
bool bt_audio_ep_is_broadcast_src(const struct bt_audio_ep *ep); bool bt_audio_ep_is_broadcast_src(const struct bt_audio_ep *ep);
bool bt_audio_ep_is_unicast_client(const struct bt_audio_ep *ep);

View file

@ -738,7 +738,7 @@ static struct bt_audio_iso *get_new_iso(struct bt_audio_unicast_group *group,
continue; continue;
} }
if (bt_audio_iso_get_ep(stream->ep->iso, dir) == NULL) { if (bt_audio_iso_get_ep(true, stream->ep->iso, dir) == NULL) {
return bt_audio_iso_ref(stream->ep->iso); return bt_audio_iso_ref(stream->ep->iso);
} }
} }

View file

@ -235,6 +235,23 @@ static struct bt_iso_chan_ops unicast_client_iso_ops = {
.disconnected = unicast_client_iso_disconnected, .disconnected = unicast_client_iso_disconnected,
}; };
bool bt_audio_ep_is_unicast_client(const struct bt_audio_ep *ep)
{
for (size_t i = 0U; i < ARRAY_SIZE(snks); i++) {
if (PART_OF_ARRAY(snks[i], ep)) {
return true;
}
}
for (size_t i = 0U; i < ARRAY_SIZE(srcs); i++) {
if (PART_OF_ARRAY(srcs[i], ep)) {
return true;
}
}
return false;
}
static void unicast_client_ep_init(struct bt_audio_ep *ep, uint16_t handle, static void unicast_client_ep_init(struct bt_audio_ep *ep, uint16_t handle,
uint8_t dir) uint8_t dir)
{ {