From: Jo?o Paulo Rechi Vita <jprvita@xxxxxxxxxxxxx> --- src/modules/bluetooth/bluez5-util.c | 84 +++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c index 8c82a32..3bf119c 100644 --- a/src/modules/bluetooth/bluez5-util.c +++ b/src/modules/bluetooth/bluez5-util.c @@ -254,6 +254,79 @@ bool pa_bluetooth_device_any_transport_connected(const pa_bluetooth_device *d) { return false; } +static int transport_state_from_string(const char* value, pa_bluetooth_transport_state_t *state) { + pa_assert(value); + pa_assert(state); + + if (pa_streq(value, "idle")) + *state = PA_BLUETOOTH_TRANSPORT_STATE_IDLE; + else if (pa_streq(value, "pending") || pa_streq(value, "active")) + *state = PA_BLUETOOTH_TRANSPORT_STATE_PLAYING; + else + return -1; + + return 0; +} + +static void parse_transport_property(pa_bluetooth_transport *t, DBusMessageIter *i) { + const char *key; + DBusMessageIter variant_i; + + key = pa_bluetooth_dbus_check_variant_property(i); + if (key == NULL) + return; + + dbus_message_iter_recurse(i, &variant_i); + + switch (dbus_message_iter_get_arg_type(&variant_i)) { + + case DBUS_TYPE_STRING: { + + const char *value; + dbus_message_iter_get_basic(&variant_i, &value); + + if (pa_streq(key, "State")) { + bool old_any_connected = pa_bluetooth_device_any_transport_connected(t->device); + + if (transport_state_from_string(value, &t->state) < 0) { + pa_log_error("Transport %s has an invalid state: '%s'", t->path, value); + return; + } + + pa_log_debug("Transport %s state changed to '%s'", t->path, value); + pa_hook_fire(&t->device->discovery->hooks[PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED], t); + + if (old_any_connected != pa_bluetooth_device_any_transport_connected(t->device)) { + t->device->dead = old_any_connected; + pa_hook_fire(&t->device->discovery->hooks[PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED], t->device); + } + } + + break; + } + } + + return; +} + +static int parse_transport_properties(pa_bluetooth_transport *t, DBusMessageIter *i) { + DBusMessageIter element_i; + + dbus_message_iter_recurse(i, &element_i); + + while (dbus_message_iter_get_arg_type(&element_i) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter dict_i; + + dbus_message_iter_recurse(&element_i, &dict_i); + + parse_transport_property(t, &dict_i); + + dbus_message_iter_next(&element_i); + } + + return 0; +} + static pa_bluetooth_device* pa_bluetooth_discovery_create_device(pa_bluetooth_discovery *y, const char *path) { pa_bluetooth_device *d; @@ -803,6 +876,13 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us } parse_device_properties(d, &arg_i, true); + } else if (pa_streq(iface, BLUEZ_MEDIA_TRANSPORT_INTERFACE)) { + pa_bluetooth_transport *t; + + if (!(t = pa_hashmap_get(y->transports, dbus_message_get_path(m)))) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + parse_transport_properties(t, &arg_i); } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -1265,6 +1345,8 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c) { "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved'", "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'" ",arg0='" BLUEZ_DEVICE_INTERFACE "'", + "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'" + ",arg0='" BLUEZ_MEDIA_TRANSPORT_INTERFACE "'", NULL) < 0) { pa_log_error("Failed to add D-Bus matches: %s", err.message); goto fail; @@ -1323,6 +1405,8 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) { "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved'", "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'" ",arg0='" BLUEZ_DEVICE_INTERFACE "'", + "type='signal',sender='" BLUEZ_SERVICE "',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'" + ",arg0='" BLUEZ_MEDIA_TRANSPORT_INTERFACE "'", NULL); if (y->filter_added) -- 1.7.11.7