2011-08-22 11:39:14

by Bartosz Szatkowski

[permalink] [raw]
Subject: [PATCH BlueZ v2 1/3] Add SetRemoteProperties method for OOB COD setting

Add method for suppling class of device through OOB mechanism, to be
available at pairing phase. At this point it may be presented to the
user, by agent, in confirmation request (or whatever).
---
doc/oob-api.txt | 13 ++++
plugins/dbusoob.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 177 insertions(+), 0 deletions(-)

diff --git a/doc/oob-api.txt b/doc/oob-api.txt
index d838712..0324758 100644
--- a/doc/oob-api.txt
+++ b/doc/oob-api.txt
@@ -36,3 +36,16 @@ Methods array{byte} hash, array{byte} randomizer ReadLocalData()

Possible errors: org.bluez.Error.Failed
org.bluez.Error.InvalidArguments
+
+ void SetRemoteProperties(string address, dict data)
+
+ This method set new properties for device with specified
+ address, to be used when device is created.
+ On success DeviceFound signal will be emitted.
+
+ Currently supported keys:
+
+ Class uint32
+
+ Possible errors: org.bluez.Error.Failed
+ org.bluez.Error.InvalidArguments
diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
index 2c03780..94aff72 100644
--- a/plugins/dbusoob.c
+++ b/plugins/dbusoob.c
@@ -43,6 +43,7 @@
#include "event.h"
#include "error.h"
#include "oob.h"
+#include "storage.h"

#define OOB_INTERFACE "org.bluez.OutOfBand"

@@ -51,6 +52,14 @@ struct oob_request {
DBusMessage *msg;
};

+struct oob_remote_parameters {
+ bdaddr_t local;
+ bdaddr_t peer;
+ const char *address;
+ uint32_t class;
+ gboolean device_found;
+};
+
static GSList *oob_requests = NULL;
static DBusConnection *connection = NULL;

@@ -153,6 +162,160 @@ static DBusMessage *add_remote_data(DBusConnection *conn, DBusMessage *msg,
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}

+static void emit_device_found(const char *path,
+ struct oob_remote_parameters *params)
+{
+ DBusMessage *signal;
+ DBusMessageIter iter, dict;
+
+ signal = dbus_message_new_signal(path, ADAPTER_INTERFACE,
+ "DeviceFound");
+ if (signal == NULL) {
+ error("Unable to allocate new %s.DeviceFound signal",
+ ADAPTER_INTERFACE);
+ return;
+ }
+
+ dbus_message_iter_init_append(signal, &iter);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
+ &params->address);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+ if (params->class != 0)
+ dict_append_entry(&dict, "Class", DBUS_TYPE_UINT32,
+ &params->class);
+
+ dbus_message_iter_close_container(&iter, &dict);
+
+ g_dbus_send_message(connection, signal);
+}
+
+static DBusMessage *parse_class(DBusMessageIter *value,
+ struct oob_remote_parameters *params, DBusMessage *msg)
+{
+ if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_UINT32)
+ return btd_error_invalid_args(msg);
+
+ dbus_message_iter_get_basic(value, &params->class);
+
+ return NULL;
+}
+
+static void set_class(struct oob_remote_parameters *params)
+{
+ if (write_remote_class(&params->local, &params->peer,
+ params->class) < 0) {
+ error("Setting device class failed");
+
+ return;
+ }
+
+ params->device_found = TRUE;
+}
+
+static DBusMessage *parse_property(const char *property,
+ DBusMessageIter *value, DBusMessage *msg,
+ struct oob_remote_parameters *params)
+{
+ if (g_str_equal("Class", property))
+ return parse_class(value, params, msg);
+
+ return NULL;
+}
+
+static void set_properties(struct btd_adapter *adapter,
+ struct oob_remote_parameters *params)
+{
+ if (params->class != 0)
+ set_class(params);
+
+ if (params->device_found)
+ emit_device_found(adapter_get_path(adapter), params);
+}
+
+static DBusMessage *set_remote_properties(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct btd_adapter *adapter = data;
+ DBusMessageIter iter_msg, iter_dict, iter_entry, iter_variant;
+ struct oob_remote_parameters *params;
+ char *addr;
+ DBusMessage *result;
+
+ if (!dbus_message_iter_init(msg, &iter_msg))
+ return btd_error_invalid_args(msg);
+
+ if (dbus_message_iter_get_arg_type(&iter_msg) != DBUS_TYPE_STRING)
+ return btd_error_invalid_args(msg);
+
+ dbus_message_iter_get_basic(&iter_msg, &addr);
+ if (bachk(addr))
+ return btd_error_invalid_args(msg);
+
+ dbus_message_iter_next(&iter_msg);
+
+ if (dbus_message_iter_get_arg_type(&iter_msg) != DBUS_TYPE_ARRAY)
+ return btd_error_invalid_args(msg);
+
+ params = g_new0(struct oob_remote_parameters, 1);
+
+ params->address = addr;
+ adapter_get_address(adapter, &params->local);
+ str2ba(addr, &params->peer);
+
+ dbus_message_iter_recurse(&iter_msg, &iter_dict);
+
+ for (; dbus_message_iter_get_arg_type(&iter_dict) != DBUS_TYPE_INVALID;
+ dbus_message_iter_next(&iter_dict)) {
+ char *property;
+
+ if (dbus_message_iter_get_arg_type(&iter_dict) !=
+ DBUS_TYPE_DICT_ENTRY) {
+ result = btd_error_invalid_args(msg);
+
+ goto done;
+ }
+
+ dbus_message_iter_recurse(&iter_dict, &iter_entry);
+
+ if (dbus_message_iter_get_arg_type(&iter_entry) !=
+ DBUS_TYPE_STRING) {
+ result = btd_error_invalid_args(msg);
+
+ goto done;
+ }
+
+ dbus_message_iter_get_basic(&iter_entry, &property);
+ dbus_message_iter_next(&iter_entry);
+
+ if (dbus_message_iter_get_arg_type(&iter_entry) !=
+ DBUS_TYPE_VARIANT) {
+ result = btd_error_invalid_args(msg);
+
+ goto done;
+ }
+
+ dbus_message_iter_recurse(&iter_entry, &iter_variant);
+
+ result = parse_property(property, &iter_variant, msg, params);
+ if (result != NULL)
+ goto done;
+ }
+
+ set_properties(adapter, params);
+
+ result = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+
+done:
+ g_free(params);
+
+ return result;
+}
+
static DBusMessage *remove_remote_data(DBusConnection *conn, DBusMessage *msg,
void *data)
{
@@ -177,6 +340,7 @@ static DBusMessage *remove_remote_data(DBusConnection *conn, DBusMessage *msg,

static GDBusMethodTable oob_methods[] = {
{"AddRemoteData", "sayay", "", add_remote_data},
+ {"SetRemoteProperties", "sa{sv}", "", set_remote_properties},
{"RemoveRemoteData", "s", "", remove_remote_data},
{"ReadLocalData", "", "ayay", read_local_data,
G_DBUS_METHOD_FLAG_ASYNC},
--
1.7.4.1



2011-08-22 11:39:16

by Bartosz Szatkowski

[permalink] [raw]
Subject: [PATCH BlueZ v2 3/3] Add support for name in OOB SetRemoteProperties

---
doc/oob-api.txt | 1 +
plugins/dbusoob.c | 34 ++++++++++++++++++++++++++++++++++
src/storage.c | 2 +-
src/storage.h | 2 +-
4 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/doc/oob-api.txt b/doc/oob-api.txt
index 500ef15..2d0d096 100644
--- a/doc/oob-api.txt
+++ b/doc/oob-api.txt
@@ -49,6 +49,7 @@ Methods array{byte} hash, array{byte} randomizer ReadLocalData()
Class uint32
Hash array{byte}
Randomizer array{byte}
+ Name String

Possible errors: org.bluez.Error.Failed
org.bluez.Error.InvalidArguments
diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
index bbe1b1f..9b38fbe 100644
--- a/plugins/dbusoob.c
+++ b/plugins/dbusoob.c
@@ -60,6 +60,7 @@ struct oob_remote_parameters {
gboolean device_found;
uint8_t *hash;
uint8_t *randomizer;
+ const char *name;
};

static GSList *oob_requests = NULL;
@@ -191,6 +192,10 @@ static void emit_device_found(const char *path,
dict_append_entry(&dict, "Class", DBUS_TYPE_UINT32,
&params->class);

+ if (params->name != NULL)
+ dict_append_entry(&dict, "Name", DBUS_TYPE_STRING,
+ &params->name);
+
dbus_message_iter_close_container(&iter, &dict);

g_dbus_send_message(connection, signal);
@@ -255,6 +260,29 @@ static void set_oob_data(struct btd_adapter *adapter,
error("Adding remote OOB data failed");
}

+static DBusMessage *parse_name(DBusMessageIter *value,
+ struct oob_remote_parameters *params, DBusMessage *msg)
+{
+ if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_STRING)
+ return btd_error_invalid_args(msg);
+
+ dbus_message_iter_get_basic(value, &params->name);
+
+ return NULL;
+}
+
+static void set_name(struct oob_remote_parameters *params)
+{
+ if (write_device_name(&params->local, &params->peer,
+ params->name) < 0) {
+ error("Setting device name failed");
+
+ return;
+ }
+
+ params->device_found = TRUE;
+}
+
static DBusMessage *parse_property(const char *property,
DBusMessageIter *value, DBusMessage *msg,
struct oob_remote_parameters *params)
@@ -262,6 +290,9 @@ static DBusMessage *parse_property(const char *property,
if (g_str_equal("Class", property))
return parse_class(value, params, msg);

+ if (g_str_equal("Name", property))
+ return parse_name(value, params, msg);
+
if (g_str_equal("Hash", property))
return parse_oob_data(value, &params->hash, msg);

@@ -277,6 +308,9 @@ static void set_properties(struct btd_adapter *adapter,
if (params->class != 0)
set_class(params);

+ if (params->name != NULL)
+ set_name(params);
+
if (parameters->hash != NULL && parameters->randomizer != NULL)
set_oob_data(adapter, params);

diff --git a/src/storage.c b/src/storage.c
index 1f3da6e..414d158 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -321,7 +321,7 @@ int read_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t *class)
return 0;
}

-int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name)
+int write_device_name(bdaddr_t *local, bdaddr_t *peer, const char *name)
{
char filename[PATH_MAX + 1], addr[18], str[249];
int i;
diff --git a/src/storage.h b/src/storage.h
index bb64727..78513ac 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -38,7 +38,7 @@ int write_local_class(bdaddr_t *bdaddr, uint8_t *class);
int read_local_class(bdaddr_t *bdaddr, uint8_t *class);
int write_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t class);
int read_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t *class);
-int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name);
+int write_device_name(bdaddr_t *local, bdaddr_t *peer, const char *name);
int read_device_name(const char *src, const char *dst, char *name);
int write_remote_eir(bdaddr_t *local, bdaddr_t *peer, uint8_t *data);
int read_remote_eir(bdaddr_t *local, bdaddr_t *peer, uint8_t *data);
--
1.7.4.1


2011-08-22 11:39:15

by Bartosz Szatkowski

[permalink] [raw]
Subject: [PATCH BlueZ v2 2/3] Add support for OOB data in SetRemoteProperties

Now its possible to exchange OOB simple pairing data through DBus API
method with other device properties.
---
doc/oob-api.txt | 5 ++++-
plugins/dbusoob.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+), 1 deletions(-)

diff --git a/doc/oob-api.txt b/doc/oob-api.txt
index 0324758..500ef15 100644
--- a/doc/oob-api.txt
+++ b/doc/oob-api.txt
@@ -41,11 +41,14 @@ Methods array{byte} hash, array{byte} randomizer ReadLocalData()

This method set new properties for device with specified
address, to be used when device is created.
- On success DeviceFound signal will be emitted.
+ On success DeviceFound signal will be emitted (except
+ situations when only hash and randomizer is supplied).

Currently supported keys:

Class uint32
+ Hash array{byte}
+ Randomizer array{byte}

Possible errors: org.bluez.Error.Failed
org.bluez.Error.InvalidArguments
diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
index 94aff72..bbe1b1f 100644
--- a/plugins/dbusoob.c
+++ b/plugins/dbusoob.c
@@ -58,6 +58,8 @@ struct oob_remote_parameters {
const char *address;
uint32_t class;
gboolean device_found;
+ uint8_t *hash;
+ uint8_t *randomizer;
};

static GSList *oob_requests = NULL;
@@ -217,6 +219,42 @@ static void set_class(struct oob_remote_parameters *params)
params->device_found = TRUE;
}

+static DBusMessage *parse_oob_data(DBusMessageIter *value, uint8_t **data,
+ DBusMessage *msg)
+{
+ DBusMessageIter array_iter;
+ int32_t len;
+ uint8_t *tmp;
+
+ if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_ARRAY)
+ return btd_error_invalid_args(msg);
+
+ dbus_message_iter_recurse(value, &array_iter);
+
+ dbus_message_iter_get_fixed_array(&array_iter, &tmp, &len);
+
+ if (len != 16)
+ return btd_error_invalid_args(msg);
+
+ *data = tmp;
+
+ return NULL;
+}
+
+static void set_oob_data(struct btd_adapter *adapter,
+ struct oob_remote_parameters *parameters)
+{
+ if (parameters->hash == NULL || parameters->randomizer == NULL) {
+ error("OOB data incomplete");
+
+ return;
+ }
+
+ if (btd_adapter_add_remote_oob_data(adapter, &parameters->peer,
+ parameters->hash, parameters->randomizer))
+ error("Adding remote OOB data failed");
+}
+
static DBusMessage *parse_property(const char *property,
DBusMessageIter *value, DBusMessage *msg,
struct oob_remote_parameters *params)
@@ -224,6 +262,12 @@ static DBusMessage *parse_property(const char *property,
if (g_str_equal("Class", property))
return parse_class(value, params, msg);

+ if (g_str_equal("Hash", property))
+ return parse_oob_data(value, &params->hash, msg);
+
+ if (g_str_equal("Randomizer", property))
+ return parse_oob_data(value, &params->randomizer, msg);
+
return NULL;
}

@@ -233,6 +277,9 @@ static void set_properties(struct btd_adapter *adapter,
if (params->class != 0)
set_class(params);

+ if (parameters->hash != NULL && parameters->randomizer != NULL)
+ set_oob_data(adapter, params);
+
if (params->device_found)
emit_device_found(adapter_get_path(adapter), params);
}
--
1.7.4.1