All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv3 0/7] Support for out of band association model
@ 2010-11-16 15:44 Szymon Janc
  2010-11-16 15:44 ` [PATCHv3 1/7] Add support for Out of Band (OOB) " Szymon Janc
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Changes since v2:
 - DBus provider Deactive() changed to Release() to be consistent with
   Agent API
 - DBus UpdateLocalOobData() changed to ReadLocalOobData() and explanation
   note in documentation added
 - renamed all update local oob data functions to read equivalents to keep
   names consistent (with hci command) in call chain

Szymon Janc (7):
  Add support for Out of Band (OOB) association model.
  Add DBus OOB plugin.
  Add DBus OOB API documentation.
  Add simple-oobprovider for testing.
  Add approval request for incoming pairing requests with OOB mechanism
  Update DBus OOB API with RequestApproval method.
  simple-agent - add RequestApproval method for OOB pairing

 Makefile.am             |   10 +-
 acinclude.m4            |    6 +
 doc/oob-api.txt         |   78 +++++++++++
 lib/hci.h               |    3 +
 plugins/dbusoob.c       |  353 +++++++++++++++++++++++++++++++++++++++++++++++
 plugins/hciops.c        |   96 +++++++++++--
 src/adapter.c           |   14 ++-
 src/adapter.h           |    6 +
 src/agent.c             |   59 ++++++++-
 src/agent.h             |    3 +
 src/device.c            |   98 +++++++++++++
 src/device.h            |   13 ++
 src/event.c             |  116 +++++++++++++---
 src/event.h             |    4 +-
 src/oob.c               |   61 ++++++++
 src/oob.h               |   47 +++++++
 test/simple-agent       |   10 ++
 test/simple-oobprovider |   61 ++++++++
 18 files changed, 1000 insertions(+), 38 deletions(-)
 create mode 100644 doc/oob-api.txt
 create mode 100644 plugins/dbusoob.c
 create mode 100644 src/oob.c
 create mode 100644 src/oob.h
 create mode 100755 test/simple-oobprovider


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCHv3 1/7] Add support for Out of Band (OOB) association model.
  2010-11-16 15:44 [PATCHv3 0/7] Support for out of band association model Szymon Janc
@ 2010-11-16 15:44 ` Szymon Janc
  2010-11-16 16:16   ` Johan Hedberg
  2010-11-16 15:44 ` [PATCHv3 2/7] Add DBus OOB plugin Szymon Janc
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 Makefile.am      |    3 +-
 lib/hci.h        |    3 ++
 plugins/hciops.c |   72 +++++++++++++++++++++++++++++++++++++++++---------
 src/adapter.c    |    7 ++++-
 src/adapter.h    |    3 ++
 src/device.c     |   76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/device.h     |   12 ++++++++
 src/event.c      |   75 +++++++++++++++++++++++++++++++++++++++-------------
 src/event.h      |    3 +-
 src/oob.c        |   61 +++++++++++++++++++++++++++++++++++++++++++
 src/oob.h        |   47 +++++++++++++++++++++++++++++++++
 11 files changed, 326 insertions(+), 36 deletions(-)
 create mode 100644 src/oob.c
 create mode 100644 src/oob.h

diff --git a/Makefile.am b/Makefile.am
index da308a7..a61e754 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -238,7 +238,8 @@ src_bluetoothd_SOURCES = $(gdbus_sources) $(builtin_sources) \
 			src/adapter.h src/adapter.c \
 			src/device.h src/device.c \
 			src/dbus-common.c src/dbus-common.h \
-			src/event.h src/event.c
+			src/event.h src/event.c \
+			src/oob.c
 src_bluetoothd_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @DBUS_LIBS@ \
 							@CAPNG_LIBS@ -ldl -lrt
 src_bluetoothd_LDFLAGS = -Wl,--export-dynamic \
diff --git a/lib/hci.h b/lib/hci.h
index 0cb120f..409abd9 100644
--- a/lib/hci.h
+++ b/lib/hci.h
@@ -524,6 +524,9 @@ typedef struct {
 
 #define OCF_REMOTE_OOB_DATA_NEG_REPLY	0x0033
 
+#define OOB_DATA_NOT_PRESENT	0x00
+#define OOB_DATA_PRESENT	0x01
+
 #define OCF_IO_CAPABILITY_NEG_REPLY	0x0034
 typedef struct {
 	bdaddr_t	bdaddr;
diff --git a/plugins/hciops.c b/plugins/hciops.c
index 829011a..75e6b0c 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -3,6 +3,7 @@
  *  BlueZ - Bluetooth protocol stack for Linux
  *
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2010  ST-Ericsson SA
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -47,6 +48,7 @@
 #include "event.h"
 #include "device.h"
 #include "manager.h"
+#include "oob.h"
 
 #define HCI_REQ_TIMEOUT         5000
 
@@ -509,20 +511,41 @@ static void user_passkey_notify(int index, void *ptr)
 
 static void remote_oob_data_request(int index, void *ptr)
 {
-	hci_send_cmd(SK(index), OGF_LINK_CTL,
-				OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, ptr);
+	bdaddr_t *dba = ptr;
+	struct btd_adapter *adapter;
+	struct btd_device *device;
+	char da[18];
+
+	ba2str(dba, da);
+	adapter = manager_find_adapter(&BDADDR(index));
+	device = adapter_find_device(adapter, da);
+
+	if (device_has_oob_data(device)) {
+		remote_oob_data_reply_cp cp;
+
+		bacpy(&cp.bdaddr, dba);
+		device_get_oob_data(device,cp.hash,cp.randomizer);
+
+		hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_REPLY,
+				REMOTE_OOB_DATA_REPLY_CP_SIZE, &cp);
+	} else
+		hci_send_cmd(SK(index),
+				OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_NEG_REPLY, 6,
+				ptr);
 }
 
 static void io_capa_request(int index, void *ptr)
 {
 	bdaddr_t *dba = ptr;
 	char sa[18], da[18];
-	uint8_t cap, auth;
 
 	ba2str(&BDADDR(index), sa); ba2str(dba, da);
 	info("io_capa_request (sba=%s, dba=%s)", sa, da);
 
-	if (btd_event_get_io_cap(&BDADDR(index), dba, &cap, &auth) < 0) {
+	/* If failed to establish IO capabilities then send negative reply
+	 * immediately. Positive reply will be sent when IO capabilities are
+	 * established. */
+	if (btd_event_request_io_cap(&BDADDR(index), dba)) {
 		io_capability_neg_reply_cp cp;
 		memset(&cp, 0, sizeof(cp));
 		bacpy(&cp.bdaddr, dba);
@@ -530,15 +553,6 @@ static void io_capa_request(int index, void *ptr)
 		hci_send_cmd(SK(index), OGF_LINK_CTL,
 					OCF_IO_CAPABILITY_NEG_REPLY,
 					IO_CAPABILITY_NEG_REPLY_CP_SIZE, &cp);
-	} else {
-		io_capability_reply_cp cp;
-		memset(&cp, 0, sizeof(cp));
-		bacpy(&cp.bdaddr, dba);
-		cp.capability = cap;
-		cp.oob_data = 0x00;
-		cp.authentication = auth;
-		hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY,
-					IO_CAPABILITY_REPLY_CP_SIZE, &cp);
 	}
 }
 
@@ -748,6 +762,15 @@ static void read_scan_complete(int index, uint8_t status, void *ptr)
 	adapter_mode_changed(adapter, rp->enable);
 }
 
+static void read_local_oob_data_complete(bdaddr_t *local, uint8_t status,
+		read_local_oob_data_rp *rp)
+{
+	if (status)
+		oob_local_data_read(local, NULL, NULL);
+	else
+		oob_local_data_read(local, rp->hash, rp->randomizer);
+}
+
 static inline void cmd_complete(int index, void *ptr)
 {
 	evt_cmd_complete *evt = ptr;
@@ -808,6 +831,10 @@ static inline void cmd_complete(int index, void *ptr)
 		ptr += sizeof(evt_cmd_complete);
 		adapter_update_tx_power(&BDADDR(index), status, ptr);
 		break;
+	case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_LOCAL_OOB_DATA):
+		ptr += sizeof(evt_cmd_complete);
+		read_local_oob_data_complete(&BDADDR(index), status, ptr);
+		break;
 	};
 }
 
@@ -2280,6 +2307,24 @@ static int hciops_get_remote_version(int index, uint16_t handle,
 	return 0;
 }
 
+static int hciops_read_local_oob_data(int index)
+{
+	int dd;
+	int err = 0;
+
+	dd = hci_open_dev(index);
+	if (dd < 0)
+		return -EIO;
+
+	err = hci_send_cmd(dd, OGF_HOST_CTL, OCF_READ_LOCAL_OOB_DATA, 0, 0);
+	if (err < 0)
+		err = -errno;
+
+	hci_close_dev(dd);
+
+	return err;
+}
+
 static struct btd_adapter_ops hci_ops = {
 	.setup = hciops_setup,
 	.cleanup = hciops_cleanup,
@@ -2326,6 +2371,7 @@ static struct btd_adapter_ops hci_ops = {
 	.write_le_host = hciops_write_le_host,
 	.get_remote_version = hciops_get_remote_version,
 	.encrypt_link = hciops_encrypt_link,
+	.read_local_oob_data = hciops_read_local_oob_data,
 };
 
 static int hciops_init(void)
diff --git a/src/adapter.c b/src/adapter.c
index 31014e5..39a6514 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3265,7 +3265,7 @@ void adapter_remove_connection(struct btd_adapter *adapter,
 	/* clean pending HCI cmds */
 	device_get_address(device, &bdaddr);
 
-	if (device_is_authenticating(device))
+	if (device_is_authenticating(device) || device_has_oob_data(device))
 		device_cancel_authentication(device, TRUE);
 
 	if (device_is_temporary(device)) {
@@ -3738,3 +3738,8 @@ int btd_adapter_encrypt_link(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 {
 	return adapter_ops->encrypt_link(adapter->dev_id, bdaddr, cb, user_data);
 }
+
+int btd_adapter_read_local_oob_data(struct btd_adapter *adapter)
+{
+	return adapter_ops->read_local_oob_data(adapter->dev_id);
+}
diff --git a/src/adapter.h b/src/adapter.h
index 8019cfc..cc62865 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -229,6 +229,7 @@ struct btd_adapter_ops {
 						gboolean delayed);
 	int (*encrypt_link) (int index, bdaddr_t *bdaddr, bt_hci_result_t cb,
 							gpointer user_data);
+	int (*read_local_oob_data) (int index);
 };
 
 int btd_register_adapter_ops(struct btd_adapter_ops *ops, gboolean priority);
@@ -289,3 +290,5 @@ int btd_adapter_get_remote_version(struct btd_adapter *adapter,
 
 int btd_adapter_encrypt_link(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 				bt_hci_result_t cb, gpointer user_data);
+
+int btd_adapter_read_local_oob_data(struct btd_adapter *adapter);
diff --git a/src/device.c b/src/device.c
index 7c421e3..24fd44d 100644
--- a/src/device.c
+++ b/src/device.c
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2006-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2010  ST-Ericsson SA
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -59,6 +60,7 @@
 #include "sdp-xml.h"
 #include "storage.h"
 #include "btio.h"
+#include "oob.h"
 
 #define DEFAULT_XML_BUF_SIZE	1024
 #define DISCONNECT_TIMER	2
@@ -132,6 +134,9 @@ struct btd_device {
 	uint8_t		cap;
 	uint8_t		auth;
 
+	uint8_t		local_cap;
+	uint8_t		local_auth;
+
 	uint16_t	handle;			/* Connection handle */
 
 	/* Whether were creating a security mode 3 connection */
@@ -149,6 +154,12 @@ struct btd_device {
 
 	gboolean	has_debug_key;
 	uint8_t		debug_key[16];
+
+	/* For OOB association model */
+	void (*oob_request_cb)(struct btd_device *device);
+	gboolean	has_oob_data;
+	uint8_t		hash[16];
+	uint8_t		randomizer[16];
 };
 
 static uint16_t uuid_list[] = {
@@ -829,6 +840,69 @@ static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
 	return NULL;
 }
 
+void device_set_oob_data(struct btd_device *device, uint8_t *hash,
+		uint8_t *randomizer)
+{
+	if (!device)
+		return;
+
+	if (hash && randomizer) {
+		memcpy(device->hash, hash, 16);
+		memcpy(device->randomizer, randomizer, 16);
+		device->has_oob_data = TRUE;
+	}
+
+	if (device->oob_request_cb) {
+		device->oob_request_cb(device);
+		device->oob_request_cb = NULL;
+	}
+}
+
+gboolean device_get_oob_data(struct btd_device *device, uint8_t *hash,
+		uint8_t *randomizer)
+{
+	if (!device || !device->has_oob_data)
+		return FALSE;
+
+	memcpy(hash, device->hash, 16);
+	memcpy(randomizer, device->randomizer, 16);
+
+	return TRUE;
+}
+
+gboolean device_has_oob_data(struct btd_device *device)
+{
+	return device && device->has_oob_data;
+}
+
+gboolean device_request_oob_data(struct btd_device *device, void *cb)
+{
+	if (!device)
+		return FALSE;
+
+	device->oob_request_cb = cb;
+	return oob_request_remote_data(device);
+}
+
+void device_set_local_auth_cap(struct btd_device *device, uint8_t auth,
+		uint8_t cap)
+{
+	if (!device)
+		return;
+
+	device->local_auth = auth;
+	device->local_cap = cap;
+}
+void device_get_local_auth_cap(struct btd_device *device, uint8_t *auth,
+		uint8_t *cap)
+{
+	if (!device)
+		return;
+
+	*auth = device->local_auth;
+	*cap = device->local_cap;
+}
+
 static GDBusMethodTable device_methods[] = {
 	{ "GetProperties",	"",	"a{sv}",	get_properties	},
 	{ "SetProperty",	"sv",	"",		set_property	},
@@ -2264,6 +2338,8 @@ void device_cancel_authentication(struct btd_device *device, gboolean aborted)
 {
 	struct authentication_req *auth = device->authr;
 
+	device->has_oob_data = FALSE;
+
 	if (!auth)
 		return;
 
diff --git a/src/device.h b/src/device.h
index b570bd1..b62cdc5 100644
--- a/src/device.h
+++ b/src/device.h
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2006-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2010  ST-Ericsson SA
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -89,6 +90,17 @@ void device_remove_connection(struct btd_device *device, DBusConnection *conn,
 gboolean device_has_connection(struct btd_device *device, uint16_t handle);
 void device_request_disconnect(struct btd_device *device, DBusMessage *msg);
 
+void device_set_oob_data(struct btd_device *device, uint8_t *hash,
+		uint8_t *randomizer);
+gboolean device_get_oob_data(struct btd_device *device, uint8_t *hash,
+		uint8_t *randomizer);
+gboolean device_has_oob_data(struct btd_device *device);
+gboolean device_request_oob_data(struct btd_device *device, void *cb);
+void device_set_local_auth_cap(struct btd_device *device, uint8_t auth,
+		uint8_t cap);
+void device_get_local_auth_cap(struct btd_device *device, uint8_t *auth,
+		uint8_t *cap);
+
 typedef void (*disconnect_watch) (struct btd_device *device, gboolean removal,
 					void *user_data);
 
diff --git a/src/event.c b/src/event.c
index e943c63..5a5a288 100644
--- a/src/event.c
+++ b/src/event.c
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2006-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2010  ST-Ericsson SA
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -274,7 +275,7 @@ void btd_event_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,
 	if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
 		return;
 
-	if (!device_is_authenticating(device)) {
+	if (!device_is_authenticating(device) && !device_has_oob_data(device)) {
 		/* This means that there was no pending PIN or SSP token
 		 * request from the controller, i.e. this is not a new
 		 * pairing */
@@ -756,26 +757,56 @@ void btd_event_returned_link_key(bdaddr_t *local, bdaddr_t *peer)
 	device_set_paired(device, TRUE);
 }
 
-int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
-						uint8_t *cap, uint8_t *auth)
+static void btd_event_io_cap_reply(struct btd_device *device)
+{
+	io_capability_reply_cp cp;
+	int dev;
+	struct btd_adapter *adapter = device_get_adapter(device);
+	uint16_t dev_id = adapter_get_dev_id(adapter);
+
+	dev = hci_open_dev(dev_id);
+	if (dev < 0) {
+		error("hci_open_dev(%d): %s (%d)", dev_id,
+		strerror(errno), errno);
+		return;
+	}
+
+	memset(&cp, 0, sizeof(cp));
+	device_get_address(device, &cp.bdaddr);
+	device_get_local_auth_cap(device, &cp.authentication, &cp.capability);
+	cp.oob_data = device_has_oob_data(device)
+			? OOB_DATA_PRESENT : OOB_DATA_NOT_PRESENT;
+
+	DBG("final capabilities reply is cap=0x%02x, auth=0x%02x, oob=0x%02x",
+	cp.capability, cp.authentication, cp.oob_data);
+
+	hci_send_cmd(dev, OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY,
+					IO_CAPABILITY_REPLY_CP_SIZE, &cp);
+
+	hci_close_dev(dev);
+}
+
+int btd_event_request_io_cap(bdaddr_t *local, bdaddr_t *remote)
 {
 	struct btd_adapter *adapter;
 	struct btd_device *device;
 	struct agent *agent = NULL;
 	uint8_t agent_cap;
 	int err;
+	uint8_t cap;
+	uint8_t auth;
 
 	if (!get_adapter_and_device(local, remote, &adapter, &device, TRUE))
 		return -ENODEV;
 
-	err = btd_adapter_get_auth_info(adapter, remote, auth);
+	err = btd_adapter_get_auth_info(adapter, remote, &auth);
 	if (err < 0)
 		return err;
 
-	DBG("initial authentication requirement is 0x%02x", *auth);
+	DBG("initial authentication requirement is 0x%02x", auth);
 
-	if (*auth == 0xff)
-		*auth = device_get_auth(device);
+	if (auth == 0xff)
+		auth = device_get_auth(device);
 
 	/* Check if the adapter is not pairable and if there isn't a bonding
 	 * in progress */
@@ -784,11 +815,11 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 		if (device_get_auth(device) < 0x02) {
 			DBG("Allowing no bonding in non-bondable mode");
 			/* No input, no output */
-			*cap = 0x03;
+			cap = 0x03;
 			/* Kernel defaults to general bonding and so
 			 * overwrite for this special case. Otherwise
 			 * non-pairable test cases will fail. */
-			*auth = 0x00;
+			auth = 0x00;
 			goto done;
 		}
 		return -EPERM;
@@ -804,13 +835,13 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 		}
 
 		/* No agent available, and no bonding case */
-		if (*auth == 0x00 || *auth == 0x04) {
+		if (auth == 0x00 || auth == 0x04) {
 			DBG("Allowing no bonding without agent");
 			/* No input, no output */
-			*cap = 0x03;
+			cap = 0x03;
 			/* If kernel defaults to general bonding, set it
 			 * back to no bonding */
-			*auth = 0x00;
+			auth = 0x00;
 			goto done;
 		}
 
@@ -820,7 +851,7 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 
 	agent_cap = agent_get_io_capability(agent);
 
-	if (*auth == 0x00 || *auth == 0x04) {
+	if (auth == 0x00 || auth == 0x04) {
 		/* If remote requests dedicated bonding follow that lead */
 		if (device_get_auth(device) == 0x02 ||
 				device_get_auth(device) == 0x03) {
@@ -829,9 +860,9 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 			 * then require it, otherwise don't */
 			if (device_get_cap(device) == 0x03 ||
 							agent_cap == 0x03)
-				*auth = 0x02;
+				auth = 0x02;
 			else
-				*auth = 0x03;
+				auth = 0x03;
 		}
 
 		/* If remote indicates no bonding then follow that. This
@@ -839,7 +870,7 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 		 * as default. */
 		if (device_get_auth(device) == 0x00 ||
 					device_get_auth(device) == 0x01)
-			*auth = 0x00;
+			auth = 0x00;
 
 		/* If remote requires MITM then also require it, unless
 		 * our IO capability is NoInputNoOutput (so some
@@ -847,13 +878,19 @@ int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
 		if (device_get_auth(device) != 0xff &&
 					(device_get_auth(device) & 0x01) &&
 					agent_cap != 0x03)
-			*auth |= 0x01;
+			auth |= 0x01;
 	}
 
-	*cap = agent_get_io_capability(agent);
+	cap = agent_get_io_capability(agent);
 
 done:
-	DBG("final authentication requirement is 0x%02x", *auth);
+	DBG("final authentication requirement is 0x%02x", auth);
+
+	device_set_local_auth_cap(device, auth, cap);
+
+	/* If failed to request remote OOB data then reply immediately. */
+	if (!device_request_oob_data(device, btd_event_io_cap_reply))
+		btd_event_io_cap_reply(device);
 
 	return 0;
 }
diff --git a/src/event.h b/src/event.h
index 4a7b9c9..a3e7dda 100644
--- a/src/event.h
+++ b/src/event.h
@@ -36,8 +36,7 @@ void btd_event_le_set_scan_enable_complete(bdaddr_t *local, uint8_t status);
 void btd_event_write_simple_pairing_mode_complete(bdaddr_t *local);
 void btd_event_read_simple_pairing_mode_complete(bdaddr_t *local, void *ptr);
 void btd_event_returned_link_key(bdaddr_t *local, bdaddr_t *peer);
-int btd_event_get_io_cap(bdaddr_t *local, bdaddr_t *remote,
-						uint8_t *cap, uint8_t *auth);
+int btd_event_request_io_cap(bdaddr_t *local, bdaddr_t *remote);
 int btd_event_set_io_cap(bdaddr_t *local, bdaddr_t *remote,
 						uint8_t cap, uint8_t auth);
 int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey);
diff --git a/src/oob.c b/src/oob.c
new file mode 100644
index 0000000..4b8b01d
--- /dev/null
+++ b/src/oob.c
@@ -0,0 +1,61 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010  ST-Ericsson SA
+ *
+ *  Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <glib.h>
+#include "manager.h"
+#include "adapter.h"
+#include "oob.h"
+
+static struct oob_plugin *active_plugin = NULL;
+
+void oob_activate_plugin(struct oob_plugin *plugin)
+{
+	if (!plugin || !plugin->local_data_read|| !plugin->plugin_deactivated
+			|| !plugin->request_remote_data
+			|| active_plugin == plugin)
+		return;
+
+	if (active_plugin)
+		active_plugin->plugin_deactivated();
+
+	active_plugin = plugin;
+}
+
+void oob_deactivate_plugin(struct oob_plugin *plugin)
+{
+	if (active_plugin == plugin)
+		active_plugin = NULL;
+}
+
+gboolean oob_request_remote_data(struct btd_device *device)
+{
+	return active_plugin && active_plugin->request_remote_data(device);
+}
+
+void oob_local_data_read(bdaddr_t *ba, uint8_t *hash, uint8_t *randomizer)
+{
+	if (active_plugin)
+		active_plugin->local_data_read(ba, hash, randomizer);
+}
diff --git a/src/oob.h b/src/oob.h
new file mode 100644
index 0000000..d0d22e2
--- /dev/null
+++ b/src/oob.h
@@ -0,0 +1,47 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010  ST-Ericsson SA
+ *
+ *  Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+struct oob_plugin
+{
+	/* If request was successfully send this functions should return TRUE.
+	 * Function should not block for too long. */
+	gboolean (*request_remote_data)(struct btd_device *device);
+
+	/* New local OOB data was read. If corresponding HCI command failed,
+	 * hash and randomizer are NULL */
+	void (*local_data_read)(bdaddr_t *ba, uint8_t *hash,
+			uint8_t *randomizer);
+
+	/* Plug-in was deactivated (called only for active plug-in). */
+	void (*plugin_deactivated)(void);
+};
+
+/* These functions are called by OOB plug-in. */
+void oob_activate_plugin(struct oob_plugin *plugin);
+void oob_deactivate_plugin(struct oob_plugin *plugin);
+
+/* These functions are called from stack to interact with OOB plug-in. */
+gboolean oob_request_remote_data(struct btd_device *device);
+void oob_local_data_read(bdaddr_t *ba, uint8_t *hash, uint8_t *randomizer);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv3 2/7] Add DBus OOB plugin.
  2010-11-16 15:44 [PATCHv3 0/7] Support for out of band association model Szymon Janc
  2010-11-16 15:44 ` [PATCHv3 1/7] Add support for Out of Band (OOB) " Szymon Janc
@ 2010-11-16 15:44 ` Szymon Janc
  2010-11-16 16:30   ` Johan Hedberg
  2010-11-16 15:44 ` [PATCHv3 3/7] Add DBus OOB API documentation Szymon Janc
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 Makefile.am       |    5 +
 acinclude.m4      |    6 +
 plugins/dbusoob.c |  353 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 364 insertions(+), 0 deletions(-)
 create mode 100644 plugins/dbusoob.c

diff --git a/Makefile.am b/Makefile.am
index a61e754..1f8f7fb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -216,6 +216,11 @@ builtin_modules += maemo6
 builtin_sources += plugins/maemo6.c
 endif
 
+if DBUSOOBPLUGIN
+builtin_modules += dbusoob
+builtin_sources += plugins/dbusoob.c
+endif
+
 sbin_PROGRAMS += src/bluetoothd
 
 src_bluetoothd_SOURCES = $(gdbus_sources) $(builtin_sources) \
diff --git a/acinclude.m4 b/acinclude.m4
index 287f07d..a52d063 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -193,6 +193,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	configfiles_enable=yes
 	telephony_driver=dummy
 	maemo6_enable=no
+	dbusoob_enable=no
 
 	AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [disable code optimization]), [
 		optimization_enable=${enableval}
@@ -316,6 +317,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 		maemo6_enable=${enableval}
 	])
 
+	AC_ARG_ENABLE(dbusoob, AC_HELP_STRING([--enable-dbusoob], [compile with DBUS OOB plugin]), [
+		dbusoob_enable=${enableval}
+	])
+
 	AC_ARG_ENABLE(hal, AC_HELP_STRING([--enable-hal], [Use HAL to determine adapter class]), [
 		hal_enable=${enableval}
 	])
@@ -372,4 +377,5 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	AM_CONDITIONAL(UDEVRULES, test "${udevrules_enable}" = "yes")
 	AM_CONDITIONAL(CONFIGFILES, test "${configfiles_enable}" = "yes")
 	AM_CONDITIONAL(MAEMO6PLUGIN, test "${maemo6_enable}" = "yes")
+	AM_CONDITIONAL(DBUSOOBPLUGIN, test "${dbusoob_enable}" = "yes")
 ])
diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
new file mode 100644
index 0000000..f347ef6
--- /dev/null
+++ b/plugins/dbusoob.c
@@ -0,0 +1,353 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010  ST-Ericsson SA
+ *
+ *  Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <gdbus.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/sdp.h>
+
+#include "plugin.h"
+#include "log.h"
+#include "manager.h"
+#include "device.h"
+#include "adapter.h"
+#include "dbus-common.h"
+#include "event.h"
+#include "error.h"
+#include "oob.h"
+
+#define REQUEST_TIMEOUT	(10 * 1000)	/* 10 seconds */
+#define OOB_INTERFACE	"org.bluez.OOB"
+#define OOB_PATH	"/org/bluez"
+
+struct oob_provider {
+	char *name;
+	char *path;
+
+	struct btd_adapter *adapter;
+	DBusMessage *msg;
+
+	guint listener_id;
+	gboolean exited;
+};
+
+static struct oob_provider *provider = NULL;
+static DBusConnection *connection = NULL;
+static struct oob_plugin dbusoob;
+
+static void destroy_provider(void)
+{
+	if (!provider->exited)
+		g_dbus_remove_watch(connection, provider->listener_id);
+
+	if (provider->msg)
+		dbus_message_unref(provider->msg);
+
+	g_free(provider->name);
+	g_free(provider->path);
+	g_free(provider);
+	provider = NULL;
+
+	oob_deactivate_plugin(&dbusoob);
+}
+
+static void provider_exited(DBusConnection *conn, void *user_data)
+{
+	DBG("Provider exited without calling Unregister");
+
+	provider->exited = TRUE;
+	destroy_provider();
+}
+
+static void create_provider(const char *path, const char *name)
+{
+	provider = g_new(struct oob_provider, 1);
+	provider->path = g_strdup(path);
+	provider->name = g_strdup(name);
+	provider->adapter = NULL;
+	provider->msg = NULL;
+	provider->exited = FALSE;
+	provider->listener_id = g_dbus_add_disconnect_watch(connection, name,
+			provider_exited, NULL, NULL);
+
+	oob_activate_plugin(&dbusoob);
+}
+
+static void request_remote_data_reply(DBusPendingCall *call, void *data)
+{
+	DBusMessage *msg;
+	DBusError err;
+	struct btd_device *device = data;
+	uint8_t *hash = NULL;
+	uint8_t *randomizer = NULL;
+	int32_t hlen, rlen;
+
+	msg = dbus_pending_call_steal_reply(call);
+
+	dbus_error_init(&err);
+	if (dbus_set_error_from_message(&err, msg)) {
+		error("Provider replied with an error: %s, %s", err.name,
+				err.message);
+		dbus_error_free(&err);
+		goto error;
+	}
+
+	dbus_error_init(&err);
+	if (!dbus_message_get_args(msg, &err,
+			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, &hlen,
+			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, &rlen,
+			DBUS_TYPE_INVALID) || hlen != 16 || rlen != 16) {
+		error("RequestRemoteOobData reply signature error: %s, %s",
+				err.name, err.message);
+		dbus_error_free(&err);
+		hash = NULL;
+		randomizer = NULL;
+	}
+
+error:
+	dbus_message_unref(msg);
+	dbus_pending_call_unref(call);
+
+	device_set_oob_data(device, hash, randomizer);
+}
+
+static gboolean request_remote_data(struct btd_device *device)
+{
+	DBusMessage* msg;
+	DBusPendingCall *call = NULL;
+	const gchar *path;
+	gboolean ret = FALSE;
+
+	msg = dbus_message_new_method_call(provider->name, provider->path,
+			OOB_INTERFACE, "RequestRemoteOobData");
+
+	if (!msg) {
+		error("Couldn't allocate D-Bus message");
+		goto error;
+	}
+
+	path = device_get_path(device);
+
+	if (!dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &path,
+			DBUS_TYPE_INVALID)) {
+		error ("Couldn't append arguments");
+		goto error;
+	}
+
+	if (!dbus_connection_send_with_reply(connection, msg, &call,
+			REQUEST_TIMEOUT)) {
+		error("D-Bus send failed");
+		goto error;
+	}
+
+	if (!dbus_pending_call_set_notify(call, request_remote_data_reply,
+			device, NULL)) {
+		error("Couldn't set reply notification.");
+		dbus_pending_call_unref(call);
+		goto error;
+	}
+
+	ret = TRUE;
+
+error:
+	if (msg)
+		dbus_message_unref(msg);
+
+	return ret;
+}
+
+static void local_data_read(bdaddr_t *ba, uint8_t *hash, uint8_t *randomizer)
+{
+	struct DBusMessage *reply;
+	bdaddr_t addr;
+
+	if (!provider)
+		return;
+
+	adapter_get_address(provider->adapter, &addr);
+	if (bacmp(ba, &addr))
+		return;
+
+	if (hash && randomizer)
+		reply = g_dbus_create_reply(provider->msg,
+			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, 16,
+			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, 16,
+			DBUS_TYPE_INVALID);
+	else
+		reply = g_dbus_create_error(provider->msg,
+				ERROR_INTERFACE ".ReadFailed",
+				"Failed to read local OOB data.");
+
+	dbus_message_unref(provider->msg);
+	provider->msg = NULL;
+	provider->adapter = NULL;
+
+	if (!reply) {
+		error("Couldn't allocate D-Bus message");
+		return;
+	}
+
+	if (!g_dbus_send_message(connection, reply))
+		error("D-Bus send failed");
+}
+
+static DBusMessage *read_local_data(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	const char *name;
+	const char *path;
+
+	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+			DBUS_TYPE_INVALID))
+		return NULL;
+
+	name = dbus_message_get_sender(msg);
+	if (!provider || strcmp(provider->name, name) != 0)
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".NoProvider",
+				"Not OOB provider or no provider registered");
+
+	if (provider->msg)
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
+				"Another request in progress.");
+
+	provider->adapter = manager_find_adapter_by_path(path);
+	if (!provider->adapter)
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".ReadFailed",
+				"No adapter with given address found");
+
+	if (btd_adapter_read_local_oob_data(provider->adapter))
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".ReadFailed",
+				"HCI request failed");
+
+	provider->msg = dbus_message_ref(msg);
+	return NULL;
+}
+
+static void plugin_deactivated(void)
+{
+	DBusMessage *msg;
+
+	msg = dbus_message_new_method_call(provider->name, provider->path,
+				OOB_INTERFACE, "Release");
+
+	if (!msg)
+		error("Couldn't allocate D-Bus message");
+	else if (!g_dbus_send_message(connection, msg))
+		error("D-Bus send failed");
+
+	destroy_provider();
+}
+
+static DBusMessage *register_provider(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	const char *path;
+	const char *name;
+
+	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+			DBUS_TYPE_INVALID))
+		return NULL;
+
+	if (provider)
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyExists",
+				"OOB provider already registered");
+
+	name = dbus_message_get_sender(msg);
+	create_provider(path, name);
+
+	DBG("OOB provider registered at %s:%s", provider->name, provider->path);
+	return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *unregister_provider(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	const char *path;
+	const char *name;
+
+	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+			DBUS_TYPE_INVALID))
+		return NULL;
+
+	name = dbus_message_get_sender(msg);
+
+	if (!provider || !g_str_equal(provider->path, path)
+			|| !g_str_equal(provider->name, name))
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist",
+				"No such OOB provider registered");
+
+	DBG("OOB provider (%s:%s) unregistered", provider->name, provider->path);
+
+	destroy_provider();
+
+	return dbus_message_new_method_return(msg);
+}
+
+static GDBusMethodTable oob_methods[] = {
+	{ "RegisterProvider",	"o", "", register_provider},
+	{ "UnregisterProvider",	"o", "", unregister_provider},
+	{ "ReadLocalOobData",	"o", "ayay", read_local_data,
+			G_DBUS_METHOD_FLAG_ASYNC},
+	{ }
+};
+
+static gboolean register_on_dbus(void)
+{
+	connection = get_dbus_connection();
+
+	if (!g_dbus_register_interface(connection, OOB_PATH, OOB_INTERFACE,
+				oob_methods, NULL, NULL, NULL, NULL)) {
+			error("OOB interface init failed on path %s", OOB_PATH);
+			return FALSE;
+		}
+
+	return TRUE;
+}
+
+static int dbusoob_init(void)
+{
+	DBG("Setup dbusoob plugin");
+
+	dbusoob.request_remote_data = request_remote_data;
+	dbusoob.local_data_read = local_data_read;
+	dbusoob.plugin_deactivated = plugin_deactivated;
+
+	return register_on_dbus();
+}
+
+static void dbusoob_exit(void)
+{
+	DBG("Cleanup dbusoob plugin");
+	oob_deactivate_plugin(&dbusoob);
+}
+
+BLUETOOTH_PLUGIN_DEFINE(dbusoob, VERSION,
+		BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, dbusoob_init, dbusoob_exit)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv3 3/7] Add DBus OOB API documentation.
  2010-11-16 15:44 [PATCHv3 0/7] Support for out of band association model Szymon Janc
  2010-11-16 15:44 ` [PATCHv3 1/7] Add support for Out of Band (OOB) " Szymon Janc
  2010-11-16 15:44 ` [PATCHv3 2/7] Add DBus OOB plugin Szymon Janc
@ 2010-11-16 15:44 ` Szymon Janc
  2010-11-16 16:37   ` Johan Hedberg
  2010-11-16 15:44 ` [PATCHv3 4/7] Add simple-oobprovider for testing Szymon Janc
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 Makefile.am     |    2 +-
 doc/oob-api.txt |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 1 deletions(-)
 create mode 100644 doc/oob-api.txt

diff --git a/Makefile.am b/Makefile.am
index 1f8f7fb..9098084 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -358,7 +358,7 @@ EXTRA_DIST += doc/manager-api.txt \
 		doc/service-api.txt doc/agent-api.txt doc/attribute-api.txt \
 		doc/serial-api.txt doc/network-api.txt \
 		doc/input-api.txt doc/audio-api.txt doc/control-api.txt \
-		doc/hfp-api.txt doc/assigned-numbers.txt
+		doc/hfp-api.txt doc/assigned-numbers.txt doc/oob-api.txt
 
 AM_YFLAGS = -d
 
diff --git a/doc/oob-api.txt b/doc/oob-api.txt
new file mode 100644
index 0000000..051b868
--- /dev/null
+++ b/doc/oob-api.txt
@@ -0,0 +1,64 @@
+BlueZ D-Bus OOB API description
+*******************************
+
+Copyright (C) 2010  ST-Ericsson SA
+
+Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+
+OOB hierarchy
+=================
+
+Service         unique name
+Interface       org.bluez.OOB
+Object path     freely definable
+
+Methods		array{byte} hash, array{byte} randomizer
+			RequestRemoteOobData(object device)
+
+			This method gets called when the service daemon needs to
+			get device's hash and randomizer for an OOB
+			authentication. Each array should be 16 bytes long.
+
+			Possible errors: org.bluez.Error.NoData
+
+		void Release()
+
+			This method gets called when DBus plug-in for OOB was
+			deactivated. There is no need to unregister provider,
+			because when this method gets called it has already been
+			unregistered.
+
+--------------------------------------------------------------------------------
+
+Service         org.bluez
+Interface       org.bluez.OOB
+Object path     /org/bluez
+
+Methods		void RegisterProvider(object provider)
+
+			This method registers provider for DBus OOB plug-in.
+			When provider is successfully registered plug-in becomes
+			active. Only one provider can be registered at time.
+
+			Possible errors: org.bluez.Error.AlreadyExists
+
+		void UnregisterProvider(object provider)
+
+			This method unregisters provider for DBus OOB plug-in.
+
+			Possible errors: org.bluez.Error.DoesNotExist
+
+
+		array{byte} hash, array{byte} randomizer
+			ReadLocalOobData(object adapter)
+
+			This method reads local OOB data for adapter. Return
+			value is pair of arrays 16 bytes each. Only registered
+			provider should call this method.
+
+			Note: This method will generate and return new local
+			OOB data.
+
+			Possible errors: org.bluez.Error.ReadFailed
+					 org.bluez.Error.NoProvider
+					 org.bluez.Error.InProgress
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv3 4/7] Add simple-oobprovider for testing.
  2010-11-16 15:44 [PATCHv3 0/7] Support for out of band association model Szymon Janc
                   ` (2 preceding siblings ...)
  2010-11-16 15:44 ` [PATCHv3 3/7] Add DBus OOB API documentation Szymon Janc
@ 2010-11-16 15:44 ` Szymon Janc
  2010-11-16 15:44 ` [PATCHv3 5/7] Add approval request for incoming pairing requests with OOB mechanism Szymon Janc
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 test/simple-oobprovider |   61 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)
 create mode 100755 test/simple-oobprovider

diff --git a/test/simple-oobprovider b/test/simple-oobprovider
new file mode 100755
index 0000000..4a1ebd8
--- /dev/null
+++ b/test/simple-oobprovider
@@ -0,0 +1,61 @@
+#!/usr/bin/python
+# Copyright (C) 2010  ST-Ericsson SA
+# Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson
+
+import gobject
+
+import sys
+import dbus
+import dbus.service
+import dbus.mainloop.glib
+
+class NoOobData(dbus.DBusException):
+        _dbus_error_name = "org.bluez.Error.NoData"
+
+
+class Provider(dbus.service.Object):
+
+	remotedata = None
+
+	@dbus.service.method("org.bluez.OOB",
+					in_signature="s", out_signature="ayay")
+
+	def RequestRemoteOobData(self, device):
+		print "RequestRemoteOobData for %s" % (device)
+		if (self.remotedata != None):
+			return self.remotedata
+		raise NoOobData("No OOB data present")
+
+if __name__ == '__main__':
+	dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+	bus = dbus.SystemBus()
+
+	manager = dbus.Interface(bus.get_object("org.bluez", "/"),
+			"org.bluez.Manager")
+
+	adapter_path = manager.DefaultAdapter()
+	adapter = dbus.Interface(bus.get_object("org.bluez",
+			adapter_path), "org.bluez.Adapter")
+
+	oob = dbus.Interface(bus.get_object("org.bluez", "/org/bluez"),
+			"org.bluez.OOB")
+
+	path = "/test/oobprovider"
+	provider = Provider(bus, path)
+
+	mainloop = gobject.MainLoop()
+
+	oob.RegisterProvider(path)
+
+	print "Local data for %s:" % (adapter_path)
+	print oob.ReadLocalOobData(adapter_path)
+
+	provider.remotedata = input("Provide remote data (in python syntax):\n")
+
+	print "You may try pairing now"
+
+	mainloop.run()
+
+	#adapter.UnregisterProvider(path)
+	#print "Provider unregistered"
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv3 5/7] Add approval request for incoming pairing requests with OOB mechanism
  2010-11-16 15:44 [PATCHv3 0/7] Support for out of band association model Szymon Janc
                   ` (3 preceding siblings ...)
  2010-11-16 15:44 ` [PATCHv3 4/7] Add simple-oobprovider for testing Szymon Janc
@ 2010-11-16 15:44 ` Szymon Janc
  2010-11-16 16:24   ` Johan Hedberg
  2010-11-16 15:44 ` [PATCHv3 6/7] Update DBus OOB API with RequestApproval method Szymon Janc
  2010-11-16 15:44 ` [PATCHv3 7/7] simple-agent - add RequestApproval method for OOB pairing Szymon Janc
  6 siblings, 1 reply; 16+ messages in thread
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 plugins/hciops.c |   42 ++++++++++++++++++++++++++++++--------
 src/adapter.c    |    7 ++++++
 src/adapter.h    |    3 ++
 src/agent.c      |   59 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/agent.h      |    3 ++
 src/device.c     |   22 ++++++++++++++++++++
 src/device.h     |    1 +
 src/event.c      |   41 +++++++++++++++++++++++++++++++++++++
 src/event.h      |    1 +
 9 files changed, 169 insertions(+), 10 deletions(-)

diff --git a/plugins/hciops.c b/plugins/hciops.c
index 75e6b0c..9546874 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -520,15 +520,8 @@ static void remote_oob_data_request(int index, void *ptr)
 	adapter = manager_find_adapter(&BDADDR(index));
 	device = adapter_find_device(adapter, da);
 
-	if (device_has_oob_data(device)) {
-		remote_oob_data_reply_cp cp;
-
-		bacpy(&cp.bdaddr, dba);
-		device_get_oob_data(device,cp.hash,cp.randomizer);
-
-		hci_send_cmd(SK(index), OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_REPLY,
-				REMOTE_OOB_DATA_REPLY_CP_SIZE, &cp);
-	} else
+	if (!device_has_oob_data(device)
+			|| btd_event_user_approve(&BDADDR(index), dba))
 		hci_send_cmd(SK(index),
 				OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_NEG_REPLY, 6,
 				ptr);
@@ -2217,6 +2210,36 @@ static int hciops_passkey_reply(int index, bdaddr_t *bdaddr, uint32_t passkey)
 	return err;
 }
 
+static int hciops_approve_reply(int index, bdaddr_t *bdaddr, gboolean approved)
+{
+	int err;
+	struct btd_adapter *adapter;
+	struct btd_device *device;
+	char da[18];
+
+	ba2str(bdaddr, da);
+	adapter = manager_find_adapter_by_id(index);
+	device = adapter_find_device(adapter, da);
+
+	if (approved) {
+		remote_oob_data_reply_cp cp;
+
+		bacpy(&cp.bdaddr, bdaddr);
+		device_get_oob_data(device,cp.hash,cp.randomizer);
+
+		err = hci_send_cmd(SK(index), OGF_LINK_CTL,
+				OCF_REMOTE_OOB_DATA_REPLY,
+				REMOTE_OOB_DATA_REPLY_CP_SIZE, &cp);
+	} else
+		err = hci_send_cmd(SK(index), OGF_LINK_CTL,
+				OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, bdaddr);
+
+	if (err < 0)
+		err = -errno;
+
+	return err;
+}
+
 static int hciops_get_auth_info(int index, bdaddr_t *bdaddr, uint8_t *auth)
 {
 	struct hci_auth_info_req req;
@@ -2365,6 +2388,7 @@ static struct btd_adapter_ops hci_ops = {
 	.pincode_reply = hciops_pincode_reply,
 	.confirm_reply = hciops_confirm_reply,
 	.passkey_reply = hciops_passkey_reply,
+	.approve_reply = hciops_approve_reply,
 	.get_auth_info = hciops_get_auth_info,
 	.read_scan_enable = hciops_read_scan_enable,
 	.read_ssp_mode = hciops_read_ssp_mode,
diff --git a/src/adapter.c b/src/adapter.c
index 39a6514..ab680f3 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3692,6 +3692,13 @@ int btd_adapter_passkey_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 	return adapter_ops->passkey_reply(adapter->dev_id, bdaddr, passkey);
 }
 
+int btd_adapter_approve_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
+							gboolean success)
+{
+	DBG("reply %u", success);
+	return adapter_ops->approve_reply(adapter->dev_id, bdaddr, success);
+}
+
 int btd_adapter_get_auth_info(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 								uint8_t *auth)
 {
diff --git a/src/adapter.h b/src/adapter.h
index cc62865..cf66129 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -221,6 +221,7 @@ struct btd_adapter_ops {
 	int (*pincode_reply) (int index, bdaddr_t *bdaddr, const char *pin);
 	int (*confirm_reply) (int index, bdaddr_t *bdaddr, gboolean success);
 	int (*passkey_reply) (int index, bdaddr_t *bdaddr, uint32_t passkey);
+	int (*approve_reply) (int index, bdaddr_t *bdaddr, gboolean success);
 	int (*get_auth_info) (int index, bdaddr_t *bdaddr, uint8_t *auth);
 	int (*read_scan_enable) (int index);
 	int (*read_ssp_mode) (int index);
@@ -272,6 +273,8 @@ int btd_adapter_confirm_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 							gboolean success);
 int btd_adapter_passkey_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 							uint32_t passkey);
+int btd_adapter_approve_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr,
+							gboolean success);
 
 int btd_adapter_get_auth_info(struct btd_adapter *adapter, bdaddr_t *bdaddr,
 								uint8_t *auth);
diff --git a/src/agent.c b/src/agent.c
index 2ddfd6e..a4b26b6 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -55,7 +55,8 @@ typedef enum {
 	AGENT_REQUEST_CONFIRMATION,
 	AGENT_REQUEST_PINCODE,
 	AGENT_REQUEST_AUTHORIZE,
-	AGENT_REQUEST_CONFIRM_MODE
+	AGENT_REQUEST_CONFIRM_MODE,
+	AGENT_REQUEST_APPROVAL
 } agent_request_type_t;
 
 struct agent {
@@ -693,6 +694,62 @@ failed:
 	return err;
 }
 
+static int approval_request_new(struct agent_request *req,
+					const char *device_path)
+{
+	struct agent *agent = req->agent;
+
+	req->msg = dbus_message_new_method_call(agent->name, agent->path,
+				"org.bluez.Agent", "RequestApproval");
+	if (req->msg == NULL) {
+		error("Couldn't allocate D-Bus message");
+		return -ENOMEM;
+	}
+
+	dbus_message_append_args(req->msg,
+				DBUS_TYPE_OBJECT_PATH, &device_path,
+				DBUS_TYPE_INVALID);
+
+	if (dbus_connection_send_with_reply(connection, req->msg,
+				&req->call, REQUEST_TIMEOUT) == FALSE) {
+		error("D-Bus send failed");
+		return -EIO;
+	}
+
+	dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL);
+
+	return 0;
+}
+
+int agent_request_approval (struct agent *agent, struct btd_device *device,
+			agent_cb cb, void *user_data, GDestroyNotify destroy)
+{
+	struct agent_request *req;
+	const gchar *dev_path = device_get_path(device);
+	int err;
+
+	if (agent->request)
+		return -EBUSY;
+
+	DBG("Calling Agent.RequestApproval: name=%s, path=%s", agent->name,
+			agent->path);
+
+	req = agent_request_new(agent, AGENT_REQUEST_APPROVAL, cb,
+				user_data, destroy);
+
+	err = approval_request_new(req, dev_path);
+	if (err < 0)
+		goto failed;
+
+	agent->request = req;
+
+	return 0;
+
+failed:
+	agent_request_free(req, FALSE);
+	return err;
+}
+
 static int request_fallback(struct agent_request *req,
 				DBusPendingCallNotifyFunction function)
 {
diff --git a/src/agent.h b/src/agent.h
index e184250..73dd531 100644
--- a/src/agent.h
+++ b/src/agent.h
@@ -64,6 +64,9 @@ int agent_request_confirmation(struct agent *agent, struct btd_device *device,
 int agent_display_passkey(struct agent *agent, struct btd_device *device,
 				uint32_t passkey);
 
+int agent_request_approval (struct agent *agent, struct btd_device *device,
+			agent_cb cb, void *user_data, GDestroyNotify destroy);
+
 int agent_cancel(struct agent *agent);
 
 gboolean agent_is_busy(struct agent *agent, void *user_data);
diff --git a/src/device.c b/src/device.c
index 24fd44d..a507fe8 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2245,6 +2245,21 @@ static void passkey_cb(struct agent *agent, DBusError *err,
 	device->authr->agent = NULL;
 }
 
+static void approve_cb(struct agent *agent, DBusError *err, void *data)
+{
+	struct authentication_req *auth = data;
+	struct btd_device *device = auth->device;
+
+	/* No need to reply anything if the authentication already failed */
+	if (auth->cb == NULL)
+		return;
+
+	((agent_cb) auth->cb)(agent, err, device);
+
+	device->authr->cb = NULL;
+	device->authr->agent = NULL;
+}
+
 int device_request_authentication(struct btd_device *device, auth_type_t type,
 						uint32_t passkey, void *cb)
 {
@@ -2283,6 +2298,10 @@ int device_request_authentication(struct btd_device *device, auth_type_t type,
 	case AUTH_TYPE_NOTIFY:
 		err = agent_display_passkey(agent, device, passkey);
 		break;
+	case AUTH_TYPE_APPROVE:
+		err = agent_request_approval (agent, device, approve_cb, auth,
+				NULL);
+		break;
 	case AUTH_TYPE_AUTO:
 		err = 0;
 		break;
@@ -2324,6 +2343,9 @@ static void cancel_authentication(struct authentication_req *auth)
 	case AUTH_TYPE_PASSKEY:
 		((agent_passkey_cb) auth->cb)(agent, &err, 0, device);
 		break;
+	case AUTH_TYPE_APPROVE:
+		((agent_cb) auth->cb)(agent, &err, device);
+		break;
 	case AUTH_TYPE_NOTIFY:
 	case AUTH_TYPE_AUTO:
 		/* User Notify/Auto doesn't require any reply */
diff --git a/src/device.h b/src/device.h
index b62cdc5..2da3311 100644
--- a/src/device.h
+++ b/src/device.h
@@ -33,6 +33,7 @@ typedef enum {
 	AUTH_TYPE_CONFIRM,
 	AUTH_TYPE_NOTIFY,
 	AUTH_TYPE_AUTO,
+	AUTH_TYPE_APPROVE
 } auth_type_t;
 
 struct btd_device *device_create(DBusConnection *conn, struct btd_adapter *adapter,
diff --git a/src/event.c b/src/event.c
index 5a5a288..957a17d 100644
--- a/src/event.c
+++ b/src/event.c
@@ -175,6 +175,18 @@ static void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey,
 	btd_adapter_passkey_reply(adapter, &bdaddr, passkey);
 }
 
+static void approve_cb(struct agent *agent, DBusError *err, void *user_data)
+{
+	struct btd_device *device = user_data;
+	struct btd_adapter *adapter = device_get_adapter(device);
+	bdaddr_t bdaddr;
+	gboolean approve = (err == NULL) ? TRUE : FALSE;
+
+	device_get_address(device, &bdaddr);
+
+	btd_adapter_approve_reply(adapter, &bdaddr, approve);
+}
+
 int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey)
 {
 	struct btd_adapter *adapter;
@@ -264,6 +276,35 @@ int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey)
 								passkey, NULL);
 }
 
+int btd_event_user_approve(bdaddr_t *sba, bdaddr_t *dba)
+{
+	struct btd_adapter *adapter;
+	struct btd_device *device;
+	struct agent *agent;
+	uint8_t cap;
+
+	if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE))
+		return -ENODEV;
+
+	agent = device_get_agent(device);
+	if (!agent)
+		return -ENODEV;
+
+	cap = agent_get_io_capability(agent);
+
+	/* If initiator or agent has no input capability approve immediately. */
+	if (device_is_bonding(device, NULL) || cap == 0x00 || cap == 0x03) {
+		bdaddr_t bdaddr;
+
+		device_get_address(device, &bdaddr);
+		btd_adapter_approve_reply(adapter, &bdaddr, TRUE);
+		return 0;
+	}
+
+	return device_request_authentication(device, AUTH_TYPE_APPROVE, 0,
+								approve_cb);
+}
+
 void btd_event_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,
 								uint8_t status)
 {
diff --git a/src/event.h b/src/event.h
index a3e7dda..c1ea2ef 100644
--- a/src/event.h
+++ b/src/event.h
@@ -42,6 +42,7 @@ int btd_event_set_io_cap(bdaddr_t *local, bdaddr_t *remote,
 int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey);
 int btd_event_user_passkey(bdaddr_t *sba, bdaddr_t *dba);
 int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey);
+int btd_event_user_approve(bdaddr_t *sba, bdaddr_t *dba);
 int btd_event_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
 				uint8_t *key, uint8_t key_type,
 				int pin_length, uint8_t old_key_type);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv3 6/7] Update DBus OOB API with RequestApproval method.
  2010-11-16 15:44 [PATCHv3 0/7] Support for out of band association model Szymon Janc
                   ` (4 preceding siblings ...)
  2010-11-16 15:44 ` [PATCHv3 5/7] Add approval request for incoming pairing requests with OOB mechanism Szymon Janc
@ 2010-11-16 15:44 ` Szymon Janc
  2010-11-16 15:44 ` [PATCHv3 7/7] simple-agent - add RequestApproval method for OOB pairing Szymon Janc
  6 siblings, 0 replies; 16+ messages in thread
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 doc/oob-api.txt |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/doc/oob-api.txt b/doc/oob-api.txt
index 051b868..3a89f59 100644
--- a/doc/oob-api.txt
+++ b/doc/oob-api.txt
@@ -62,3 +62,17 @@ Methods		void RegisterProvider(object provider)
 			Possible errors: org.bluez.Error.ReadFailed
 					 org.bluez.Error.NoProvider
 					 org.bluez.Error.InProgress
+
+--------------------------------------------------------------------------------
+
+Service		unique name
+Interface	org.bluez.Agent
+Object path	freely definable
+
+Methods		void RequestApproval(object device)
+
+			This method gets called when the service daemon
+			needs to confirm incoming OOB pairing request.
+
+			Possible errors: org.bluez.Error.Rejected
+					 org.bluez.Error.Canceled
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv3 7/7] simple-agent - add RequestApproval method for OOB pairing
  2010-11-16 15:44 [PATCHv3 0/7] Support for out of band association model Szymon Janc
                   ` (5 preceding siblings ...)
  2010-11-16 15:44 ` [PATCHv3 6/7] Update DBus OOB API with RequestApproval method Szymon Janc
@ 2010-11-16 15:44 ` Szymon Janc
  6 siblings, 0 replies; 16+ messages in thread
From: Szymon Janc @ 2010-11-16 15:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 test/simple-agent |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/test/simple-agent b/test/simple-agent
index f2cc3dd..43f03fe 100755
--- a/test/simple-agent
+++ b/test/simple-agent
@@ -69,6 +69,16 @@ class Agent(dbus.service.Object):
 		raise Rejected("Mode change by user")
 
 	@dbus.service.method("org.bluez.Agent",
+			in_signature="o", out_signature="")
+
+	def RequestApproval(self, device):
+		print "RequestApproval (%s)" % (device)
+		approve = raw_input("Approve pairing (yes/no): ")
+		if (approve == "yes"):
+			return
+		raise Rejected("Not approved")
+
+	@dbus.service.method("org.bluez.Agent",
 					in_signature="", out_signature="")
 	def Cancel(self):
 		print "Cancel"
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCHv3 1/7] Add support for Out of Band (OOB) association model.
  2010-11-16 15:44 ` [PATCHv3 1/7] Add support for Out of Band (OOB) " Szymon Janc
@ 2010-11-16 16:16   ` Johan Hedberg
  0 siblings, 0 replies; 16+ messages in thread
From: Johan Hedberg @ 2010-11-16 16:16 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth

Hi Szymon,

On Tue, Nov 16, 2010, Szymon Janc wrote:
> +gboolean device_get_oob_data(struct btd_device *device, uint8_t *hash,
> +		uint8_t *randomizer)

Looks like the continuation line should be indented a bit more. Basicly
indent at least past the ( on the above line and as much as possible as
long as the entire line stays under 79 columns. I think I saw other
places with the same issue so please fix those too.

> +void device_set_oob_data(struct btd_device *device, uint8_t *hash,
> +		uint8_t *randomizer);
> +gboolean device_get_oob_data(struct btd_device *device, uint8_t *hash,
> +		uint8_t *randomizer);
> +gboolean device_has_oob_data(struct btd_device *device);

I suppose you could just use get_oob_data(dev, NULL, NULL) instead of
having a separate has_oob_data function.

> +gboolean device_request_oob_data(struct btd_device *device, void *cb);

Why is the callback type void* instead of having a well defined
signature?

> +void device_set_local_auth_cap(struct btd_device *device, uint8_t auth,
> +		uint8_t cap);
> +void device_get_local_auth_cap(struct btd_device *device, uint8_t *auth,
> +		uint8_t *cap);

This local_cap/auth in struct device had me wondering a little bit since
it felt like that should actually be in struct adapter, however this is
really per adapter-device pair data in which case it should be fine,
right?

> +static void btd_event_io_cap_reply(struct btd_device *device)
> +{
> +	io_capability_reply_cp cp;
> +	int dev;
> +	struct btd_adapter *adapter = device_get_adapter(device);
> +	uint16_t dev_id = adapter_get_dev_id(adapter);
> +
> +	dev = hci_open_dev(dev_id);

That's a no no. Only hciops should use raw HCI sockets anymore. If you
need to do something like this you'll need to add a new adapter_ops
callback and send your HCI command through that.

>  {
>  	struct btd_adapter *adapter;
>  	struct btd_device *device;
>  	struct agent *agent = NULL;
>  	uint8_t agent_cap;
>  	int err;
> +	uint8_t cap;
> +	uint8_t auth;

These can be on the same line.

> +	if (!plugin || !plugin->local_data_read|| !plugin->plugin_deactivated
> +			|| !plugin->request_remote_data
> +			|| active_plugin == plugin)
> +		return;

When you split lines the break should be after || && etc. In this case
you could also consider splitting this up into multiple if-statements
for better readability.

Johan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCHv3 5/7] Add approval request for incoming pairing requests with OOB mechanism
  2010-11-16 15:44 ` [PATCHv3 5/7] Add approval request for incoming pairing requests with OOB mechanism Szymon Janc
@ 2010-11-16 16:24   ` Johan Hedberg
  2010-11-17 16:03     ` Szymon Janc
  0 siblings, 1 reply; 16+ messages in thread
From: Johan Hedberg @ 2010-11-16 16:24 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth, marcel

Hi Szymon,

On Tue, Nov 16, 2010, Szymon Janc wrote:
> +	if (!device_has_oob_data(device)
> +			|| btd_event_user_approve(&BDADDR(index), dba))

That should be:

if (!device_has_oob_data(device) ||
			btd_event_user_approve(&BDADDR(index), dba) < 0)

Otherwise it looks like btd_event_user_approve might return a boolean.

> +	req->msg = dbus_message_new_method_call(agent->name, agent->path,
> +				"org.bluez.Agent", "RequestApproval");

I think the name of this method is one of the more important things to
get right before we push this upstream. I'm not so sure of the current
proposal. I have a feeling that it'd be a good idea to have the term
"pair" somewhere explicitly in the name. How about "RequestPairing"? I
know Marcel will have something to say about this too.

Johan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCHv3 2/7] Add DBus OOB plugin.
  2010-11-16 15:44 ` [PATCHv3 2/7] Add DBus OOB plugin Szymon Janc
@ 2010-11-16 16:30   ` Johan Hedberg
  0 siblings, 0 replies; 16+ messages in thread
From: Johan Hedberg @ 2010-11-16 16:30 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth

Hi Szymon,

On Tue, Nov 16, 2010, Szymon Janc wrote:
> +#define REQUEST_TIMEOUT	(10 * 1000)	/* 10 seconds */

Are you sure 10 seconds is enough. What if the provider does user
interaction? In that case I suppose 30 seconds or even a minute (which I
think we use elsewhere for user interaction) would be better.

> +static DBusMessage *register_provider(DBusConnection *conn, DBusMessage *msg,
> +								void *data)
> +{
> +	const char *path;
> +	const char *name;

Just combine these on the same line.

> +static DBusMessage *unregister_provider(DBusConnection *conn, DBusMessage *msg,
> +								void *data)
> +{
> +	const char *path;
> +	const char *name;

Same here.

> +	if (!provider || !g_str_equal(provider->path, path)
> +			|| !g_str_equal(provider->name, name))
> +		return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist",
> +				"No such OOB provider registered");

Same thing about line splitting and || as I mentioned in the other
email, i.e. line break comes after || and not before it.

Johan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCHv3 3/7] Add DBus OOB API documentation.
  2010-11-16 15:44 ` [PATCHv3 3/7] Add DBus OOB API documentation Szymon Janc
@ 2010-11-16 16:37   ` Johan Hedberg
  2010-11-17 12:49     ` Szymon Janc
  0 siblings, 1 reply; 16+ messages in thread
From: Johan Hedberg @ 2010-11-16 16:37 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth

Hi Szymon,

On Tue, Nov 16, 2010, Szymon Janc wrote:
> +Service         org.bluez
> +Interface       org.bluez.OOB
> +Object path     /org/bluez

I think this should use the same path as the Manager API, which at the
moment is /

> +Methods		void RegisterProvider(object provider)
> +
> +			This method registers provider for DBus OOB plug-in.
> +			When provider is successfully registered plug-in becomes
> +			active. Only one provider can be registered at time.
> +
> +			Possible errors: org.bluez.Error.AlreadyExists
> +
> +		void UnregisterProvider(object provider)
> +
> +			This method unregisters provider for DBus OOB plug-in.
> +
> +			Possible errors: org.bluez.Error.DoesNotExist

Ok, these methods make sense.

> +		array{byte} hash, array{byte} randomizer
> +			ReadLocalOobData(object adapter)

Having to pass an adapter path as a parameter seems weird. Wouldn't it
make more sense to have this method in the Adapter path/interface
instead? Also, we could toy around with the thought of putting the two
other methods into the current Manager interface.

One general thing throughout your patches, both the in-code comments and
commit messages: D-Bus is spelled D-Bus, not DBus :)

Johan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCHv3 3/7] Add DBus OOB API documentation.
  2010-11-16 16:37   ` Johan Hedberg
@ 2010-11-17 12:49     ` Szymon Janc
  2010-11-18 10:51       ` Szymon Janc
  0 siblings, 1 reply; 16+ messages in thread
From: Szymon Janc @ 2010-11-17 12:49 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth

Hi Johan,

> > +Service         org.bluez
> > +Interface       org.bluez.OOB
> > +Object path     /org/bluez
> 
> I think this should use the same path as the Manager API, which at the
> moment is /

I was following HealthManager way, but I'm fine if you prefer / path.

> > +		array{byte} hash, array{byte} randomizer
> > +			ReadLocalOobData(object adapter)
> 
> Having to pass an adapter path as a parameter seems weird. Wouldn't it
> make more sense to have this method in the Adapter path/interface
> instead? Also, we could toy around with the thought of putting the two
> other methods into the current Manager interface.

It is OK to me to move ReadLocalOobData to adapter path as this is an adapter
related data.

My initial idea was to keep all oob related methods in org.bluez.OOB interface
but I'm not going to insist on it.

-- 
Szymon Janc
on behalf of ST-Ericsson

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCHv3 5/7] Add approval request for incoming pairing requests with OOB mechanism
  2010-11-16 16:24   ` Johan Hedberg
@ 2010-11-17 16:03     ` Szymon Janc
  0 siblings, 0 replies; 16+ messages in thread
From: Szymon Janc @ 2010-11-17 16:03 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth, marcel

Hi Johan,

> > +	req->msg = dbus_message_new_method_call(agent->name, agent->path,
> > +				"org.bluez.Agent", "RequestApproval");
> 
> I think the name of this method is one of the more important things to
> get right before we push this upstream. I'm not so sure of the current
> proposal. I have a feeling that it'd be a good idea to have the term
> "pair" somewhere explicitly in the name. How about "RequestPairing"? I
> know Marcel will have something to say about this too.

Maybe make it more descriptive like RequestPairingApproval ?
Yet, RequestPairing sounds ok.

-- 
Szymon Janc
on behalf of ST-Ericsson

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCHv3 3/7] Add DBus OOB API documentation.
  2010-11-17 12:49     ` Szymon Janc
@ 2010-11-18 10:51       ` Szymon Janc
  2010-11-18 13:45         ` Johan Hedberg
  0 siblings, 1 reply; 16+ messages in thread
From: Szymon Janc @ 2010-11-18 10:51 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth

> > > +Service         org.bluez
> > > +Interface       org.bluez.OOB
> > > +Object path     /org/bluez
> > 
> > I think this should use the same path as the Manager API, which at the
> > moment is /
> 
> I was following HealthManager way, but I'm fine if you prefer / path.
> 
> > > +		array{byte} hash, array{byte} randomizer
> > > +			ReadLocalOobData(object adapter)
> > 
> > Having to pass an adapter path as a parameter seems weird. Wouldn't it
> > make more sense to have this method in the Adapter path/interface
> > instead? Also, we could toy around with the thought of putting the two
> > other methods into the current Manager interface.
> 
> It is OK to me to move ReadLocalOobData to adapter path as this is an adapter
> related data.
> 
> My initial idea was to keep all oob related methods in org.bluez.OOB interface
> but I'm not going to insist on it.

Please see the following proposal.

Register/UnregisterProvider methods can be easily moved to manager interface if
decided (with name changes to i.e. RegisterOobProvider for clarity).

Moving ReadLocalOobData to adapter path requires some code changes in dbusoob
plugin so I prefer to clarify that before coding.


Any comments?


BlueZ D-Bus OOB API description
*******************************

Copyright (C) 2010  ST-Ericsson SA

Author: Szymon Janc <szymon.janc@tieto.com> for ST-Ericsson

OOB hierarchy
=================

Service         unique name
Interface       org.bluez.OOB
Object path     freely definable

Methods		array{byte} hash, array{byte} randomizer
			RequestRemoteOobData(object device)

			This method gets called when the service daemon needs to
			get device's hash and randomizer for an OOB
			authentication. Each array should be 16 bytes long.

			Possible errors: org.bluez.Error.NoData

		void Release()

			This method gets called when D-Bus plug-in for OOB was
			deactivated. There is no need to unregister provider,
			because when this method gets called it has already been
			unregistered.

--------------------------------------------------------------------------------

Service         org.bluez
Interface       org.bluez.OOB
Object path     /

Methods		void RegisterProvider(object provider)

			This method registers provider for D-Bus OOB plug-in.
			When provider is successfully registered plug-in becomes
			active. Only one provider can be registered at time.

			Possible errors: org.bluez.Error.AlreadyExists

		void UnregisterProvider(object provider)

			This method unregisters provider for D-Bus OOB plug-in.

			Possible errors: org.bluez.Error.DoesNotExist

--------------------------------------------------------------------------------

Service		org.bluez
Interface	org.bluez.Adapter
Object path	[variable prefix]/{hci0,hci1,...}

		array{byte} hash, array{byte} randomizer ReadLocalOobData()

			This method reads local OOB data for adapter. Return
			value is pair of arrays 16 bytes each. Only registered
			provider should call this method. This method is
			available only for 2.1 (or higher) adapters.

			Note: This method will generate and return new local
			OOB data.

			Possible errors: org.bluez.Error.ReadFailed
					 org.bluez.Error.NoProvider
					 org.bluez.Error.InProgress

--------------------------------------------------------------------------------

Service		unique name
Interface	org.bluez.Agent
Object path	freely definable

Methods		void RequestPairingApproval(object device)

			This method gets called when the service daemon
			needs to confirm incoming OOB pairing request.

			Possible errors: org.bluez.Error.Rejected
					 org.bluez.Error.Canceled



-- 
Szymon Janc
on behalf of ST-Ericsson

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCHv3 3/7] Add DBus OOB API documentation.
  2010-11-18 10:51       ` Szymon Janc
@ 2010-11-18 13:45         ` Johan Hedberg
  0 siblings, 0 replies; 16+ messages in thread
From: Johan Hedberg @ 2010-11-18 13:45 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth

Hi Szymon,

On Thu, Nov 18, 2010, Szymon Janc wrote:
> OOB hierarchy
> =================
> 
> Service         unique name
> Interface       org.bluez.OOB

I suppose this should be called org.bluez.OobProvider, OobAgent or
something similar?

> Methods		array{byte} hash, array{byte} randomizer
> 			RequestRemoteOobData(object device)
> 
> 			This method gets called when the service daemon needs to
> 			get device's hash and randomizer for an OOB
> 			authentication. Each array should be 16 bytes long.
> 
> 			Possible errors: org.bluez.Error.NoData
> 
> 		void Release()
> 
> 			This method gets called when D-Bus plug-in for OOB was
> 			deactivated. There is no need to unregister provider,
> 			because when this method gets called it has already been
> 			unregistered.
> 
> --------------------------------------------------------------------------------
> 
> Service         org.bluez
> Interface       org.bluez.OOB

Interface definitions are supposed to be unique. You can't reuse the
same interface name for a different set of methods and signals.

> Object path     /

Regarding this, as you said the healt stuff is using /org/bluez. I'd
like to have someone who knows comment on the reasons why /org/bluez was
chosen instead of /. It seems inconsistent to me since the manager
interface uses /.

> --------------------------------------------------------------------------------
> 
> Service		org.bluez
> Interface	org.bluez.Adapter
> Object path	[variable prefix]/{hci0,hci1,...}
> 
> 		array{byte} hash, array{byte} randomizer ReadLocalOobData()

I agree that this is good to have in the Adapter path, but we can still
discuss about whether it should be on it's own interface or not. Maybe
reusing the adapter path is fine since we're only dealing with one
method in it.

> Service		unique name
> Interface	org.bluez.Agent
> Object path	freely definable
> 
> Methods		void RequestPairingApproval(object device)

I still like RequestPairing better (it's shorter). Marcel, do you have
any opinion or new suggestions for this? It would be reused for incoming
just-works pairing too (though only for 5.x).

Johan

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2010-11-18 13:45 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-16 15:44 [PATCHv3 0/7] Support for out of band association model Szymon Janc
2010-11-16 15:44 ` [PATCHv3 1/7] Add support for Out of Band (OOB) " Szymon Janc
2010-11-16 16:16   ` Johan Hedberg
2010-11-16 15:44 ` [PATCHv3 2/7] Add DBus OOB plugin Szymon Janc
2010-11-16 16:30   ` Johan Hedberg
2010-11-16 15:44 ` [PATCHv3 3/7] Add DBus OOB API documentation Szymon Janc
2010-11-16 16:37   ` Johan Hedberg
2010-11-17 12:49     ` Szymon Janc
2010-11-18 10:51       ` Szymon Janc
2010-11-18 13:45         ` Johan Hedberg
2010-11-16 15:44 ` [PATCHv3 4/7] Add simple-oobprovider for testing Szymon Janc
2010-11-16 15:44 ` [PATCHv3 5/7] Add approval request for incoming pairing requests with OOB mechanism Szymon Janc
2010-11-16 16:24   ` Johan Hedberg
2010-11-17 16:03     ` Szymon Janc
2010-11-16 15:44 ` [PATCHv3 6/7] Update DBus OOB API with RequestApproval method Szymon Janc
2010-11-16 15:44 ` [PATCHv3 7/7] simple-agent - add RequestApproval method for OOB pairing Szymon Janc

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.