diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index 00549544e..2e4d93c8c 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 248ca47d3..2752a69c9 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 d90f7792f..880d581b1 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -1834,6 +1834,56 @@ 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 = PA_BT_AUDIO_STATE_INVALID; + + 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 +2985,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 +3059,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);