From: Mikel Astiz <mikel.astiz@xxxxxxxxxxxx> The microphone gain represents the volume of the incoming audio stream from the headset. This can be nicely abstracted inside the transport object in bluetooth-util, so the modules don't have to take care about the D-Bus details. --- src/modules/bluetooth/bluetooth-util.c | 60 +++++++++++++++++++++++++ src/modules/bluetooth/bluetooth-util.h | 6 +++ src/modules/bluetooth/module-bluetooth-device.c | 1 - 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index f3e9b53..a319db3 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -528,6 +528,27 @@ static int parse_audio_property(pa_bluetooth_device *d, const char *interface, D break; } + + case DBUS_TYPE_UINT16: { + uint16_t value; + + dbus_message_iter_get_basic(&variant_i, &value); + + if (pa_streq(key, "MicrophoneGain")) { + pa_log_debug("dbus: property 'State' changed to value '%u'", value); + + if (!transport) { + pa_log("Volume change does not have an associated transport"); + return -1; + } + + transport->microphone_gain = PA_MIN(value, HSP_MAX_GAIN); + + pa_hook_fire(&d->discovery->hooks[PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED], transport); + } + + break; + } } return 0; @@ -1086,6 +1107,45 @@ void pa_bluetooth_transport_release(pa_bluetooth_transport *t, const char *acces pa_log_info("Transport %s released", t->path); } +static void pa_bt_set_property(pa_bluetooth_discovery *y, const char *path, const char *interface, const char *prop_name, + int prop_type, void *prop_value) { + DBusMessage *m; + DBusMessageIter i; + DBusMessageIter variant; + const char *variant_signature; + + pa_assert(y); + pa_assert(path); + pa_assert(interface); + pa_assert(prop_name); + + pa_assert_se(m = dbus_message_new_method_call("org.bluez", path, interface, "SetProperty")); + dbus_message_iter_init_append(m, &i); + dbus_message_iter_append_basic(&i, DBUS_TYPE_STRING, &prop_name); + + switch (prop_type) { + case DBUS_TYPE_UINT16: + variant_signature = DBUS_TYPE_UINT16_AS_STRING; + break; + default: + pa_assert_not_reached(); /* Not implemented */ + } + + dbus_message_iter_open_container(&i, DBUS_TYPE_VARIANT, variant_signature, &variant); + dbus_message_iter_append_basic(&variant, prop_type, prop_value); + dbus_message_iter_close_container(&i, &variant); + + pa_assert_se(dbus_connection_send(pa_dbus_connection_get(y->connection), m, NULL)); + dbus_message_unref(m); +} + +void pa_bluetooth_transport_set_microphone_gain(pa_bluetooth_transport *t, uint16_t value) { + pa_assert(t); + pa_assert(t->profile == PROFILE_HSP); + + pa_bt_set_property(t->device->discovery, t->device->path, "org.bluez.Headset", "MicrophoneGain", DBUS_TYPE_UINT16, &value); +} + static int setup_dbus(pa_bluetooth_discovery *y) { DBusError err; diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index 254eded..4c909ab 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -43,6 +43,8 @@ #define A2DP_SOURCE_UUID "0000110a-0000-1000-8000-00805f9b34fb" #define A2DP_SINK_UUID "0000110b-0000-1000-8000-00805f9b34fb" +#define HSP_MAX_GAIN 15 + typedef struct pa_bluetooth_uuid pa_bluetooth_uuid; typedef struct pa_bluetooth_device pa_bluetooth_device; typedef struct pa_bluetooth_discovery pa_bluetooth_discovery; @@ -76,6 +78,7 @@ typedef enum pa_bluetooth_hook { PA_BLUETOOTH_HOOK_DEVICE_UUID_ADDED, /* Call data: pa_bluetooth_hook_uuid_data */ PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED, /* Call data: pa_bluetooth_transport */ PA_BLUETOOTH_HOOK_TRANSPORT_NREC_CHANGED, /* Call data: pa_bluetooth_transport */ + PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED, /* Call data: pa_bluetooth_transport */ PA_BLUETOOTH_HOOK_MAX } pa_bluetooth_hook_t; @@ -96,6 +99,7 @@ struct pa_bluetooth_transport { pa_bluetooth_transport_state_t state; pa_bool_t nrec; + uint16_t microphone_gain; /* Used for HSP/HFP */ }; /* This enum is shared among Audio, Headset, AudioSink, and AudioSource, although not all values are acceptable in all profiles */ @@ -145,6 +149,8 @@ bool pa_bluetooth_device_any_audio_connected(const pa_bluetooth_device *d); int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, const char *accesstype, size_t *imtu, size_t *omtu); void pa_bluetooth_transport_release(pa_bluetooth_transport *t, const char *accesstype); +void pa_bluetooth_transport_set_microphone_gain(pa_bluetooth_transport *t, uint16_t value); + pa_hook* pa_bluetooth_discovery_hook(pa_bluetooth_discovery *y, pa_bluetooth_hook_t hook); const char* pa_bluetooth_get_form_factor(uint32_t class); diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index e5f7f6d..70d3334 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -60,7 +60,6 @@ #define BITPOOL_DEC_LIMIT 32 #define BITPOOL_DEC_STEP 5 -#define HSP_MAX_GAIN 15 PA_MODULE_AUTHOR("Joao Paulo Rechi Vita"); PA_MODULE_DESCRIPTION("Bluetooth audio sink and source"); -- 1.7.11.7