[PATCH BlueZ] audio: Separate profile specific fields from media_transport

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

 



From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>

---
 audio/transport.c |  116 +++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 82 insertions(+), 34 deletions(-)

diff --git a/audio/transport.c b/audio/transport.c
index 1fccff8..3953c4e 100644
--- a/audio/transport.c
+++ b/audio/transport.c
@@ -62,11 +62,20 @@ struct media_owner {
 	guint			watch;
 };
 
+struct a2dp_transport {
+	struct avdtp		*session;
+	uint16_t		delay;
+	uint16_t		volume;
+};
+
+struct headset_transport {
+	unsigned int		nrec_id;
+};
+
 struct media_transport {
 	DBusConnection		*conn;
 	char			*path;		/* Transport object path */
 	struct audio_device	*device;	/* Transport device */
-	struct avdtp		*session;	/* Signalling session (a2dp only) */
 	struct media_endpoint	*endpoint;	/* Transport endpoint */
 	GSList			*owners;	/* Transport owners */
 	uint8_t			*configuration; /* Transport configuration */
@@ -74,9 +83,6 @@ struct media_transport {
 	int			fd;		/* Transport file descriptor */
 	uint16_t		imtu;		/* Transport input mtu */
 	uint16_t		omtu;		/* Transport output mtu */
-	uint16_t		delay;		/* Transport delay (a2dp only) */
-	unsigned int		nrec_id;	/* Transport nrec watch (headset only) */
-	uint16_t		volume;		/* Transport volume */
 	gboolean		read_lock;
 	gboolean		write_lock;
 	gboolean		in_use;
@@ -93,6 +99,8 @@ struct media_transport {
 					struct media_transport *transport,
 					const char *property,
 					DBusMessageIter *value);
+	GDestroyNotify		destroy;
+	void			*data;
 };
 
 void media_transport_destroy(struct media_transport *transport)
@@ -276,26 +284,26 @@ fail:
 static guint resume_a2dp(struct media_transport *transport,
 				struct media_owner *owner)
 {
+	struct a2dp_transport *a2dp = transport->data;
 	struct media_endpoint *endpoint = transport->endpoint;
 	struct audio_device *device = transport->device;
 	struct a2dp_sep *sep = media_endpoint_get_sep(endpoint);
 
-	if (transport->session == NULL) {
-		transport->session = avdtp_get(&device->src, &device->dst);
-		if (transport->session == NULL)
+	if (a2dp->session == NULL) {
+		a2dp->session = avdtp_get(&device->src, &device->dst);
+		if (a2dp->session == NULL)
 			return 0;
 	}
 
 	if (transport->in_use == TRUE)
 		goto done;
 
-	transport->in_use = a2dp_sep_lock(sep, transport->session);
+	transport->in_use = a2dp_sep_lock(sep, a2dp->session);
 	if (transport->in_use == FALSE)
 		return 0;
 
 done:
-	return a2dp_resume(transport->session, sep, a2dp_resume_complete,
-				owner);
+	return a2dp_resume(a2dp->session, sep, a2dp_resume_complete, owner);
 }
 
 static void a2dp_suspend_complete(struct avdtp *session,
@@ -303,6 +311,7 @@ static void a2dp_suspend_complete(struct avdtp *session,
 {
 	struct media_owner *owner = user_data;
 	struct media_transport *transport = owner->transport;
+	struct a2dp_transport *a2dp = transport->data;
 	struct a2dp_sep *sep = media_endpoint_get_sep(transport->endpoint);
 
 	/* Release always succeeds */
@@ -312,7 +321,7 @@ static void a2dp_suspend_complete(struct avdtp *session,
 		media_owner_remove(owner);
 	}
 
-	a2dp_sep_unlock(sep, transport->session);
+	a2dp_sep_unlock(sep, a2dp->session);
 	transport->in_use = FALSE;
 	media_transport_remove(transport, owner);
 }
@@ -320,17 +329,17 @@ static void a2dp_suspend_complete(struct avdtp *session,
 static guint suspend_a2dp(struct media_transport *transport,
 						struct media_owner *owner)
 {
+	struct a2dp_transport *a2dp = transport->data;
 	struct media_endpoint *endpoint = transport->endpoint;
 	struct a2dp_sep *sep = media_endpoint_get_sep(endpoint);
 
 	if (!owner) {
-		a2dp_sep_unlock(sep, transport->session);
+		a2dp_sep_unlock(sep, a2dp->session);
 		transport->in_use = FALSE;
 		return 0;
 	}
 
-	return a2dp_suspend(transport->session, sep, a2dp_suspend_complete,
-				owner);
+	return a2dp_suspend(a2dp->session, sep, a2dp_suspend_complete, owner);
 }
 
 static void cancel_a2dp(struct media_transport *transport, guint id)
@@ -745,10 +754,12 @@ static int set_property_a2dp(struct media_transport *transport,
 						const char *property,
 						DBusMessageIter *value)
 {
+	struct a2dp_transport *a2dp = transport->data;
+
 	if (g_strcmp0(property, "Delay") == 0) {
 		if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_UINT16)
 			return -EINVAL;
-		dbus_message_iter_get_basic(value, &transport->delay);
+		dbus_message_iter_get_basic(value, &a2dp->delay);
 
 		/* FIXME: send new delay */
 		return 0;
@@ -763,7 +774,7 @@ static int set_property_a2dp(struct media_transport *transport,
 		if (volume > 127)
 			return -EINVAL;
 
-		if (transport->volume == volume)
+		if (a2dp->volume == volume)
 			return 0;
 
 		return avrcp_set_volume(transport->device, volume);
@@ -855,11 +866,13 @@ static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
 static void get_properties_a2dp(struct media_transport *transport,
 						DBusMessageIter *dict)
 {
-	dict_append_entry(dict, "Delay", DBUS_TYPE_UINT16, &transport->delay);
+	struct a2dp_transport *a2dp = transport->data;
+
+	dict_append_entry(dict, "Delay", DBUS_TYPE_UINT16, &a2dp->delay);
 
-	if (transport->volume <= 127)
+	if (a2dp->volume <= 127)
 		dict_append_entry(dict, "Volume", DBUS_TYPE_UINT16,
-							&transport->volume);
+							&a2dp->volume);
 }
 
 static void get_properties_headset(struct media_transport *transport,
@@ -957,6 +970,28 @@ static const GDBusSignalTable transport_signals[] = {
 	{ }
 };
 
+static void destroy_a2dp(void *data)
+{
+	struct media_transport *transport = data;
+	struct a2dp_transport *a2dp = transport->data;
+
+	if (a2dp->session)
+		avdtp_unref(a2dp->session);
+
+	g_free(a2dp);
+}
+
+static void destroy_headset(void *data)
+{
+	struct media_transport *transport = data;
+	struct headset_transport *headset = transport->data;
+
+	if (headset->nrec_id > 0)
+		headset_remove_nrec_cb(transport->device, headset->nrec_id);
+
+	g_free(headset);
+}
+
 static void media_transport_free(void *data)
 {
 	struct media_transport *transport = data;
@@ -970,11 +1005,8 @@ static void media_transport_free(void *data)
 
 	g_slist_free(transport->owners);
 
-	if (transport->session)
-		avdtp_unref(transport->session);
-
-	if (transport->nrec_id)
-		headset_remove_nrec_cb(transport->device, transport->nrec_id);
+	if (transport->destroy != NULL)
+		transport->destroy(transport);
 
 	if (transport->conn)
 		dbus_connection_unref(transport->conn);
@@ -1015,26 +1047,38 @@ struct media_transport *media_transport_create(DBusConnection *conn,
 	transport->size = size;
 	transport->path = g_strdup_printf("%s/fd%d", device->path, fd++);
 	transport->fd = -1;
-	transport->volume = -1;
 
 	uuid = media_endpoint_get_uuid(endpoint);
 	if (strcasecmp(uuid, A2DP_SOURCE_UUID) == 0 ||
 			strcasecmp(uuid, A2DP_SINK_UUID) == 0) {
+		struct a2dp_transport *a2dp;
+
+		a2dp = g_new0(struct a2dp_transport, 1);
+		a2dp->volume = -1;
+
 		transport->resume = resume_a2dp;
 		transport->suspend = suspend_a2dp;
 		transport->cancel = cancel_a2dp;
 		transport->get_properties = get_properties_a2dp;
 		transport->set_property = set_property_a2dp;
+		transport->data = a2dp;
+		transport->destroy = destroy_a2dp;
 	} else if (strcasecmp(uuid, HFP_AG_UUID) == 0 ||
 			strcasecmp(uuid, HSP_AG_UUID) == 0) {
+		struct headset_transport *headset;
+
+		headset = g_new0(struct headset_transport, 1);
+		headset->nrec_id = headset_add_nrec_cb(device,
+							headset_nrec_changed,
+							transport);
+
 		transport->resume = resume_headset;
 		transport->suspend = suspend_headset;
 		transport->cancel = cancel_headset;
 		transport->get_properties = get_properties_headset;
 		transport->set_property = set_property_headset;
-		transport->nrec_id = headset_add_nrec_cb(device,
-							headset_nrec_changed,
-							transport);
+		transport->data = headset;
+		transport->destroy = destroy_headset;
 	} else if (strcasecmp(uuid, HFP_HS_UUID) == 0 ||
 			strcasecmp(uuid, HSP_HS_UUID) == 0) {
 		transport->resume = resume_gateway;
@@ -1068,15 +1112,17 @@ const char *media_transport_get_path(struct media_transport *transport)
 void media_transport_update_delay(struct media_transport *transport,
 							uint16_t delay)
 {
+	struct a2dp_transport *a2dp = transport->data;
+
 	/* Check if delay really changed */
-	if (transport->delay == delay)
+	if (a2dp->delay == delay)
 		return;
 
-	transport->delay = delay;
+	a2dp->delay = delay;
 
 	emit_property_changed(transport->conn, transport->path,
 				MEDIA_TRANSPORT_INTERFACE, "Delay",
-				DBUS_TYPE_UINT16, &transport->delay);
+				DBUS_TYPE_UINT16, &a2dp->delay);
 }
 
 struct audio_device *media_transport_get_dev(struct media_transport *transport)
@@ -1087,13 +1133,15 @@ struct audio_device *media_transport_get_dev(struct media_transport *transport)
 void media_transport_update_volume(struct media_transport *transport,
 								uint8_t volume)
 {
+	struct a2dp_transport *a2dp = transport->data;
+
 	/* Check if volume really changed */
-	if (transport->volume == volume)
+	if (a2dp->volume == volume)
 		return;
 
-	transport->volume = volume;
+	a2dp->volume = volume;
 
 	emit_property_changed(transport->conn, transport->path,
 				MEDIA_TRANSPORT_INTERFACE, "Volume",
-				DBUS_TYPE_UINT16, &transport->volume);
+				DBUS_TYPE_UINT16, &a2dp->volume);
 }
-- 
1.7.10.2

--
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