[pulseaudio-discuss] [RFC v3 14/16] bluetooth: Handle transports configured before UUID received

Mikel Astiz mikel.astiz.oss at gmail.com
Fri Apr 19 05:44:19 PDT 2013


From: Mikel Astiz <mikel.astiz at bmw-carit.de>

Now that the transport can be configured from some other process (i.e.
oFono), there is no guarantee that the UUID from BlueZ will already have
been received.

This requires PulseAudio to assume that the UUID is actually supported
by the device and that BlueZ will eventually propagate it.
---
 src/modules/bluetooth/bluetooth-util.c | 53 ++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c
index 4b93ab2..5cea246 100644
--- a/src/modules/bluetooth/bluetooth-util.c
+++ b/src/modules/bluetooth/bluetooth-util.c
@@ -178,6 +178,33 @@ static int profile_from_interface(const char *interface, enum profile *p) {
     return -1;
 }
 
+static void profile_to_remote_uuid(enum profile p, const char *res[2]) {
+    pa_assert(p != PROFILE_OFF);
+
+    switch(p) {
+        case PROFILE_A2DP:
+            res[0] = A2DP_SINK_UUID;
+            res[1] = NULL;
+            return;
+        case PROFILE_A2DP_SOURCE:
+            res[0] = A2DP_SOURCE_UUID;
+            res[1] = NULL;
+            return;
+        case PROFILE_HSP:
+            res[0] = HSP_HS_UUID;
+            res[1] = HFP_HS_UUID;
+            return;
+        case PROFILE_HFGW:
+            res[0] = HSP_AG_UUID;
+            res[1] = HFP_AG_UUID;
+            return;
+        case PROFILE_OFF:
+            break;
+    }
+
+    pa_assert_not_reached();
+}
+
 static pa_bluetooth_transport_state_t audio_state_to_transport_state(pa_bt_audio_state_t state) {
     switch (state) {
         case PA_BT_AUDIO_STATE_INVALID: /* Typically if state hasn't been received yet */
@@ -1640,6 +1667,7 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage
     DBusMessageIter args, props;
     DBusMessage *r;
     bool old_any_connected;
+    const char *remote_uuid[2];
 
     if (!dbus_message_iter_init(m, &args) || !pa_streq(dbus_message_get_signature(m), "oa{sv}")) {
         pa_log("Invalid signature for method SetConfiguration");
@@ -1702,6 +1730,10 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage
         dbus_message_iter_next(&props);
     }
 
+    /* FIXME: with BlueZ 5, check if this is racy in case a newly paired
+     * device gets connected very fast, before BlueZ has created it. This is
+     * very unlikely since the device will be created before the pairing
+     * procedure is complete */
     d = found_device(y, dev_path);
     if (!d)
         goto fail;
@@ -1715,6 +1747,27 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage
     else
         p = PROFILE_A2DP_SOURCE;
 
+    /* Check if the UUID was already reported by BlueZ, since the telephony
+     * component (oFono) could be faster than BlueZ */
+    profile_to_remote_uuid(p, remote_uuid);
+
+    if (!pa_bluetooth_uuid_has(d->uuids, remote_uuid[0]) && !pa_bluetooth_uuid_has(d->uuids, remote_uuid[1])) {
+        pa_bluetooth_uuid *node;
+        struct pa_bluetooth_hook_uuid_data uuiddata;
+
+        pa_log_info("Endpoint with UUID '%s' configured before remote UUID was reported by BlueZ.", uuid);
+
+        /* This might generate duplicated UUID_ADDED hooks since the endpoint
+         * doesn't receive the exact remote UUID (HSP cannot be distinguished
+         * from HFP). However, these duplicated hooks should do no harm */
+        node = uuid_new(remote_uuid[0]);
+        PA_LLIST_PREPEND(pa_bluetooth_uuid, d->uuids, node);
+
+        uuiddata.device = d;
+        uuiddata.uuid = uuid;
+        pa_hook_fire(&d->discovery->hooks[PA_BLUETOOTH_HOOK_DEVICE_UUID_ADDED], &uuiddata);
+    }
+
     if (d->transports[p] != NULL) {
         pa_log("Cannot configure transport %s because profile %d is already used", path, p);
         goto fail2;
-- 
1.8.1.4



More information about the pulseaudio-discuss mailing list