Re: [pulseaudio-discuss] [PATCH] Absolute volume control for A2DP transport
There are Bluetooth devices which support absolute volume but does not handle it correctly. For example, some Bluetooth headsets are unacceptable loud on the lowest volume, that's why it's better to completely disable absolute volume control for such devices. Google created a database for broken devices for Android, which I have linked. Please add these exceptions if possible. On 14.10.2018 21:54, ValdikSS wrote: > Can you please integrate exceptions from the Android database? > https://android.googlesource.com/platform/system/bt/+/master/device/include/interop_database.h > Ones with INTEROP_DISABLE_ABSOLUTE_VOLUME > > > On 03/10/2018 16:12, EHfive wrote: >> On 10/3/18 8:37 PM, EHfive wrote: >>> Require bluez-tools/mpris-proxy running. (No hurt if dosen't) >>> >>> If you need play/pause/next... controls , add configurations below to >>> /etc/dbus-1/system.d/ >>> >>> mpris.conf >>> >>> >> 1.0//EN" >>> "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd;> >>> >>> >>> >>> >>> >>> >>> >>> >> An alternative >> >> https://gist.github.com/EHfive/e2a28d0279a6247fab4bac93d73b8571 >> >> A python script which implement org.mpris.MediaPlayer2.Player and register >> mpris player object by calling org.bluez.Media1.RegisterPlayer. >> >>> === >>> >>> diff --git a/src/modules/bluetooth/bluez5-util.c >>> b/src/modules/bluetooth/bluez5-util.c >>> index 2d83373..72cd05a 100644 >>> --- a/src/modules/bluetooth/bluez5-util.c >>> +++ b/src/modules/bluetooth/bluez5-util.c >>> @@ -348,6 +348,50 @@ void >>> pa_bluetooth_transport_free(pa_bluetooth_transport *t) { >>> pa_xfree(t); >>> } >>> >>> +static int bluez5_transport_set_property(pa_bluetooth_transport *t, const >>> char *prop_name, int prop_type, void *prop_value){ >>> + DBusMessage *m, *r; >>> + DBusError err; >>> + DBusMessageIter i; >>> + const char * interface = BLUEZ_MEDIA_TRANSPORT_INTERFACE; >>> + >>> + pa_log_debug("Setting property, Owner: %s; Path: %s; Property: >>> %s",t->owner, t->path, prop_name); >>> + >>> + pa_assert(t); >>> + pa_assert(t->device); >>> + pa_assert(t->device->discovery); >>> + >>> + dbus_error_init(); >>> + >>> + pa_assert_se(m = dbus_message_new_method_call(t->owner, t->path, >>> "org.freedesktop.DBus.Properties", "Set")); >>> + >>> + dbus_message_iter_init_append(m, ); >>> + >>> + pa_assert_se(dbus_message_iter_append_basic(, DBUS_TYPE_STRING, >>> )); >>> + pa_assert_se(dbus_message_iter_append_basic(, DBUS_TYPE_STRING, >>> _name)); >>> + pa_dbus_append_basic_variant(, prop_type, prop_value); >>> + >>> + r = >>> dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t->device->discovery->connection), >>> m, -1, ); >>> + dbus_message_unref(m); >>> + m = NULL; >>> + if(r) { >>> + dbus_message_unref(r); >>> + r = NULL; >>> + } >>> + >>> + if(dbus_error_is_set()) { >>> + pa_log_debug("Failed to set property \"%s.%s\"", interface, >>> prop_name); >>> + return -1; >>> + } >>> + >>> + return 0; >>> +} >>> + >>> +static int bluez5_transport_set_volume(pa_bluetooth_transport *t, uint16_t >>> volume){ >>> + if(t->a2dp_gain == volume) >>> + return 0; >>> + return bluez5_transport_set_property(t, "Volume", DBUS_TYPE_UINT16, >>> ); >>> +} >>> + >>> static int bluez5_transport_acquire_cb(pa_bluetooth_transport *t, bool >>> optional, size_t *imtu, size_t *omtu) { >>> DBusMessage *m, *r; >>> DBusError err; >>> @@ -441,6 +485,14 @@ bool pa_bluetooth_device_any_transport_connected(const >>> pa_bluetooth_device *d) { >>> return false; >>> } >>> >>> +void pa_transport_set_a2dp_gain(pa_bluetooth_transport *t, uint16_t >>> a2dp_gain){ >>> + if(t->a2dp_gain == a2dp_gain) >>> + return; >>> + t->a2dp_gain = a2dp_gain; >>> + pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, >>> PA_BLUETOOTH_HOOK_TRANSPORT_A2DP_GAIN_CHANGED), t); >>> +} >>> + >>> + >>> static int transport_state_from_string(const char* value, >>> pa_bluetooth_transport_state_t *state) { >>> pa_assert(value); >>> pa_assert(state); >>> @@ -483,6 +535,18 @@ static void >>> parse_transport_property(pa_bluetooth_transport *t, DBusMessageIter >>> pa_bluetooth_transport_set_state(t, state); >>> } >>> >>> + break; >>> + } >>> + case DBUS_TYPE_UINT16: { >>> + >>> + uint16_t value; >>> + dbus_message_iter_get_basic(_i, ); >>> + >>> + if (pa_streq(key, "Volume")) { >>> + pa_log_debug("Transport Volume Changed to %u ", value); >>> + pa_transport_set_a2dp_gain(t, value); >>> + } >>> + >>> break; >>> } >>> } >>> @@ -1468,6 +1532,7 @@ static DBusMessage >>> *endpoint_set_configuration(DBusConnection *conn, DBusMessage >>> t = pa_bluetooth_transport_new(d, sender, path, p,
Re: [pulseaudio-discuss] [PATCH] Absolute volume control for A2DP transport
On 10/15/18 7:44 AM, EHfive wrote: Simply add some lines. Also, volume means host (as sink role) volume when in profile a2dp_source(device as source role) , don't need to disable it. But should we do it in PA? Isn't it Bluez's job? On 10/15/18 2:54 AM, ValdikSS wrote: Can you please integrate exceptions from the Android database? https://android.googlesource.com/platform/system/bt/+/master/device/include/interop_database.h Ones with INTEROP_DISABLE_ABSOLUTE_VOLUME On 03/10/2018 16:12, EHfive wrote: On 10/3/18 8:37 PM, EHfive wrote: Require bluez-tools/mpris-proxy running. (No hurt if dosen't) If you need play/pause/next... controls , add configurations below to /etc/dbus-1/system.d/ mpris.conf http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd;> An alternative https://gist.github.com/EHfive/e2a28d0279a6247fab4bac93d73b8571 A python script which implement org.mpris.MediaPlayer2.Player and register mpris player object by calling org.bluez.Media1.RegisterPlayer. === diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c index 2d83373..72cd05a 100644 --- a/src/modules/bluetooth/bluez5-util.c +++ b/src/modules/bluetooth/bluez5-util.c @@ -348,6 +348,50 @@ void pa_bluetooth_transport_free(pa_bluetooth_transport *t) { pa_xfree(t); } +static int bluez5_transport_set_property(pa_bluetooth_transport *t, const char *prop_name, int prop_type, void *prop_value){ + DBusMessage *m, *r; + DBusError err; + DBusMessageIter i; + const char * interface = BLUEZ_MEDIA_TRANSPORT_INTERFACE; + + pa_log_debug("Setting property, Owner: %s; Path: %s; Property: %s",t->owner, t->path, prop_name); + + pa_assert(t); + pa_assert(t->device); + pa_assert(t->device->discovery); + + dbus_error_init(); + + pa_assert_se(m = dbus_message_new_method_call(t->owner, t->path, "org.freedesktop.DBus.Properties", "Set")); + + dbus_message_iter_init_append(m, ); + + pa_assert_se(dbus_message_iter_append_basic(, DBUS_TYPE_STRING, )); + pa_assert_se(dbus_message_iter_append_basic(, DBUS_TYPE_STRING, _name)); + pa_dbus_append_basic_variant(, prop_type, prop_value); + + r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t->device->discovery->connection), m, -1, ); + dbus_message_unref(m); + m = NULL; + if(r) { + dbus_message_unref(r); + r = NULL; + } + + if(dbus_error_is_set()) { + pa_log_debug("Failed to set property \"%s.%s\"", interface, prop_name); + return -1; + } + + return 0; +} + +static int bluez5_transport_set_volume(pa_bluetooth_transport *t, uint16_t volume){ + if(t->a2dp_gain == volume) + return 0; + return bluez5_transport_set_property(t, "Volume", DBUS_TYPE_UINT16, ); +} + static int bluez5_transport_acquire_cb(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) { DBusMessage *m, *r; DBusError err; @@ -441,6 +485,14 @@ bool pa_bluetooth_device_any_transport_connected(const pa_bluetooth_device *d) { return false; } +void pa_transport_set_a2dp_gain(pa_bluetooth_transport *t, uint16_t a2dp_gain){ + if(t->a2dp_gain == a2dp_gain) + return; + t->a2dp_gain = a2dp_gain; + pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_A2DP_GAIN_CHANGED), t); +} + + static int transport_state_from_string(const char* value, pa_bluetooth_transport_state_t *state) { pa_assert(value); pa_assert(state); @@ -483,6 +535,18 @@ static void parse_transport_property(pa_bluetooth_transport *t, DBusMessageIter pa_bluetooth_transport_set_state(t, state); } + break; + } + case DBUS_TYPE_UINT16: { + + uint16_t value; + dbus_message_iter_get_basic(_i, ); + + if (pa_streq(key, "Volume")) { + pa_log_debug("Transport Volume Changed to %u ", value); + pa_transport_set_a2dp_gain(t, value); + } + break; } } @@ -1468,6 +1532,7 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage t = pa_bluetooth_transport_new(d, sender, path, p, config, size); t->acquire = bluez5_transport_acquire_cb; t->release = bluez5_transport_release_cb; + t->set_volume = bluez5_transport_set_volume; pa_bluetooth_transport_put(t); pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile)); diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h index ad30708..5b8149d 100644 --- a/src/modules/bluetooth/bluez5-util.h +++ b/src/modules/bluetooth/bluez5-util.h @@ -47,6 +47,7 @@ typedef enum pa_bluetooth_hook { PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED, /* Call data: pa_bluetooth_transport */
Re: [pulseaudio-discuss] [PATCH] Absolute volume control for A2DP transport
Simply add some lines. Also, volume means host (as sink role) volume when in profile a2dp_source(device as source role) , don't need to disable it. But should we do it in PA? Isn't it Bluez's job? On 10/15/18 2:54 AM, ValdikSS wrote: Can you please integrate exceptions from the Android database? https://android.googlesource.com/platform/system/bt/+/master/device/include/interop_database.h Ones with INTEROP_DISABLE_ABSOLUTE_VOLUME On 03/10/2018 16:12, EHfive wrote: On 10/3/18 8:37 PM, EHfive wrote: Require bluez-tools/mpris-proxy running. (No hurt if dosen't) If you need play/pause/next... controls , add configurations below to /etc/dbus-1/system.d/ mpris.conf http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd;> An alternative https://gist.github.com/EHfive/e2a28d0279a6247fab4bac93d73b8571 A python script which implement org.mpris.MediaPlayer2.Player and register mpris player object by calling org.bluez.Media1.RegisterPlayer. === diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c index 2d83373..72cd05a 100644 --- a/src/modules/bluetooth/bluez5-util.c +++ b/src/modules/bluetooth/bluez5-util.c @@ -348,6 +348,50 @@ void pa_bluetooth_transport_free(pa_bluetooth_transport *t) { pa_xfree(t); } +static int bluez5_transport_set_property(pa_bluetooth_transport *t, const char *prop_name, int prop_type, void *prop_value){ + DBusMessage *m, *r; + DBusError err; + DBusMessageIter i; + const char * interface = BLUEZ_MEDIA_TRANSPORT_INTERFACE; + + pa_log_debug("Setting property, Owner: %s; Path: %s; Property: %s",t->owner, t->path, prop_name); + + pa_assert(t); + pa_assert(t->device); + pa_assert(t->device->discovery); + + dbus_error_init(); + + pa_assert_se(m = dbus_message_new_method_call(t->owner, t->path, "org.freedesktop.DBus.Properties", "Set")); + + dbus_message_iter_init_append(m, ); + + pa_assert_se(dbus_message_iter_append_basic(, DBUS_TYPE_STRING, )); + pa_assert_se(dbus_message_iter_append_basic(, DBUS_TYPE_STRING, _name)); + pa_dbus_append_basic_variant(, prop_type, prop_value); + + r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t->device->discovery->connection), m, -1, ); + dbus_message_unref(m); + m = NULL; + if(r) { + dbus_message_unref(r); + r = NULL; + } + + if(dbus_error_is_set()) { + pa_log_debug("Failed to set property \"%s.%s\"", interface, prop_name); + return -1; + } + + return 0; +} + +static int bluez5_transport_set_volume(pa_bluetooth_transport *t, uint16_t volume){ + if(t->a2dp_gain == volume) + return 0; + return bluez5_transport_set_property(t, "Volume", DBUS_TYPE_UINT16, ); +} + static int bluez5_transport_acquire_cb(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) { DBusMessage *m, *r; DBusError err; @@ -441,6 +485,14 @@ bool pa_bluetooth_device_any_transport_connected(const pa_bluetooth_device *d) { return false; } +void pa_transport_set_a2dp_gain(pa_bluetooth_transport *t, uint16_t a2dp_gain){ + if(t->a2dp_gain == a2dp_gain) + return; + t->a2dp_gain = a2dp_gain; + pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_A2DP_GAIN_CHANGED), t); +} + + static int transport_state_from_string(const char* value, pa_bluetooth_transport_state_t *state) { pa_assert(value); pa_assert(state); @@ -483,6 +535,18 @@ static void parse_transport_property(pa_bluetooth_transport *t, DBusMessageIter pa_bluetooth_transport_set_state(t, state); } + break; + } + case DBUS_TYPE_UINT16: { + + uint16_t value; + dbus_message_iter_get_basic(_i, ); + + if (pa_streq(key, "Volume")) { + pa_log_debug("Transport Volume Changed to %u ", value); + pa_transport_set_a2dp_gain(t, value); + } + break; } } @@ -1468,6 +1532,7 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage t = pa_bluetooth_transport_new(d, sender, path, p, config, size); t->acquire = bluez5_transport_acquire_cb; t->release = bluez5_transport_release_cb; + t->set_volume = bluez5_transport_set_volume; pa_bluetooth_transport_put(t); pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile)); diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h index ad30708..5b8149d 100644 --- a/src/modules/bluetooth/bluez5-util.h +++ b/src/modules/bluetooth/bluez5-util.h @@ -47,6 +47,7 @@ typedef enum pa_bluetooth_hook { PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED, /* Call data: pa_bluetooth_transport */
Re: [pulseaudio-discuss] [PATCH] Absolute volume control for A2DP transport
Can you please integrate exceptions from the Android database? https://android.googlesource.com/platform/system/bt/+/master/device/include/interop_database.h Ones with INTEROP_DISABLE_ABSOLUTE_VOLUME On 03/10/2018 16:12, EHfive wrote: > On 10/3/18 8:37 PM, EHfive wrote: >> Require bluez-tools/mpris-proxy running. (No hurt if dosen't) >> >> If you need play/pause/next... controls , add configurations below to >> /etc/dbus-1/system.d/ >> >> mpris.conf >> >> > 1.0//EN" >> "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd;> >> >> >> >> >> >> >> >> > An alternative > > https://gist.github.com/EHfive/e2a28d0279a6247fab4bac93d73b8571 > > A python script which implement org.mpris.MediaPlayer2.Player and register > mpris player object by calling org.bluez.Media1.RegisterPlayer. > >> === >> >> diff --git a/src/modules/bluetooth/bluez5-util.c >> b/src/modules/bluetooth/bluez5-util.c >> index 2d83373..72cd05a 100644 >> --- a/src/modules/bluetooth/bluez5-util.c >> +++ b/src/modules/bluetooth/bluez5-util.c >> @@ -348,6 +348,50 @@ void pa_bluetooth_transport_free(pa_bluetooth_transport >> *t) { >> pa_xfree(t); >> } >> >> +static int bluez5_transport_set_property(pa_bluetooth_transport *t, const >> char *prop_name, int prop_type, void *prop_value){ >> + DBusMessage *m, *r; >> + DBusError err; >> + DBusMessageIter i; >> + const char * interface = BLUEZ_MEDIA_TRANSPORT_INTERFACE; >> + >> + pa_log_debug("Setting property, Owner: %s; Path: %s; Property: >> %s",t->owner, t->path, prop_name); >> + >> + pa_assert(t); >> + pa_assert(t->device); >> + pa_assert(t->device->discovery); >> + >> + dbus_error_init(); >> + >> + pa_assert_se(m = dbus_message_new_method_call(t->owner, t->path, >> "org.freedesktop.DBus.Properties", "Set")); >> + >> + dbus_message_iter_init_append(m, ); >> + >> + pa_assert_se(dbus_message_iter_append_basic(, DBUS_TYPE_STRING, >> )); >> + pa_assert_se(dbus_message_iter_append_basic(, DBUS_TYPE_STRING, >> _name)); >> + pa_dbus_append_basic_variant(, prop_type, prop_value); >> + >> + r = >> dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t->device->discovery->connection), >> m, -1, ); >> + dbus_message_unref(m); >> + m = NULL; >> + if(r) { >> + dbus_message_unref(r); >> + r = NULL; >> + } >> + >> + if(dbus_error_is_set()) { >> + pa_log_debug("Failed to set property \"%s.%s\"", interface, >> prop_name); >> + return -1; >> + } >> + >> + return 0; >> +} >> + >> +static int bluez5_transport_set_volume(pa_bluetooth_transport *t, uint16_t >> volume){ >> + if(t->a2dp_gain == volume) >> + return 0; >> + return bluez5_transport_set_property(t, "Volume", DBUS_TYPE_UINT16, >> ); >> +} >> + >> static int bluez5_transport_acquire_cb(pa_bluetooth_transport *t, bool >> optional, size_t *imtu, size_t *omtu) { >> DBusMessage *m, *r; >> DBusError err; >> @@ -441,6 +485,14 @@ bool pa_bluetooth_device_any_transport_connected(const >> pa_bluetooth_device *d) { >> return false; >> } >> >> +void pa_transport_set_a2dp_gain(pa_bluetooth_transport *t, uint16_t >> a2dp_gain){ >> + if(t->a2dp_gain == a2dp_gain) >> + return; >> + t->a2dp_gain = a2dp_gain; >> + pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, >> PA_BLUETOOTH_HOOK_TRANSPORT_A2DP_GAIN_CHANGED), t); >> +} >> + >> + >> static int transport_state_from_string(const char* value, >> pa_bluetooth_transport_state_t *state) { >> pa_assert(value); >> pa_assert(state); >> @@ -483,6 +535,18 @@ static void >> parse_transport_property(pa_bluetooth_transport *t, DBusMessageIter >> pa_bluetooth_transport_set_state(t, state); >> } >> >> + break; >> + } >> + case DBUS_TYPE_UINT16: { >> + >> + uint16_t value; >> + dbus_message_iter_get_basic(_i, ); >> + >> + if (pa_streq(key, "Volume")) { >> + pa_log_debug("Transport Volume Changed to %u ", value); >> + pa_transport_set_a2dp_gain(t, value); >> + } >> + >> break; >> } >> } >> @@ -1468,6 +1532,7 @@ static DBusMessage >> *endpoint_set_configuration(DBusConnection *conn, DBusMessage >> t = pa_bluetooth_transport_new(d, sender, path, p, config, size); >> t->acquire = bluez5_transport_acquire_cb; >> t->release = bluez5_transport_release_cb; >> + t->set_volume = bluez5_transport_set_volume; >> pa_bluetooth_transport_put(t); >> >> pa_log_debug("Transport %s available for profile %s", t->path, >> pa_bluetooth_profile_to_string(t->profile)); >> diff --git a/src/modules/bluetooth/bluez5-util.h >> b/src/modules/bluetooth/bluez5-util.h >> index ad30708..5b8149d 100644 >> --- a/src/modules/bluetooth/bluez5-util.h >> +++ b/src/modules/bluetooth/bluez5-util.h >> @@ -47,6 +47,7 @@
Re: [pulseaudio-discuss] [PATCH] Absolute volume control for A2DP transport
On 10/3/18 8:37 PM, EHfive wrote: Require bluez-tools/mpris-proxy running. (No hurt if dosen't) If you need play/pause/next... controls , add configurations below to /etc/dbus-1/system.d/ mpris.conf Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd;> An alternative https://gist.github.com/EHfive/e2a28d0279a6247fab4bac93d73b8571 A python script which implement org.mpris.MediaPlayer2.Player and register mpris player object by calling org.bluez.Media1.RegisterPlayer. === diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c index 2d83373..72cd05a 100644 --- a/src/modules/bluetooth/bluez5-util.c +++ b/src/modules/bluetooth/bluez5-util.c @@ -348,6 +348,50 @@ void pa_bluetooth_transport_free(pa_bluetooth_transport *t) { pa_xfree(t); } +static int bluez5_transport_set_property(pa_bluetooth_transport *t, const char *prop_name, int prop_type, void *prop_value){ + DBusMessage *m, *r; + DBusError err; + DBusMessageIter i; + const char * interface = BLUEZ_MEDIA_TRANSPORT_INTERFACE; + + pa_log_debug("Setting property, Owner: %s; Path: %s; Property: %s",t->owner, t->path, prop_name); + + pa_assert(t); + pa_assert(t->device); + pa_assert(t->device->discovery); + + dbus_error_init(); + + pa_assert_se(m = dbus_message_new_method_call(t->owner, t->path, "org.freedesktop.DBus.Properties", "Set")); + + dbus_message_iter_init_append(m, ); + + pa_assert_se(dbus_message_iter_append_basic(, DBUS_TYPE_STRING, )); + pa_assert_se(dbus_message_iter_append_basic(, DBUS_TYPE_STRING, _name)); + pa_dbus_append_basic_variant(, prop_type, prop_value); + + r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(t->device->discovery->connection), m, -1, ); + dbus_message_unref(m); + m = NULL; + if(r) { + dbus_message_unref(r); + r = NULL; + } + + if(dbus_error_is_set()) { + pa_log_debug("Failed to set property \"%s.%s\"", interface, prop_name); + return -1; + } + + return 0; +} + +static int bluez5_transport_set_volume(pa_bluetooth_transport *t, uint16_t volume){ + if(t->a2dp_gain == volume) + return 0; + return bluez5_transport_set_property(t, "Volume", DBUS_TYPE_UINT16, ); +} + static int bluez5_transport_acquire_cb(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) { DBusMessage *m, *r; DBusError err; @@ -441,6 +485,14 @@ bool pa_bluetooth_device_any_transport_connected(const pa_bluetooth_device *d) { return false; } +void pa_transport_set_a2dp_gain(pa_bluetooth_transport *t, uint16_t a2dp_gain){ + if(t->a2dp_gain == a2dp_gain) + return; + t->a2dp_gain = a2dp_gain; + pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_A2DP_GAIN_CHANGED), t); +} + + static int transport_state_from_string(const char* value, pa_bluetooth_transport_state_t *state) { pa_assert(value); pa_assert(state); @@ -483,6 +535,18 @@ static void parse_transport_property(pa_bluetooth_transport *t, DBusMessageIter pa_bluetooth_transport_set_state(t, state); } + break; + } + case DBUS_TYPE_UINT16: { + + uint16_t value; + dbus_message_iter_get_basic(_i, ); + + if (pa_streq(key, "Volume")) { + pa_log_debug("Transport Volume Changed to %u ", value); + pa_transport_set_a2dp_gain(t, value); + } + break; } } @@ -1468,6 +1532,7 @@ static DBusMessage *endpoint_set_configuration(DBusConnection *conn, DBusMessage t = pa_bluetooth_transport_new(d, sender, path, p, config, size); t->acquire = bluez5_transport_acquire_cb; t->release = bluez5_transport_release_cb; + t->set_volume = bluez5_transport_set_volume; pa_bluetooth_transport_put(t); pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile)); diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h index ad30708..5b8149d 100644 --- a/src/modules/bluetooth/bluez5-util.h +++ b/src/modules/bluetooth/bluez5-util.h @@ -47,6 +47,7 @@ typedef enum pa_bluetooth_hook { PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED, /* Call data: pa_bluetooth_transport */ PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED, /* Call data: pa_bluetooth_transport */ PA_BLUETOOTH_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED, /* Call data: pa_bluetooth_transport */ + PA_BLUETOOTH_HOOK_TRANSPORT_A2DP_GAIN_CHANGED, /* Call data: pa_bluetooth_transport */ PA_BLUETOOTH_HOOK_MAX } pa_bluetooth_hook_t; @@ -70,6 +71,7 @@ typedef void (*pa_bluetooth_transport_release_cb)(pa_bluetooth_transport *t); typedef void