From 345131475ca3bf4ddb34c7cd934d77ca60f08f1c Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Fri, 10 May 2024 20:15:18 +0300 Subject: [PATCH] bluez5: cleanup bluez5.bcast_source.config parsing Also fix doc. --- doc/dox/config/pipewire-devices.7.md | 33 +++-- spa/plugins/bluez5/bap-codec-lc3.c | 2 +- spa/plugins/bluez5/bluez5-dbus.c | 178 ++++++++++++++------------- 3 files changed, 106 insertions(+), 107 deletions(-) diff --git a/doc/dox/config/pipewire-devices.7.md b/doc/dox/config/pipewire-devices.7.md index a662a0cbd..b15813d37 100644 --- a/doc/dox/config/pipewire-devices.7.md +++ b/doc/dox/config/pipewire-devices.7.md @@ -425,26 +425,23 @@ PipeWire Opus Pro audio profile duplex frame duration (1/10 ms). @PAR@ device-param bluez5.bcast_source.config # JSON \parblock -example JSON -{ - "broadcast_code": [ // broadcast code - 1, 2, 104, 5, 83, 241, 65, 90, 162, 101, 187, 175, 198, 234, 3, 184 - ], +Example: +``` +bluez5.bcast_source.config = [ + { + "broadcast_code": [ 1, 2, 104, 5, 83, 241, 65, 90, 162, 101, 187, 175, 198, 234, 3, 184 ], "bis": [ - { // BIS configuration - "qos_preset": "16_2_1", // QOS preset name from table Table 6.4 from BAP_v1.0.1. - "audio_channel_allocation": 1, // audio channel allocation configuration for the BIS - "metadata": [ // metadata configurations for the BIS - { - "type": 1, - "value": [ - 1, 1 - ] - } - ] - } + { # BIS configuration + "qos_preset": "16_2_1", # QOS preset name from table Table 6.4 from BAP_v1.0.1. + "audio_channel_allocation": 1, # audio channel allocation configuration for the BIS + "metadata": [ # metadata configurations for the BIS + { "type": 1, "value": [ 1, 1 ] } + ] + } ] -} + } +] +``` \endparblock ## Device properties diff --git a/spa/plugins/bluez5/bap-codec-lc3.c b/spa/plugins/bluez5/bap-codec-lc3.c index 6d996a733..2595bdeb0 100644 --- a/spa/plugins/bluez5/bap-codec-lc3.c +++ b/spa/plugins/bluez5/bap-codec-lc3.c @@ -1174,7 +1174,7 @@ static int codec_get_bis_config(const struct media_codec *codec, uint8_t *caps, return -EINVAL; SPA_FOR_EACH_ELEMENT_VAR(bap_bcast_qos_configs, c) { - if (strcmp(c->name, preset) == 0) { + if (spa_streq(c->name, preset)) { preset_found = true; break; } diff --git a/spa/plugins/bluez5/bluez5-dbus.c b/spa/plugins/bluez5/bluez5-dbus.c index 72c9ac089..49f4731bc 100644 --- a/spa/plugins/bluez5/bluez5-dbus.c +++ b/spa/plugins/bluez5/bluez5-dbus.c @@ -6078,121 +6078,123 @@ static void parse_broadcast_source_config(struct spa_bt_monitor *monitor, const int cursor; int big_id = 0; struct spa_json it[4], it_array[4]; - struct spa_bt_big *big_entry = NULL; - struct spa_bt_bis *bis_entry = NULL; - struct spa_bt_metadata *metadata_entry = NULL; - int temp_val = 0; struct spa_list big_list = SPA_LIST_INIT(&big_list); + struct spa_error_location loc; + struct spa_bt_big *big; /* Search for bluez5.bcast_source.config */ - if (info && (str = spa_dict_lookup(info, "bluez5.bcast_source.config"))) { - spa_json_init(&it[0], str, strlen(str)); - /* Verify is an array of BIGS */ - if (spa_json_enter_array(&it[0], &it_array[0]) <= 0) - goto parse_failed; + if (!(info && (str = spa_dict_lookup(info, "bluez5.bcast_source.config")))) + return; - /* Iterate on all BIG objects */ - while (spa_json_enter_object(&it_array[0], &it[1]) > 0) { - big_entry = calloc(1, sizeof(struct spa_bt_big)); - spa_list_init(&big_entry->bis_list); - spa_list_append(&big_list, &big_entry->link); - /* Iterate on all BIG values */ - while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) { - if (spa_streq(key, "broadcast_code")) { - if (spa_json_enter_array(&it[1], &it_array[1]) <= 0) + spa_json_init(&it[0], str, strlen(str)); + + /* Verify is an array of BIGS */ + if (spa_json_enter_array(&it[0], &it_array[0]) <= 0) + goto parse_failed; + + /* Iterate on all BIG objects */ + while (spa_json_enter_object(&it_array[0], &it[1]) > 0) { + struct spa_bt_big *big_entry = calloc(1, sizeof(struct spa_bt_big)); + + if (!big_entry) + goto errno_failed; + + big_entry->big_id = big_id++; + spa_list_init(&big_entry->bis_list); + spa_list_append(&big_list, &big_entry->link); + + /* Iterate on all BIG values */ + while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) { + if (spa_streq(key, "broadcast_code")) { + if (spa_json_enter_array(&it[1], &it_array[1]) <= 0) + goto parse_failed; + for (cursor = 0; cursor < BROADCAST_CODE_LEN; cursor++) { + if (spa_json_get_int(&it_array[1], &big_entry->broadcast_code[cursor]) <= 0) goto parse_failed; - for (cursor = 0; cursor < BROADCAST_CODE_LEN; cursor++) { - if (spa_json_get_int(&it_array[1], &big_entry->broadcast_code[cursor]) <= 0) - goto parse_failed; - spa_log_debug(monitor->log, "big_entry->broadcast_code %d", big_entry->broadcast_code[cursor]); - } - } else if (spa_streq(key, "bis")) { - if (spa_json_enter_array(&it[1], &it_array[1]) <= 0) - goto parse_failed; - while (spa_json_enter_object(&it_array[1], &it[2]) > 0) { - /* Iterate on all BIS values */ - bis_entry = calloc(1, sizeof(struct spa_bt_bis)); - spa_list_init(&bis_entry->metadata_list); - while (spa_json_get_string(&it[2], bis_key, sizeof(bis_key)) > 0) { - if (spa_streq(bis_key, "qos_preset")) { - spa_json_get_string(&it[2], bis_entry->qos_preset, sizeof(bis_entry->qos_preset)); - spa_log_debug(monitor->log, "bis_entry->qos_preset %s", bis_entry->qos_preset); - } else if (spa_streq(bis_key, "audio_channel_allocation")) { - if (spa_json_get_int(&it[2], &bis_entry->channel_allocation) <= 0) + spa_log_debug(monitor->log, "big_entry->broadcast_code[%d] %d", cursor, big_entry->broadcast_code[cursor]); + } + } else if (spa_streq(key, "bis")) { + if (spa_json_enter_array(&it[1], &it_array[1]) <= 0) + goto parse_failed; + while (spa_json_enter_object(&it_array[1], &it[2]) > 0) { + /* Iterate on all BIS values */ + struct spa_bt_bis *bis_entry = calloc(1, sizeof(struct spa_bt_bis)); + + if (!bis_entry) + goto errno_failed; + + spa_list_init(&bis_entry->metadata_list); + spa_list_append(&big_entry->bis_list, &bis_entry->link); + + while (spa_json_get_string(&it[2], bis_key, sizeof(bis_key)) > 0) { + if (spa_streq(bis_key, "qos_preset")) { + if (spa_json_get_string(&it[2], bis_entry->qos_preset, sizeof(bis_entry->qos_preset)) <= 0) + goto parse_failed; + spa_log_debug(monitor->log, "bis_entry->qos_preset %s", bis_entry->qos_preset); + } else if (spa_streq(bis_key, "audio_channel_allocation")) { + if (spa_json_get_int(&it[2], &bis_entry->channel_allocation) <= 0) + goto parse_failed; + spa_log_debug(monitor->log, "bis_entry->channel_allocation %d", bis_entry->channel_allocation); + } else if (spa_streq(bis_key, "metadata")) { + if (spa_json_enter_array(&it[2], &it_array[2]) <= 0) + goto parse_failed; + while (spa_json_enter_object(&it_array[2], &it[3]) > 0) { + struct spa_bt_metadata *metadata_entry = calloc(1, sizeof(struct spa_bt_metadata)); + + if (!metadata_entry) + goto errno_failed; + + spa_list_append(&bis_entry->metadata_list, &metadata_entry->link); + + while (spa_json_get_string(&it[3], qos_key, sizeof(qos_key)) > 0) { + if (spa_streq(qos_key, "type")) { + if (spa_json_get_int(&it[3], &metadata_entry->type) <= 0) goto parse_failed; - spa_log_debug(monitor->log, "bis_entry->channel_allocation %d", bis_entry->channel_allocation); - } else if (spa_streq(bis_key, "metadata")) { - if (spa_json_enter_array(&it[2], &it_array[2]) <= 0) - goto parse_failed; - while (spa_json_enter_object(&it_array[2], &it[3]) > 0) { - metadata_entry = calloc(1, sizeof(struct spa_bt_metadata)); - while (spa_json_get_string(&it[3], qos_key, sizeof(qos_key)) > 0) { - if (spa_streq(qos_key, "type")) { - if (spa_json_get_int(&it[3], &metadata_entry->type) <= 0) - goto parse_failed; - spa_log_debug(monitor->log, "metadata_entry->type %d", metadata_entry->type); - } else if (spa_streq(qos_key, "value")) { - if (spa_json_enter_array(&it[3], &it_array[3]) <= 0) - goto parse_failed; - for (cursor = 0; cursor < METADATA_MAX_LEN; cursor++) { - if (spa_json_get_int(&it_array[3], &temp_val) <= 0) - break; - metadata_entry->value[cursor] = (uint8_t)temp_val; - spa_log_debug(monitor->log, "metadata_entry->value[cursor] %d", metadata_entry->value[cursor]); - } - /* length is size of value plus 1 octet for type */ - metadata_entry->length = cursor + 1; - spa_log_debug(monitor->log, "metadata_entry->length %d", metadata_entry->length); - spa_log_debug(monitor->log, "metadata_entry->value_size %d", cursor); - spa_list_append(&bis_entry->metadata_list, &metadata_entry->link); - metadata_entry = NULL; + spa_log_debug(monitor->log, "metadata_entry->type %d", metadata_entry->type); + } else if (spa_streq(qos_key, "value")) { + if (spa_json_enter_array(&it[3], &it_array[3]) <= 0) + goto parse_failed; + for (cursor = 0; cursor < METADATA_MAX_LEN; cursor++) { + int temp_val = 0; + if (spa_json_get_int(&it_array[3], &temp_val) <= 0) + break; + metadata_entry->value[cursor] = (uint8_t)temp_val; + spa_log_debug(monitor->log, "metadata_entry->value[%d] %d", cursor, metadata_entry->value[cursor]); } - + /* length is size of value plus 1 octet for type */ + metadata_entry->length = cursor + 1; + spa_log_debug(monitor->log, "metadata_entry->length %d", metadata_entry->length); + spa_log_debug(monitor->log, "metadata_entry->value_size %d", cursor); } } } } - spa_list_append(&big_entry->bis_list, &bis_entry->link); - bis_entry = NULL; } } } - big_entry->big_id = big_id; - big_id ++; - big_entry = NULL; } } spa_list_insert_list(&monitor->bcast_source_config_list, &big_list); return; -parse_failed: - struct spa_error_location loc; +errno_failed: + spa_log_warn(monitor->log, "failed in bluez5.bcast_source.config: %m"); + goto cleanup; +parse_failed: str = spa_dict_lookup(info, "bluez5.bcast_source.config"); if (spa_json_get_error(&it[0], str, &loc)) { spa_debug_log_error_location(monitor->log, SPA_LOG_LEVEL_WARN, &loc, "malformed bluez5.bcast_source.config: %s", loc.reason); + } else { + spa_log_warn(monitor->log, "malformed bluez5.bcast_source.config"); } + goto cleanup; - if (metadata_entry) - free(metadata_entry); - - if (bis_entry) { - spa_list_consume(metadata_entry, &bis_entry->metadata_list, link) - free(metadata_entry); - free(bis_entry); - } - - if (big_entry) { - spa_list_consume(bis_entry, &big_entry->bis_list, link) - bis_entry_free(bis_entry); - free(big_entry); - } - - spa_list_consume(big_entry, &big_list, link) - big_entry_free(big_entry); - +cleanup: + spa_list_consume(big, &big_list, link) + big_entry_free(big); } static int parse_codec_array(struct spa_bt_monitor *this, const struct spa_dict *info)