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 | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 183 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..ca0c635 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,13 @@ struct oob_request {
DBusMessage *msg;
};
+struct oob_remote_parameters {
+ bdaddr_t local;
+ bdaddr_t peer;
+ const char *address;
+ uint32_t class;
+};
+
static GSList *oob_requests = NULL;
static DBusConnection *connection = NULL;
@@ -153,6 +161,167 @@ 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,
+ ¶ms->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,
+ ¶ms->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, ¶ms->class);
+
+ return NULL;
+}
+
+static gboolean set_class(struct oob_remote_parameters *params)
+{
+ if (params->class == 0)
+ return FALSE;
+
+ if (write_remote_class(¶ms->local, ¶ms->peer,
+ params->class) < 0) {
+ error("Setting device class failed");
+
+ return FALSE;
+ }
+
+ return 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, DBusMessage *msg,
+ struct oob_remote_parameters *params)
+{
+ gboolean device_found = FALSE;
+
+ if (set_class(params))
+ device_found = TRUE;
+
+ if (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_get_basic(&iter_msg, &addr);
+ 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, ¶ms->local);
+ str2ba(addr, ¶ms->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, msg, 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 +346,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
On Mon, Aug 22, 2011 at 9:22 AM, Johan Hedberg <[email protected]> wrote:
> Hi Bartosz,
>
> On Fri, Aug 12, 2011, Bartosz Szatkowski wrote:
>> +struct oob_remote_parameters {
>> + bdaddr_t local;
>> + bdaddr_t peer;
>> + const char *address;
>> + uint32_t class;
>> +};
>
> Could you add a "gboolean device_found;" to this struct and then use it
> as follows:
OK
>
>> +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, ¶ms->class);
>
> params->device_found = TRUE;
I would move (above) line to set_class function (and same for other
patches) as there is no point of emiting device_found in case of some
error when trying to set it, it would look something like:
static void set_class(struct oob_remote_parameters *params)
+{
+ if (write_remote_class(¶ms->local, ¶ms->peer,
+ params->class) < 0) {
+ error("Setting device class failed");
+
+ return;
+ }
params->device_found = TRUE;
+}
--
Pozdrowienia,
Bartosz Szatkowski
Hi Bartosz,
On Fri, Aug 12, 2011, Bartosz Szatkowski wrote:
> +struct oob_remote_parameters {
> + bdaddr_t local;
> + bdaddr_t peer;
> + const char *address;
> + uint32_t class;
> +};
Could you add a "gboolean device_found;" to this struct and then use it
as follows:
> +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, ¶ms->class);
params->device_found = TRUE;
> + return NULL;
> +}
> +
> +static gboolean set_class(struct oob_remote_parameters *params)
> +{
> + if (params->class == 0)
> + return FALSE;
You can move the above if-statement here:
> +static void set_properties(struct btd_adapter *adapter,
> + struct oob_remote_parameters *params)
> +{
> + gboolean device_found = FALSE;
> +
> + if (set_class(params))
> + device_found = TRUE;
I.e. change this to:
if (params->class != 0)
write_remote_class(...);
I suppose you could keep the set_class function if you want, but since
all it does is make a single write_remote_class call you might as well
do the call directly as above.
> + if (device_found)
> + emit_device_found(adapter_get_path(adapter), params);
> +}
The above would become:
if (params->device_found)
emit_device_found(..., params);
With these changes the flow of logic becomes a bit easier to follow (to
me at least).
Johan
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 | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 181 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..cdf894a 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,13 @@ struct oob_request {
DBusMessage *msg;
};
+struct oob_remote_parameters {
+ bdaddr_t local;
+ bdaddr_t peer;
+ const char *address;
+ uint32_t class;
+};
+
static GSList *oob_requests = NULL;
static DBusConnection *connection = NULL;
@@ -153,6 +161,165 @@ 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,
+ ¶ms->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,
+ ¶ms->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, ¶ms->class);
+
+ return NULL;
+}
+
+static gboolean set_class(struct oob_remote_parameters *params)
+{
+ if (params->class == 0)
+ return FALSE;
+
+ if (write_remote_class(¶ms->local, ¶ms->peer,
+ params->class) < 0) {
+ error("Setting device class failed");
+
+ return FALSE;
+ }
+
+ return 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)
+{
+ gboolean device_found = FALSE;
+
+ if (set_class(params))
+ device_found = TRUE;
+
+ if (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, ¶ms->local);
+ str2ba(addr, ¶ms->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 +344,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
On Thu, Aug 11, 2011 at 6:51 PM, Vinicius Costa Gomes
<[email protected]> wrote:
> Hi Bartosz,
>
> On 13:14 Thu 11 Aug, Bartosz Szatkowski wrote:
>> 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 | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 183 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..ca0c635 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,13 @@ struct oob_request {
>> DBusMessage *msg;
>> };
>>
>> +struct oob_remote_parameters {
>> + bdaddr_t local;
>> + bdaddr_t peer;
>> + const char *address;
>> + uint32_t class;
>> +};
>> +
>> static GSList *oob_requests = NULL;
>> static DBusConnection *connection = NULL;
>>
>> @@ -153,6 +161,167 @@ 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,
>> + ¶ms->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,
>> + ¶ms->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, ¶ms->class);
>> +
>> + return NULL;
>> +}
>> +
>> +static gboolean set_class(struct oob_remote_parameters *params)
>> +{
>> + if (params->class == 0)
>> + return FALSE;
>> +
>> + if (write_remote_class(¶ms->local, ¶ms->peer,
>> + params->class) < 0) {
>> + error("Setting device class failed");
>> +
>> + return FALSE;
>> + }
>> +
>> + return 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, DBusMessage *msg,
>> + struct oob_remote_parameters *params)
>> +{
>
> Why is DBusMessage needed here?
>
>> + gboolean device_found = FALSE;
>> +
>> + if (set_class(params))
>> + device_found = TRUE;
>> +
>> + if (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_get_basic(&iter_msg, &addr);
>
> I may be missing something obvious here, but this loooks uneeded. You are
> doing the same thing you did a few lines above.
>
>> + 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, ¶ms->local);
>> + str2ba(addr, ¶ms->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, msg, 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 +346,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
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
> Cheers,
> --
> Vinicius
>
Of course you are right -- I've been moving this around a bit and must
lost it in the process.
Will fix it tomorrow. Thanks!
--
Pozdrowienia,
Bartosz Szatkowski
Hi Bartosz,
On 13:14 Thu 11 Aug, Bartosz Szatkowski wrote:
> 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 | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 183 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..ca0c635 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,13 @@ struct oob_request {
> DBusMessage *msg;
> };
>
> +struct oob_remote_parameters {
> + bdaddr_t local;
> + bdaddr_t peer;
> + const char *address;
> + uint32_t class;
> +};
> +
> static GSList *oob_requests = NULL;
> static DBusConnection *connection = NULL;
>
> @@ -153,6 +161,167 @@ 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,
> + ¶ms->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,
> + ¶ms->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, ¶ms->class);
> +
> + return NULL;
> +}
> +
> +static gboolean set_class(struct oob_remote_parameters *params)
> +{
> + if (params->class == 0)
> + return FALSE;
> +
> + if (write_remote_class(¶ms->local, ¶ms->peer,
> + params->class) < 0) {
> + error("Setting device class failed");
> +
> + return FALSE;
> + }
> +
> + return 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, DBusMessage *msg,
> + struct oob_remote_parameters *params)
> +{
Why is DBusMessage needed here?
> + gboolean device_found = FALSE;
> +
> + if (set_class(params))
> + device_found = TRUE;
> +
> + if (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_get_basic(&iter_msg, &addr);
I may be missing something obvious here, but this loooks uneeded. You are
doing the same thing you did a few lines above.
> + 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, ¶ms->local);
> + str2ba(addr, ¶ms->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, msg, 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 +346,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
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Cheers,
--
Vinicius
---
doc/oob-api.txt | 1 +
plugins/dbusoob.c | 37 +++++++++++++++++++++++++++++++++++++
src/storage.c | 2 +-
src/storage.h | 2 +-
4 files changed, 40 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 c6237f9..d83c982 100644
--- a/plugins/dbusoob.c
+++ b/plugins/dbusoob.c
@@ -59,6 +59,7 @@ struct oob_remote_parameters {
uint32_t class;
uint8_t *hash;
uint8_t *randomizer;
+ const char *name;
};
static GSList *oob_requests = NULL;
@@ -190,6 +191,10 @@ static void emit_device_found(const char *path,
dict_append_entry(&dict, "Class", DBUS_TYPE_UINT32,
¶ms->class);
+ if (params->name != NULL)
+ dict_append_entry(&dict, "Name", DBUS_TYPE_STRING,
+ ¶ms->name);
+
dbus_message_iter_close_container(&iter, &dict);
g_dbus_send_message(connection, signal);
@@ -263,6 +268,32 @@ static void set_oob_data(struct btd_adapter *adapter,
}
}
+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, ¶ms->name);
+
+ return NULL;
+}
+
+static gboolean set_name(struct oob_remote_parameters *params)
+{
+ if (params->name == NULL)
+ return FALSE;
+
+ if (write_device_name(¶ms->local, ¶ms->peer,
+ params->name) < 0) {
+ error("Setting device name failed");
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static DBusMessage *parse_property(const char *property,
DBusMessageIter *value, DBusMessage *msg,
struct oob_remote_parameters *params)
@@ -270,6 +301,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, ¶ms->hash, msg);
@@ -287,6 +321,9 @@ static void set_properties(struct btd_adapter *adapter, DBusMessage *msg,
if (set_class(params))
device_found = TRUE;
+ if (set_name(params))
+ device_found = TRUE;
+
set_oob_data(adapter, params);
if (device_found)
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
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 | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 56 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 ca0c635..c6237f9 100644
--- a/plugins/dbusoob.c
+++ b/plugins/dbusoob.c
@@ -57,6 +57,8 @@ struct oob_remote_parameters {
bdaddr_t peer;
const char *address;
uint32_t class;
+ uint8_t *hash;
+ uint8_t *randomizer;
};
static GSList *oob_requests = NULL;
@@ -219,6 +221,48 @@ static gboolean set_class(struct oob_remote_parameters *params)
return 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)
+ return;
+
+ if (parameters->hash == NULL || parameters->randomizer == NULL) {
+ error("OOB data incomplete");
+
+ return;
+ }
+
+ if (btd_adapter_add_remote_oob_data(adapter, ¶meters->peer,
+ parameters->hash, parameters->randomizer)) {
+ error("Adding remote OOB data failed");
+
+ return;
+ }
+}
+
static DBusMessage *parse_property(const char *property,
DBusMessageIter *value, DBusMessage *msg,
struct oob_remote_parameters *params)
@@ -226,6 +270,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, ¶ms->hash, msg);
+
+ if (g_str_equal("Randomizer", property))
+ return parse_oob_data(value, ¶ms->randomizer, msg);
+
return NULL;
}
@@ -237,6 +287,8 @@ static void set_properties(struct btd_adapter *adapter, DBusMessage *msg,
if (set_class(params))
device_found = TRUE;
+ set_oob_data(adapter, params);
+
if (device_found)
emit_device_found(adapter_get_path(adapter), params);
}
--
1.7.4.1