[pulseaudio-discuss] [PATCH 39/56] bluetooth: Handle PropertiesChanged for org.bluez.MediaTransport1

jprvita at gmail.com jprvita at gmail.com
Fri Jul 12 11:06:54 PDT 2013


From: João Paulo Rechi Vita <jprvita at openbossa.org>

---
 src/modules/bluetooth/bluez5-util.c | 84 +++++++++++++++++++++++++++++++++++++
 src/modules/bluetooth/bluez5-util.h |  1 +
 2 files changed, 85 insertions(+)

diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c
index e29a19a..45052a2 100644
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -253,6 +253,79 @@ bool pa_bluetooth_device_any_transport_connected(const pa_bluetooth_device *d) {
     return false;
 }
 
+static pa_bluetooth_transport_state_t 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 PA_BLUETOOTH_TRANSPORT_STATE_INVALID;
+
+    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) == PA_BLUETOOTH_TRANSPORT_STATE_INVALID) {
+                    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_uuid *pa_bluetooth_uuid_new(const char *uuid) {
     pa_bluetooth_uuid *u;
 
@@ -793,6 +866,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;
@@ -1238,6 +1318,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;
@@ -1293,6 +1375,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)
diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h
index b1a112f..cf90003 100644
--- a/src/modules/bluetooth/bluez5-util.h
+++ b/src/modules/bluetooth/bluez5-util.h
@@ -46,6 +46,7 @@ typedef enum profile {
 #define PA_BLUETOOTH_PROFILE_COUNT PROFILE_OFF
 
 typedef enum pa_bluetooth_transport_state {
+    PA_BLUETOOTH_TRANSPORT_STATE_INVALID = -1,
     PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED,
     PA_BLUETOOTH_TRANSPORT_STATE_IDLE,
     PA_BLUETOOTH_TRANSPORT_STATE_PLAYING
-- 
1.7.11.7



More information about the pulseaudio-discuss mailing list