diff options
| author | Johan Hedberg <johan.hedberg@nokia.com> | 2009-02-21 14:30:27 +0200 | 
|---|---|---|
| committer | Johan Hedberg <johan.hedberg@nokia.com> | 2009-02-21 14:30:27 +0200 | 
| commit | 96762463061ffbe566c7f8916d230b4190ec3b6f (patch) | |
| tree | ff7f5b3e32184c9261ecbbedeb53bdcea4dd707e /src | |
| parent | 3d579217297b23df62123eba7807a66b0b93cd1c (diff) | |
Convert pairing code to use BtIO
Diffstat (limited to 'src')
| -rw-r--r-- | src/adapter.c | 4 | ||||
| -rw-r--r-- | src/device.c | 197 | 
2 files changed, 63 insertions, 138 deletions
| diff --git a/src/adapter.c b/src/adapter.c index e106ae11..a452a328 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -2156,8 +2156,8 @@ int adapter_start(struct btd_adapter *adapter)  		err = -errno;  		error("Can't read simple pairing mode on %s: %s (%d)",  					adapter->path, strerror(err), err); -		hci_close_dev(dd); -		return err; +		/* Fall through since some chips have broken +		 * read_simple_pairing_mode bahavior */  	}  setup: diff --git a/src/device.c b/src/device.c index fe369502..2c85d33c 100644 --- a/src/device.c +++ b/src/device.c @@ -57,6 +57,7 @@  #include "agent.h"  #include "sdp-xml.h"  #include "storage.h" +#include "btio.h"  #define DEFAULT_XML_BUF_SIZE	1024  #define DISCONNECT_TIMER	2 @@ -73,7 +74,6 @@ struct bonding_req {  	GIOChannel *io;  	guint io_id;  	guint listener_id; -	gboolean auth_required;  	struct btd_device *device;  }; @@ -1475,7 +1475,13 @@ DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status)  		return dbus_message_new_method_return(msg);  	case 0x04: /* page timeout */ +		return dbus_message_new_error(msg, +				ERROR_INTERFACE ".ConnectionAttemptFailed", +				"Page Timeout");  	case 0x08: /* connection timeout */ +		return dbus_message_new_error(msg, +				ERROR_INTERFACE ".ConnectionAttemptFailed", +				"Connection Timeout");  	case 0x10: /* connection accept timeout */  	case 0x22: /* LMP response timeout */  	case 0x28: /* instant passed - is this a timeout? */ @@ -1608,69 +1614,50 @@ proceed:  	return bonding;  } -static gboolean create_bonding_io_cb(GIOChannel *io, GIOCondition cond, -					struct btd_device *device) +static gboolean bonding_io_cb(GIOChannel *io, GIOCondition cond, +							gpointer user_data)  { +	struct btd_device *device = user_data; + +	if (!device->bonding) +		return FALSE; + +	error_connection_attempt_failed(device->bonding->conn, +					device->bonding->msg, ENETDOWN); + +	return FALSE; +} + +static void bonding_connect_cb(GIOChannel *io, GError *err, gpointer user_data) +{ +	struct btd_device *device = user_data;  	struct hci_request rq;  	auth_requested_cp cp;  	evt_cmd_status rp; -	struct l2cap_conninfo cinfo; -	socklen_t len; -	int sk, dd, ret; +	int dd; +	uint8_t handle;  	if (!device->bonding) {  		g_io_channel_shutdown(io, TRUE, NULL); -		return FALSE; +		return;  	} -	if (cond & G_IO_NVAL) { -		if (device->bonding) { -			DBusMessage *reply; - -			reply = new_authentication_return(device->bonding->msg, -							0x09); -			g_dbus_send_message(device->bonding->conn, reply); -		} - +	if (err) { +		error("%s", err->message); +		error_connection_attempt_failed(device->bonding->conn, +						device->bonding->msg, +						ENETDOWN);  		goto cleanup;  	} -	if (cond & (G_IO_HUP | G_IO_ERR)) { -		debug("Hangup or error on bonding IO channel"); - -		if (device->bonding) -			error_connection_attempt_failed(device->bonding->conn, -							device->bonding->msg, -							ENETDOWN); - -		goto failed; -	} - -	sk = g_io_channel_unix_get_fd(io); - -	len = sizeof(ret); -	if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) { -		error("Can't get socket error: %s (%d)", -				strerror(errno), errno); -		error_failed_errno(device->bonding->conn, device->bonding->msg, -				errno); -		goto failed; -	} - -	if (ret != 0) { -		if (device->bonding) -			error_connection_attempt_failed(device->bonding->conn, -							device->bonding->msg, -							ret); -		goto failed; -	} - -	len = sizeof(cinfo); -	if (getsockopt(sk, SOL_L2CAP, L2CAP_CONNINFO, &cinfo, &len) < 0) { -		error("Can't get connection info: %s (%d)", -				strerror(errno), errno); -		error_failed_errno(device->bonding->conn, device->bonding->msg, -				errno); +	if (!bt_io_get(io, BT_IO_L2RAW, &err, +			BT_IO_OPT_HANDLE, &handle, +			BT_IO_OPT_INVALID)) { +		error("Unable to get connection handle: %s", err->message); +		error_connection_attempt_failed(device->bonding->conn, +						device->bonding->msg, +						ENETDOWN); +		g_error_free(err);  		goto failed;  	} @@ -1684,7 +1671,7 @@ static gboolean create_bonding_io_cb(GIOChannel *io, GIOCondition cond,  	memset(&rp, 0, sizeof(rp));  	memset(&cp, 0, sizeof(cp)); -	cp.handle = htobs(cinfo.hci_handle); +	cp.handle = htobs(handle);  	memset(&rq, 0, sizeof(rq));  	rq.ogf    = OGF_LINK_CTL; @@ -1716,11 +1703,10 @@ static gboolean create_bonding_io_cb(GIOChannel *io, GIOCondition cond,  	hci_close_dev(dd);  	device->bonding->io_id = g_io_add_watch(io, -						G_IO_NVAL | G_IO_HUP | G_IO_ERR, -						(GIOFunc) create_bonding_io_cb, -						device); +					G_IO_NVAL | G_IO_HUP | G_IO_ERR, +					bonding_io_cb, device); -	return FALSE; +	return;  failed:  	g_io_channel_shutdown(io, TRUE, NULL); @@ -1728,8 +1714,6 @@ failed:  cleanup:  	device->bonding->io_id = 0;  	bonding_request_free(device->bonding, FALSE); - -	return FALSE;  }  static void create_bond_req_exit(DBusConnection *conn, void *user_data) @@ -1748,69 +1732,6 @@ static void create_bond_req_exit(DBusConnection *conn, void *user_data)  	}  } -static int l2raw_connect(const bdaddr_t *src, const bdaddr_t *dst, -						gboolean *auth_required) -{ -	struct sockaddr_l2 addr; -	long arg; -	int sk, err, opt; - -	sk = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP); -	if (sk < 0) { -		error("Can't create socket: %s (%d)", strerror(errno), errno); -		return sk; -	} - -	memset(&addr, 0, sizeof(addr)); -	addr.l2_family = AF_BLUETOOTH; -	bacpy(&addr.l2_bdaddr, src); - -	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { -		error("Can't bind socket: %s (%d)", strerror(errno), errno); -		goto failed; -	} - -	opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE; - -	err = setsockopt(sk, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)); -	if (err < 0) { -		error("setsockopt: %s (%d)", strerror(errno), errno); -		goto failed; -	} - -	arg = fcntl(sk, F_GETFL); -	if (arg < 0) { -		error("Can't get file flags: %s (%d)", strerror(errno), errno); -		goto failed; -	} - -	arg |= O_NONBLOCK; -	if (fcntl(sk, F_SETFL, arg) < 0) { -		error("Can't set file flags: %s (%d)", strerror(errno), errno); -		goto failed; -	} - -	memset(&addr, 0, sizeof(addr)); -	addr.l2_family = AF_BLUETOOTH; -	bacpy(&addr.l2_bdaddr, dst); - -	if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { -		if (errno == EAGAIN || errno == EINPROGRESS) -			return sk; -		error("Can't connect socket: %s (%d)", strerror(errno), errno); -		goto failed; -	} - -	if (auth_required) -		*auth_required = TRUE; - -	return sk; - -failed: -	close(sk); -	return -1; -} -  DBusMessage *device_create_bonding(struct btd_device *device,  					DBusConnection *conn,  					DBusMessage *msg, @@ -1822,8 +1743,8 @@ DBusMessage *device_create_bonding(struct btd_device *device,  	struct btd_adapter *adapter = device->adapter;  	struct bonding_req *bonding;  	bdaddr_t src; -	int sk; -	gboolean auth_required; +	GError *err = NULL; +	GIOChannel *io;  	adapter_get_address(adapter, &src);  	ba2str(&src, srcaddr); @@ -1845,26 +1766,30 @@ DBusMessage *device_create_bonding(struct btd_device *device,  	} -	sk = l2raw_connect(&src, &device->bdaddr, &auth_required); -	if (sk < 0) -		return g_dbus_create_error(msg, +	io = bt_io_connect(BT_IO_L2RAW, bonding_connect_cb, device, +				NULL, &err, +				BT_IO_OPT_SOURCE_BDADDR, &src, +				BT_IO_OPT_DEST_BDADDR, &device->bdaddr, +				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_HIGH, +				BT_IO_OPT_INVALID); +	if (io == NULL) { +		DBusMessage *reply; +		reply = g_dbus_create_error(msg,  				ERROR_INTERFACE ".ConnectionAttemptFailed", -				"Connection attempt failed"); +				err->message); +		error("bt_io_connect: %s", err->message); +		g_error_free(err); +		return reply; +	}  	bonding = bonding_request_new(conn, msg, device, agent_path,  					capability);  	if (!bonding) { -		close(sk); +		g_io_channel_shutdown(io, TRUE, NULL);  		return NULL;  	} -	bonding->auth_required = auth_required; - -	bonding->io = g_io_channel_unix_new(sk); -	bonding->io_id = g_io_add_watch(bonding->io, -					G_IO_OUT | G_IO_NVAL | G_IO_HUP | G_IO_ERR, -					(GIOFunc) create_bonding_io_cb, -					device); +	bonding->io = io;  	bonding->listener_id = g_dbus_add_disconnect_watch(conn,  						dbus_message_get_sender(msg), | 
