[PATCH v2 9/9] Implement media_transport for HFP_HS_UUID

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The transport is used by pulseaudio to suspend and resume streams.
---
 audio/transport.c |  130 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 130 insertions(+), 0 deletions(-)

diff --git a/audio/transport.c b/audio/transport.c
index f915262..2739199 100644
--- a/audio/transport.c
+++ b/audio/transport.c
@@ -42,6 +42,7 @@
 #include "transport.h"
 #include "a2dp.h"
 #include "headset.h"
+#include "gateway.h"
 
 #ifndef DBUS_TYPE_UNIX_FD
 #define DBUS_TYPE_UNIX_FD -1
@@ -436,6 +437,115 @@ static void cancel_headset(struct media_transport *transport, guint id)
 	headset_cancel_stream(transport->device, id);
 }
 
+static void gateway_resume_complete(struct audio_device *dev, GError *err,
+							void *user_data)
+{
+	struct media_owner *owner = user_data;
+	struct media_request *req = owner->pending;
+	struct media_transport *transport = owner->transport;
+	int fd;
+	uint16_t imtu, omtu;
+	gboolean ret;
+
+	req->id = 0;
+
+	if (dev == NULL)
+		goto fail;
+
+	if (err) {
+		error("Failed to resume gateway: error %s", err->message);
+		goto fail;
+	}
+
+	fd = gateway_get_sco_fd(dev);
+	if (fd < 0)
+		goto fail;
+
+	imtu = 48;
+	omtu = 48;
+
+	media_transport_set_fd(transport, fd, imtu, omtu);
+
+	if (g_strstr_len(owner->accesstype, -1, "r") == NULL)
+		imtu = 0;
+
+	if (g_strstr_len(owner->accesstype, -1, "w") == NULL)
+		omtu = 0;
+
+	ret = g_dbus_send_reply(transport->conn, req->msg,
+						DBUS_TYPE_UNIX_FD, &fd,
+						DBUS_TYPE_UINT16, &imtu,
+						DBUS_TYPE_UINT16, &omtu,
+						DBUS_TYPE_INVALID);
+	if (ret == FALSE)
+		goto fail;
+
+	media_owner_remove(owner);
+
+	return;
+
+fail:
+	media_transport_remove(transport, owner);
+}
+
+static guint resume_gateway(struct media_transport *transport,
+				struct media_owner *owner)
+{
+	struct audio_device *device = transport->device;
+
+	if (transport->in_use == TRUE)
+		goto done;
+
+	transport->in_use = gateway_lock(device, GATEWAY_LOCK_READ |
+						GATEWAY_LOCK_WRITE);
+	if (transport->in_use == FALSE)
+		return 0;
+
+done:
+	return gateway_request_stream(device, gateway_resume_complete,
+					owner);
+}
+
+static gboolean gateway_suspend_complete(gpointer user_data)
+{
+	struct media_owner *owner = user_data;
+	struct media_transport *transport = owner->transport;
+
+	/* Release always succeeds */
+	if (owner->pending) {
+		owner->pending->id = 0;
+		media_request_reply(owner->pending, transport->conn, 0);
+		media_owner_remove(owner);
+	}
+
+	transport->in_use = FALSE;
+	media_transport_remove(transport, owner);
+	return FALSE;
+}
+
+static guint suspend_gateway(struct media_transport *transport,
+						struct media_owner *owner)
+{
+	struct audio_device *device = transport->device;
+	static int id = 1;
+
+	if (!owner) {
+		gateway_unlock(device, GATEWAY_LOCK_READ | GATEWAY_LOCK_WRITE);
+		transport->in_use = FALSE;
+		return 0;
+	}
+
+	gateway_suspend_stream(device);
+	gateway_unlock(device, GATEWAY_LOCK_READ | GATEWAY_LOCK_WRITE);
+	g_idle_add(gateway_suspend_complete, owner);
+	return id++;
+}
+
+static void cancel_gateway(struct media_transport *transport, guint id)
+{
+	gateway_cancel_stream(transport->device, id);
+}
+
 static void media_owner_exit(DBusConnection *connection, void *user_data)
 {
 	struct media_owner *owner = user_data;
@@ -672,6 +782,13 @@ static int set_property_headset(struct media_transport *transport,
 	return -EINVAL;
 }
 
+static int set_property_gateway(struct media_transport *transport,
+						const char *property,
+						DBusMessageIter *value)
+{
+	return -EINVAL;
+}
+
 static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
 								void *data)
 {
@@ -740,6 +857,12 @@ static void get_properties_headset(struct media_transport *transport,
 	dict_append_entry(dict, "Routing", DBUS_TYPE_STRING, &routing);
 }
 
+static void get_properties_gateway(struct media_transport *transport,
+						DBusMessageIter *dict)
+{
+	/* None */
+}
+
 void transport_get_properties(struct media_transport *transport,
 							DBusMessageIter *iter)
 {
@@ -881,6 +1004,13 @@ struct media_transport *media_transport_create(DBusConnection *conn,
 		transport->nrec_id = headset_add_nrec_cb(device,
 							headset_nrec_changed,
 							transport);
+	} else if (strcasecmp(uuid, HFP_HS_UUID) == 0 ||
+			strcasecmp(uuid, HSP_HS_UUID) == 0) {
+		transport->resume = resume_gateway;
+		transport->suspend = suspend_gateway;
+		transport->cancel = cancel_gateway;
+		transport->get_properties = get_properties_gateway;
+		transport->set_property = set_property_gateway;
 	} else
 		goto fail;
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux