[pulseaudio-discuss] [PATCH v3 5/7] bluetooth: Set hfgw profile when HandsfreeGateway is playing

Frédéric Dalleau frederic.dalleau at linux.intel.com
Tue Sep 20 04:55:24 PDT 2011


Allow module-bluetooth-device to listens to HandsfreeGateway state
changes using DBUS signals. When an handsfree connects, module-bluetooth-device
is loaded and goes to playing state. When the handsfree disconnect audio,
the card profile is set to "off". If the headset connects audio again after
that, the card profile should switch to "hfgw" again to match state of audio
connection.
---
 src/modules/bluetooth/bluetooth-util.c          |    2 +-
 src/modules/bluetooth/bluetooth-util.h          |    1 +
 src/modules/bluetooth/module-bluetooth-device.c |   54 ++++++++++++++++++++++-
 3 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c
index 9a56592..f5a270f 100644
--- a/src/modules/bluetooth/bluetooth-util.c
+++ b/src/modules/bluetooth/bluetooth-util.c
@@ -76,7 +76,7 @@ struct pa_bluetooth_discovery {
 static void get_properties_reply(DBusPendingCall *pending, void *userdata);
 static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_discovery *y, DBusMessage *m, DBusPendingCallNotifyFunction func, void *call_data);
 
-static pa_bt_audio_state_t pa_bt_audio_state_from_string(const char* value) {
+pa_bt_audio_state_t pa_bt_audio_state_from_string(const char* value) {
     pa_assert(value);
 
     if (pa_streq(value, "disconnected"))
diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h
index 248ca47..2752a69 100644
--- a/src/modules/bluetooth/bluetooth-util.h
+++ b/src/modules/bluetooth/bluetooth-util.h
@@ -138,5 +138,6 @@ const char* pa_bluetooth_get_form_factor(uint32_t class);
 char *pa_bluetooth_cleanup_name(const char *name);
 
 pa_bool_t pa_bluetooth_uuid_has(pa_bluetooth_uuid *uuids, const char *uuid);
+pa_bt_audio_state_t pa_bt_audio_state_from_string(const char* value);
 
 #endif
diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index 3db9e8f..a456167 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -1830,6 +1830,55 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
             pa_log_debug("dbus: property 'NREC' changed to value '%s'", t->nrec ? "True" : "False");
             pa_proplist_sets(u->source->proplist, "bluetooth.nrec", t->nrec ? "1" : "0");
         }
+    } else if (dbus_message_is_signal(m, "org.bluez.HandsfreeGateway", "PropertyChanged")) {
+        const char *key;
+        DBusMessageIter iter;
+        DBusMessageIter variant;
+        pa_bt_audio_state_t state;
+
+        if (!dbus_message_iter_init(m, &iter)) {
+            pa_log("Failed to parse PropertyChanged: %s", err.message);
+            goto fail;
+        }
+
+        if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
+            pa_log("Property name not a string.");
+            goto fail;
+        }
+
+        dbus_message_iter_get_basic(&iter, &key);
+
+        if (!dbus_message_iter_next(&iter)) {
+            pa_log("Property value missing");
+            goto fail;
+        }
+
+        dbus_message_iter_recurse(&iter, &variant);
+
+        if (dbus_message_iter_get_arg_type(&variant) == DBUS_TYPE_STRING) {
+            const char *value;
+            dbus_message_iter_get_basic(&variant, &value);
+
+            if (pa_streq(key, "State")) {
+                pa_log_debug("dbus: HSHFAG property 'State' changed to value '%s'", value);
+                state = pa_bt_audio_state_from_string(value);
+            }
+        }
+
+        switch(state) {
+        case PA_BT_AUDIO_STATE_INVALID:
+        case PA_BT_AUDIO_STATE_DISCONNECTED:
+        case PA_BT_AUDIO_STATE_CONNECTED:
+        case PA_BT_AUDIO_STATE_CONNECTING:
+            goto fail;
+        case PA_BT_AUDIO_STATE_PLAYING:
+            if (u->card) {
+                pa_log_debug("Changing profile to hfgw");
+                if (pa_card_set_profile(u->card, "hfgw", FALSE) < 0)
+                    pa_log("Failed to change profile to hfgw");
+            }
+            break;
+        }
     }
 
 fail:
@@ -2928,6 +2977,7 @@ int pa__init(pa_module* m) {
                 speaker,
                 mike,
                 transport,
+                "type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged'",
                 NULL) < 0) {
 
         pa_xfree(speaker);
@@ -3001,7 +3051,9 @@ void pa__done(pa_module *m) {
             speaker = pa_sprintf_malloc("type='signal',sender='org.bluez',interface='org.bluez.Headset',member='SpeakerGainChanged',path='%s'", u->path);
             mike = pa_sprintf_malloc("type='signal',sender='org.bluez',interface='org.bluez.Headset',member='MicrophoneGainChanged',path='%s'", u->path);
 
-            pa_dbus_remove_matches(pa_dbus_connection_get(u->connection), speaker, mike, NULL);
+            pa_dbus_remove_matches(pa_dbus_connection_get(u->connection), speaker, mike,
+                "type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged'",
+                NULL);
 
             pa_xfree(speaker);
             pa_xfree(mike);
-- 
1.7.4.1



More information about the pulseaudio-discuss mailing list