From: Mikel Astiz <mikel.astiz@xxxxxxxxxxxx> Transports can be acquired with different access rights, but in practice "rw" was always used inside module-bluetooth-device. In addition, this feature is removed in BlueZ 5.0 and therefore it is convenient to abstract all this inside bluetooth-util. --- src/modules/bluetooth/bluetooth-util.c | 20 +++++++++++++++-- src/modules/bluetooth/bluetooth-util.h | 4 ++-- src/modules/bluetooth/module-bluetooth-device.c | 29 +++++-------------------- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c index c1ea953..587214c 100644 --- a/src/modules/bluetooth/bluetooth-util.c +++ b/src/modules/bluetooth/bluetooth-util.c @@ -1058,7 +1058,8 @@ bool pa_bluetooth_device_any_audio_connected(const pa_bluetooth_device *d) { d->profile_state[PROFILE_HFGW] >= PA_BT_AUDIO_STATE_CONNECTED; } -int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, const char *accesstype, size_t *imtu, size_t *omtu) { +int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) { + const char *accesstype = "rw"; DBusMessage *m, *r; DBusError err; int ret; @@ -1068,6 +1069,20 @@ int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, const char *access pa_assert(t->device); pa_assert(t->device->discovery); + if (optional) { + /* FIXME: we are trying to acquire the transport only if the stream is + playing, without actually initiating the stream request from our side + (which is typically undesireable specially for hfgw use-cases. + However this approach is racy, since the stream could have been + suspended in the meantime, so we can't really guarantee that the + stream will not be requested until BlueZ's API supports this + atomically. */ + if (t->state < PA_BLUETOOTH_TRANSPORT_STATE_PLAYING) { + pa_log_info("Failed optional acquire of transport %s", t->path); + return -1; + } + } + dbus_error_init(&err); pa_assert_se(m = dbus_message_new_method_call(t->owner, t->path, "org.bluez.MediaTransport", "Acquire")); @@ -1097,7 +1112,8 @@ fail: return ret; } -void pa_bluetooth_transport_release(pa_bluetooth_transport *t, const char *accesstype) { +void pa_bluetooth_transport_release(pa_bluetooth_transport *t) { + const char *accesstype = "rw"; DBusMessage *m; DBusError err; diff --git a/src/modules/bluetooth/bluetooth-util.h b/src/modules/bluetooth/bluetooth-util.h index e471e0d..7b0a6b8 100644 --- a/src/modules/bluetooth/bluetooth-util.h +++ b/src/modules/bluetooth/bluetooth-util.h @@ -148,8 +148,8 @@ pa_bluetooth_device* pa_bluetooth_discovery_get_by_address(pa_bluetooth_discover 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); +int pa_bluetooth_transport_acquire(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu); +void pa_bluetooth_transport_release(pa_bluetooth_transport *t); void pa_bluetooth_transport_set_microphone_gain(pa_bluetooth_transport *t, uint16_t value); void pa_bluetooth_transport_set_speaker_gain(pa_bluetooth_transport *t, uint16_t value); diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 3b4b218..aa6a05e 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -141,7 +141,7 @@ struct userdata { char *address; char *path; pa_bluetooth_transport *transport; - char *accesstype; + bool transport_acquired; pa_hook_slot *discovery_slot; pa_hook_slot *sink_state_changed_slot; pa_hook_slot *source_state_changed_slot; @@ -339,7 +339,7 @@ static void setup_stream(struct userdata *u) { } static bool bt_transport_is_acquired(struct userdata *u) { - if (u->accesstype == NULL) { + if (!u->transport_acquired) { pa_assert(u->stream_fd < 0); return FALSE; } else { @@ -376,17 +376,14 @@ static void bt_transport_release(struct userdata *u) { pa_log_debug("Releasing transport %s", u->transport->path); - pa_bluetooth_transport_release(u->transport, u->accesstype); + pa_bluetooth_transport_release(u->transport); - pa_xfree(u->accesstype); - u->accesstype = NULL; + u->transport_acquired = false; teardown_stream(u); } static int bt_transport_acquire(struct userdata *u, pa_bool_t start) { - const char *accesstype = "rw"; - pa_assert(u->transport); if (bt_transport_is_acquired(u)) { @@ -397,21 +394,7 @@ static int bt_transport_acquire(struct userdata *u, pa_bool_t start) { pa_log_debug("Acquiring transport %s", u->transport->path); - if (!start) { - /* FIXME: we are trying to acquire the transport only if the stream is - playing, without actually initiating the stream request from our side - (which is typically undesireable specially for hfgw use-cases. - However this approach is racy, since the stream could have been - suspended in the meantime, so we can't really guarantee that the - stream will not be requested until BlueZ's API supports this - atomically. */ - if (u->device->profile_state[u->profile] < PA_BT_AUDIO_STATE_PLAYING) { - pa_log_info("Failed optional acquire of transport %s", u->transport->path); - return -1; - } - } - - u->stream_fd = pa_bluetooth_transport_acquire(u->transport, accesstype, &u->read_link_mtu, &u->write_link_mtu); + u->stream_fd = pa_bluetooth_transport_acquire(u->transport, !start, &u->read_link_mtu, &u->write_link_mtu); if (u->stream_fd < 0) { if (start) pa_log("Failed to acquire transport %s", u->transport->path); @@ -421,7 +404,7 @@ static int bt_transport_acquire(struct userdata *u, pa_bool_t start) { return -1; } - u->accesstype = pa_xstrdup(accesstype); + u->transport_acquired = true; pa_log_info("Transport %s acquired: fd %d", u->transport->path, u->stream_fd); if (!start) -- 1.7.11.7