Split bt_bap_stream_new and two specific functions for unicast and broadcast. Add a function to find an remote endpoint for broadcast source. --- src/shared/bap.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ src/shared/bap.h | 6 ++++ 2 files changed, 98 insertions(+) diff --git a/src/shared/bap.c b/src/shared/bap.c index 0a336fc01..0931c8fa2 100644 --- a/src/shared/bap.c +++ b/src/shared/bap.c @@ -5043,6 +5043,16 @@ static bool find_ep_pacs(const void *data, const void *user_data) return false; } +static bool find_ep_source(const void *data, const void *user_data) +{ + const struct bt_bap_endpoint *ep = data; + + if (ep->dir == BT_BAP_BCAST_SINK) + return true; + else + return false; +} + unsigned int bt_bap_stream_config(struct bt_bap_stream *stream, struct bt_bap_qos *qos, struct iovec *data, @@ -5153,6 +5163,88 @@ int bt_bap_select(struct bt_bap_pac *lpac, struct bt_bap_pac *rpac, return 0; } +struct bt_bap_stream *bt_bap_stream_bcast_new(struct bt_bap *bap, + struct bt_bap_pac *lpac, + struct bt_bap_pac *rpac, + struct bt_bap_qos *pqos, + struct iovec *data) +{ + struct bt_bap_stream *stream = NULL; + struct bt_bap_endpoint *ep = NULL; + struct match_pac match; + + if (!bap) + return NULL; + + if (!rpac && (lpac->type != BT_BAP_BCAST_SOURCE) + && queue_isempty(bap->remote_eps)) + return NULL; + + if (lpac && rpac) { + if ((rpac->type != BT_BAP_BCAST_SOURCE) + && (!bap_codec_equal(&lpac->codec, &rpac->codec))) + return NULL; + } else { + uint8_t type; + + match.lpac = lpac; + match.rpac = rpac; + memset(&match.codec, 0, sizeof(match.codec)); + + if (rpac) + type = rpac->type; + else if (lpac) { + switch (lpac->type) { + case BT_BAP_BCAST_SOURCE: + type = BT_BAP_BCAST_SINK; + break; + case BT_BAP_BCAST_SINK: + type = BT_BAP_BCAST_SOURCE; + break; + default: + return NULL; + } + } else + return NULL; + + bt_bap_foreach_pac(bap, type, match_pac, &match); + if ((!match.lpac) || (!lpac)) + return NULL; + if (!match.rpac && (lpac->type != BT_BAP_BCAST_SOURCE)) + return NULL; + + lpac = match.lpac; + rpac = match.rpac; + } + + match.lpac = lpac; + match.rpac = rpac; + + if (lpac->type != BT_BAP_BCAST_SOURCE) { + /* Check for existing stream */ + ep = queue_find(bap->remote_eps, find_ep_pacs, &match); + if (!ep) { + /* Check for unused ASE */ + ep = queue_find(bap->remote_eps, find_ep_unused, + &match); + if (!ep) { + DBG(bap, "Unable to find unused ASE"); + return NULL; + } + } + stream = ep->stream; + } else { + ep = queue_find(bap->remote_eps, find_ep_source, NULL); + if (!ep) + return NULL; + } + + if (!stream) + stream = bap_stream_new(bap, ep, lpac, rpac, data, true); + + return stream; +} + struct bt_bap_stream *bt_bap_stream_new(struct bt_bap *bap, struct bt_bap_pac *lpac, struct bt_bap_pac *rpac, diff --git a/src/shared/bap.h b/src/shared/bap.h index 2c3550921..fa0d4b524 100644 --- a/src/shared/bap.h +++ b/src/shared/bap.h @@ -244,6 +244,12 @@ struct bt_bap_stream *bt_bap_stream_new(struct bt_bap *bap, struct bt_bap_qos *pqos, struct iovec *data); +struct bt_bap_stream *bt_bap_stream_bcast_new(struct bt_bap *bap, + struct bt_bap_pac *lpac, + struct bt_bap_pac *rpac, + struct bt_bap_qos *pqos, + struct iovec *data); + struct bt_bap *bt_bap_stream_get_session(struct bt_bap_stream *stream); uint8_t bt_bap_stream_get_state(struct bt_bap_stream *stream); -- 2.39.2