Skip to content
This repository has been archived by the owner on Jun 27, 2019. It is now read-only.

Commit

Permalink
sol-gatt: Update to the new BlueZ API
Browse files Browse the repository at this point in the history
Since commit "93b64d9ca8a2bb6 doc/gatt-api: Add options dictionary to
ReadValue/WriteValue" BlueZ passes a dictionary to its
ReadValue()/WriteValue() operations, informing the device which is
making the operation and the offset of the operation.

Signed-off-by: Vinicius Costa Gomes <[email protected]>
  • Loading branch information
vcgomes committed May 23, 2016
1 parent c76de29 commit f2a7f98
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 7 deletions.
30 changes: 28 additions & 2 deletions src/lib/comms/sol-bluetooth-impl-bluez.c
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,20 @@ remote_attr_read_reply(sd_bus_message *m, void *userdata, sd_bus_error *ret_erro
return r;
}

static int
append_empty_dict(sd_bus_message *m)
{
int r;

r = sd_bus_message_open_container(m, 'a', "{sv}");
SOL_INT_CHECK(r, < 0, r);

r = sd_bus_message_close_container(m);
SOL_INT_CHECK(r, < 0, r);

return r;
}

static int
remote_attr_read(struct sol_gatt_pending *op,
uint16_t offset)
Expand All @@ -947,15 +961,23 @@ remote_attr_read(struct sol_gatt_pending *op,
const char *service = sol_bus_client_get_service(ctx->bluez);
const struct sol_gatt_attr *attr = op->attr;
const char *interface, *path = attr->_priv;
sd_bus_message *m;
int r;

if (attr->type == SOL_GATT_ATTR_TYPE_DESCRIPTOR)
interface = "org.bluez.GattDescriptor1";
else
interface = "org.bluez.GattCharacteristic1";

r = sd_bus_call_method_async(bus, &op->slot, service, path,
interface, "ReadValue", remote_attr_read_reply, op, NULL);
r = sd_bus_message_new_method_call(bus, &m, service, path,
interface, "ReadValue");
SOL_INT_CHECK(r, < 0, r);

/* FIXME: add support for specifying the offset */
r = append_empty_dict(m);
SOL_INT_CHECK(r, < 0, r);

r = sd_bus_call_async(bus, &op->slot, m, remote_attr_read_reply, op, 0);
SOL_INT_CHECK(r, < 0, r);

return 0;
Expand Down Expand Up @@ -1002,6 +1024,10 @@ remote_attr_write(struct sol_gatt_pending *op,
r = sd_bus_message_append_array(m, 'y', buf->data, buf->used);
SOL_INT_CHECK_GOTO(r, < 0, done);

/* FIXME: add support for specifying the offset */
r = append_empty_dict(m);
SOL_INT_CHECK_GOTO(r, < 0, done);

r = sd_bus_call_async(bus, &op->slot, m, remote_attr_write_reply, op, 0);
SOL_INT_CHECK_GOTO(r, < 0, done);

Expand Down
80 changes: 75 additions & 5 deletions src/lib/comms/sol-gatt-impl-bluez.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <sol-bluetooth.h>
#include <sol-network.h>
#include <sol-util.h>
#include <sol-util-internal.h>
#include <sol-mainloop.h>
#include <sol-str-table.h>

Expand Down Expand Up @@ -192,15 +193,65 @@ sol_gatt_pending_reply(struct sol_gatt_pending *pending, int error,
return r;
}

static int
parse_operation_dict(sd_bus_message *m, uint16_t *offset, const char **path)
{
int r;

*offset = 0;
*path = NULL;

r = sd_bus_message_enter_container(m, 'a', "{sv}");
SOL_INT_CHECK(r, < 0, r);

do {
const char *member;

r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv");
if (r <= 0) {
r = 0;
break;
}

r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member);
SOL_INT_CHECK_GOTO(r, < 0, end);

if (streq(member, "offset")) {
r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "q");
SOL_INT_CHECK_GOTO(r, < 0, end);

r = sd_bus_message_read_basic(m, 'q', offset);
SOL_INT_CHECK_GOTO(r, < 0, end);

} else if (streq(member, "device")) {
r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "o");
SOL_INT_CHECK_GOTO(r, < 0, end);

r = sd_bus_message_read_basic(m, 'o', path);
SOL_INT_CHECK_GOTO(r, < 0, end);
} else {
r = sd_bus_message_skip(m, "v");
SOL_INT_CHECK_GOTO(r, < 0, end);
}
} while (1);

end:
return r;

}

static int
attr_method(enum pending_type type, sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
{
struct context *ctx = bluetooth_get_context();
struct sol_gatt_attr *attr = userdata;
sd_bus_message *reply = NULL;
struct sol_gatt_pending *pending;
const void *data;
size_t len;
struct sol_buffer buf;
uint16_t offset;
const char *path;
int r = -EINVAL;

if (sol_bus_log_callback(m, userdata, ret_error))
Expand All @@ -224,7 +275,18 @@ attr_method(enum pending_type type, sd_bus_message *m, void *userdata, sd_bus_er

switch (type) {
case PENDING_READ:
r = attr->read(pending, 0);
r = parse_operation_dict(m, &offset, &path);
SOL_INT_CHECK_GOTO(r, < 0, error_op);

/*
* FIXME: need to decide if this is an error if it fails. Right now,
* any BlueZ build earlier than commit:
* 93b64d9ca8a2bb6 doc/gatt-api: Add options dictionary to ReadValue/WriteValue
* would fail.
*/
pending->conn = get_conn_by_path(ctx, path);

r = attr->read(pending, offset);
SOL_INT_CHECK_GOTO(r, < 0, error_op);
break;
case PENDING_WRITE:
Expand All @@ -235,6 +297,14 @@ attr_method(enum pending_type type, sd_bus_message *m, void *userdata, sd_bus_er
SOL_BUFFER_FLAGS_MEMORY_NOT_OWNED | SOL_BUFFER_FLAGS_NO_NUL_BYTE);
buf.used = len;

r = parse_operation_dict(m, &offset, &path);
SOL_INT_CHECK_GOTO(r, < 0, error_op);

/*
* See note above.
*/
pending->conn = get_conn_by_path(ctx, path);

r = attr->write(pending, &buf, 0);
SOL_INT_CHECK_GOTO(r, < 0, error_op);
default:
Expand Down Expand Up @@ -502,9 +572,9 @@ static const sd_bus_vtable characteristic_vtable[] = {
SD_BUS_PROPERTY("Service", "o", chr_prop_get_service, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Value", "ay", cached_prop_value, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("Flags", "as", chr_prop_get_flags, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_METHOD("ReadValue", NULL, "ay",
SD_BUS_METHOD("ReadValue", "a{sv}", "ay",
attr_read_value, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("WriteValue", "ay", NULL,
SD_BUS_METHOD("WriteValue", "aya{sv}", NULL,
attr_write_value, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END,
};
Expand All @@ -516,9 +586,9 @@ static const sd_bus_vtable descriptor_vtable[] = {
desc_prop_get_characteristic, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Value", "ay", cached_prop_value, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("Flags", "as", desc_prop_get_flags, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_METHOD("ReadValue", NULL, "ay",
SD_BUS_METHOD("ReadValue", "a{sv}", "ay",
attr_read_value, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("WriteValue", "ay", NULL,
SD_BUS_METHOD("WriteValue", "aya{sv}", NULL,
attr_write_value, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END,
};
Expand Down

0 comments on commit f2a7f98

Please sign in to comment.