From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> This adds optional argument which indicates a suspend from IO thread so the callback can choose to close the fd or leave it open. --- src/modules/bluetooth/backend-native.c | 3 ++- src/modules/bluetooth/backend-ofono.c | 12 ++++++++++-- src/modules/bluetooth/bluez5-util.c | 9 ++++++--- src/modules/bluetooth/bluez5-util.h | 2 +- src/modules/bluetooth/module-bluez5-device.c | 25 +++++++++++++------------ 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c index 6eb4e16..4e6c986 100644 --- a/src/modules/bluetooth/backend-native.c +++ b/src/modules/bluetooth/backend-native.c @@ -217,9 +217,10 @@ fail: return -1; } -static void sco_release_cb(pa_bluetooth_transport *t) { +static bool sco_release_cb(pa_bluetooth_transport *t, bool optional) { pa_log_info("Transport %s released", t->path); /* device will close the SCO socket for us */ + return true; } static void sco_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) { diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index a24747c..66a7c47 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -196,20 +196,28 @@ static int hf_audio_agent_transport_acquire(pa_bluetooth_transport *t, bool opti return card->fd; } -static void hf_audio_agent_transport_release(pa_bluetooth_transport *t) { +static bool hf_audio_agent_transport_release(pa_bluetooth_transport *t, bool optional) { struct hf_audio_card *card = t->userdata; pa_assert(card); + /* Don't release the fd since this is just to suspend the stream */ + if (optional) + return false; + if (card->fd < 0) { pa_log_info("Transport %s already released", t->path); - return; + return true; } /* shutdown to make sure connection is dropped immediately */ shutdown(card->fd, SHUT_RDWR); close(card->fd); card->fd = -1; + + pa_log_info("Transport %s released", t->path); + + return true; } static void hf_audio_agent_card_found(pa_bluetooth_backend *backend, const char *path, DBusMessageIter *props_i) { diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c index 8956fb1..27a1647 100644 --- a/src/modules/bluetooth/bluez5-util.c +++ b/src/modules/bluetooth/bluez5-util.c @@ -392,7 +392,7 @@ finish: return ret; } -static void bluez5_transport_release_cb(pa_bluetooth_transport *t) { +static bool bluez5_transport_release_cb(pa_bluetooth_transport *t, bool suspend) { DBusMessage *m; DBusError err; @@ -404,7 +404,7 @@ static void bluez5_transport_release_cb(pa_bluetooth_transport *t) { if (t->state <= PA_BLUETOOTH_TRANSPORT_STATE_IDLE) { pa_log_info("Transport %s auto-released by BlueZ or already released", t->path); - return; + return true; } pa_assert_se(m = dbus_message_new_method_call(t->owner, t->path, BLUEZ_MEDIA_TRANSPORT_INTERFACE, "Release")); @@ -413,8 +413,11 @@ static void bluez5_transport_release_cb(pa_bluetooth_transport *t) { if (dbus_error_is_set(&err)) { pa_log_error("Failed to release transport %s: %s", t->path, err.message); dbus_error_free(&err); - } else + return false; + } else { pa_log_info("Transport %s released", t->path); + return true; + } } bool pa_bluetooth_device_any_transport_connected(const pa_bluetooth_device *d) { diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h index a3e7bf3..7911e30 100644 --- a/src/modules/bluetooth/bluez5-util.h +++ b/src/modules/bluetooth/bluez5-util.h @@ -59,7 +59,7 @@ typedef enum pa_bluetooth_transport_state { } pa_bluetooth_transport_state_t; typedef int (*pa_bluetooth_transport_acquire_cb)(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu); -typedef void (*pa_bluetooth_transport_release_cb)(pa_bluetooth_transport *t); +typedef bool (*pa_bluetooth_transport_release_cb)(pa_bluetooth_transport *t, bool optional); typedef void (*pa_bluetooth_transport_destroy_cb)(pa_bluetooth_transport *t); typedef void (*pa_bluetooth_transport_set_speaker_gain_cb)(pa_bluetooth_transport *t, uint16_t gain); typedef void (*pa_bluetooth_transport_set_microphone_gain_cb)(pa_bluetooth_transport *t, uint16_t gain); diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c index 2f0ec97..0c9771f 100644 --- a/src/modules/bluetooth/module-bluez5-device.c +++ b/src/modules/bluetooth/module-bluez5-device.c @@ -751,20 +751,21 @@ static int transport_acquire(struct userdata *u, bool optional) { return 0; } -static void transport_release(struct userdata *u) { +static void transport_release(struct userdata *u, bool optional) { + bool ret; + pa_assert(u->transport); /* Ignore if already released */ if (!u->transport_acquired) return; - pa_log_debug("Releasing transport %s", u->transport->path); - - u->transport->release(u->transport); - - u->transport_acquired = false; - - teardown_stream(u); + ret = u->transport->release(u->transport, optional); + if (ret || !optional) { + pa_log_debug("Releasing transport %s", u->transport->path); + u->transport_acquired = false; + teardown_stream(u); + } } /* Run from I/O thread */ @@ -852,7 +853,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off /* Stop the device if the sink is suspended as well */ if (!u->sink || u->sink->state == PA_SINK_SUSPENDED) - transport_release(u); + transport_release(u, true); if (u->read_smoother) pa_smoother_pause(u->read_smoother, pa_rtclock_now()); @@ -1019,7 +1020,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse /* We deliberately ignore whether stopping * actually worked. Since the stream_fd is * closed it doesn't really matter */ - transport_release(u); + transport_release(u, true); break; @@ -1516,7 +1517,7 @@ static void thread_func(void *userdata) { } if (ret == 0) { pa_log_debug("IO thread shutdown requested, stopping cleanly"); - transport_release(u); + transport_release(u, false); goto finish; } } @@ -1599,7 +1600,7 @@ static void stop_thread(struct userdata *u) { } if (u->transport) { - transport_release(u); + transport_release(u, false); u->transport = NULL; } -- 2.9.3