diff options
| author | Johan Hedberg <johan.hedberg@nokia.com> | 2009-02-19 22:22:20 +0200 | 
|---|---|---|
| committer | Johan Hedberg <johan.hedberg@nokia.com> | 2009-02-19 22:22:20 +0200 | 
| commit | e03af126e1b79d4096dc9147859f74f256af28bb (patch) | |
| tree | 6fcbaa90b74db1ff49c349102197aba3902adfd1 | |
| parent | 10d6858927cb3db0a06c42f41cdb5f3175082df3 (diff) | |
Convert control.c to use btio confirm_cb
| -rw-r--r-- | audio/control.c | 189 | 
1 files changed, 81 insertions, 108 deletions
| diff --git a/audio/control.c b/audio/control.c index efe9f987..74879656 100644 --- a/audio/control.c +++ b/audio/control.c @@ -165,9 +165,8 @@ struct avctp {  	int uinput; -	int sock; - -	guint io; +	GIOChannel *io; +	guint io_id;  	uint16_t mtu;  }; @@ -332,7 +331,6 @@ static struct avctp *avctp_get(const bdaddr_t *src, const bdaddr_t *dst)  	session = g_new0(struct avctp, 1);  	session->uinput = -1; -	session->sock = -1;  	bacpy(&session->src, src);  	bacpy(&session->dst, dst); @@ -429,10 +427,12 @@ static void avctp_unref(struct avctp *session)  					DBUS_TYPE_BOOLEAN, &value);  	} -	if (session->sock >= 0) -		close(session->sock); -	if (session->io) -		g_source_remove(session->io); +	if (session->io) { +		g_io_channel_shutdown(session->io, TRUE, NULL); +		g_io_channel_unref(session->io); +	} +	if (session->io_id) +		g_source_remove(session->io_id);  	if (session->dev)  		session->dev->control->session = NULL; @@ -452,12 +452,14 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,  	unsigned char buf[1024], *operands;  	struct avctp_header *avctp;  	struct avrcp_header *avrcp; -	int ret, packet_size, operand_count; +	int ret, packet_size, operand_count, sock;  	if (!(cond | G_IO_IN))  		goto failed; -	ret = read(session->sock, buf, sizeof(buf)); +	sock = g_io_channel_unix_get_fd(session->io); + +	ret = read(sock, buf, sizeof(buf));  	if (ret <= 0)  		goto failed; @@ -505,7 +507,7 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,  		handle_panel_passthrough(session, operands, operand_count);  		avctp->cr = AVCTP_RESPONSE;  		avrcp->code = CTYPE_ACCEPTED; -		ret = write(session->sock, buf, packet_size); +		ret = write(sock, buf, packet_size);  	}  	if (avctp->packet_type == AVCTP_PACKET_SINGLE && @@ -518,7 +520,7 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,  		avrcp->code = CTYPE_STABLE;  		debug("reply to %s", avrcp->opcode == OP_UNITINFO ?  				"OP_UNITINFO" : "OP_SUBUNITINFO"); -		ret = write(session->sock, buf, packet_size); +		ret = write(sock, buf, packet_size);  	}  	return TRUE; @@ -603,20 +605,46 @@ static void init_uinput(struct avctp *session)  		debug("AVRCP: uinput initialized for %s", address);  } -static gboolean avctp_connect_session(struct avctp *session) +static void avctp_connect_cb(GIOChannel *chan, GError *err, gpointer data)  { -	GIOChannel *io; +	struct control *control = data; +	struct avctp *session = control->session; +	char address[18]; +	uint16_t imtu; +	GError *gerr = NULL;  	gboolean value; -	session->dev = manager_find_device(&session->dst, NULL, FALSE); -	if (!session->dev) { -		error("Connecting audio device not known (SDP not completed)"); -		return FALSE; +	if (!session) { +		debug("avctp_connect_cb: session removed while connecting"); +		g_io_channel_shutdown(chan, TRUE, NULL); +		g_io_channel_unref(chan); +		return;  	} -	session->state = AVCTP_STATE_CONNECTED; +	if (err) { +		avctp_unref(session); +		error("%s", err->message); +		return; +	} -	session->dev->control->session = session; +	bt_io_get(chan, BT_IO_L2CAP, &gerr, +			BT_IO_OPT_DEST, &address, +			BT_IO_OPT_IMTU, &imtu, +			BT_IO_OPT_INVALID); +	if (gerr) { +		avctp_unref(session); +		error("%s", gerr->message); +		g_error_free(gerr); +		g_io_channel_shutdown(chan, TRUE, NULL); +		return; +	} + +	debug("AVCTP: connected to %s", address); + +	g_io_channel_set_close_on_unref(chan, FALSE); + +	if (!session->io) +		session->io = g_io_channel_ref(chan);  	init_uinput(session); @@ -628,57 +656,51 @@ static gboolean avctp_connect_session(struct avctp *session)  				AUDIO_CONTROL_INTERFACE, "Connected",  				DBUS_TYPE_BOOLEAN, &value); -	if (session->io) -		g_source_remove(session->io); - -	io = g_io_channel_unix_new(session->sock); -	session->io = g_io_add_watch(io, -			G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, -			(GIOFunc) session_cb, session); -	g_io_channel_unref(io); - -	return TRUE; +	session->state = AVCTP_STATE_CONNECTED; +	session->mtu = imtu; +	session->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)  { -	struct avctp *session = user_data; +	struct control *control = user_data; +	struct avctp *session = control->session; +	GError *err = NULL;  	if (derr && dbus_error_is_set(derr)) {  		error("Access denied: %s", derr->message); -  		avctp_unref(session);  		return;  	} -	avctp_connect_session(session); +	if (!bt_io_accept(session->io, avctp_connect_cb, control, +								NULL, &err)) { +		error("bt_io_accept: %s", err->message); +		g_error_free(err); +		avctp_unref(session); +	}  } -static void avctp_server_cb(GIOChannel *chan, GError *err, gpointer data) +static void avctp_confirm_cb(GIOChannel *chan, gpointer data)  {  	struct avctp *session;  	GIOCondition flags = G_IO_ERR | G_IO_HUP | G_IO_NVAL;  	struct audio_device *dev;  	char address[18];  	bdaddr_t src, dst; -	uint16_t imtu;  	int perr; -	GError *gerr = NULL; - -	if (err) { -		error("%s", err->message); -		return; -	} +	GError *err = NULL; -	bt_io_get(chan, BT_IO_L2CAP, &gerr, +	bt_io_get(chan, BT_IO_L2CAP, &err,  			BT_IO_OPT_SOURCE_BDADDR, &src,  			BT_IO_OPT_DEST_BDADDR, &dst,  			BT_IO_OPT_DEST, address, -			BT_IO_OPT_IMTU, &imtu,  			BT_IO_OPT_INVALID); -	if (gerr) { -		error("%s", gerr->message); -		g_error_free(gerr); +	if (err) { +		error("%s", err->message); +		g_error_free(err);  		g_io_channel_shutdown(chan, TRUE, NULL);  		return;  	} @@ -690,7 +712,7 @@ static void avctp_server_cb(GIOChannel *chan, GError *err, gpointer data)  		goto drop;  	} -	if (session->sock >= 0) { +	if (session->io) {  		error("Refusing unexpected connect from %s", address);  		goto drop;  	} @@ -704,28 +726,32 @@ static void avctp_server_cb(GIOChannel *chan, GError *err, gpointer data)  	if (!dev->control)  		dev->control = control_init(dev); +	if (!dev->control->session) +		dev->control->session = session; + +	if (!session->dev) +		session->dev = dev; +  	device_remove_control_timer(dev);  	session->state = AVCTP_STATE_CONNECTING; -	session->sock = g_io_channel_unix_get_fd(chan); - -	session->mtu = imtu; +	session->io = g_io_channel_ref(chan); -	session->io = g_io_add_watch(chan, flags, (GIOFunc) session_cb, -				session); +	session->io_id = g_io_add_watch(chan, flags, (GIOFunc) session_cb, +								session);  	if (avdtp_is_connected(&src, &dst))  		goto proceed;  	perr = btd_request_authorization(&src, &dst, AVRCP_TARGET_UUID, -				auth_cb, session); +				auth_cb, dev->control);  	if (perr < 0)  		goto drop;  	return;  proceed: -	if (!avctp_connect_session(session)) +	if (!bt_io_accept(chan, avctp_connect_cb, dev->control, NULL, NULL))  		goto drop;  	return; @@ -740,7 +766,7 @@ static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master)  	GError *err = NULL;  	GIOChannel *io; -	io = bt_io_listen(BT_IO_L2CAP, avctp_server_cb, NULL, NULL, +	io = bt_io_listen(BT_IO_L2CAP, NULL, avctp_confirm_cb, NULL,  				NULL, &err,  				BT_IO_OPT_SOURCE_BDADDR, src,  				BT_IO_OPT_PSM, AVCTP_PSM, @@ -755,59 +781,6 @@ static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master)  	return io;  } -static void avctp_connect_cb(GIOChannel *chan, GError *err, gpointer data) -{ -	struct control *control = data; -	struct avctp *session = control->session; -	int sk; -	char address[18]; -	uint16_t imtu; -	GError *gerr = NULL; - -	if (!session) { -		debug("avctp_connect_cb: session removed while connecting"); -		g_io_channel_shutdown(chan, TRUE, NULL); -		g_io_channel_unref(chan); -		return; -	} - -	if (err) { -		avctp_unref(session); -		error("%s", err->message); -		return; -	} - -	bt_io_get(chan, BT_IO_L2CAP, &gerr, -			BT_IO_OPT_DEST, &address, -			BT_IO_OPT_IMTU, &imtu, -			BT_IO_OPT_INVALID); -	if (gerr) { -		avctp_unref(session); -		error("%s", gerr->message); -		g_error_free(gerr); -		g_io_channel_shutdown(chan, TRUE, NULL); -		return; -	} - -	debug("AVCTP: connected to %s", address); - -	g_io_channel_set_close_on_unref(chan, FALSE); -	sk = g_io_channel_unix_get_fd(chan); -	session->sock = sk; - -	init_uinput(session); - -	g_dbus_emit_signal(session->dev->conn, session->dev->path, -				AUDIO_CONTROL_INTERFACE, "Connected", -				DBUS_TYPE_INVALID); - -	session->state = AVCTP_STATE_CONNECTED; -	session->mtu = imtu; -	session->io = g_io_add_watch(chan, -				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, -				(GIOFunc) session_cb, session); -} -  gboolean avrcp_connect(struct audio_device *dev)  {  	struct control *control = dev->control; | 
