diff options
| author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2009-02-18 19:17:54 -0300 | 
|---|---|---|
| committer | Johan Hedberg <johan.hedberg@nokia.com> | 2009-02-19 14:27:38 +0200 | 
| commit | d048052453e0a8ea53061e68424f671df8c405a0 (patch) | |
| tree | e66b94261ad103d0398e79eb914b4ca4a3e115b7 | |
| parent | 2ecef94bcdd0324da979752352a286be85520059 (diff) | |
Make audio plugin to use BtIO API.
| -rw-r--r-- | audio/avdtp.c | 136 | ||||
| -rw-r--r-- | audio/control.c | 123 | ||||
| -rw-r--r-- | audio/headset.c | 52 | ||||
| -rw-r--r-- | audio/main.c | 27 | ||||
| -rw-r--r-- | audio/manager.c | 96 | 
5 files changed, 253 insertions, 181 deletions
| diff --git a/audio/avdtp.c b/audio/avdtp.c index a7960f25..da1a4df7 100644 --- a/audio/avdtp.c +++ b/audio/avdtp.c @@ -50,6 +50,7 @@  #include "control.h"  #include "avdtp.h"  #include "glib-helper.h" +#include "btio.h"  #include "sink.h"  #include <bluetooth/l2cap.h> @@ -1764,22 +1765,20 @@ failed:  	return FALSE;  } -static void l2cap_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, -			const bdaddr_t *dst, gpointer user_data) +static void l2cap_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)  {  	struct avdtp *session = user_data; -	struct l2cap_options l2o; -	socklen_t len;  	int sk;  	char address[18]; +	GError *gerr = NULL;  	if (!g_slist_find(sessions, session)) {  		debug("l2cap_connect_cb: session got removed");  		return;  	} -	if (err < 0) { -		error("connect(): %s (%d)", strerror(-err), -err); +	if (err) { +		error("%s", err->message);  		goto failed;  	} @@ -1790,27 +1789,24 @@ static void l2cap_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,  		session->state = AVDTP_SESSION_STATE_CONNECTING;  	} +	bt_io_get(chan, BT_IO_L2CAP, &gerr, +			BT_IO_OPT_OMTU, &session->omtu, +			BT_IO_OPT_IMTU, &session->imtu, +			BT_IO_OPT_INVALID); +	if (gerr) { +		error("%s", gerr->message); +		g_clear_error(&gerr); +		goto failed; +	} +  	ba2str(&session->dst, address);  	debug("AVDTP: connected %s channel to %s",  			session->pending_open ? "transport" : "signaling",  			address); -	memset(&l2o, 0, sizeof(l2o)); -	len = sizeof(l2o); -	if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, -				&len) < 0) { -		err = errno; -		error("getsockopt(L2CAP_OPTIONS): %s (%d)", strerror(err), -				err); -		goto failed; -	} -  	if (session->state == AVDTP_SESSION_STATE_CONNECTING) {  		struct audio_device *dev; -		session->imtu = l2o.imtu; -		session->omtu = l2o.omtu; -  		debug("AVDTP imtu=%u, omtu=%u", session->imtu, session->omtu);  		session->buf = g_malloc0(session->imtu); @@ -1824,13 +1820,10 @@ static void l2cap_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,  						AUDIO_CONTROL_INTERFACE, FALSE);  		if (dev)  			avrcp_connect(dev); -	} -	else if (session->pending_open) -		handle_transport_connect(session, sk, l2o.imtu, l2o.omtu); -	else { -		err = -EIO; +	} else if (session->pending_open) +		handle_transport_connect(session, sk, session->imtu, session->omtu); +	else  		goto failed; -	}  	process_queue(session); @@ -1846,22 +1839,30 @@ failed:  			avdtp_sep_set_state(session, stream->lsep,  						AVDTP_STATE_IDLE);  	} else -		connection_lost(session, -err); +		connection_lost(session, EIO);  	return;  }  static int l2cap_connect(struct avdtp *session)  { -	int err; +	GError *err = NULL; +	GIOChannel *io; -	err = bt_l2cap_connect(&session->server->src, &session->dst, AVDTP_PSM, -				0, l2cap_connect_cb, session); -	if (err < 0) { -		error("Connect failed. %s(%d)", strerror(-err), -err); -		return err; +	io = bt_io_connect(BT_IO_L2CAP, l2cap_connect_cb, session, +				NULL, &err, +				BT_IO_OPT_SOURCE_BDADDR, &session->server->src, +				BT_IO_OPT_DEST_BDADDR, &session->dst, +				BT_IO_OPT_PSM, AVDTP_PSM, +				BT_IO_OPT_INVALID); +	if (!io) { +		error("%s", err->message); +		g_error_free(err); +		return -EIO;  	} +	g_io_channel_unref(io); +  	return 0;  } @@ -2997,38 +2998,43 @@ static void auth_cb(DBusError *derr, void *user_data)  	g_io_channel_unref(io);  } -static void avdtp_server_cb(GIOChannel *chan, int err, const bdaddr_t *src, -		const bdaddr_t *dst, gpointer data) +static void avdtp_server_cb(GIOChannel *chan, GError *err, gpointer data)  {  	int sk; -	socklen_t size; -	struct l2cap_options l2o;  	struct avdtp *session;  	struct audio_device *dev;  	char address[18]; +	bdaddr_t src, dst; +	uint16_t imtu, omtu; +	int perr; +	GError *gerr = NULL; -	if (err < 0) { -		error("accept: %s (%d)", strerror(-err), -err); +	if (err) { +		error("%s", err->message);  		return;  	} -	sk = g_io_channel_unix_get_fd(chan); +	bt_io_get(chan, BT_IO_L2CAP, &gerr, +			BT_IO_OPT_SOURCE_BDADDR, &src, +			BT_IO_OPT_DEST_BDADDR, &dst, +			BT_IO_OPT_DEST, address, +			BT_IO_OPT_OMTU, &omtu, +			BT_IO_OPT_IMTU, &imtu, +			BT_IO_OPT_INVALID); +	if (gerr) { +		error("%s", gerr->message); +		g_error_free(gerr); +		goto drop; +	} -	ba2str(dst, address);  	debug("AVDTP: incoming connect from %s", address); -	memset(&l2o, 0, sizeof(l2o)); -	size = sizeof(l2o); -	if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &size) < 0) { -		error("getsockopt(L2CAP_OPTIONS): %s (%d)", strerror(errno), -			errno); -		goto drop; -	} +	session = avdtp_get_internal(&src, &dst); -	session = avdtp_get_internal(src, dst); +	sk = g_io_channel_unix_get_fd(chan);  	if (session->pending_open && session->pending_open->open_acp) { -		handle_transport_connect(session, sk, l2o.imtu, l2o.omtu); +		handle_transport_connect(session, sk, imtu, omtu);  		return;  	} @@ -3037,47 +3043,53 @@ static void avdtp_server_cb(GIOChannel *chan, int err, const bdaddr_t *src,  		goto drop;  	} -	dev = manager_get_device(src, dst); +	dev = manager_get_device(&src, &dst);  	if (!dev) {  		error("Unable to get audio device object for %s", address);  		goto drop;  	} -	session->imtu = l2o.imtu; -	session->omtu = l2o.omtu; +	session->imtu = imtu; +	session->omtu = omtu;  	session->sock = sk;  	debug("AVDTP imtu=%u, omtu=%u", session->imtu, session->omtu);  	session->io = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,  					(GIOFunc) session_cb, session); -	err = btd_request_authorization(src, dst, ADVANCED_AUDIO_UUID, +	perr = btd_request_authorization(&src, &dst, ADVANCED_AUDIO_UUID,  							auth_cb, session); -	if (err < 0) { +	if (perr < 0) {  		avdtp_unref(session);  		goto drop;  	} -	g_io_channel_unref(chan); -  	session->state = AVDTP_SESSION_STATE_CONNECTING;  	return;  drop:  	g_io_channel_close(chan); -	g_io_channel_unref(chan);  }  static GIOChannel *avdtp_server_socket(const bdaddr_t *src, gboolean master)  { -	int lm = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT; +	GError *err = NULL; +	GIOChannel *io; -	if (master) -		lm |= L2CAP_LM_MASTER; +	io = bt_io_listen(BT_IO_L2CAP, avdtp_server_cb, NULL, NULL, +				NULL, &err, +				BT_IO_OPT_SOURCE_BDADDR, src, +				BT_IO_OPT_PSM, AVDTP_PSM, +				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, +				BT_IO_OPT_MASTER, master, +				BT_IO_OPT_INVALID); +	if (!io) { +		error("%s", err->message); +		g_error_free(err); +	} -	return bt_l2cap_listen(src, AVDTP_PSM, 0, lm, avdtp_server_cb, -			NULL); +	return io;  }  const char *avdtp_strerror(struct avdtp_error *err) diff --git a/audio/control.c b/audio/control.c index 5cf68cdf..941e1477 100644 --- a/audio/control.c +++ b/audio/control.c @@ -55,6 +55,7 @@  #include "control.h"  #include "sdpd.h"  #include "glib-helper.h" +#include "btio.h"  #include "dbus-common.h"  #define AVCTP_PSM 23 @@ -653,36 +654,48 @@ static void auth_cb(DBusError *derr, void *user_data)  	avctp_connect_session(session);  } -static void avctp_server_cb(GIOChannel *chan, int err, const bdaddr_t *src, -				const bdaddr_t *dst, gpointer data) +static void avctp_server_cb(GIOChannel *chan, GError *err, gpointer data)  { -	socklen_t size; -	struct l2cap_options l2o;  	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 < 0) { -		error("AVCTP server socket: %s (%d)", strerror(-err), -err); +	if (err) { +		error("%s", err->message);  		return;  	} -	session = avctp_get(src, dst); +	bt_io_get(chan, BT_IO_L2CAP, &gerr, +			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); +		g_io_channel_close(chan); +		return; +	} + +	session = avctp_get(&src, &dst);  	if (!session) {  		error("Unable to create new AVCTP session");  		goto drop;  	} -	ba2str(dst, address); -  	if (session->sock >= 0) {  		error("Refusing unexpected connect from %s", address);  		goto drop;  	} -	dev = manager_get_device(src, dst); +	dev = manager_get_device(&src, &dst);  	if (!dev) {  		error("Unable to get audio device object for %s", address);  		goto drop; @@ -696,27 +709,17 @@ static void avctp_server_cb(GIOChannel *chan, int err, const bdaddr_t *src,  	session->state = AVCTP_STATE_CONNECTING;  	session->sock = g_io_channel_unix_get_fd(chan); -	memset(&l2o, 0, sizeof(l2o)); -	size = sizeof(l2o); -	if (getsockopt(session->sock, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &size) < 0) { -		err = errno; -		error("getsockopt(L2CAP_OPTIONS): %s (%d)", strerror(err), -				err); -		goto drop; -	} - -	session->mtu = l2o.imtu; +	session->mtu = imtu;  	session->io = g_io_add_watch(chan, flags, (GIOFunc) session_cb,  				session); -	g_io_channel_unref(chan); -	if (avdtp_is_connected(src, dst)) +	if (avdtp_is_connected(&src, &dst))  		goto proceed; -	err = btd_request_authorization(src, dst, AVRCP_TARGET_UUID, +	perr = btd_request_authorization(&src, &dst, AVRCP_TARGET_UUID,  				auth_cb, session); -	if (err < 0) +	if (perr < 0)  		goto drop;  	return; @@ -734,31 +737,32 @@ drop:  static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master)  { +	GError *err = NULL;  	GIOChannel *io; -	int lm = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT; -	if (master) -		lm |= L2CAP_LM_MASTER; - -	io = bt_l2cap_listen(src, AVCTP_PSM, 0, lm, avctp_server_cb, -				NULL); +	io = bt_io_listen(BT_IO_L2CAP, avctp_server_cb, NULL, NULL, +				NULL, &err, +				BT_IO_OPT_SOURCE_BDADDR, src, +				BT_IO_OPT_PSM, AVCTP_PSM, +				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, +				BT_IO_OPT_MASTER, master, +				BT_IO_OPT_INVALID);  	if (!io) { -		error("Unable to allocate new io channel"); -		return NULL; +		error("%s", err->message); +		g_error_free(err);  	}  	return io;  } -static void avctp_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, -			const bdaddr_t *dst, gpointer data) +static void avctp_connect_cb(GIOChannel *chan, GError *err, gpointer data)  {  	struct control *control = data;  	struct avctp *session = control->session; -	struct l2cap_options l2o; -	socklen_t len;  	int sk;  	char address[18]; +	uint16_t imtu; +	GError *gerr = NULL;  	if (!session) {  		debug("avctp_connect_cb: session removed while connecting"); @@ -767,12 +771,21 @@ static void avctp_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,  		return;  	} -	ba2str(&session->dst, address); +	if (err) { +		avctp_unref(session); +		error("%s", err->message); +		return; +	} -	if (err < 0) { +	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("AVCTP connect(%s): %s (%d)", address, strerror(-err), -				-err); +		error("%s", gerr->message); +		g_error_free(gerr); +		g_io_channel_close(chan);  		return;  	} @@ -782,17 +795,6 @@ static void avctp_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,  	sk = g_io_channel_unix_get_fd(chan);  	session->sock = sk; -	memset(&l2o, 0, sizeof(l2o)); -	len = sizeof(l2o); -	if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &len) < 0) { -		err = errno; -		g_io_channel_unref(chan); -		avctp_unref(session); -		error("getsockopt(L2CAP_OPTIONS): %s (%d)", strerror(err), -				err); -		return; -	} -  	init_uinput(session);  	g_dbus_emit_signal(session->dev->conn, session->dev->path, @@ -800,7 +802,7 @@ static void avctp_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,  				DBUS_TYPE_INVALID);  	session->state = AVCTP_STATE_CONNECTED; -	session->mtu = l2o.imtu; +	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); @@ -811,7 +813,8 @@ gboolean avrcp_connect(struct audio_device *dev)  {  	struct control *control = dev->control;  	struct avctp *session; -	int err; +	GError *err = NULL; +	GIOChannel *io;  	if (control->session)  		return TRUE; @@ -827,14 +830,20 @@ gboolean avrcp_connect(struct audio_device *dev)  	session->dev = dev;  	session->state = AVCTP_STATE_CONNECTING; -	err = bt_l2cap_connect(&dev->src, &dev->dst, AVCTP_PSM, 0, -				avctp_connect_cb, control); -	if (err < 0) { +	io = bt_io_connect(BT_IO_L2CAP, avctp_connect_cb, control, NULL, &err, +				BT_IO_OPT_SOURCE_BDADDR, &dev->src, +				BT_IO_OPT_DEST_BDADDR, &dev->dst, +				BT_IO_OPT_PSM, AVCTP_PSM, +				BT_IO_OPT_INVALID); +	if (err) {  		avctp_unref(session); -		error("Connect failed. %s(%d)", strerror(-err), -err); +		error("%s", err->message); +		g_error_free(err);  		return FALSE;  	} +	g_io_channel_unref(io); +  	control->session = session;  	return TRUE; diff --git a/audio/headset.c b/audio/headset.c index 9fdabe4c..b83ce906 100644 --- a/audio/headset.c +++ b/audio/headset.c @@ -58,6 +58,7 @@  #include "telephony.h"  #include "headset.h"  #include "glib-helper.h" +#include "btio.h"  #include "dbus-common.h"  #include "../src/adapter.h"  #include "../src/device.h" @@ -509,16 +510,15 @@ static gboolean ring_timer_cb(gpointer data)  	return TRUE;  } -static void sco_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, -			const bdaddr_t *dst, gpointer user_data) +static void sco_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)  {  	int sk;  	struct audio_device *dev = user_data;  	struct headset *hs = dev->headset;  	struct pending_connect *p = hs->pending; -	if (err < 0) { -		error("connect(): %s (%d)", strerror(-err), -err); +	if (err) { +		error("%s", err->message);  		if (p->msg)  			error_connection_attempt_failed(dev->conn, p->msg, p->err); @@ -564,17 +564,24 @@ static int sco_connect(struct audio_device *dev, headset_stream_cb_t cb,  			void *user_data, unsigned int *cb_id)  {  	struct headset *hs = dev->headset; -	int err; +	GError *err = NULL; +	GIOChannel *io;  	if (hs->state != HEADSET_STATE_CONNECTED)  		return -EINVAL; -	err = bt_sco_connect(&dev->src, &dev->dst, sco_connect_cb, dev); -	if (err < 0) { -		error("connect: %s (%d)", strerror(-err), -err); -		return err; +	io = bt_io_connect(BT_IO_SCO, sco_connect_cb, dev, NULL, &err, +				BT_IO_OPT_SOURCE_BDADDR, &dev->src, +				BT_IO_OPT_DEST_BDADDR, &dev->dst, +				BT_IO_OPT_INVALID); +	if (!io) { +		error("%s", err->message); +		g_error_free(err); +		return -EIO;  	} +	g_io_channel_unref(io); +  	headset_set_state(dev, HEADSET_STATE_PLAY_IN_PROGRESS);  	pending_connect_init(hs, HEADSET_STATE_PLAYING); @@ -1221,16 +1228,15 @@ static gboolean sco_cb(GIOChannel *chan, GIOCondition cond,  	return FALSE;  } -static void rfcomm_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, -			const bdaddr_t *dst, gpointer user_data) +static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)  {  	struct audio_device *dev = user_data;  	struct headset *hs = dev->headset;  	struct pending_connect *p = hs->pending;  	char hs_address[18]; -	if (err < 0) { -		error("connect(): %s (%d)", strerror(-err), -err); +	if (err) { +		error("%s", err->message);  		goto failed;  	} @@ -1397,7 +1403,8 @@ static int rfcomm_connect(struct audio_device *dev, headset_stream_cb_t cb,  {  	struct headset *hs = dev->headset;  	char address[18]; -	int err; +	GError *err = NULL; +	GIOChannel *io;  	if (hs->rfcomm_ch < 0)  		return get_records(dev, cb, user_data, cb_id); @@ -1407,13 +1414,20 @@ static int rfcomm_connect(struct audio_device *dev, headset_stream_cb_t cb,  	debug("%s: Connecting to %s channel %d", dev->path, address,  		hs->rfcomm_ch); -	err = bt_rfcomm_connect(&dev->src, &dev->dst, hs->rfcomm_ch, -			rfcomm_connect_cb, dev); -	if (err < 0) { -		error("connect() failed: %s (%d)", strerror(-err), -err); -		return err; +	io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, dev, +				NULL, &err, +				BT_IO_OPT_SOURCE_BDADDR, &dev->src, +				BT_IO_OPT_DEST_BDADDR, &dev->dst, +				BT_IO_OPT_CHANNEL, hs->rfcomm_ch, +				BT_IO_OPT_INVALID); +	if (!io) { +		error("%s", err->message); +		g_error_free(err); +		return -EIO;  	} +	g_io_channel_unref(io); +  	headset_set_state(dev, HEADSET_STATE_CONNECT_IN_PROGRESS);  	pending_connect_init(hs, HEADSET_STATE_CONNECTED); diff --git a/audio/main.c b/audio/main.c index 846866a8..0e5afc42 100644 --- a/audio/main.c +++ b/audio/main.c @@ -38,6 +38,7 @@  #include <dbus/dbus.h>  #include "glib-helper.h" +#include "btio.h"  #include "plugin.h"  #include "logging.h"  #include "unix.h" @@ -64,19 +65,28 @@ static GKeyFile *load_config_file(const char *file)  	return keyfile;  } -static void sco_server_cb(GIOChannel *chan, int err, const bdaddr_t *src, -			const bdaddr_t *dst, gpointer data) +static void sco_server_cb(GIOChannel *chan, GError *err, gpointer data)  {  	int sk;  	struct audio_device *device;  	char addr[18]; +	bdaddr_t dst; -	if (err < 0) { -		error("accept: %s (%d)", strerror(-err), -err); +	if (err) { +		error("sco_server_cb: %s", err->message);  		return;  	} -	device = manager_find_device(dst, NULL, FALSE); +	bt_io_get(chan, BT_IO_SCO, &err, +			BT_IO_OPT_DEST_BDADDR, &dst, +			BT_IO_OPT_DEST, addr, +			BT_IO_OPT_INVALID); +	if (err) { +		error("bt_io_get: %s", err->message); +		goto drop; +	} + +	device = manager_find_device(&dst, NULL, FALSE);  	if (!device)  		goto drop; @@ -85,8 +95,6 @@ static void sco_server_cb(GIOChannel *chan, int err, const bdaddr_t *src,  		goto drop;  	} -	ba2str(dst, addr); -  	if (!get_hfp_active(device)) {  		error("Refusing non-HFP SCO connect attempt from %s", addr);  		goto drop; @@ -104,7 +112,6 @@ static void sco_server_cb(GIOChannel *chan, int err, const bdaddr_t *src,  drop:  	g_io_channel_close(chan); -	g_io_channel_unref(chan);  }  static DBusConnection *connection; @@ -129,7 +136,9 @@ static int audio_init(void)  		return -EIO;  	} -	sco_server = bt_sco_listen(BDADDR_ANY, 0, sco_server_cb, NULL); +	sco_server = bt_io_listen(BT_IO_SCO, sco_server_cb, NULL, NULL, +					NULL, NULL, +					BT_IO_OPT_INVALID);  	if (!sco_server) {  		error("Unable to start SCO server socket");  		return -EIO; diff --git a/audio/manager.c b/audio/manager.c index 1c7c46b5..8ef04824 100644 --- a/audio/manager.c +++ b/audio/manager.c @@ -50,6 +50,7 @@  #include <gdbus.h>  #include "glib-helper.h" +#include "btio.h"  #include "../src/manager.h"  #include "../src/adapter.h"  #include "../src/device.h" @@ -423,21 +424,34 @@ static void auth_cb(DBusError *derr, void *user_data)  	}  } -static void ag_io_cb(GIOChannel *chan, int err, const bdaddr_t *src, -			const bdaddr_t *dst, gpointer data) +static void ag_io_cb(GIOChannel *chan, GError *err, gpointer data)  { -	struct audio_adapter *adapter = data;  	const char *server_uuid, *remote_uuid;  	uint16_t svclass;  	struct audio_device *device;  	gboolean hfp_active; +	bdaddr_t src, dst; +	int perr; +	GError *gerr = NULL; +	uint8_t ch; -	if (err < 0) { -		error("accept: %s (%d)", strerror(-err), -err); +	if (err) { +		error("%s", err->message);  		return;  	} -	if (chan == adapter->hsp_ag_server) { +	bt_io_get(chan, BT_IO_RFCOMM, &gerr, +			BT_IO_OPT_SOURCE_BDADDR, &src, +			BT_IO_OPT_DEST_BDADDR, &dst, +			BT_IO_OPT_CHANNEL &ch, +			BT_IO_OPT_INVALID); +	if (gerr) { +		error("%s", gerr->message); +		g_clear_error(&gerr); +		goto drop; +	} + +	if (ch == DEFAULT_HS_AG_CHANNEL) {  		hfp_active = FALSE;  		server_uuid = HSP_AG_UUID;  		remote_uuid = HSP_HS_UUID; @@ -449,7 +463,7 @@ static void ag_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,  		svclass = HANDSFREE_SVCLASS_ID;  	} -	device = manager_get_device(src, dst); +	device = manager_get_device(&src, &dst);  	if (!device)  		goto drop; @@ -478,10 +492,10 @@ static void ag_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,  	headset_set_state(device, HEADSET_STATE_CONNECT_IN_PROGRESS); -	err = btd_request_authorization(&device->src, &device->dst, +	perr = btd_request_authorization(&device->src, &device->dst,  					server_uuid, auth_cb, device); -	if (err < 0) { -		debug("Authorization denied: %s", strerror(-err)); +	if (perr < 0) { +		debug("Authorization denied: %s", strerror(-perr));  		headset_set_state(device, HEADSET_STATE_DISCONNECTED);  		return;  	} @@ -490,11 +504,9 @@ static void ag_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,  drop:  	g_io_channel_close(chan); -	g_io_channel_unref(chan);  } -static void hs_io_cb(GIOChannel *chan, int err, const bdaddr_t *src, -		const bdaddr_t *dst, void *data) +static void hs_io_cb(GIOChannel *chan, GError *err, void *data)  {  	/*Stub*/  	return; @@ -506,7 +518,8 @@ static int headset_server_init(struct audio_adapter *adapter)  	sdp_record_t *record;  	gboolean master = TRUE;  	GError *err = NULL; -	uint32_t features, flags; +	uint32_t features; +	GIOChannel *io;  	if (config) {  		gboolean tmp; @@ -520,16 +533,17 @@ static int headset_server_init(struct audio_adapter *adapter)  			master = tmp;  	} -	flags = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT; - -	if (master) -		flags |= RFCOMM_LM_MASTER; - -	adapter->hsp_ag_server = bt_rfcomm_listen(&adapter->src, chan, flags, -							ag_io_cb, adapter); -	if (!adapter->hsp_ag_server) +	io =  bt_io_listen(BT_IO_RFCOMM, ag_io_cb, NULL, adapter, NULL, &err, +				BT_IO_OPT_SOURCE_BDADDR, &adapter->src, +				BT_IO_OPT_CHANNEL, chan, +				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, +				BT_IO_OPT_MASTER, master, +				BT_IO_OPT_INVALID); +	if (!io)  		goto failed; +	adapter->hsp_ag_server = io; +  	record = hsp_ag_record(chan);  	if (!record) {  		error("Unable to allocate new service record"); @@ -550,11 +564,17 @@ static int headset_server_init(struct audio_adapter *adapter)  	chan = DEFAULT_HF_AG_CHANNEL; -	adapter->hfp_ag_server = bt_rfcomm_listen(&adapter->src, chan, flags, -							ag_io_cb, adapter); -	if (!adapter->hfp_ag_server) +	io = bt_io_listen(BT_IO_RFCOMM, ag_io_cb, NULL, adapter, NULL, &err, +				BT_IO_OPT_SOURCE_BDADDR, &adapter->src, +				BT_IO_OPT_CHANNEL, chan, +				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, +				BT_IO_OPT_MASTER, master, +				BT_IO_OPT_INVALID); +	if (!io)  		goto failed; +	adapter->hfp_ag_server = io; +  	record = hfp_ag_record(chan, features);  	if (!record) {  		error("Unable to allocate new service record"); @@ -571,12 +591,16 @@ static int headset_server_init(struct audio_adapter *adapter)  	return 0;  failed: +	error("%s", err->message); +	g_clear_error(&err);  	if (adapter->hsp_ag_server) { +		g_io_channel_close(adapter->hsp_ag_server);  		g_io_channel_unref(adapter->hsp_ag_server);  		adapter->hsp_ag_server = NULL;  	}  	if (adapter->hfp_ag_server) { +		g_io_channel_close(adapter->hfp_ag_server);  		g_io_channel_unref(adapter->hfp_ag_server);  		adapter->hfp_ag_server = NULL;  	} @@ -590,7 +614,7 @@ static int gateway_server_init(struct audio_adapter *adapter)  	sdp_record_t *record;  	gboolean master = TRUE;  	GError *err = NULL; -	uint32_t flags; +	GIOChannel *io;  	if (config) {  		gboolean tmp; @@ -604,15 +628,19 @@ static int gateway_server_init(struct audio_adapter *adapter)  			master = tmp;  	} -	flags = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT; - -	if (master) -		flags |= RFCOMM_LM_MASTER; - -	adapter->hsp_hs_server = bt_rfcomm_listen(&adapter->src, chan, flags, -				hs_io_cb, adapter); -	if (!adapter->hsp_hs_server) +	io = bt_io_listen(BT_IO_RFCOMM, hs_io_cb, NULL, adapter, NULL, &err, +				BT_IO_OPT_SOURCE_BDADDR, &adapter->src, +				BT_IO_OPT_CHANNEL, chan, +				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, +				BT_IO_OPT_MASTER, master, +				BT_IO_OPT_INVALID); +	if (!io) { +		error("%s", err->message); +		g_error_free(err);  		return -1; +	} + +	adapter->hsp_hs_server = io;  	record = hsp_hs_record(chan);  	if (!record) { | 
