[PATCH v4 5/7] bluetooth: Set hfgw profile when HandsfreeGateway is playing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 0054954..2e4d93c 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 d90f779..9dbfc3a 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -1834,6 +1834,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:
@@ -2935,6 +2984,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);
@@ -3008,7 +3058,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



[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux