Skip to content

Commit 32ff1b6

Browse files
Thalleycarlescufi
authored andcommitted
Bluetooth: Audio: Add (un)bind of audio iso for streams
This allows us to allocate and bind the Audio ISO structs to Audio Streams, thus allowing us to create the unicast group before they have been configured. Signed-off-by: Emil Gydesen <[email protected]>
1 parent 4c05840 commit 32ff1b6

File tree

4 files changed

+128
-24
lines changed

4 files changed

+128
-24
lines changed

include/zephyr/bluetooth/audio/audio.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,17 +1289,27 @@ struct bt_audio_lc3_preset {
12891289
* symmetric in both directions.
12901290
*/
12911291
struct bt_audio_stream {
1292+
/** Stream direction */
1293+
enum bt_audio_dir dir;
1294+
12921295
/** Connection reference */
12931296
struct bt_conn *conn;
1297+
12941298
/** Endpoint reference */
12951299
struct bt_audio_ep *ep;
1300+
12961301
/** Codec Configuration */
12971302
struct bt_codec *codec;
1303+
12981304
/** QoS Configuration */
12991305
struct bt_codec_qos *qos;
1306+
13001307
/** Audio stream operations */
13011308
struct bt_audio_stream_ops *ops;
13021309

1310+
/** Audio ISO reference */
1311+
struct bt_audio_iso *audio_iso;
1312+
13031313
union {
13041314
void *group;
13051315
struct bt_audio_unicast_group *unicast_group;

subsys/bluetooth/audio/audio_iso.c

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,12 @@ void bt_audio_iso_init(struct bt_audio_iso *iso, struct bt_iso_chan_ops *ops)
141141

142142
void bt_audio_iso_bind_ep(struct bt_audio_iso *iso, struct bt_audio_ep *ep)
143143
{
144-
struct bt_iso_chan_qos *qos;
145-
146144
__ASSERT_NO_MSG(ep != NULL);
147145
__ASSERT_NO_MSG(iso != NULL);
148146
__ASSERT(ep->iso == NULL, "ep %p bound with iso %p already", ep, ep->iso);
149147
__ASSERT(ep->dir == BT_AUDIO_DIR_SINK || ep->dir == BT_AUDIO_DIR_SOURCE,
150148
"invalid dir: %u", ep->dir);
151149

152-
qos = iso->chan.qos;
153-
154150
if (IS_ENABLED(CONFIG_BT_AUDIO_UNICAST_CLIENT) &&
155151
bt_audio_ep_is_unicast_client(ep)) {
156152
/* For the unicast client, the direction and tx/rx is reversed */
@@ -180,17 +176,13 @@ void bt_audio_iso_bind_ep(struct bt_audio_iso *iso, struct bt_audio_ep *ep)
180176

181177
void bt_audio_iso_unbind_ep(struct bt_audio_iso *iso, struct bt_audio_ep *ep)
182178
{
183-
struct bt_iso_chan_qos *qos;
184-
185179
__ASSERT_NO_MSG(ep != NULL);
186180
__ASSERT_NO_MSG(iso != NULL);
187181
__ASSERT(ep->iso == iso, "ep %p not bound with iso %p, was bound to %p",
188182
ep, iso, ep->iso);
189183
__ASSERT(ep->dir == BT_AUDIO_DIR_SINK || ep->dir == BT_AUDIO_DIR_SOURCE,
190184
"Invalid dir: %u", ep->dir);
191185

192-
qos = iso->chan.qos;
193-
194186
if (IS_ENABLED(CONFIG_BT_AUDIO_UNICAST_CLIENT) &&
195187
bt_audio_ep_is_unicast_client(ep)) {
196188
/* For the unicast client, the direction and tx/rx is reversed */
@@ -242,3 +234,72 @@ struct bt_audio_ep *bt_audio_iso_get_ep(bool unicast_client,
242234
return iso->tx.ep;
243235
}
244236
}
237+
238+
#if defined(CONFIG_BT_AUDIO_UNICAST_CLIENT)
239+
void bt_audio_iso_bind_stream(struct bt_audio_iso *audio_iso,
240+
struct bt_audio_stream *stream)
241+
{
242+
struct bt_audio_iso_dir *audio_iso_ep;
243+
244+
__ASSERT_NO_MSG(stream != NULL);
245+
__ASSERT_NO_MSG(audio_iso != NULL);
246+
__ASSERT(stream->audio_iso == NULL,
247+
"stream %p bound with audio_iso %p already",
248+
stream, stream->audio_iso);
249+
250+
/* For the unicast client, the direction and tx/rx is reversed */
251+
if (stream->dir == BT_AUDIO_DIR_SOURCE) {
252+
audio_iso_ep = &audio_iso->rx;
253+
} else {
254+
audio_iso_ep = &audio_iso->tx;
255+
}
256+
257+
__ASSERT(audio_iso_ep->stream == NULL,
258+
"audio_iso %p bound with stream %p",
259+
audio_iso, audio_iso_ep->stream);
260+
audio_iso_ep->stream = stream;
261+
262+
stream->audio_iso = bt_audio_iso_ref(audio_iso);
263+
}
264+
265+
void bt_audio_iso_unbind_stream(struct bt_audio_iso *audio_iso,
266+
struct bt_audio_stream *stream)
267+
{
268+
struct bt_audio_iso_dir *audio_iso_ep;
269+
270+
__ASSERT_NO_MSG(stream != NULL);
271+
__ASSERT_NO_MSG(audio_iso != NULL);
272+
__ASSERT(stream->audio_iso != NULL,
273+
"stream %p not bound with an audio_iso",
274+
stream);
275+
276+
/* For the unicast client, the direction and tx/rx is reversed */
277+
if (stream->dir == BT_AUDIO_DIR_SOURCE) {
278+
audio_iso_ep = &audio_iso->rx;
279+
} else {
280+
audio_iso_ep = &audio_iso->tx;
281+
}
282+
283+
__ASSERT(audio_iso_ep->stream == stream,
284+
"audio_iso %p (%p) not bound with stream %p (%p)",
285+
audio_iso, audio_iso_ep->stream, stream, stream->audio_iso);
286+
audio_iso_ep->stream = NULL;
287+
288+
bt_audio_iso_unref(audio_iso);
289+
stream->audio_iso = NULL;
290+
}
291+
292+
struct bt_audio_stream *bt_audio_iso_get_stream(struct bt_audio_iso *iso,
293+
enum bt_audio_dir dir)
294+
{
295+
__ASSERT(dir == BT_AUDIO_DIR_SINK || dir == BT_AUDIO_DIR_SOURCE,
296+
"invalid dir: %u", dir);
297+
298+
/* For the unicast client, the direction and tx/rx is reversed */
299+
if (dir == BT_AUDIO_DIR_SOURCE) {
300+
return iso->rx.stream;
301+
} else {
302+
return iso->tx.stream;
303+
}
304+
}
305+
#endif /* CONFIG_BT_AUDIO_UNICAST_CLIENT */

subsys/bluetooth/audio/audio_iso.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
#include <zephyr/bluetooth/iso.h>
1010
#include <zephyr/bluetooth/audio/audio.h>
1111

12-
struct bt_audio_iso_ep {
12+
struct bt_audio_iso_dir {
13+
struct bt_audio_stream *stream;
1314
struct bt_audio_ep *ep;
1415
struct bt_iso_chan_path path;
1516
struct bt_iso_chan_io_qos qos;
@@ -20,8 +21,8 @@ struct bt_audio_iso {
2021
struct bt_iso_chan chan;
2122
struct bt_iso_chan_qos qos;
2223

23-
struct bt_audio_iso_ep rx;
24-
struct bt_audio_iso_ep tx;
24+
struct bt_audio_iso_dir rx;
25+
struct bt_audio_iso_dir tx;
2526

2627
/* Must be at the end so that everything else in the structure can be
2728
* memset to zero without affecting the ref.
@@ -43,3 +44,10 @@ void bt_audio_iso_unbind_ep(struct bt_audio_iso *iso, struct bt_audio_ep *ep);
4344
struct bt_audio_ep *bt_audio_iso_get_ep(bool unicast_client,
4445
struct bt_audio_iso *iso,
4546
enum bt_audio_dir dir);
47+
/* Unicast client-only functions*/
48+
void bt_audio_iso_bind_stream(struct bt_audio_iso *audio_iso,
49+
struct bt_audio_stream *stream);
50+
void bt_audio_iso_unbind_stream(struct bt_audio_iso *audio_iso,
51+
struct bt_audio_stream *stream);
52+
struct bt_audio_stream *bt_audio_iso_get_stream(struct bt_audio_iso *iso,
53+
enum bt_audio_dir dir);

subsys/bluetooth/audio/stream.c

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -565,11 +565,12 @@ int bt_audio_stream_qos(struct bt_conn *conn,
565565
return -EINVAL;
566566
}
567567

568-
if (ep->iso == NULL) {
568+
if (stream->audio_iso == NULL) {
569569
/* This can only happen if the stream was somehow added
570570
* to a group without the audio_iso being bound to it
571571
*/
572-
LOG_ERR("Could not find audio_iso for stream %p", stream);
572+
LOG_ERR("Could not find audio_iso for stream %p",
573+
stream);
573574
return -EINVAL;
574575
}
575576
}
@@ -594,6 +595,11 @@ int bt_audio_stream_qos(struct bt_conn *conn,
594595

595596
op->num_ases++;
596597

598+
if (stream->ep->iso == NULL) {
599+
/* Not yet bound with the audio_iso */
600+
bt_audio_iso_bind_ep(stream->audio_iso, stream->ep);
601+
}
602+
597603
err = bt_unicast_client_ep_qos(stream->ep, buf, stream->qos);
598604
if (err) {
599605
audio_stream_qos_cleanup(conn, group);
@@ -741,18 +747,24 @@ static struct bt_audio_iso *get_new_iso(struct bt_audio_unicast_group *group,
741747

742748
/* Check if there's already an ISO that can be used for this direction */
743749
SYS_SLIST_FOR_EACH_CONTAINER(&group->streams, stream, _node) {
744-
__ASSERT(stream->ep, "stream->ep is NULL");
745-
__ASSERT(stream->ep->iso, "ep->iso is NULL");
750+
__ASSERT(stream->audio_iso != NULL, "stream->audio_iso is NULL");
746751

747-
if (stream->conn != acl) {
752+
/* Don't attempt to couple streams if the ACL is either NULL,
753+
* or the connection points differ
754+
*/
755+
if (acl == NULL || stream->conn != acl) {
748756
continue;
749757
}
750758

751-
if (bt_audio_iso_get_ep(true, stream->ep->iso, dir) == NULL) {
752-
return bt_audio_iso_ref(stream->ep->iso);
759+
if (bt_audio_iso_get_stream(stream->audio_iso, dir) == NULL) {
760+
LOG_DBG("Returning existing audio_iso for group %p",
761+
group);
762+
763+
return bt_audio_iso_ref(stream->audio_iso);
753764
}
754765
}
755766

767+
LOG_DBG("Returning new audio_iso for group %p", group);
756768
return bt_unicast_client_new_audio_iso();
757769
}
758770

@@ -861,8 +873,10 @@ static int unicast_group_add_stream(struct bt_audio_unicast_group *group,
861873

862874
__ASSERT_NO_MSG(group != NULL);
863875
__ASSERT_NO_MSG(stream != NULL);
864-
__ASSERT_NO_MSG(stream->ep != NULL);
865-
__ASSERT_NO_MSG(stream->ep->iso == NULL);
876+
__ASSERT_NO_MSG(stream->ep == NULL ||
877+
(stream->ep != NULL && stream->ep->iso == NULL));
878+
879+
LOG_DBG("group %p stream %p dir %u", group, stream, dir);
866880

867881
iso = get_new_iso(group, stream->conn, dir);
868882
if (iso == NULL) {
@@ -875,16 +889,20 @@ static int unicast_group_add_stream(struct bt_audio_unicast_group *group,
875889
return err;
876890
}
877891

892+
stream->qos = qos;
893+
stream->dir = dir;
894+
stream->unicast_group = group;
895+
878896
/* iso initialized already */
879-
bt_audio_iso_bind_ep(iso, stream->ep);
897+
bt_audio_iso_bind_stream(iso, stream);
898+
if (stream->ep != NULL) {
899+
bt_audio_iso_bind_ep(iso, stream->ep);
900+
}
880901

881902
/* Store the Codec QoS in the audio_iso */
882903
unicast_client_codec_qos_to_iso_qos(iso, qos, dir);
883904

884905
bt_audio_iso_unref(iso);
885-
886-
stream->qos = qos;
887-
stream->unicast_group = group;
888906
sys_slist_append(&group->streams, &stream->_node);
889907

890908
LOG_DBG("Added stream %p to group %p", stream, group);
@@ -901,6 +919,10 @@ static void unicast_group_del_stream(struct bt_audio_unicast_group *group,
901919
if (sys_slist_find_and_remove(&group->streams, &stream->_node)) {
902920
struct bt_audio_ep *ep = stream->ep;
903921

922+
if (stream->audio_iso != NULL) {
923+
bt_audio_iso_unbind_stream(stream->audio_iso, stream);
924+
}
925+
904926
if (ep != NULL && ep->iso != NULL) {
905927
unicast_group_del_iso(group, ep->iso);
906928

@@ -941,6 +963,9 @@ static void unicast_group_free(struct bt_audio_unicast_group *group)
941963
struct bt_audio_ep *ep = stream->ep;
942964

943965
stream->unicast_group = NULL;
966+
if (stream->audio_iso != NULL) {
967+
bt_audio_iso_unbind_stream(stream->audio_iso, stream);
968+
}
944969

945970
if (ep != NULL && ep->iso != NULL) {
946971
bt_audio_iso_unbind_ep(ep->iso, ep);

0 commit comments

Comments
 (0)