linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Support for out of band association model
@ 2010-11-04 10:10 Szymon Janc
  2010-11-04 10:10 ` [PATCH 1/4] Add support for Out of Band (OOB) " Szymon Janc
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: Szymon Janc @ 2010-11-04 10:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

This set of patches add support for out of band association model.
Suggestions from previous discussion ([RFC] D-Bus API for out of
band association model) are taken into account.

Also exemplary plugin which exports OOB functionality over DBus
(proposed API) is included.

Comments are welcome.


Szymon Janc (4):
  Add support for Out of Band (OOB) association model.
  Add DBus OOB plugin.
  Add DBus OOB API documentation.
  Add simple-oobprovider for testing.

 Makefile.am             |   11 ++-
 acinclude.m4            |    6 +
 doc/oob-api.txt         |   62 ++++++++
 lib/hci.h               |    3 +
 plugins/dbusoob.c       |  356 +++++++++++++++++++++++++++++++++++++++++++++++
 plugins/hciops.c        |   70 ++++++++--
 src/adapter.c           |    5 +
 src/adapter.h           |    3 +
 src/device.c            |   80 +++++++++++-
 src/device.h            |   12 ++
 src/event.c             |   73 +++++++---
 src/event.h             |    3 +-
 src/oob.c               |   61 ++++++++
 src/oob.h               |   47 ++++++
 test/simple-oobprovider |   54 +++++++
 15 files changed, 811 insertions(+), 35 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] 13+ messages in thread

* [PATCH 1/4] Add support for Out of Band (OOB) association model.
  2010-11-04 10:10 [PATCH 0/4] Support for out of band association model Szymon Janc
@ 2010-11-04 10:10 ` Szymon Janc
  2010-11-04 10:10 ` [PATCH 2/4] Add DBus OOB plugin Szymon Janc
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 13+ messages in thread
From: Szymon Janc @ 2010-11-04 10:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 Makefile.am      |    3 +-
 lib/hci.h        |    3 ++
 plugins/hciops.c |   70 +++++++++++++++++++++++++++++++++++++++--------
 src/adapter.c    |    5 +++
 src/adapter.h    |    3 ++
 src/device.c     |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/device.h     |   12 ++++++++
 src/event.c      |   73 +++++++++++++++++++++++++++++++++++++------------
 src/event.h      |    3 +-
 src/oob.c        |   61 +++++++++++++++++++++++++++++++++++++++++
 src/oob.h        |   47 +++++++++++++++++++++++++++++++
 11 files changed, 326 insertions(+), 34 deletions(-)
 create mode 100644 src/oob.c
 create mode 100644 src/oob.h

diff --git a/Makefile.am b/Makefile.am
index 873f2df..1b71cc4 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 8a79010..d8a1d2c 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
 
@@ -504,33 +506,45 @@ static void user_passkey_notify(int dev, bdaddr_t *sba, void *ptr)
 
 static void remote_oob_data_request(int dev, bdaddr_t *sba, void *ptr)
 {
-	hci_send_cmd(dev, 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(sba);
+	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(dev, OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_REPLY,
+				REMOTE_OOB_DATA_REPLY_CP_SIZE, &cp);
+	} else
+		hci_send_cmd(dev, OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_NEG_REPLY,
+				6, ptr);
 }
 
 static void io_capa_request(int dev, bdaddr_t *sba, bdaddr_t *dba)
 {
 	char sa[18], da[18];
-	uint8_t cap, auth;
 
 	ba2str(sba, sa); ba2str(dba, da);
 	info("io_capa_request (sba=%s, dba=%s)", sa, da);
 
-	if (btd_event_get_io_cap(sba, 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(sba, dba)) {
 		io_capability_neg_reply_cp cp;
 		memset(&cp, 0, sizeof(cp));
 		bacpy(&cp.bdaddr, dba);
 		cp.reason = HCI_PAIRING_NOT_ALLOWED;
 		hci_send_cmd(dev, 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(dev, OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY,
-					IO_CAPABILITY_REPLY_CP_SIZE, &cp);
 	}
 }
 
@@ -731,6 +745,15 @@ static void read_scan_complete(bdaddr_t *sba, 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_updated(local, NULL, NULL);
+	else
+		oob_local_data_updated(local, rp->hash, rp->randomizer);
+}
+
 static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr)
 {
 	evt_cmd_complete *evt = ptr;
@@ -785,6 +808,10 @@ static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr)
 		ptr += sizeof(evt_cmd_complete);
 		adapter_update_tx_power(sba, 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(sba, status, ptr);
+		break;
 	};
 }
 
@@ -2289,6 +2316,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,
@@ -2335,6 +2380,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 b25a7fc..3ec562b 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3752,3 +3752,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 aa4d686..4ca82b3 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -231,6 +231,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);
@@ -291,3 +292,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 b14865c..31cfd89 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,13 @@ 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	was_oob_ssp;
+	gboolean	has_oob_data;
+	uint8_t		hash[16];
+	uint8_t		randomizer[16];
 };
 
 static uint16_t uuid_list[] = {
@@ -830,6 +842,72 @@ 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;
+		device->was_oob_ssp = 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);
+	device->has_oob_data = FALSE;
+
+	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->was_oob_ssp = 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	},
@@ -2282,7 +2360,7 @@ void device_cancel_authentication(struct btd_device *device, gboolean aborted)
 
 gboolean device_is_authenticating(struct btd_device *device)
 {
-	return (device->authr != NULL);
+	return (device->authr != NULL || device->was_oob_ssp);
 }
 
 gboolean device_is_authorizing(struct btd_device *device)
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 60249f0..b551020 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
@@ -757,26 +758,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 */
@@ -785,11 +816,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;
@@ -805,13 +836,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;
 		}
 
@@ -821,7 +852,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) {
@@ -830,9 +861,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
@@ -840,7 +871,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
@@ -848,13 +879,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 e918c9e..33d2f76 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..cc20c67
--- /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_updated|| !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_updated(bdaddr_t *ba, uint8_t *hash, uint8_t *randomizer)
+{
+	if (active_plugin)
+		active_plugin->local_data_updated(ba, hash, randomizer);
+}
diff --git a/src/oob.h b/src/oob.h
new file mode 100644
index 0000000..ed9fe84
--- /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);
+
+	/* Local OOB data updated. If corresponding HCI command failed, hash
+	 * and randomizer are NULL */
+	void (*local_data_updated)(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_updated(bdaddr_t *ba, uint8_t *hash, uint8_t *randomizer);
-- 
1.7.1


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

* [PATCH 2/4] Add DBus OOB plugin.
  2010-11-04 10:10 [PATCH 0/4] Support for out of band association model Szymon Janc
  2010-11-04 10:10 ` [PATCH 1/4] Add support for Out of Band (OOB) " Szymon Janc
@ 2010-11-04 10:10 ` Szymon Janc
  2010-11-04 10:11 ` [PATCH 3/4] Add DBus OOB API documentation Szymon Janc
  2010-11-04 10:11 ` [PATCH 4/4] Add simple-oobprovider for testing Szymon Janc
  3 siblings, 0 replies; 13+ messages in thread
From: Szymon Janc @ 2010-11-04 10:10 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

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

diff --git a/Makefile.am b/Makefile.am
index 1b71cc4..d6cbf92 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..335de76
--- /dev/null
+++ b/plugins/dbusoob.c
@@ -0,0 +1,356 @@
+/*
+ *
+ *  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 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 *user_data)
+{
+	DBusMessage *msg;
+	DBusError err;
+	struct btd_device *device = user_data;
+	uint8_t *hash = NULL;
+	uint8_t *randomizer = NULL;
+	int32_t hash_len;
+	int32_t rand_len;
+
+	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, &hash_len,
+			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, &rand_len,
+			DBUS_TYPE_INVALID)
+			|| hash_len != 16 || rand_len != 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;
+	bdaddr_t ba;
+	char addr[18];
+	const char *paddr = addr;
+	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;
+	}
+
+	device_get_address(device, &ba);
+	ba2str(&ba, addr);
+
+	if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &paddr,
+			DBUS_TYPE_INVALID)) {
+		error ("Couldn't append arguments");
+		goto error;
+	}
+
+	if (!dbus_connection_send_with_reply(connection, msg, &call, -1)) {
+		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_updated(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 ".UpdateFailed",
+				"Failed to update local OOB.");
+
+	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 *update_local_data(DBusConnection *conn, DBusMessage *msg,
+								void *data)
+{
+	const char *name;
+	const char *addr;
+
+	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr,
+			DBUS_TYPE_INVALID))
+		return NULL;
+
+	name = dbus_message_get_sender(msg);
+	if (!provider || provider->name != name)
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".UpdateFailed",
+				"Not a OOB provider or no provider registered");
+
+	if (provider->msg)
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".UpdateFailed",
+				"Another request in progress.");
+
+	provider->adapter = manager_find_adapter_by_address(addr);
+	if (!provider->adapter)
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".UpdateFailed",
+				"No adapter with given address found");
+
+	if (btd_adapter_read_local_oob_data(provider->adapter))
+		return g_dbus_create_error(msg, ERROR_INTERFACE ".UpdateFailed",
+				"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, "Deactivate");
+
+	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},
+	{ "UpdateLocalOobData",	"s", "ayay", update_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_updated = local_data_updated;
+	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] 13+ messages in thread

* [PATCH 3/4] Add DBus OOB API documentation.
  2010-11-04 10:10 [PATCH 0/4] Support for out of band association model Szymon Janc
  2010-11-04 10:10 ` [PATCH 1/4] Add support for Out of Band (OOB) " Szymon Janc
  2010-11-04 10:10 ` [PATCH 2/4] Add DBus OOB plugin Szymon Janc
@ 2010-11-04 10:11 ` Szymon Janc
  2010-11-12 18:20   ` jaikumar Ganesh
  2010-11-04 10:11 ` [PATCH 4/4] Add simple-oobprovider for testing Szymon Janc
  3 siblings, 1 reply; 13+ messages in thread
From: Szymon Janc @ 2010-11-04 10:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

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

diff --git a/Makefile.am b/Makefile.am
index d6cbf92..b5157cd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -358,7 +358,8 @@ 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..fce18a7
--- /dev/null
+++ b/doc/oob-api.txt
@@ -0,0 +1,62 @@
+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{bye}, array{byte} RequestRemoteOobData(string address)
+
+			This method gets called when the service daemon needs to
+			get hash and randomizer for an OOB authentication.
+
+			The return value should be pair of arrays of 16 bytes
+			each. First hash, second randomizer.
+
+			If no OOB data is present for specified address empty
+			reply should be returned.
+
+		void Deactivate()
+
+			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
+
+		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.
+			When provider is successfully unregistered plug-in
+			becomes inactive and will emit Deactivated() signal.
+
+			Possible errors: org.bluez.Error.DoesNotExist
+
+		array{bye}, array{byte} UpdateLocalOobData(string address)
+
+			This method generates new local OOB data for specified
+			address (adapter). Return value is pair of arrays 16
+			bytes each. First hash, second randomizer. Only
+			registered provider should call this method.
+
+			Possible errors: org.bluez.Error.UpdateFailed
-- 
1.7.1


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

* [PATCH 4/4] Add simple-oobprovider for testing.
  2010-11-04 10:10 [PATCH 0/4] Support for out of band association model Szymon Janc
                   ` (2 preceding siblings ...)
  2010-11-04 10:11 ` [PATCH 3/4] Add DBus OOB API documentation Szymon Janc
@ 2010-11-04 10:11 ` Szymon Janc
  3 siblings, 0 replies; 13+ messages in thread
From: Szymon Janc @ 2010-11-04 10:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

---
 test/simple-oobprovider |   54 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 54 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..135f0f7
--- /dev/null
+++ b/test/simple-oobprovider
@@ -0,0 +1,54 @@
+#!/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 Provider(dbus.service.Object):
+
+	remotedata = None
+
+	@dbus.service.method("org.bluez.OOB",
+					in_signature="s", out_signature="ayay")
+
+	def RequestRemoteOobData(self, address):
+		print "RequestRemoteOobData for %s" % (address)
+		return self.remotedata
+
+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 = dbus.Interface(bus.get_object("org.bluez",
+			manager.DefaultAdapter()), "org.bluez.Adapter")
+	adr = adapter.GetProperties()['Address']
+
+	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:" % (adr)
+	print oob.UpdateLocalOobData(adr)
+
+	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] 13+ messages in thread

* Re: [PATCH 3/4] Add DBus OOB API documentation.
  2010-11-04 10:11 ` [PATCH 3/4] Add DBus OOB API documentation Szymon Janc
@ 2010-11-12 18:20   ` jaikumar Ganesh
  2010-11-12 18:29     ` Johan Hedberg
  2010-11-15  8:54     ` Szymon Janc
  0 siblings, 2 replies; 13+ messages in thread
From: jaikumar Ganesh @ 2010-11-12 18:20 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth

Hi Szymon:

On Thu, Nov 4, 2010 at 3:11 AM, Szymon Janc <szymon.janc@tieto.com> wrote:
> ---
>  Makefile.am     |    3 +-
>  doc/oob-api.txt |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 64 insertions(+), 1 deletions(-)
>  create mode 100644 doc/oob-api.txt
>
> diff --git a/Makefile.am b/Makefile.am
> index d6cbf92..b5157cd 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -358,7 +358,8 @@ 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..fce18a7
> --- /dev/null
> +++ b/doc/oob-api.txt
> @@ -0,0 +1,62 @@
> +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{bye}, array{byte} RequestRemoteOobData(string address)
> +
> +                       This method gets called when the service daemon needs to
> +                       get hash and randomizer for an OOB authentication.
> +
> +                       The return value should be pair of arrays of 16 bytes
> +                       each. First hash, second randomizer.
> +
> +                       If no OOB data is present for specified address empty
> +                       reply should be returned.
> +
> +               void Deactivate()

Would it better to make this a signal ? Deactivate by itself as the
only method doesn't seem to be right.

> +
> +                       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
> +
> +               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.

Why are we enforcing this limitation ?
> +
> +                       Possible errors: org.bluez.Error.AlreadyExists
> +
> +               void UnregisterProvider(object provider)
> +
> +                       This method unregisters provider for DBus OOB plug-in.
> +                       When provider is successfully unregistered plug-in
> +                       becomes inactive and will emit Deactivated() signal.
> +
> +                       Possible errors: org.bluez.Error.DoesNotExist
> +
> +               array{bye}, array{byte} UpdateLocalOobData(string address)

You are not updating anything here. You are just reading the local
adapter OOB data

> +
> +                       This method generates new local OOB data for specified
> +                       address (adapter). Return value is pair of arrays 16
> +                       bytes each. First hash, second randomizer. Only
> +                       registered provider should call this method.
> +
> +                       Possible errors: org.bluez.Error.UpdateFailed
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

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

* Re: [PATCH 3/4] Add DBus OOB API documentation.
  2010-11-12 18:20   ` jaikumar Ganesh
@ 2010-11-12 18:29     ` Johan Hedberg
  2010-11-12 19:07       ` jaikumar Ganesh
  2010-11-15  8:54     ` Szymon Janc
  1 sibling, 1 reply; 13+ messages in thread
From: Johan Hedberg @ 2010-11-12 18:29 UTC (permalink / raw)
  To: jaikumar Ganesh; +Cc: Szymon Janc, linux-bluetooth

Hi Jaikumar,

On Fri, Nov 12, 2010, jaikumar Ganesh wrote:
> > +               void Deactivate()
> 
> Would it better to make this a signal ? Deactivate by itself as the
> only method doesn't seem to be right.

I guess this is analogous to the Release() method which we have for
agents, so in that sense a method call would be consistent with the rest
of the BlueZ D-Bus API (but you'd really need to rename this to Release
then).

Johan

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

* Re: [PATCH 3/4] Add DBus OOB API documentation.
  2010-11-12 18:29     ` Johan Hedberg
@ 2010-11-12 19:07       ` jaikumar Ganesh
  2010-11-15 10:11         ` Szymon Janc
  0 siblings, 1 reply; 13+ messages in thread
From: jaikumar Ganesh @ 2010-11-12 19:07 UTC (permalink / raw)
  To: jaikumar Ganesh, Szymon Janc, linux-bluetooth

Hi Szymon:

On Fri, Nov 12, 2010 at 10:29 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Jaikumar,
>
> On Fri, Nov 12, 2010, jaikumar Ganesh wrote:
>> > +               void Deactivate()
>>
>> Would it better to make this a signal ? Deactivate by itself as the
>> only method doesn't seem to be right.
>
> I guess this is analogous to the Release() method which we have for
> agents, so in that sense a method call would be consistent with the rest
> of the BlueZ D-Bus API (but you'd really need to rename this to Release
> then).
>
> Johan
>

So the only APIs added are these provider ones and one API in Agent
code for approval.

So how does bluetoothd decide whether OOB is present for a particular
remote device for an outgoing pairing case ? Just on the basis of
whether a provider is registered or am I missing something here.

RequestRemoteOobData is called before initiating pairing or when the
remote end asks for the OOB data ?
Its unclear from the API description.

Thanks
Jaikumar

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

* Re: [PATCH 3/4] Add DBus OOB API documentation.
  2010-11-12 18:20   ` jaikumar Ganesh
  2010-11-12 18:29     ` Johan Hedberg
@ 2010-11-15  8:54     ` Szymon Janc
  2010-11-16  4:16       ` jaikumar Ganesh
  1 sibling, 1 reply; 13+ messages in thread
From: Szymon Janc @ 2010-11-15  8:54 UTC (permalink / raw)
  To: jaikumar Ganesh; +Cc: linux-bluetooth@vger.kernel.org

Hi Jaikumar,

> > +               void Deactivate()
> 
> Would it better to make this a signal ? Deactivate by itself as the
> only method doesn't seem to be right.

I'll change it to Release() to be consistent with other (Agent) API as
suggested by Johan.

> > +               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.
> 
> Why are we enforcing this limitation ?

Spec requires that each hash&randomizer values should be used only for one OOB
transfer. Implementation enforces that by allowing only one active OOB plugin
at time and DBUS OOB plugin only 'expose' plugin API over DBUS. So this
limitation is a consequence of that.

This limitation also allows for (IMHO) simpler plugins implementation as they
don't have to care about other plugins hanging around to fulfill that
requirement.

> > +               array{bye}, array{byte} UpdateLocalOobData(string address)
> 
> You are not updating anything here. You are just reading the local
> adapter OOB data

It is updating hash and randomizer. Underlying functions are called Read* as
this is how corresponding HCI command is called (see Vol2. Part E. 7.3.60).
I'll change it to Read to keep all calls name consistent with HCI command name
and add appropriate note in API documentation as this name may be somewhat
misleading (yet OOB plugin implementer should be aware of that already).

-- 
Szymon Janc

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

* Re: [PATCH 3/4] Add DBus OOB API documentation.
  2010-11-12 19:07       ` jaikumar Ganesh
@ 2010-11-15 10:11         ` Szymon Janc
  0 siblings, 0 replies; 13+ messages in thread
From: Szymon Janc @ 2010-11-15 10:11 UTC (permalink / raw)
  To: jaikumar Ganesh; +Cc: linux-bluetooth@vger.kernel.org

Hi,

> So the only APIs added are these provider ones and one API in Agent
> code for approval.
> 
> So how does bluetoothd decide whether OOB is present for a particular
> remote device for an outgoing pairing case ? Just on the basis of
> whether a provider is registered or am I missing something here.

If there is an active OOB plugin then it is asked for remote OOB data when
io capabilities are established. Based on the answer oob_data field in io
capability reply is set. Dbus OOB plugin becomes active when provider is
registered. If no oob plugin is active oob_data field is always set to 0x00.

> RequestRemoteOobData is called before initiating pairing or when the
> remote end asks for the OOB data ?
> Its unclear from the API description.

I can see that OOB mechanism is somewhat unclear, let me try to clarify:
- local oob data are data generated by local adapter
- remote oob data are data received from remote device
- remote and/or local data are exchange through some OOB mechanism - this takes
  place before SSP is started
  (note that data exchanged on OOB also contains BT address)
- during SSP active oob plugin is asked for oob data for remote device

So, RequestRemoteOobData is called when io capabilities are being established,
but this asks plugin if it already has OOB data for this device and not
a remote device to provide this data.

Hope this clarifies things a bit :)

-- 
Szymon Janc

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

* Re: [PATCH 3/4] Add DBus OOB API documentation.
  2010-11-15  8:54     ` Szymon Janc
@ 2010-11-16  4:16       ` jaikumar Ganesh
  2010-11-16 10:12         ` Szymon Janc
  0 siblings, 1 reply; 13+ messages in thread
From: jaikumar Ganesh @ 2010-11-16  4:16 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth@vger.kernel.org

On Mon, Nov 15, 2010 at 12:54 AM, Szymon Janc <szymon.janc@tieto.com> wrote:
> Hi Jaikumar,
>
>> > +               void Deactivate()
>>
>> Would it better to make this a signal ? Deactivate by itself as the
>> only method doesn't seem to be right.
>
> I'll change it to Release() to be consistent with other (Agent) API as
> suggested by Johan.
>
>> > +               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.
>>
>> Why are we enforcing this limitation ?
>
> Spec requires that each hash&randomizer values should be used only for one OOB
> transfer. Implementation enforces that by allowing only one active OOB plugin
> at time and DBUS OOB plugin only 'expose' plugin API over DBUS. So this
> limitation is a consequence of that.

I don't think the spec says that. It just says every single time the
call to read the local adapters hash
and randomizer is done you get new values. You can use the value that
you have obtained for as many OOB pairings
as you wish.

>
> This limitation also allows for (IMHO) simpler plugins implementation as they
> don't have to care about other plugins hanging around to fulfill that
> requirement.
>
>> > +               array{bye}, array{byte} UpdateLocalOobData(string address)
>>
>> You are not updating anything here. You are just reading the local
>> adapter OOB data
>
> It is updating hash and randomizer. Underlying functions are called Read* as
> this is how corresponding HCI command is called (see Vol2. Part E. 7.3.60).
> I'll change it to Read to keep all calls name consistent with HCI command name
> and add appropriate note in API documentation as this name may be somewhat
> misleading (yet OOB plugin implementer should be aware of that already).
>
> --
> Szymon Janc
>

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

* Re: [PATCH 3/4] Add DBus OOB API documentation.
  2010-11-16  4:16       ` jaikumar Ganesh
@ 2010-11-16 10:12         ` Szymon Janc
  2010-11-17 17:15           ` jaikumar Ganesh
  0 siblings, 1 reply; 13+ messages in thread
From: Szymon Janc @ 2010-11-16 10:12 UTC (permalink / raw)
  To: jaikumar Ganesh; +Cc: linux-bluetooth@vger.kernel.org

> >> Why are we enforcing this limitation ?
> >
> > Spec requires that each hash&randomizer values should be used only for one OOB
> > transfer. Implementation enforces that by allowing only one active OOB plugin
> > at time and DBUS OOB plugin only 'expose' plugin API over DBUS. So this
> > limitation is a consequence of that.
> 
> I don't think the spec says that. It just says every single time the
> call to read the local adapters hash
> and randomizer is done you get new values. You can use the value that
> you have obtained for as many OOB pairings
> as you wish.

Please see note in Vol2. Part E. 7.3.60:

	"Each OOB transfer will have unique C and R values so after each OOB
	transfer this command shall be used to obtain a new set of values for the next
	OOB transfer."


-- 
Szymon Janc

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

* Re: [PATCH 3/4] Add DBus OOB API documentation.
  2010-11-16 10:12         ` Szymon Janc
@ 2010-11-17 17:15           ` jaikumar Ganesh
  0 siblings, 0 replies; 13+ messages in thread
From: jaikumar Ganesh @ 2010-11-17 17:15 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth@vger.kernel.org

Hi Szymon:

On Tue, Nov 16, 2010 at 2:12 AM, Szymon Janc <szymon.janc@tieto.com> wrote:
>> >> Why are we enforcing this limitation ?
>> >
>> > Spec requires that each hash&randomizer values should be used only for one OOB
>> > transfer. Implementation enforces that by allowing only one active OOB plugin
>> > at time and DBUS OOB plugin only 'expose' plugin API over DBUS. So this
>> > limitation is a consequence of that.
>>
>> I don't think the spec says that. It just says every single time the
>> call to read the local adapters hash
>> and randomizer is done you get new values. You can use the value that
>> you have obtained for as many OOB pairings
>> as you wish.
>
> Please see note in Vol2. Part E. 7.3.60:
>
>        "Each OOB transfer will have unique C and R values so after each OOB
>        transfer this command shall be used to obtain a new set of values for the next
>        OOB transfer."
>

Yes we were talking about the same thing, just at different layers. I
was talking about it from the user of the provider.
This looks fine to me.

>
> --
> Szymon Janc
>

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

end of thread, other threads:[~2010-11-17 17:15 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-04 10:10 [PATCH 0/4] Support for out of band association model Szymon Janc
2010-11-04 10:10 ` [PATCH 1/4] Add support for Out of Band (OOB) " Szymon Janc
2010-11-04 10:10 ` [PATCH 2/4] Add DBus OOB plugin Szymon Janc
2010-11-04 10:11 ` [PATCH 3/4] Add DBus OOB API documentation Szymon Janc
2010-11-12 18:20   ` jaikumar Ganesh
2010-11-12 18:29     ` Johan Hedberg
2010-11-12 19:07       ` jaikumar Ganesh
2010-11-15 10:11         ` Szymon Janc
2010-11-15  8:54     ` Szymon Janc
2010-11-16  4:16       ` jaikumar Ganesh
2010-11-16 10:12         ` Szymon Janc
2010-11-17 17:15           ` jaikumar Ganesh
2010-11-04 10:11 ` [PATCH 4/4] Add simple-oobprovider for testing Szymon Janc

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).