[PATCH BlueZ 4/7] 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 | 159 +++++++++++++++++++++++++++++-----------------------------
 1 file changed, 79 insertions(+), 80 deletions(-)

diff --git a/audio/avctp.c b/audio/avctp.c
index 6fd5491..dfc5601 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,13 +145,8 @@ struct avctp {
 
 	int uinput;
 
-	GIOChannel *control_io;
-	GIOChannel *browsing_io;
-	guint control_io_id;
-	guint browsing_io_id;
-
-	uint16_t control_mtu;
-	uint16_t browsing_mtu;
+	struct avctp_channel *control;
+	struct avctp_channel *browsing;
 
 	uint8_t key_quirks[256];
 	GSList *handlers;
@@ -332,6 +333,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;
@@ -339,36 +351,11 @@ 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->control_io_id) {
-		g_source_remove(session->control_io_id);
-		session->control_io_id = 0;
+	if (session->browsing)
+		avctp_channel_destroy(session->browsing);
 
-		if (session->state == AVCTP_STATE_CONNECTING) {
-			struct audio_device *dev;
-
-			dev = manager_get_device(&session->server->src,
-							&session->dst, FALSE);
-			audio_device_cancel_authorization(dev, auth_cb,
-								session);
-		}
-	}
+	if (session->control)
+		avctp_channel_destroy(session->control);
 
 	if (session->uinput >= 0) {
 		char address[18];
@@ -431,7 +418,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)
 {
@@ -467,7 +454,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)
@@ -519,7 +506,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)
@@ -559,7 +546,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;
 	}
 
@@ -687,6 +674,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)
 {
@@ -697,10 +694,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,
@@ -711,20 +705,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)
 {
@@ -752,16 +754,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)
@@ -769,9 +772,9 @@ static void auth_cb(DBusError *derr, void *user_data)
 	struct avctp *session = user_data;
 	GError *err = NULL;
 
-	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)) {
@@ -780,7 +783,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);
@@ -845,20 +848,20 @@ 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);
 
 	if (audio_device_request_authorization(dev, AVRCP_TARGET_UUID,
 						auth_cb, session) < 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;
 
@@ -871,7 +874,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;
@@ -918,8 +921,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) {
@@ -949,13 +952,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);
 }
 
@@ -1093,7 +1090,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;
@@ -1122,7 +1119,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));
 
@@ -1306,7 +1303,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;
 }
@@ -1319,7 +1317,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,
@@ -1334,14 +1332,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