[pulseaudio-discuss] [PATCH v8 11/12] bluetooth: Implement A2DP codec switching and backchannel support

Pali Rohár pali.rohar at gmail.com
Fri Apr 12 12:38:07 UTC 2019


On Saturday 06 April 2019 11:16:06 Pali Rohár wrote:
> --- a/src/modules/bluetooth/bluez5-util.c
> +++ b/src/modules/bluetooth/bluez5-util.c
> @@ -812,6 +901,149 @@ static void parse_device_properties(pa_bluetooth_device *d, DBusMessageIter *i)
>      }
>  }
>  
> +static void parse_remote_endpoint_properties(pa_bluetooth_discovery *y, const char *endpoint, DBusMessageIter *i) {
> +    DBusMessageIter element_i;
> +    pa_bluetooth_device *device;
> +    pa_hashmap *codec_endpoints;
> +    pa_hashmap *endpoints;
> +    pa_a2dp_codec_id *a2dp_codec_id;
> +    pa_a2dp_codec_capabilities *a2dp_codec_capabilities;
> +    const char *uuid = NULL;
> +    const char *device_path = NULL;
> +    uint8_t codec_id = 0;
> +    bool have_codec_id = false;
> +    const uint8_t *capabilities = NULL;
> +    int capabilities_size = 0;
> +
> +    pa_log_debug("Parsing remote endpoint %s", endpoint);
> +
> +    dbus_message_iter_recurse(i, &element_i);
> +
> +    while (dbus_message_iter_get_arg_type(&element_i) == DBUS_TYPE_DICT_ENTRY) {
> +        DBusMessageIter dict_i, variant_i;
> +        const char *key;
> +
> +        dbus_message_iter_recurse(&element_i, &dict_i);
> +
> +        key = check_variant_property(&dict_i);
> +        if (key == NULL) {
> +            pa_log_error("Received invalid property for remote endpoint %s", endpoint);
> +            return;
> +        }
> +
> +        dbus_message_iter_recurse(&dict_i, &variant_i);
> +
> +        if (pa_streq(key, "UUID")) {
> +            if (dbus_message_iter_get_arg_type(&variant_i) != DBUS_TYPE_STRING) {
> +                pa_log_warn("Remote endpoint %s property 'UUID' is not string, ignoring", endpoint);
> +                return;
> +            }
> +
> +            dbus_message_iter_get_basic(&variant_i, &uuid);
> +        } else if (pa_streq(key, "Codec")) {
> +            if (dbus_message_iter_get_arg_type(&variant_i) != DBUS_TYPE_BYTE) {
> +                pa_log_warn("Remote endpoint %s property 'Codec' is not byte, ignoring", endpoint);
> +                return;
> +            }
> +
> +            dbus_message_iter_get_basic(&variant_i, &codec_id);
> +            have_codec_id = true;
> +        } else if (pa_streq(key, "Capabilities")) {
> +            DBusMessageIter array;
> +
> +            if (dbus_message_iter_get_arg_type(&variant_i) != DBUS_TYPE_ARRAY) {
> +                pa_log_warn("Remote endpoint %s property 'Capabilities' is not array, ignoring", endpoint);
> +                return;
> +            }
> +
> +            dbus_message_iter_recurse(&variant_i, &array);
> +            if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_BYTE) {
> +                pa_log_warn("Remote endpoint %s property 'Capabilities' is not array of bytes, ignoring", endpoint);
> +                return;
> +            }
> +
> +            dbus_message_iter_get_fixed_array(&array, &capabilities, &capabilities_size);
> +        } else if (pa_streq(key, "Device")) {
> +            if (dbus_message_iter_get_arg_type(&variant_i) != DBUS_TYPE_OBJECT_PATH) {
> +                pa_log_warn("Remote endpoint %s property 'Device' is not path, ignoring", endpoint);
> +                return;
> +            }
> +
> +            dbus_message_iter_get_basic(&variant_i, &device_path);
> +        }
> +
> +        dbus_message_iter_next(&element_i);
> +    }
> +
> +    if (!uuid) {
> +        pa_log_warn("Remote endpoint %s does not have property 'UUID', ignoring", endpoint);
> +        return;
> +    }
> +
> +    if (!have_codec_id) {
> +        pa_log_warn("Remote endpoint %s does not have property 'Codec', ignoring", endpoint);
> +        return;
> +    }
> +
> +    if (!capabilities || !capabilities_size) {
> +        pa_log_warn("Remote endpoint %s does not have property 'Capabilities', ignoring", endpoint);
> +        return;
> +    }
> +
> +    if (!device_path) {
> +        pa_log_warn("Remote endpoint %s does not have property 'Device', ignoring", endpoint);
> +        return;
> +    }
> +
> +    device = pa_hashmap_get(y->devices, device_path);
> +    if (!device) {
> +        pa_log_warn("Device for remote endpoint %s was not found", endpoint);
> +        return;
> +    }
> +
> +    if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SINK)) {
> +        codec_endpoints = device->a2dp_source_endpoints;
> +    } else if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SOURCE)) {
> +        codec_endpoints = device->a2dp_sink_endpoints;

This is incorrect and was caused by bug in bluez git code. Now it is
fixed in bluez git master. So I fix it in next patch version. Correctly
for PA_BLUETOOTH_UUID_A2DP_SINK should be used a2dp_sink_endpoints, not
source endpoints. And vice-versa for A2DP_SOURCE.

> +    } else {
> +        pa_log_warn("Remote endpoint %s does not have valid property 'UUID', ignoring", endpoint);
> +        return;
> +    }

-- 
Pali Rohár
pali.rohar at gmail.com


More information about the pulseaudio-discuss mailing list