@@ -1034,13 +1034,6 @@ static void iso_bcast_confirm_cb(GIOChannel *io, GError *err, void *user_data)
}
}
-static void print_ltv(size_t i, uint8_t l, uint8_t t, uint8_t *v,
- void *user_data)
-{
- util_debug(user_data, NULL, "CC #%zu: l:%u t:%u", i, l, t);
- util_hexdump(' ', v, l, user_data, NULL);
-}
-
void bap_qos_to_iso_qos(struct bt_bap_qos *bap_qos,
struct bt_iso_qos *iso_qos)
{
@@ -1093,15 +1086,16 @@ void bap_iso_qos_to_bap_qos(struct bt_iso_qos *iso_qos,
}
static void create_stream_for_bis(struct bap_data *bap_data,
- struct bt_bap_pac *lpac, struct bt_iso_qos *qos,
+ struct bt_bap_pac *lpac, struct bt_bap_qos *qos,
struct iovec *caps, struct iovec *meta, char *path)
{
struct bap_setup *setup;
setup = setup_new(NULL);
+ setup->qos = *qos;
- /* Create BAP QoS structure */
- bap_iso_qos_to_bap_qos(qos, &setup->qos);
+ /* Create an internal copy for bcode */
+ setup->qos.bcast.bcode = util_iov_dup(qos->bcast.bcode, 1);
queue_push_tail(bap_data->bcast_snks, setup);
@@ -1116,170 +1110,37 @@ static void create_stream_for_bis(struct bap_data *bap_data,
NULL, NULL);
}
-static bool parse_base(struct bap_data *bap_data, struct bt_iso_base *base,
- struct bt_iso_qos *qos, util_debug_func_t func)
+static void bis_handler(uint8_t bis, uint8_t sgrp, struct iovec *caps,
+ struct iovec *meta, struct bt_bap_qos *qos, void *user_data)
{
- struct iovec iov = {
- .iov_base = base->base,
- .iov_len = base->base_len,
- };
- uint32_t pres_delay;
- uint8_t num_subgroups;
- bool ret = true;
-
- util_debug(func, NULL, "BASE len: %ld", iov.iov_len);
-
- if (!util_iov_pull_le24(&iov, &pres_delay))
- return false;
- util_debug(func, NULL, "PresentationDelay: %d", pres_delay);
-
- if (!util_iov_pull_u8(&iov, &num_subgroups))
- return false;
- util_debug(func, NULL, "Number of Subgroups: %d", num_subgroups);
-
- /* Loop subgroups */
- for (int idx = 0; idx < num_subgroups; idx++) {
- uint8_t num_bis;
- struct bt_bap_codec codec;
- struct iovec *l2_caps = NULL;
- struct iovec *meta = NULL;
-
- util_debug(func, NULL, "Subgroup #%d", idx);
-
- if (!util_iov_pull_u8(&iov, &num_bis)) {
- ret = false;
- goto fail;
- }
- util_debug(func, NULL, "Number of BISes: %d", num_bis);
-
- memcpy(&codec,
- util_iov_pull_mem(&iov,
- sizeof(struct bt_bap_codec)),
- sizeof(struct bt_bap_codec));
- util_debug(func, NULL, "Codec: ID %d CID 0x%2.2x VID 0x%2.2x",
- codec.id, codec.cid, codec.vid);
-
- /* Level 2 */
- /* Read Codec Specific Configuration */
- l2_caps = new0(struct iovec, 1);
- if (!util_iov_pull_u8(&iov, (void *)&l2_caps->iov_len)) {
- ret = false;
- goto group_fail;
- }
-
- util_iov_memcpy(l2_caps, util_iov_pull_mem(&iov,
- l2_caps->iov_len),
- l2_caps->iov_len);
-
- /* Print Codec Specific Configuration */
- util_debug(func, NULL, "CC len: %ld", l2_caps->iov_len);
- util_ltv_foreach(l2_caps->iov_base, l2_caps->iov_len, NULL,
- print_ltv, func);
-
- /* Read Metadata */
- meta = new0(struct iovec, 1);
- if (!util_iov_pull_u8(&iov, (void *)&meta->iov_len)) {
- ret = false;
- goto group_fail;
- }
-
- util_iov_memcpy(meta,
- util_iov_pull_mem(&iov, meta->iov_len),
- meta->iov_len);
-
- /* Print Metadata */
- util_debug(func, NULL, "Metadata len: %i",
- (uint8_t)meta->iov_len);
- util_hexdump(' ', meta->iov_base, meta->iov_len, func, NULL);
-
- /* Level 3 */
- for (; num_bis; num_bis--) {
- uint8_t bis_index;
- struct iovec *l3_caps;
- struct iovec *merged_caps;
- struct bt_bap_pac *matched_lpac;
- char *path;
- int err;
-
- if (!util_iov_pull_u8(&iov, &bis_index)) {
- ret = false;
- goto group_fail;
- }
-
- util_debug(func, NULL, "BIS #%d", bis_index);
- err = asprintf(&path, "%s/bis%d",
- device_get_path(bap_data->device),
- bis_index);
- if (err < 0)
- continue;
-
- /* Read Codec Specific Configuration */
- l3_caps = new0(struct iovec, 1);
- if (!util_iov_pull_u8(&iov,
- (void *)&l3_caps->iov_len)) {
- free(l3_caps);
- free(path);
- ret = false;
- goto group_fail;
- }
-
- util_iov_memcpy(l3_caps,
- util_iov_pull_mem(&iov,
- l3_caps->iov_len),
- l3_caps->iov_len);
-
- /* Print Codec Specific Configuration */
- util_debug(func, NULL, "CC Len: %d",
- (uint8_t)l3_caps->iov_len);
- util_ltv_foreach(l3_caps->iov_base,
- l3_caps->iov_len, NULL, print_ltv,
- func);
-
- merged_caps = bt_bap_merge_caps(l2_caps, l3_caps);
- if (!merged_caps) {
- free(path);
- continue;
- }
-
- bass_add_stream(bap_data->device, meta, merged_caps,
- qos, idx, bis_index);
-
- if (!bass_check_bis(bap_data->device, bis_index)) {
- /* If this Broadcast Sink is acting as a Scan
- * Delegator, only attempt to create streams
- * for the BISes required by the peer Broadcast
- * Assistant.
- */
- continue;
- }
+ struct bap_data *data = user_data;
+ struct bt_bap_pac *lpac;
+ char *path;
- /* Check if this BIS matches any local PAC */
- bt_bap_verify_bis(bap_data->bap, bis_index,
- merged_caps, &matched_lpac);
+ bass_add_stream(data->device, meta, caps, qos, sgrp, bis);
- if (matched_lpac == NULL) {
- free(path);
- continue;
- }
+ if (!bass_check_bis(data->device, bis))
+ /* If this Broadcast Sink is acting as a Scan
+ * Delegator, only attempt to create streams
+ * for the BISes required by the peer Broadcast
+ * Assistant.
+ */
+ return;
- create_stream_for_bis(bap_data, matched_lpac, qos,
- merged_caps, meta, path);
- }
+ /* Check if this BIS matches any local PAC */
+ bt_bap_verify_bis(data->bap, bis,
+ caps, &lpac);
-group_fail:
- if (l2_caps != NULL)
- free(l2_caps);
- if (meta != NULL)
- free(meta);
- if (!ret)
- break;
- }
+ if (!lpac)
+ return;
-fail:
- if (!ret)
- util_debug(func, NULL, "Unable to parse Base");
+ if (asprintf(&path, "%s/bis%d",
+ device_get_path(data->device),
+ bis) < 0)
+ return;
- return ret;
+ create_stream_for_bis(data, lpac, qos,
+ caps, meta, path);
}
static gboolean big_info_report_cb(GIOChannel *io, GIOCondition cond,
@@ -1290,6 +1151,8 @@ static gboolean big_info_report_cb(GIOChannel *io, GIOCondition cond,
struct bap_data *data = btd_service_get_user_data(req->data.service);
struct bt_iso_base base;
struct bt_iso_qos qos;
+ struct iovec iov;
+ struct bt_bap_qos bap_qos = {0};
DBG("BIG Info received");
@@ -1329,7 +1192,15 @@ static gboolean big_info_report_cb(GIOChannel *io, GIOCondition cond,
/* Analyze received BASE data and create remote media endpoints for each
* BIS matching our capabilities
*/
- parse_base(data, &base, &qos, bap_debug);
+ iov.iov_base = base.base;
+ iov.iov_len = base.base_len;
+
+ /* Create BAP QoS structure */
+ bap_iso_qos_to_bap_qos(&qos, &bap_qos);
+
+ bt_bap_parse_base(&iov, &bap_qos, bap_debug, bis_handler, data);
+
+ util_iov_free(bap_qos.bcast.bcode, 1);
service_set_connecting(req->data.service);
@@ -92,7 +92,7 @@ struct bass_assistant {
uint8_t sgrp;
uint8_t bis;
uint32_t bid;
- struct bt_iso_qos qos;
+ struct bt_bap_qos qos;
struct iovec *meta;
struct iovec *caps;
enum assistant_state state;
@@ -399,8 +399,8 @@ static int assistant_parse_qos(struct bass_assistant *assistant,
return -EINVAL;
}
- memcpy(assistant->qos.bcast.bcode, iov.iov_base,
- iov.iov_len);
+ util_iov_free(assistant->qos.bcast.bcode, 1);
+ assistant->qos.bcast.bcode = util_iov_dup(&iov, 1);
return 0;
}
@@ -592,7 +592,12 @@ static gboolean get_qos(const GDBusPropertyTable *property,
{
struct bass_assistant *assistant = data;
DBusMessageIter dict;
- uint8_t *bcode = assistant->qos.bcast.bcode;
+ uint8_t arr[BT_BASS_BCAST_CODE_SIZE] = {0};
+ uint8_t *bcode = arr;
+
+ if (assistant->qos.bcast.bcode)
+ memcpy(arr, assistant->qos.bcast.bcode->iov_base,
+ BT_BASS_BCAST_CODE_SIZE);
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
@@ -648,7 +653,7 @@ static void src_ad_search_bid(void *data, void *user_data)
static struct bass_assistant *assistant_new(struct btd_adapter *adapter,
struct btd_device *device, struct bass_data *data,
- uint8_t sgrp, uint8_t bis, struct bt_iso_qos *qos,
+ uint8_t sgrp, uint8_t bis, struct bt_bap_qos *qos,
struct iovec *meta, struct iovec *caps)
{
struct bass_assistant *assistant;
@@ -666,6 +671,10 @@ static struct bass_assistant *assistant_new(struct btd_adapter *adapter,
assistant->sgrp = sgrp;
assistant->bis = bis;
assistant->qos = *qos;
+
+ /* Create an internal copy for bcode */
+ assistant->qos.bcast.bcode = util_iov_dup(qos->bcast.bcode, 1);
+
assistant->meta = util_iov_dup(meta, 1);
assistant->caps = util_iov_dup(caps, 1);
@@ -689,7 +698,7 @@ static struct bass_assistant *assistant_new(struct btd_adapter *adapter,
}
void bass_add_stream(struct btd_device *device, struct iovec *meta,
- struct iovec *caps, struct bt_iso_qos *qos,
+ struct iovec *caps, struct bt_bap_qos *qos,
uint8_t sgrp, uint8_t bis)
{
const struct queue_entry *entry;
@@ -998,7 +1007,7 @@ static void bass_attached(struct bt_bass *bass, void *user_data)
static void bass_handle_bcode_req(struct bass_assistant *assistant, int id)
{
struct bt_bass_bcast_audio_scan_cp_hdr hdr;
- struct bt_bass_set_bcast_code_params params;
+ struct bt_bass_set_bcast_code_params params = {0};
struct iovec iov = {0};
int err;
@@ -1007,8 +1016,11 @@ static void bass_handle_bcode_req(struct bass_assistant *assistant, int id)
hdr.op = BT_BASS_SET_BCAST_CODE;
params.id = id;
- memcpy(params.bcast_code, assistant->qos.bcast.bcode,
- BT_BASS_BCAST_CODE_SIZE);
+
+ if (assistant->qos.bcast.bcode)
+ memcpy(params.bcast_code,
+ assistant->qos.bcast.bcode->iov_base,
+ BT_BASS_BCAST_CODE_SIZE);
iov.iov_base = malloc0(sizeof(params));
if (!iov.iov_base)
@@ -8,7 +8,7 @@
*/
void bass_add_stream(struct btd_device *device, struct iovec *meta,
- struct iovec *caps, struct bt_iso_qos *qos,
+ struct iovec *caps, struct bt_bap_qos *qos,
uint8_t sgrp, uint8_t bis);
void bass_remove_stream(struct btd_device *device);