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;
}
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",
&iso->chan, ep->dir);
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;
if (ep->dir == BT_AUDIO_DIR_SINK) {
__ASSERT(iso->rx.ep == NULL,
"iso %p bound with ep %p", iso, iso->rx.ep);
iso->rx.ep = ep;
if (IS_ENABLED(CONFIG_BT_AUDIO_UNICAST_CLIENT) &&
bt_audio_ep_is_unicast_client(ep)) {
/* For the unicast client, the direction and tx/rx is reversed */
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 {
__ASSERT(iso->tx.ep == NULL,
"iso %p bound with ep %p", iso, iso->tx.ep);
iso->tx.ep = ep;
if (ep->dir == BT_AUDIO_DIR_SINK) {
__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;
}
}
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;
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;
if (IS_ENABLED(CONFIG_BT_AUDIO_UNICAST_CLIENT) &&
bt_audio_ep_is_unicast_client(ep)) {
/* For the unicast client, the direction and tx/rx is reversed */
if (ep->dir == BT_AUDIO_DIR_SOURCE) {
__ASSERT(iso->rx.ep == NULL,
"iso %p not bound with ep %p", iso, iso->rx.ep);
iso->rx.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);
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)
{
__ASSERT(dir == BT_AUDIO_DIR_SINK || dir == BT_AUDIO_DIR_SOURCE,
"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) {
return iso->rx.ep;
} 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_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);
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);

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_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;
}
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);
}
}

View file

@ -235,6 +235,23 @@ static struct bt_iso_chan_ops unicast_client_iso_ops = {
.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,
uint8_t dir)
{