diff --git a/tools/gatt-service.c b/tools/gatt-service.c
index 329d1af..0c78c4d 100644
--- a/tools/gatt-service.c
+++ b/tools/gatt-service.c
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
+#include <string.h>
#include <sys/signalfd.h>
#include <glib.h>
return desc_read(desc, iter);
}
-static void desc_write(struct descriptor *desc, DBusMessageIter *iter)
+static void desc_write(struct descriptor *desc, const uint8_t *value, int len)
{
- DBusMessageIter array;
- const uint8_t *value;
- int vlen;
-
- dbus_message_iter_recurse(iter, &array);
- dbus_message_iter_get_fixed_array(&array, &value, &vlen);
-
g_free(desc->value);
- desc->value = g_memdup(value, vlen);
- desc->vlen = vlen;
+ desc->value = g_memdup(value, len);
+ desc->vlen = len;
g_dbus_emit_property_changed(connection, desc->path,
GATT_DESCRIPTOR_IFACE, "Value");
}
+static int parse_value(DBusMessageIter *iter, const uint8_t **value, int *len)
+{
+ DBusMessageIter array;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return -EINVAL;
+
+ dbus_message_iter_recurse(iter, &array);
+ dbus_message_iter_get_fixed_array(&array, value, len);
+
+ return 0;
+}
+
static void desc_set_value(const GDBusPropertyTable *property,
DBusMessageIter *iter,
GDBusPendingPropertySet id, void *user_data)
{
struct descriptor *desc = user_data;
+ const uint8_t *value;
+ int len;
printf("Descriptor(%s): Set(\"Value\", ...)\n", desc->uuid);
- desc_write(desc, iter);
+ if (parse_value(iter, &value, &len)) {
+ printf("Invalid value for Set('Value'...)\n");
+ g_dbus_pending_property_error(id,
+ ERROR_INTERFACE ".InvalidArguments",
+ "Invalid arguments in method call");
+ return;
+ }
+
+ desc_write(desc, value, len);
g_dbus_pending_property_success(id);
}
return TRUE;
}
-static void chr_write(struct characteristic *chr, DBusMessageIter *iter)
+static void chr_write(struct characteristic *chr, const uint8_t *value, int len)
{
- DBusMessageIter array;
- uint8_t *value;
- int len;
-
- dbus_message_iter_recurse(iter, &array);
- dbus_message_iter_get_fixed_array(&array, &value, &len);
-
g_free(chr->value);
chr->value = g_memdup(value, len);
chr->vlen = len;
GDBusPendingPropertySet id, void *user_data)
{
struct characteristic *chr = user_data;
+ const uint8_t *value;
+ int len;
printf("Characteristic(%s): Set('Value', ...)\n", chr->uuid);
- if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY) {
+ if (!parse_value(iter, &value, &len)) {
printf("Invalid value for Set('Value'...)\n");
g_dbus_pending_property_error(id,
ERROR_INTERFACE ".InvalidArguments",
return;
}
- chr_write(chr, iter);
+ chr_write(chr, value, len);
g_dbus_pending_property_success(id);
}
g_free(desc);
}
+static int parse_options(DBusMessageIter *iter, const char **device)
+{
+ DBusMessageIter dict;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return -EINVAL;
+
+ dbus_message_iter_recurse(iter, &dict);
+
+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+ const char *key;
+ DBusMessageIter value, entry;
+ int var;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &value);
+
+ var = dbus_message_iter_get_arg_type(&value);
+ if (strcasecmp(key, "device") == 0) {
+ if (var != DBUS_TYPE_OBJECT_PATH)
+ return -EINVAL;
+ dbus_message_iter_get_basic(&value, device);
+ printf("Device: %s\n", *device);
+ }
+ }
+
+ return 0;
+}
+
static DBusMessage *chr_read_value(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
struct characteristic *chr = user_data;
DBusMessage *reply;
DBusMessageIter iter;
+ const char *device;
+
+ if (!dbus_message_iter_init(msg, &iter))
+ return g_dbus_create_error(msg, DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments");
+
+ if (parse_options(&iter, &device))
+ return g_dbus_create_error(msg, DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments");
reply = dbus_message_new_method_return(msg);
if (!reply)
{
struct characteristic *chr = user_data;
DBusMessageIter iter;
+ const uint8_t *value;
+ int len;
+ const char *device;
dbus_message_iter_init(msg, &iter);
- chr_write(chr, &iter);
+ if (parse_value(&iter, &value, &len))
+ return g_dbus_create_error(msg, DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments");
+
+ if (parse_options(&iter, &device))
+ return g_dbus_create_error(msg, DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments");
+
+ chr_write(chr, value, len);
return dbus_message_new_method_return(msg);
}
}
static const GDBusMethodTable chr_methods[] = {
- { GDBUS_ASYNC_METHOD("ReadValue", NULL, GDBUS_ARGS({ "value", "ay" }),
- chr_read_value) },
- { GDBUS_ASYNC_METHOD("WriteValue", GDBUS_ARGS({ "value", "ay" }),
- NULL, chr_write_value) },
+ { GDBUS_ASYNC_METHOD("ReadValue", GDBUS_ARGS({ "options", "a{sv}" }),
+ GDBUS_ARGS({ "value", "ay" }),
+ chr_read_value) },
+ { GDBUS_ASYNC_METHOD("WriteValue", GDBUS_ARGS({ "value", "ay" },
+ { "options", "a{sv}" }),
+ NULL, chr_write_value) },
{ GDBUS_ASYNC_METHOD("StartNotify", NULL, NULL, chr_start_notify) },
{ GDBUS_METHOD("StopNotify", NULL, NULL, chr_stop_notify) },
{ }
struct descriptor *desc = user_data;
DBusMessage *reply;
DBusMessageIter iter;
+ const char *device;
+
+ if (!dbus_message_iter_init(msg, &iter))
+ return g_dbus_create_error(msg, DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments");
+
+ if (parse_options(&iter, &device))
+ return g_dbus_create_error(msg, DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments");
reply = dbus_message_new_method_return(msg);
if (!reply)
dbus_message_iter_init_append(reply, &iter);
+ if (parse_options(&iter, &device))
+ return g_dbus_create_error(msg, DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments");
+
desc_read(desc, &iter);
return reply;
{
struct descriptor *desc = user_data;
DBusMessageIter iter;
+ const char *device;
+ const uint8_t *value;
+ int len;
- dbus_message_iter_init(msg, &iter);
+ if (!dbus_message_iter_init(msg, &iter))
+ return g_dbus_create_error(msg, DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments");
+
+ if (parse_value(&iter, &value, &len))
+ return g_dbus_create_error(msg, DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments");
+
+ if (parse_options(&iter, &device))
+ return g_dbus_create_error(msg, DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments");
- desc_write(desc, &iter);
+ desc_write(desc, value, len);
return dbus_message_new_method_return(msg);
}
static const GDBusMethodTable desc_methods[] = {
- { GDBUS_ASYNC_METHOD("ReadValue", NULL, GDBUS_ARGS({ "value", "ay" }),
- desc_read_value) },
- { GDBUS_ASYNC_METHOD("WriteValue", GDBUS_ARGS({ "value", "ay" }),
- NULL,
- desc_write_value) },
+ { GDBUS_ASYNC_METHOD("ReadValue", GDBUS_ARGS({ "options", "a{sv}" }),
+ GDBUS_ARGS({ "value", "ay" }),
+ desc_read_value) },
+ { GDBUS_ASYNC_METHOD("WriteValue", GDBUS_ARGS({ "value", "ay" },
+ { "options", "a{sv}" }),
+ NULL, desc_write_value) },
{ }
};