[PATCH BlueZ 4/9] AVCTP: Simplify channel handling

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

 



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

Make both control and browsing channels to use the same structure to
store its channel information.
---
 audio/avctp.c | 155 +++++++++++++++++++++++++++++++---------------------------
 1 file changed, 82 insertions(+), 73 deletions(-)

diff --git a/audio/avctp.c b/audio/avctp.c
index 53c28ec..092a5e2 100644
--- a/audio/avctp.c
+++ b/audio/avctp.c
@@ -131,6 +131,12 @@ struct avctp_rsp_handler {
 	void *user_data;
 };
 
+struct avctp_channel {
+	GIOChannel *io;
+	guint watch;
+	uint16_t mtu;
+};
+
 struct avctp {
 	struct avctp_server *server;
 	bdaddr_t dst;
@@ -139,14 +145,10 @@ struct avctp {
 
 	int uinput;
 
-	GIOChannel *control_io;
-	GIOChannel *browsing_io;
-	guint control_io_id;
-	guint browsing_io_id;
 	guint auth_id;
 
-	uint16_t control_mtu;
-	uint16_t browsing_mtu;
+	struct avctp_channel *control;
+	struct avctp_channel *browsing;
 
 	uint8_t key_quirks[256];
 	GSList *handlers;
@@ -333,6 +335,17 @@ static struct avctp_pdu_handler *find_handler(GSList *list, uint8_t opcode)
 	return NULL;
 }
 
+static void avctp_channel_destroy(struct avctp_channel *chan)
+{
+	g_io_channel_shutdown(chan->io, TRUE, NULL);
+	g_io_channel_unref(chan->io);
+
+	if (chan->watch)
+		g_source_remove(chan->watch);
+
+	g_free(chan);
+}
+
 static void avctp_disconnected(struct avctp *session)
 {
 	struct avctp_server *server;
@@ -340,31 +353,15 @@ static void avctp_disconnected(struct avctp *session)
 	if (!session)
 		return;
 
-	if (session->browsing_io) {
-		g_io_channel_shutdown(session->browsing_io, TRUE, NULL);
-		g_io_channel_unref(session->browsing_io);
-		session->browsing_io = NULL;
-	}
-
-	if (session->browsing_io_id) {
-		g_source_remove(session->browsing_io_id);
-		session->browsing_io_id = 0;
-	}
-
-	if (session->control_io) {
-		g_io_channel_shutdown(session->control_io, TRUE, NULL);
-		g_io_channel_unref(session->control_io);
-		session->control_io = NULL;
-	}
+	if (session->browsing)
+		avctp_channel_destroy(session->browsing);
 
-	if (session->control_io_id) {
-		g_source_remove(session->control_io_id);
-		session->control_io_id = 0;
+	if (session->control)
+		avctp_channel_destroy(session->control);
 
-		if (session->auth_id != 0) {
-			btd_cancel_authorization(session->auth_id);
-			session->auth_id = 0;
-		}
+	if (session->auth_id != 0) {
+		btd_cancel_authorization(session->auth_id);
+		session->auth_id = 0;
 	}
 
 	if (session->uinput >= 0) {
@@ -420,7 +417,7 @@ static void avctp_set_state(struct avctp *session, avctp_state_t new_state)
 	}
 }
 
-static void handle_response(struct avctp *session, struct avctp_header *avctp,
+static void control_response(struct avctp *session, struct avctp_header *avctp,
 				struct avc_header *avc, uint8_t *operands,
 				size_t operand_count)
 {
@@ -456,7 +453,7 @@ static gboolean session_browsing_cb(GIOChannel *chan, GIOCondition cond,
 	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
 		goto failed;
 
-	sock = g_io_channel_unix_get_fd(session->browsing_io);
+	sock = g_io_channel_unix_get_fd(chan);
 
 	ret = read(sock, buf, sizeof(buf));
 	if (ret <= 0)
@@ -508,7 +505,7 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
 		goto failed;
 
-	sock = g_io_channel_unix_get_fd(session->control_io);
+	sock = g_io_channel_unix_get_fd(chan);
 
 	ret = read(sock, buf, sizeof(buf));
 	if (ret <= 0)
@@ -548,7 +545,7 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 			avc->opcode, operand_count);
 
 	if (avctp->cr == AVCTP_RESPONSE) {
-		handle_response(session, avctp, avc, operands, operand_count);
+		control_response(session, avctp, avc, operands, operand_count);
 		return TRUE;
 	}
 
@@ -676,6 +673,16 @@ static void init_uinput(struct avctp *session)
 		DBG("AVRCP: uinput initialized for %s", address);
 }
 
+static struct avctp_channel *avctp_channel_create(GIOChannel *io)
+{
+	struct avctp_channel *chan;
+
+	chan = g_new0(struct avctp_channel, 1);
+	chan->io = g_io_channel_ref(io);
+
+	return chan;
+}
+
 static void avctp_connect_browsing_cb(GIOChannel *chan, GError *err,
 							gpointer data)
 {
@@ -686,10 +693,7 @@ static void avctp_connect_browsing_cb(GIOChannel *chan, GError *err,
 
 	if (err) {
 		error("Browsing: %s", err->message);
-		g_io_channel_shutdown(chan, TRUE, NULL);
-		g_io_channel_unref(chan);
-		session->browsing_io = NULL;
-		return;
+		goto fail;
 	}
 
 	bt_io_get(chan, &gerr,
@@ -700,20 +704,28 @@ static void avctp_connect_browsing_cb(GIOChannel *chan, GError *err,
 		error("%s", gerr->message);
 		g_io_channel_shutdown(chan, TRUE, NULL);
 		g_io_channel_unref(chan);
-		session->browsing_io = NULL;
 		g_error_free(gerr);
-		return;
+		goto fail;
 	}
 
 	DBG("AVCTP Browsing: connected to %s", address);
 
-	if (!session->browsing_io)
-		session->browsing_io = g_io_channel_ref(chan);
+	if (session->browsing == NULL)
+		session->browsing = avctp_channel_create(chan);
 
-	session->browsing_mtu = imtu;
-	session->browsing_io_id = g_io_add_watch(chan,
+	session->browsing->mtu = imtu;
+	session->browsing->watch = g_io_add_watch(session->browsing->io,
 				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-				(GIOFunc) session_browsing_cb, session); }
+				(GIOFunc) session_browsing_cb, session);
+
+	return;
+
+fail:
+	if (session->browsing) {
+		avctp_channel_destroy(session->browsing);
+		session->browsing = NULL;
+	}
+}
 
 static void avctp_connect_cb(GIOChannel *chan, GError *err, gpointer data)
 {
@@ -741,16 +753,17 @@ static void avctp_connect_cb(GIOChannel *chan, GError *err, gpointer data)
 
 	DBG("AVCTP: connected to %s", address);
 
-	if (!session->control_io)
-		session->control_io = g_io_channel_ref(chan);
+	if (session->control == NULL)
+		session->control = avctp_channel_create(chan);
+
+	session->control->mtu = imtu;
+	session->control->watch = g_io_add_watch(session->control->io,
+				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+				(GIOFunc) session_cb, session);
 
 	init_uinput(session);
 
 	avctp_set_state(session, AVCTP_STATE_CONNECTED);
-	session->control_mtu = imtu;
-	session->control_io_id = g_io_add_watch(chan,
-				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-				(GIOFunc) session_cb, session);
 }
 
 static void auth_cb(DBusError *derr, void *user_data)
@@ -760,9 +773,9 @@ static void auth_cb(DBusError *derr, void *user_data)
 
 	session->auth_id = 0;
 
-	if (session->control_io_id) {
-		g_source_remove(session->control_io_id);
-		session->control_io_id = 0;
+	if (session->control->watch > 0) {
+		g_source_remove(session->control->watch);
+		session->control->watch = 0;
 	}
 
 	if (derr && dbus_error_is_set(derr)) {
@@ -771,7 +784,7 @@ static void auth_cb(DBusError *derr, void *user_data)
 		return;
 	}
 
-	if (!bt_io_accept(session->control_io, avctp_connect_cb, session,
+	if (!bt_io_accept(session->control->io, avctp_connect_cb, session,
 								NULL, &err)) {
 		error("bt_io_accept: %s", err->message);
 		g_error_free(err);
@@ -836,14 +849,14 @@ static struct avctp *avctp_get_internal(const bdaddr_t *src,
 static void avctp_control_confirm(struct avctp *session, GIOChannel *chan,
 						struct audio_device *dev)
 {
-	if (session->control_io) {
+	if (session->control != NULL) {
 		error("Control: Refusing unexpected connect");
 		g_io_channel_shutdown(chan, TRUE, NULL);
 		return;
 	}
 
 	avctp_set_state(session, AVCTP_STATE_CONNECTING);
-	session->control_io = g_io_channel_ref(chan);
+	session->control = avctp_channel_create(chan);
 
 	session->auth_id = btd_request_authorization(&dev->src, &dev->dst,
 							AVRCP_TARGET_UUID,
@@ -851,7 +864,7 @@ static void avctp_control_confirm(struct avctp *session, GIOChannel *chan,
 	if (session->auth_id == 0)
 		goto drop;
 
-	session->control_io_id = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP |
+	session->control->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP |
 						G_IO_NVAL, session_cb, session);
 	return;
 
@@ -864,7 +877,7 @@ static void avctp_browsing_confirm(struct avctp *session, GIOChannel *chan,
 {
 	GError *err = NULL;
 
-	if (session->control_io == NULL || session->browsing_io) {
+	if (session->control == NULL || session->browsing != NULL) {
 		error("Browsing: Refusing unexpected connect");
 		g_io_channel_shutdown(chan, TRUE, NULL);
 		return;
@@ -911,8 +924,8 @@ static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
 	DBG("AVCTP: incoming connect from %s", address);
 
 	session = avctp_get_internal(&src, &dst);
-	if (!session)
-		goto drop;
+	if (session == NULL)
+		return;
 
 	dev = manager_get_device(&src, &dst, FALSE);
 	if (!dev) {
@@ -942,13 +955,7 @@ static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
 	return;
 
 drop:
-	if (session && session->browsing_io)
-		g_io_channel_unref(session->browsing_io);
-
-	if (session && session->control_io)
-		g_io_channel_unref(session->control_io);
-
-	if (session && psm == AVCTP_CONTROL_PSM)
+	if (psm == AVCTP_CONTROL_PSM)
 		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
 }
 
@@ -1086,7 +1093,7 @@ int avctp_send_passthrough(struct avctp *session, uint8_t op)
 	operands[0] = op & 0x7f;
 	operands[1] = 0;
 
-	sk = g_io_channel_unix_get_fd(session->control_io);
+	sk = g_io_channel_unix_get_fd(session->control->io);
 
 	if (write(sk, buf, sizeof(buf)) < 0)
 		return -errno;
@@ -1115,7 +1122,7 @@ static int avctp_send(struct avctp *session, uint8_t transaction, uint8_t cr,
 	if (session->state != AVCTP_STATE_CONNECTED)
 		return -ENOTCONN;
 
-	sk = g_io_channel_unix_get_fd(session->control_io);
+	sk = g_io_channel_unix_get_fd(session->control->io);
 
 	memset(buf, 0, sizeof(buf));
 
@@ -1299,7 +1306,8 @@ struct avctp *avctp_connect(const bdaddr_t *src, const bdaddr_t *dst)
 		return NULL;
 	}
 
-	session->control_io = io;
+	session->control = avctp_channel_create(io);
+	g_io_channel_unref(io);
 
 	return session;
 }
@@ -1312,7 +1320,7 @@ int avctp_connect_browsing(struct avctp *session)
 	if (session->state != AVCTP_STATE_CONNECTED)
 		return -ENOTCONN;
 
-	if (session->browsing_io != NULL)
+	if (session->browsing != NULL)
 		return 0;
 
 	io = bt_io_connect(avctp_connect_browsing_cb, session, NULL, &err,
@@ -1327,14 +1335,15 @@ int avctp_connect_browsing(struct avctp *session)
 		return -EIO;
 	}
 
-	session->browsing_io = io;
+	session->browsing = avctp_channel_create(io);
+	g_io_channel_unref(io);
 
 	return 0;
 }
 
 void avctp_disconnect(struct avctp *session)
 {
-	if (!session->control_io)
+	if (session->state == AVCTP_STATE_DISCONNECTED)
 		return;
 
 	avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
-- 
1.7.11.4

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