From: Jo?o Paulo Rechi Vita <jprvita@xxxxxxxxx> bluetoothd always send the GetManagedObjects() reply messages with the objects array argument following an in-depth order starting from the root. That means parents will always be known at the time their children objects are parsed, if clients parse the objects in the same order they appear in the array, as we do in PulseAudio. This commit tries to protect PulseAudio in the case bluetoothd changes that behavior for some reason. It hasn't been tested, since this situation never occurs. --- src/modules/bluetooth/bluez5-util.c | 16 ++++++++++++++-- src/modules/bluetooth/bluez5-util.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c index 541948f..17889b6 100644 --- a/src/modules/bluetooth/bluez5-util.c +++ b/src/modules/bluetooth/bluez5-util.c @@ -489,11 +489,13 @@ static void parse_device_property(pa_bluetooth_device *d, DBusMessageIter *i, bo return; } - if (d->adapter) { + if (d->adapter_path) { pa_log_warn("Device %s: Received a duplicate 'Adapter' property, ignoring", d->path); return; } + d->adapter_path = pa_xstrdup(value); + d->adapter = pa_hashmap_get(d->discovery->adapters, value); if (!d->adapter) pa_log_info("Device %s: 'Adapter' property references an unknown adapter %s.", d->path, value); @@ -561,7 +563,7 @@ static int parse_device_properties(pa_bluetooth_device *d, DBusMessageIter *i, b dbus_message_iter_next(&element_i); } - if (!d->address || !d->adapter || !d->alias) { + if (!d->address || !d->adapter_path || !d->alias) { pa_log_error("Non-optional information missing for device %s", d->path); d->device_info_valid = -1; return -1; @@ -685,6 +687,7 @@ static void register_endpoint(pa_bluetooth_discovery *y, const char *path, const static void parse_interfaces_and_properties(pa_bluetooth_discovery *y, DBusMessageIter *dict_i) { DBusMessageIter element_i; const char *path; + void *state; pa_bluetooth_device *d; pa_assert(dbus_message_iter_get_arg_type(dict_i) == DBUS_TYPE_OBJECT_PATH); @@ -745,6 +748,15 @@ static void parse_interfaces_and_properties(pa_bluetooth_discovery *y, DBusMessa dbus_message_iter_next(&element_i); } + PA_HASHMAP_FOREACH(d, y->devices, state) + if (!d->adapter && d->adapter_path) { + d->adapter = pa_hashmap_get(d->discovery->adapters, d->adapter_path); + if (!d->adapter) { + pa_log_error("Device %s is child of nonexistent adapter %s", d->path, d->adapter_path); + d->device_info_valid = -1; + } + } + return; } diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h index 41673e3..bbc5b71 100644 --- a/src/modules/bluetooth/bluez5-util.h +++ b/src/modules/bluetooth/bluez5-util.h @@ -80,6 +80,7 @@ struct pa_bluetooth_device { /* Device information */ char *path; + char *adapter_path; char *alias; char *address; uint32_t class_of_device; -- 1.8.3.1