[pulseaudio-discuss] [PATCH v4 8/8] Bluetooth: Add optional argument to release callback

Luiz Augusto von Dentz luiz.dentz at gmail.com
Wed Apr 26 12:20:00 UTC 2017


From: Luiz Augusto von Dentz <luiz.von.dentz at intel.com>

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



More information about the pulseaudio-discuss mailing list