2011-03-26 11:27:05

by Szymon Janc

[permalink] [raw]
Subject: [PATCH v7 0/6] Support for out of band association mode

Changes since v6:
- fixed issues pointed out by Johan

BR,
Szymon Janc
on behalf of ST-Ericsson

Szymon Janc (6):
Add initial support for Out of Band (OOB) association model
Add support for Out of Band (OOB) association model in mgmtops
Add support for Out of Band (OOB) association model in hciops
Add D-Bus OOB plugin
Update mgmt-api.txt with OOB commands
Add oob-api.txt with documentation about OOB D-Bus methods

Makefile.am | 8 ++-
acinclude.m4 | 6 ++
doc/mgmt-api.txt | 30 +++++++
doc/oob-api.txt | 38 +++++++++
lib/mgmt.h | 18 ++++
plugins/dbusoob.c | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++++
plugins/hciops.c | 142 +++++++++++++++++++++++++++++++-
plugins/mgmtops.c | 129 +++++++++++++++++++++++++++++
src/adapter.c | 18 ++++
src/adapter.h | 12 +++
src/oob.c | 41 +++++++++
src/oob.h | 32 +++++++
12 files changed, 702 insertions(+), 6 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



2011-03-27 20:04:46

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH v7 0/6] Support for out of band association mode

Hi Szymon,

On Sat, Mar 26, 2011, Szymon Janc wrote:
> Changes since v6:
> - fixed issues pointed out by Johan
>
> BR,
> Szymon Janc
> on behalf of ST-Ericsson
>
> Szymon Janc (6):
> Add initial support for Out of Band (OOB) association model
> Add support for Out of Band (OOB) association model in mgmtops
> Add support for Out of Band (OOB) association model in hciops
> Add D-Bus OOB plugin
> Update mgmt-api.txt with OOB commands
> Add oob-api.txt with documentation about OOB D-Bus methods
>
> Makefile.am | 8 ++-
> acinclude.m4 | 6 ++
> doc/mgmt-api.txt | 30 +++++++
> doc/oob-api.txt | 38 +++++++++
> lib/mgmt.h | 18 ++++
> plugins/dbusoob.c | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> plugins/hciops.c | 142 +++++++++++++++++++++++++++++++-
> plugins/mgmtops.c | 129 +++++++++++++++++++++++++++++
> src/adapter.c | 18 ++++
> src/adapter.h | 12 +++
> src/oob.c | 41 +++++++++
> src/oob.h | 32 +++++++
> 12 files changed, 702 insertions(+), 6 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

All six patches have been pushed upstream. Thanks.

Do you think you could come up with a test script to test this (through
the dbusoob plugin) between two local adapters? We could then add that
to the test subdirectory.

Johan

2011-03-26 11:27:11

by Szymon Janc

[permalink] [raw]
Subject: [PATCH v7 6/6] Add oob-api.txt with documentation about OOB D-Bus methods

---
doc/oob-api.txt | 38 ++++++++++++++++++++++++++++++++++++++
1 files changed, 38 insertions(+), 0 deletions(-)
create mode 100644 doc/oob-api.txt

diff --git a/doc/oob-api.txt b/doc/oob-api.txt
new file mode 100644
index 0000000..7fa09f7
--- /dev/null
+++ b/doc/oob-api.txt
@@ -0,0 +1,38 @@
+BlueZ D-Bus Out Of Band API description
+***********************************
+
+Copyright (C) 2011 Szymon Janc <[email protected]> for ST-Ericsson
+
+Service org.bluez
+Interface org.bluez.Oob
+Object path [variable prefix]/{hci0,hci1,...}
+
+Methods array{byte} hash, array{byte} randomizer ReadLocalOobData()
+
+ This method reads local OOB data from adapter. Return
+ value is pair of arrays 16 bytes each.
+
+ Note: This method will generate and return new local
+ OOB data.
+
+ Possible errors: org.bluez.Error.Failed
+ org.bluez.Error.InProgress
+
+ void AddRemoteOobData(string address, array{byte} hash,
+ array{byte} randomizer)
+
+ This method adds new Out Of Band data for specified
+ address. If data for specified address already exists it
+ will be overwritten with new one.
+
+ Possible errors: org.bluez.Error.Failed
+ org.bluez.Error.InvalidArguments
+
+ void RemoveRemoteOobData(string address)
+
+ This method removes Out Of Band data for specified
+ address. If data for specified address does not exist
+ nothing is removed.
+
+ Possible errors: org.bluez.Error.Failed
+ org.bluez.Error.InvalidArguments
--
1.7.0.4


2011-03-26 11:27:10

by Szymon Janc

[permalink] [raw]
Subject: [PATCH v7 5/6] Update mgmt-api.txt with OOB commands

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

diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt
index dd179ee..f02738e 100644
--- a/doc/mgmt-api.txt
+++ b/doc/mgmt-api.txt
@@ -274,6 +274,36 @@ Set Local Name Command
Command Parameters: Name (249 Octets)
Return Paramters: Name (249 Octets)

+Read Local Out Of Band Data Command
+========================================
+
+ Command Code: 0x0018
+ Controller Index: <controller id>
+ Command Parameters:
+ Return Paramters: Hash (16 Octets)
+ Randomizer (16 Octets)
+
+
+Add Remote Out Of Band Data Command
+========================================
+
+ Command Code: 0x0019
+ Controller Index: <controller id>
+ Command Parameters: Address (6 Octets)
+ Hash (16 Octets)
+ Randomizer (16 Octets)
+ Return Paramters:
+
+
+Remove Remote Out Of Band Data Command
+========================================
+
+ Command Code: 0x001A
+ Controller Index: <controller id>
+ Command Parameters: Address (6 Octets)
+ Return Paramters:
+
+
Read Tracing Buffer Size Command
================================

--
1.7.0.4


2011-03-26 11:27:09

by Szymon Janc

[permalink] [raw]
Subject: [PATCH v7 4/6] Add D-Bus OOB plugin

A sample OOB plugin that directly exposes OOB functionality over D-Bus.
---
Makefile.am | 5 +
acinclude.m4 | 6 ++
plugins/dbusoob.c | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 245 insertions(+), 0 deletions(-)
create mode 100644 plugins/dbusoob.c

diff --git a/Makefile.am b/Makefile.am
index 0ed2acf..a23cc60 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -237,6 +237,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 faa7f7c..69e0740 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -206,6 +206,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
telephony_driver=dummy
maemo6_enable=no
sap_driver=dummy
+ dbusoob_enable=no

AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [disable code optimization]), [
optimization_enable=${enableval}
@@ -338,6 +339,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [
maemo6_enable=${enableval}
])

+ AC_ARG_ENABLE(dbusoob, AC_HELP_STRING([--enable-dbusoob], [compile with D-Bus OOB plugin]), [
+ dbusoob_enable=${enableval}
+ ])
+
AC_ARG_ENABLE(hal, AC_HELP_STRING([--enable-hal], [Use HAL to determine adapter class]), [
hal_enable=${enableval}
])
@@ -396,4 +401,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..fac5ba5
--- /dev/null
+++ b/plugins/dbusoob.c
@@ -0,0 +1,234 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2011 ST-Ericsson SA
+ *
+ * Author: Szymon Janc <[email protected]> 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 "adapter.h"
+#include "device.h"
+#include "manager.h"
+#include "dbus-common.h"
+#include "event.h"
+#include "error.h"
+#include "oob.h"
+
+#define REQUEST_TIMEOUT (60 * 1000) /* 60 seconds */
+#define OOB_INTERFACE "org.bluez.Oob"
+
+struct oob_request {
+ struct btd_adapter *adapter;
+ DBusMessage *msg;
+};
+
+static GSList *oob_requests = NULL;
+static DBusConnection *connection = NULL;
+
+static gint oob_request_cmp(gconstpointer a, gconstpointer b)
+{
+ const struct oob_request *data = a;
+ const struct btd_adapter *adapter = b;
+
+ return data->adapter != adapter;
+}
+
+static struct oob_request *find_oob_request(struct btd_adapter *adapter)
+{
+ GSList *match;
+
+ match = g_slist_find_custom(oob_requests, adapter, oob_request_cmp);
+
+ if (match)
+ return match->data;
+
+ return NULL;
+}
+
+static void read_local_data_complete(struct btd_adapter *adapter, uint8_t *hash,
+ uint8_t *randomizer)
+{
+ struct DBusMessage *reply;
+ struct oob_request *oob_request;
+
+ oob_request = find_oob_request(adapter);
+ if (!oob_request)
+ return;
+
+ if (hash && randomizer)
+ reply = g_dbus_create_reply(oob_request->msg,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, 16,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, 16,
+ DBUS_TYPE_INVALID);
+ else
+ reply = btd_error_failed(oob_request->msg,
+ "Failed to read local OOB data.");
+
+ oob_requests = g_slist_remove(oob_requests, oob_request);
+ dbus_message_unref(oob_request->msg);
+ g_free(oob_request);
+
+ 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)
+{
+ struct btd_adapter *adapter = data;
+ struct oob_request *oob_request;
+
+ if (find_oob_request(adapter))
+ return btd_error_in_progress(msg);
+
+ if (btd_adapter_read_local_oob_data(adapter))
+ return btd_error_failed(msg, "Request failed.");
+
+ oob_request = g_new(struct oob_request, 1);
+ oob_request->adapter = adapter;
+ oob_requests = g_slist_append(oob_requests, oob_request);
+ oob_request->msg = dbus_message_ref(msg);
+ return NULL;
+}
+
+static DBusMessage *add_remote_data(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ struct btd_adapter *adapter = data;
+ uint8_t *hash, *randomizer;
+ int32_t hlen, rlen;
+ const char *addr;
+ bdaddr_t bdaddr;
+
+ if (!dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_STRING, &addr,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, &hlen,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, &rlen,
+ DBUS_TYPE_INVALID))
+ return btd_error_invalid_args(msg);
+
+ if (hlen != 16 || rlen != 16 || bachk(addr))
+ return btd_error_invalid_args(msg);
+
+ str2ba(addr, &bdaddr);
+
+ if (btd_adapter_add_remote_oob_data(adapter, &bdaddr, hash, randomizer))
+ return btd_error_failed(msg, "Request failed");
+
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
+static DBusMessage *remove_remote_data(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ struct btd_adapter *adapter = data;
+ const char *addr;
+ bdaddr_t bdaddr;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr,
+ DBUS_TYPE_INVALID))
+ return btd_error_invalid_args(msg);
+
+ if (bachk(addr))
+ return btd_error_invalid_args(msg);
+
+ str2ba(addr, &bdaddr);
+
+ if (btd_adapter_remove_remote_oob_data(adapter, &bdaddr))
+ return btd_error_failed(msg, "Request failed");
+
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
+static GDBusMethodTable oob_methods[] = {
+ {"AddRemoteOobData", "sayay", "", add_remote_data},
+ {"RemoveRemoteOobData", "s", "", remove_remote_data},
+ {"ReadLocalOobData", "", "ayay", read_local_data,
+ G_DBUS_METHOD_FLAG_ASYNC},
+ {}
+};
+
+static int oob_probe(struct btd_adapter *adapter)
+{
+ const char *path = adapter_get_path(adapter);
+
+ if (!g_dbus_register_interface(connection, path, OOB_INTERFACE,
+ oob_methods, NULL, NULL, adapter, NULL)) {
+ error("OOB interface init failed on path %s", path);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static void oob_remove(struct btd_adapter *adapter)
+{
+ read_local_data_complete(adapter, NULL, NULL);
+
+ g_dbus_unregister_interface(connection, adapter_get_path(adapter),
+ OOB_INTERFACE);
+}
+
+static struct btd_adapter_driver oob_driver = {
+ .name = "oob",
+ .probe = oob_probe,
+ .remove = oob_remove,
+};
+
+static int dbusoob_init(void)
+{
+ DBG("Setup dbusoob plugin");
+
+ connection = get_dbus_connection();
+
+ oob_register_cb(read_local_data_complete);
+
+ return btd_register_adapter_driver(&oob_driver);
+}
+
+static void dbusoob_exit(void)
+{
+ DBG("Cleanup dbusoob plugin");
+
+ manager_foreach_adapter((adapter_cb) oob_remove, NULL);
+
+ btd_unregister_adapter_driver(&oob_driver);
+}
+
+BLUETOOTH_PLUGIN_DEFINE(dbusoob, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
+ dbusoob_init, dbusoob_exit)
--
1.7.0.4


2011-03-26 11:27:08

by Szymon Janc

[permalink] [raw]
Subject: [PATCH v7 3/6] Add support for Out of Band (OOB) association model in hciops

---
plugins/hciops.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 109 insertions(+), 8 deletions(-)

diff --git a/plugins/hciops.c b/plugins/hciops.c
index ffda339..93f6f21 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -50,6 +50,7 @@
#include "storage.h"
#include "event.h"
#include "manager.h"
+#include "oob.h"

static int child_pipe[2] = { -1, -1 };

@@ -77,11 +78,18 @@ struct bt_conn {
uint8_t loc_auth;
uint8_t rem_cap;
uint8_t rem_auth;
+ uint8_t rem_oob_data;
gboolean bonding_initiator;
gboolean secmode3;
GIOChannel *io; /* For raw L2CAP socket (bonding) */
};

+struct oob_data {
+ bdaddr_t bdaddr;
+ uint8_t hash[16];
+ uint8_t randomizer[16];
+};
+
static int max_dev = -1;
static struct dev_info {
int id;
@@ -120,6 +128,8 @@ static struct dev_info {
GSList *keys;
uint8_t pin_length;

+ GSList *oob_data;
+
GSList *uuids;

GSList *connections;
@@ -1053,14 +1063,42 @@ static void user_passkey_notify(int index, void *ptr)
btohl(req->passkey));
}

-static void remote_oob_data_request(int index, void *ptr)
+static gint oob_bdaddr_cmp(gconstpointer a, gconstpointer b)
+{
+ const struct oob_data *data = a;
+ const bdaddr_t *bdaddr = b;
+
+ return bacmp(&data->bdaddr, bdaddr);
+}
+
+static void remote_oob_data_request(int index, bdaddr_t *bdaddr)
{
struct dev_info *dev = &devs[index];
+ GSList *match;

DBG("hci%d", index);

- hci_send_cmd(dev->sk, OGF_LINK_CTL,
- OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, ptr);
+ match = g_slist_find_custom(dev->oob_data, bdaddr, oob_bdaddr_cmp);
+
+ if (match) {
+ struct oob_data *data;
+ remote_oob_data_reply_cp cp;
+
+ data = match->data;
+
+ bacpy(&cp.bdaddr, &data->bdaddr);
+ memcpy(cp.hash, data->hash, sizeof(cp.hash));
+ memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
+
+ dev->oob_data = g_slist_delete_link(dev->oob_data, match);
+
+ hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_REPLY,
+ REMOTE_OOB_DATA_REPLY_CP_SIZE, &cp);
+
+ } else {
+ hci_send_cmd(dev->sk, OGF_LINK_CTL,
+ OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, bdaddr);
+ }
}

static int get_io_cap(int index, bdaddr_t *bdaddr, uint8_t *cap, uint8_t *auth)
@@ -1158,11 +1196,23 @@ static void io_capa_request(int index, void *ptr)
IO_CAPABILITY_NEG_REPLY_CP_SIZE, &cp);
} else {
io_capability_reply_cp cp;
+ struct bt_conn *conn;
+ GSList *match;
+
memset(&cp, 0, sizeof(cp));
bacpy(&cp.bdaddr, dba);
cp.capability = cap;
- cp.oob_data = 0x00;
cp.authentication = auth;
+
+ conn = find_connection(dev, dba);
+ match = g_slist_find_custom(dev->oob_data, dba, oob_bdaddr_cmp);
+
+ if ((conn->bonding_initiator || conn->rem_oob_data == 0x01) &&
+ match)
+ cp.oob_data = 0x01;
+ else
+ cp.oob_data = 0x00;
+
hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY,
IO_CAPABILITY_REPLY_CP_SIZE, &cp);
}
@@ -1182,6 +1232,7 @@ static void io_capa_response(int index, void *ptr)
if (conn) {
conn->rem_cap = evt->capability;
conn->rem_auth = evt->authentication;
+ conn->rem_oob_data = evt->oob_data;
}
}

@@ -1785,6 +1836,20 @@ static void write_class_complete(int index, uint8_t status)
write_class(index, dev->wanted_cod);
}

+static void read_local_oob_data_complete(int index, uint8_t status,
+ read_local_oob_data_rp *rp)
+{
+ struct btd_adapter *adapter = manager_find_adapter_by_id(index);
+
+ if (!adapter)
+ return;
+
+ if (status)
+ oob_read_local_data_complete(adapter, NULL, NULL);
+ else
+ oob_read_local_data_complete(adapter, rp->hash, rp->randomizer);
+}
+
static inline void cmd_complete(int index, void *ptr)
{
struct dev_info *dev = &devs[index];
@@ -1858,6 +1923,10 @@ static inline void cmd_complete(int index, void *ptr)
ptr += sizeof(evt_cmd_complete);
read_tx_power_complete(index, ptr);
break;
+ case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_LOCAL_OOB_DATA):
+ ptr += sizeof(evt_cmd_complete);
+ read_local_oob_data_complete(index, status, ptr);
+ break;
};
}

@@ -2387,7 +2456,7 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond,
break;

case EVT_REMOTE_OOB_DATA_REQUEST:
- remote_oob_data_request(index, ptr);
+ remote_oob_data_request(index, (bdaddr_t *) ptr);
break;
}

@@ -3557,30 +3626,62 @@ static int hciops_cancel_bonding(int index, bdaddr_t *bdaddr)

static int hciops_read_local_oob_data(int index)
{
+ struct dev_info *dev = &devs[index];
+
DBG("hci%d", index);

- return -ENOSYS;
+ if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_READ_LOCAL_OOB_DATA, 0, 0)
+ < 0)
+ return -errno;
+
+ return 0;
}

static int hciops_add_remote_oob_data(int index, bdaddr_t *bdaddr,
uint8_t *hash, uint8_t *randomizer)
{
char addr[18];
+ struct dev_info *dev = &devs[index];
+ GSList *match;
+ struct oob_data *data;

ba2str(bdaddr, addr);
DBG("hci%d bdaddr %s", index, addr);

- return -ENOSYS;
+ match = g_slist_find_custom(dev->oob_data, &bdaddr, oob_bdaddr_cmp);
+
+ if (match) {
+ data = match->data;
+ } else {
+ data = g_new(struct oob_data, 1);
+ bacpy(&data->bdaddr, bdaddr);
+ dev->oob_data = g_slist_prepend(dev->oob_data, data);
+ }
+
+ memcpy(data->hash, hash, sizeof(data->hash));
+ memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
+
+ return 0;
}

static int hciops_remove_remote_oob_data(int index, bdaddr_t *bdaddr)
{
char addr[18];
+ struct dev_info *dev = &devs[index];
+ GSList *match;

ba2str(bdaddr, addr);
DBG("hci%d bdaddr %s", index, addr);

- return -ENOSYS;
+ match = g_slist_find_custom(dev->oob_data, &bdaddr, oob_bdaddr_cmp);
+
+ if (!match)
+ return -ENOENT;
+
+ g_free(match->data);
+ dev->oob_data = g_slist_delete_link(dev->oob_data, match);
+
+ return 0;
}

static struct btd_adapter_ops hci_ops = {
--
1.7.0.4


2011-03-26 11:27:06

by Szymon Janc

[permalink] [raw]
Subject: [PATCH v7 1/6] Add initial support for Out of Band (OOB) association model

---
Makefile.am | 3 ++-
plugins/hciops.c | 31 +++++++++++++++++++++++++++++++
plugins/mgmtops.c | 31 +++++++++++++++++++++++++++++++
src/adapter.c | 18 ++++++++++++++++++
src/adapter.h | 12 ++++++++++++
src/oob.c | 41 +++++++++++++++++++++++++++++++++++++++++
src/oob.h | 32 ++++++++++++++++++++++++++++++++
7 files changed, 167 insertions(+), 1 deletions(-)
create mode 100644 src/oob.c
create mode 100644 src/oob.h

diff --git a/Makefile.am b/Makefile.am
index 2994bf9..0ed2acf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -259,7 +259,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.h 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/plugins/hciops.c b/plugins/hciops.c
index 69627eb..ffda339 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -3555,6 +3555,34 @@ static int hciops_cancel_bonding(int index, bdaddr_t *bdaddr)
return 0;
}

+static int hciops_read_local_oob_data(int index)
+{
+ DBG("hci%d", index);
+
+ return -ENOSYS;
+}
+
+static int hciops_add_remote_oob_data(int index, bdaddr_t *bdaddr,
+ uint8_t *hash, uint8_t *randomizer)
+{
+ char addr[18];
+
+ ba2str(bdaddr, addr);
+ DBG("hci%d bdaddr %s", index, addr);
+
+ return -ENOSYS;
+}
+
+static int hciops_remove_remote_oob_data(int index, bdaddr_t *bdaddr)
+{
+ char addr[18];
+
+ ba2str(bdaddr, addr);
+ DBG("hci%d bdaddr %s", index, addr);
+
+ return -ENOSYS;
+}
+
static struct btd_adapter_ops hci_ops = {
.setup = hciops_setup,
.cleanup = hciops_cleanup,
@@ -3594,6 +3622,9 @@ static struct btd_adapter_ops hci_ops = {
.set_io_capability = hciops_set_io_capability,
.create_bonding = hciops_create_bonding,
.cancel_bonding = hciops_cancel_bonding,
+ .read_local_oob_data = hciops_read_local_oob_data,
+ .add_remote_oob_data = hciops_add_remote_oob_data,
+ .remove_remote_oob_data = hciops_remove_remote_oob_data,
};

static int hciops_init(void)
diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c
index 0c376f7..6bb033b 100644
--- a/plugins/mgmtops.c
+++ b/plugins/mgmtops.c
@@ -1748,6 +1748,34 @@ static int mgmt_cancel_bonding(int index, bdaddr_t *bdaddr)
return -ENOSYS;
}

+static int mgmt_read_local_oob_data(int index)
+{
+ DBG("hci%d", index);
+
+ return -ENOSYS;
+}
+
+static int mgmt_add_remote_oob_data(int index, bdaddr_t *bdaddr,
+ uint8_t *hash, uint8_t *randomizer)
+{
+ char addr[18];
+
+ ba2str(bdaddr, addr);
+ DBG("hci%d bdaddr %s", index, addr);
+
+ return -ENOSYS;
+}
+
+static int mgmt_remove_remote_oob_data(int index, bdaddr_t *bdaddr)
+{
+ char addr[18];
+
+ ba2str(bdaddr, addr);
+ DBG("hci%d bdaddr %s", index, addr);
+
+ return -ENOSYS;
+}
+
static struct btd_adapter_ops mgmt_ops = {
.setup = mgmt_setup,
.cleanup = mgmt_cleanup,
@@ -1787,6 +1815,9 @@ static struct btd_adapter_ops mgmt_ops = {
.set_io_capability = mgmt_set_io_capability,
.create_bonding = mgmt_create_bonding,
.cancel_bonding = mgmt_cancel_bonding,
+ .read_local_oob_data = mgmt_read_local_oob_data,
+ .add_remote_oob_data = mgmt_add_remote_oob_data,
+ .remove_remote_oob_data = mgmt_remove_remote_oob_data,
};

static int mgmt_init(void)
diff --git a/src/adapter.c b/src/adapter.c
index 691b963..5894146 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3729,3 +3729,21 @@ int adapter_cancel_bonding(struct btd_adapter *adapter, bdaddr_t *bdaddr)
{
return adapter_ops->cancel_bonding(adapter->dev_id, bdaddr);
}
+
+int btd_adapter_read_local_oob_data(struct btd_adapter *adapter)
+{
+ return adapter_ops->read_local_oob_data(adapter->dev_id);
+}
+
+int btd_adapter_add_remote_oob_data(struct btd_adapter *adapter,
+ bdaddr_t *bdaddr, uint8_t *hash, uint8_t *randomizer)
+{
+ return adapter_ops->add_remote_oob_data(adapter->dev_id, bdaddr, hash,
+ randomizer);
+}
+
+int btd_adapter_remove_remote_oob_data(struct btd_adapter *adapter,
+ bdaddr_t *bdaddr)
+{
+ return adapter_ops->remove_remote_oob_data(adapter->dev_id, bdaddr);
+}
diff --git a/src/adapter.h b/src/adapter.h
index 8bc687d..308af75 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -237,6 +237,10 @@ struct btd_adapter_ops {
int (*set_io_capability) (int index, uint8_t io_capability);
int (*create_bonding) (int index, bdaddr_t *bdaddr, uint8_t io_cap);
int (*cancel_bonding) (int index, bdaddr_t *bdaddr);
+ int (*read_local_oob_data) (int index);
+ int (*add_remote_oob_data) (int index, bdaddr_t *bdaddr, uint8_t *hash,
+ uint8_t *randomizer);
+ int (*remove_remote_oob_data) (int index, bdaddr_t *bdaddr);
};

int btd_register_adapter_ops(struct btd_adapter_ops *ops, gboolean priority);
@@ -288,3 +292,11 @@ int adapter_create_bonding(struct btd_adapter *adapter, bdaddr_t *bdaddr,
uint8_t io_cap);

int adapter_cancel_bonding(struct btd_adapter *adapter, bdaddr_t *bdaddr);
+
+int btd_adapter_read_local_oob_data(struct btd_adapter *adapter);
+
+int btd_adapter_add_remote_oob_data(struct btd_adapter *adapter,
+ bdaddr_t *bdaddr, uint8_t *hash, uint8_t *randomizer);
+
+int btd_adapter_remove_remote_oob_data(struct btd_adapter *adapter,
+ bdaddr_t *bdaddr);
diff --git a/src/oob.c b/src/oob.c
new file mode 100644
index 0000000..75798fb
--- /dev/null
+++ b/src/oob.c
@@ -0,0 +1,41 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2011 ST-Ericsson SA
+ *
+ * Author: Szymon Janc <[email protected]> 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 "adapter.h"
+#include "oob.h"
+
+static oob_read_cb_t local_oob_read_cb = NULL;
+
+void oob_register_cb(oob_read_cb_t cb)
+{
+ local_oob_read_cb = cb;
+}
+
+void oob_read_local_data_complete(struct btd_adapter *adapter, uint8_t *hash,
+ uint8_t *randomizer)
+{
+ if (local_oob_read_cb)
+ local_oob_read_cb(adapter, hash, randomizer);
+}
diff --git a/src/oob.h b/src/oob.h
new file mode 100644
index 0000000..5805082
--- /dev/null
+++ b/src/oob.h
@@ -0,0 +1,32 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2011 ST-Ericsson SA
+ *
+ * Author: Szymon Janc <[email protected]> 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
+ *
+ */
+
+typedef void (*oob_read_cb_t) (struct btd_adapter *adapter, uint8_t *hash,
+ uint8_t *randomizer);
+
+void oob_register_cb(oob_read_cb_t cb);
+
+void oob_read_local_data_complete(struct btd_adapter *adapter, uint8_t *hash,
+ uint8_t *randomizer);
--
1.7.0.4


2011-03-26 11:27:07

by Szymon Janc

[permalink] [raw]
Subject: [PATCH v7 2/6] Add support for Out of Band (OOB) association model in mgmtops

---
lib/mgmt.h | 18 +++++++++
plugins/mgmtops.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 119 insertions(+), 3 deletions(-)

diff --git a/lib/mgmt.h b/lib/mgmt.h
index bd65328..3d29b24 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -179,6 +179,24 @@ struct mgmt_cp_set_local_name {
uint8_t name[249];
} __packed;

+#define MGMT_OP_READ_LOCAL_OOB_DATA 0x0018
+struct mgmt_rp_read_local_oob_data {
+ uint8_t hash[16];
+ uint8_t randomizer[16];
+} __packed;
+
+#define MGMT_OP_ADD_REMOTE_OOB_DATA 0x0019
+struct mgmt_cp_add_remote_oob_data {
+ bdaddr_t bdaddr;
+ uint8_t hash[16];
+ uint8_t randomizer[16];
+} __packed;
+
+#define MGMT_OP_REMOVE_REMOTE_OOB_DATA 0x001A
+struct mgmt_cp_remove_remote_oob_data {
+ bdaddr_t bdaddr;
+} __packed;
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
uint16_t opcode;
diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c
index 6bb033b..3aca861 100644
--- a/plugins/mgmtops.c
+++ b/plugins/mgmtops.c
@@ -47,6 +47,7 @@
#include "manager.h"
#include "device.h"
#include "event.h"
+#include "oob.h"

#define MGMT_BUF_SIZE 1024

@@ -1029,6 +1030,49 @@ static void set_local_name_complete(int sk, uint16_t index, void *buf,
adapter_update_local_name(adapter, (char *) rp->name);
}

+static void read_local_oob_data_complete(int sk, uint16_t index, void *buf,
+ size_t len)
+{
+ struct mgmt_rp_read_local_oob_data *rp = buf;
+ struct btd_adapter *adapter;
+
+ if (len != sizeof(*rp)) {
+ error("Wrong read_local_oob_data_complete event size");
+ return;
+ }
+
+ if (index > max_index) {
+ error("Unexpected index %u in read_local_oob_data_complete",
+ index);
+ return;
+ }
+
+ DBG("hci%u", index);
+
+ adapter = manager_find_adapter_by_id(index);
+
+ if (adapter)
+ oob_read_local_data_complete(adapter, rp->hash, rp->randomizer);
+}
+
+static void read_local_oob_data_failed(int sk, uint16_t index)
+{
+ struct btd_adapter *adapter;
+
+ if (index > max_index) {
+ error("Unexpected index %u in read_local_oob_data_failed",
+ index);
+ return;
+ }
+
+ DBG("hci%u", index);
+
+ adapter = manager_find_adapter_by_id(index);
+
+ if (adapter)
+ oob_read_local_data_complete(adapter, NULL, NULL);
+}
+
static void mgmt_cmd_complete(int sk, uint16_t index, void *buf, size_t len)
{
struct mgmt_ev_cmd_complete *ev = buf;
@@ -1113,6 +1157,15 @@ static void mgmt_cmd_complete(int sk, uint16_t index, void *buf, size_t len)
case MGMT_OP_SET_LOCAL_NAME:
set_local_name_complete(sk, index, ev->data, len);
break;
+ case MGMT_OP_READ_LOCAL_OOB_DATA:
+ read_local_oob_data_complete(sk, index, ev->data, len);
+ break;
+ case MGMT_OP_ADD_REMOTE_OOB_DATA:
+ DBG("add_remote_oob_data complete");
+ break;
+ case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
+ DBG("remove_remote_oob_data complete");
+ break;
default:
error("Unknown command complete for opcode %u", opcode);
break;
@@ -1132,6 +1185,12 @@ static void mgmt_cmd_status(int sk, uint16_t index, void *buf, size_t len)
opcode = btohs(bt_get_unaligned(&ev->opcode));

DBG("status %u opcode %u (index %u)", ev->status, opcode, index);
+
+ switch (opcode) {
+ case MGMT_OP_READ_LOCAL_OOB_DATA:
+ read_local_oob_data_failed(sk, index);
+ break;
+ }
}

static void mgmt_controller_error(int sk, uint16_t index, void *buf, size_t len)
@@ -1750,30 +1809,69 @@ static int mgmt_cancel_bonding(int index, bdaddr_t *bdaddr)

static int mgmt_read_local_oob_data(int index)
{
+ struct mgmt_hdr hdr;
+
DBG("hci%d", index);

- return -ENOSYS;
+ hdr.opcode = htobs(MGMT_OP_READ_LOCAL_OOB_DATA);
+ hdr.len = 0;
+ hdr.index = htobs(index);
+
+ if (write(mgmt_sock, &hdr, sizeof(hdr)) < 0)
+ return -errno;
+
+ return 0;
}

static int mgmt_add_remote_oob_data(int index, bdaddr_t *bdaddr,
uint8_t *hash, uint8_t *randomizer)
{
+ char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_add_remote_oob_data)];
+ struct mgmt_hdr *hdr = (void *) buf;
+ struct mgmt_cp_add_remote_oob_data *cp = (void *) &buf[sizeof(*hdr)];
char addr[18];

ba2str(bdaddr, addr);
DBG("hci%d bdaddr %s", index, addr);

- return -ENOSYS;
+ memset(buf, 0, sizeof(buf));
+
+ hdr->opcode = htobs(MGMT_OP_ADD_REMOTE_OOB_DATA);
+ hdr->index = htobs(index);
+ hdr->len = htobs(sizeof(*cp));
+
+ bacpy(&cp->bdaddr, bdaddr);
+ memcpy(cp->hash, hash, 16);
+ memcpy(cp->randomizer, randomizer, 16);
+
+ if (write(mgmt_sock, &buf, sizeof(buf)) < 0)
+ return -errno;
+
+ return 0;
}

static int mgmt_remove_remote_oob_data(int index, bdaddr_t *bdaddr)
{
+ char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_remove_remote_oob_data)];
+ struct mgmt_hdr *hdr = (void *) buf;
+ struct mgmt_cp_remove_remote_oob_data *cp = (void *) &buf[sizeof(*hdr)];
char addr[18];

ba2str(bdaddr, addr);
DBG("hci%d bdaddr %s", index, addr);

- return -ENOSYS;
+ memset(buf, 0, sizeof(buf));
+
+ hdr->opcode = htobs(MGMT_OP_REMOVE_REMOTE_OOB_DATA);
+ hdr->index = htobs(index);
+ hdr->len = htobs(sizeof(*cp));
+
+ bacpy(&cp->bdaddr, bdaddr);
+
+ if (write(mgmt_sock, &buf, sizeof(buf)) < 0)
+ return -errno;
+
+ return 0;
}

static struct btd_adapter_ops mgmt_ops = {
--
1.7.0.4