2016-05-17 21:16:52

by Puthikorn Voravootivat

[permalink] [raw]
Subject: Re: [PATCHv2 BlueZ 1/6] doc/gatt-api: Add options dictionary to ReadValue/WriteValue

*resend in plain text

Hi.
I found a possible bug below. Comment in line.
Thanks

On Mon, May 9, 2016 at 6:51 AM, Luiz Augusto von Dentz
<[email protected]> wrote:
>
> From: Luiz Augusto von Dentz <[email protected]>
>
> This adds the possibility to pass an offset to these operations, and
> also in the server case to give the device object.
> ---
> v2: Fix Vinicius comments, add necessary changes to other tools affected.
>
> doc/gatt-api.txt | 20 ++++-
> src/gatt-client.c | 180 ++++++++++++++++++++++++++++--------------
> src/gatt-database.c | 219 ++++++++++++++++++++++++++++++++++++++--------------
> 3 files changed, 296 insertions(+), 123 deletions(-)
>
> diff --git a/doc/gatt-api.txt b/doc/gatt-api.txt
> index ad2ab16..683b1b7 100644
> --- a/doc/gatt-api.txt
> +++ b/doc/gatt-api.txt
> @@ -61,23 +61,29 @@ Service org.bluez
> Interface org.bluez.GattCharacteristic1 [Experimental]
> Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY
>
> -Methods array{byte} ReadValue()
> +Methods array{byte} ReadValue(dict options)
>
> Issues a request to read the value of the
> characteristic and returns the value if the
> operation was successful.
>
> + Possible options: "offset": uint16 offset
> + "device": Object Device (Server only)
> +
> Possible Errors: org.bluez.Error.Failed
> org.bluez.Error.InProgress
> org.bluez.Error.NotPermitted
> org.bluez.Error.NotAuthorized
> org.bluez.Error.NotSupported
>
> - void WriteValue(array{byte} value)
> + void WriteValue(array{byte} value, dict options)
>
> Issues a request to write the value of the
> characteristic.
>
> + Possible options: "offset": Start offset
> + "device": Device path (Server only)
> +
> Possible Errors: org.bluez.Error.Failed
> org.bluez.Error.InProgress
> org.bluez.Error.NotPermitted
> @@ -154,23 +160,29 @@ Service org.bluez
> Interface org.bluez.GattDescriptor1 [Experimental]
> Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ
>
> -Methods array{byte} ReadValue()
> +Methods array{byte} ReadValue(dict flags)
>
> Issues a request to read the value of the
> characteristic and returns the value if the
> operation was successful.
>
> + Possible options: "offset": Start offset
> + "device": Device path (Server only)
> +
> Possible Errors: org.bluez.Error.Failed
> org.bluez.Error.InProgress
> org.bluez.Error.NotPermitted
> org.bluez.Error.NotAuthorized
> org.bluez.Error.NotSupported
>
> - void WriteValue(array{byte} value)
> + void WriteValue(array{byte} value, dict flags)
>
> Issues a request to write the value of the
> characteristic.
>
> + Possible options: "offset": Start offset
> + "device": Device path (Server only)
> +
> Possible Errors: org.bluez.Error.Failed
> org.bluez.Error.InProgress
> org.bluez.Error.NotPermitted
> diff --git a/src/gatt-client.c b/src/gatt-client.c
> index 16a1f6c..0cbacca 100644
> --- a/src/gatt-client.c
> +++ b/src/gatt-client.c
> @@ -23,6 +23,7 @@
>
> #include <stdbool.h>
> #include <stdint.h>
> +#include <errno.h>
>
> #include <dbus/dbus.h>
>
> @@ -191,33 +192,17 @@ static gboolean descriptor_value_exists(const GDBusPropertyTable *property,
> return ret;
> }
>
> -static bool parse_value_arg(DBusMessage *msg, uint8_t **value,
> - size_t *value_len)
> +static int parse_value_arg(DBusMessageIter *iter, uint8_t **value, int *len)
> {
> - DBusMessageIter iter, array;
> - uint8_t *val;
> - int len;
> -
> - if (!dbus_message_iter_init(msg, &iter))
> - return false;
> -
> - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
> - return false;
> -
> - dbus_message_iter_recurse(&iter, &array);
> - dbus_message_iter_get_fixed_array(&array, &val, &len);
> - dbus_message_iter_next(&iter);
> -
> - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID)
> - return false;
> + DBusMessageIter array;
>
> - if (len < 0)
> - return false;
> + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
> + return -EINVAL;
>
> - *value = val;
> - *value_len = len;
> + dbus_message_iter_recurse(iter, &array);
> + dbus_message_iter_get_fixed_array(&array, value, len);
>
> - return true;
> + return 0;
> }
>
> typedef bool (*async_dbus_op_complete_t)(void *data);
> @@ -390,12 +375,60 @@ fail:
> return;
> }
>
> +static int parse_options(DBusMessageIter *iter, uint16_t *offset)
> +{
> + 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, "offset") == 0) {
> + if (var != DBUS_TYPE_UINT16)
> + return -EINVAL;
> + dbus_message_iter_get_basic(&value, offset);
> + }

Add dbus_message_iter_next(&dict); here?
>
> + }
> +
> + return 0;
> +}
> +
> +static unsigned int read_value(struct bt_gatt_client *gatt, uint16_t handle,
> + bt_gatt_client_read_callback_t callback,
> + struct async_dbus_op *op)
> +{
> + if (op->offset)
> + return bt_gatt_client_read_long_value(gatt, handle, op->offset,
> + callback,
> + async_dbus_op_ref(op),
> + async_dbus_op_unref);
> + else
> + return bt_gatt_client_read_value(gatt, handle, callback,
> + async_dbus_op_ref(op),
> + async_dbus_op_unref);
> +}
> +
> static DBusMessage *descriptor_read_value(DBusConnection *conn,
> DBusMessage *msg, void *user_data)
> {
> struct descriptor *desc = user_data;
> struct bt_gatt_client *gatt = desc->chrc->service->client->gatt;
> + DBusMessageIter iter;
> struct async_dbus_op *op;
> + uint16_t offset = 0;
>
> if (!gatt)
> return btd_error_failed(msg, "Not connected");
> @@ -403,14 +436,17 @@ static DBusMessage *descriptor_read_value(DBusConnection *conn,
> if (desc->read_id)
> return btd_error_in_progress(msg);
>
> + dbus_message_iter_init(msg, &iter);
> +
> + if (parse_options(&iter, &offset))
> + return btd_error_invalid_args(msg);
> +
> op = new0(struct async_dbus_op, 1);
> op->msg = dbus_message_ref(msg);
> op->data = desc;
> + op->offset = offset;
>
> - desc->read_id = bt_gatt_client_read_value(gatt, desc->handle,
> - desc_read_cb,
> - async_dbus_op_ref(op),
> - async_dbus_op_unref);
> + desc->read_id = read_value(gatt, desc->handle, desc_read_cb, op);
> if (desc->read_id)
> return NULL;
>
> @@ -450,7 +486,6 @@ done:
> g_dbus_send_message(btd_get_dbus_connection(), reply);
> }
>
> -
> static void write_cb(bool success, uint8_t att_ecode, void *user_data)
> {
> write_result_cb(success, false, att_ecode, user_data);
> @@ -459,7 +494,8 @@ static void write_cb(bool success, uint8_t att_ecode, void *user_data)
> static unsigned int start_long_write(DBusMessage *msg, uint16_t handle,
> struct bt_gatt_client *gatt,
> bool reliable, const uint8_t *value,
> - size_t value_len, void *data,
> + size_t value_len, uint16_t offset,
> + void *data,
> async_dbus_op_complete_t complete)
> {
> struct async_dbus_op *op;
> @@ -469,9 +505,10 @@ static unsigned int start_long_write(DBusMessage *msg, uint16_t handle,
> op->msg = dbus_message_ref(msg);
> op->data = data;
> op->complete = complete;
> + op->offset = offset;
>
> - id = bt_gatt_client_write_long_value(gatt, reliable, handle,
> - 0, value, value_len,
> + id = bt_gatt_client_write_long_value(gatt, reliable, handle, offset,
> + value, value_len,
> write_result_cb, op,
> async_dbus_op_free);
>
> @@ -522,8 +559,10 @@ static DBusMessage *descriptor_write_value(DBusConnection *conn,
> {
> struct descriptor *desc = user_data;
> struct bt_gatt_client *gatt = desc->chrc->service->client->gatt;
> + DBusMessageIter iter;
> uint8_t *value = NULL;
> - size_t value_len = 0;
> + int value_len = 0;
> + uint16_t offset = 0;
>
> if (!gatt)
> return btd_error_failed(msg, "Not connected");
> @@ -531,7 +570,12 @@ static DBusMessage *descriptor_write_value(DBusConnection *conn,
> if (desc->write_id)
> return btd_error_in_progress(msg);
>
> - if (!parse_value_arg(msg, &value, &value_len))
> + dbus_message_iter_init(msg, &iter);
> +
> + if (parse_value_arg(&iter, &value, &value_len))
> + return btd_error_invalid_args(msg);
> +
> + if (parse_options(&iter, &offset))
> return btd_error_invalid_args(msg);
>
> /*
> @@ -546,15 +590,15 @@ static DBusMessage *descriptor_write_value(DBusConnection *conn,
> * Based on the value length and the MTU, either use a write or a long
> * write.
> */
> - if (value_len <= (unsigned) bt_gatt_client_get_mtu(gatt) - 3)
> + if (value_len <= bt_gatt_client_get_mtu(gatt) - 3 && !offset)
> desc->write_id = start_write_request(msg, desc->handle,
> gatt, value,
> value_len, desc,
> desc_write_complete);
> else
> - desc->write_id = start_long_write(msg, desc->handle,
> - gatt, false, value,
> - value_len, desc,
> + desc->write_id = start_long_write(msg, desc->handle, gatt,
> + false, value,
> + value_len, offset, desc,
> desc_write_complete);
>
> if (!desc->write_id)
> @@ -574,13 +618,15 @@ static const GDBusPropertyTable descriptor_properties[] = {
> };
>
> static const GDBusMethodTable descriptor_methods[] = {
> - { GDBUS_EXPERIMENTAL_ASYNC_METHOD("ReadValue", NULL,
> - GDBUS_ARGS({ "value", "ay" }),
> - descriptor_read_value) },
> + { GDBUS_EXPERIMENTAL_ASYNC_METHOD("ReadValue",
> + GDBUS_ARGS({ "options", "a{sv}" }),
> + GDBUS_ARGS({ "value", "ay" }),
> + descriptor_read_value) },
> { GDBUS_EXPERIMENTAL_ASYNC_METHOD("WriteValue",
> - GDBUS_ARGS({ "value", "ay" }),
> - NULL,
> - descriptor_write_value) },
> + GDBUS_ARGS({ "value", "ay" },
> + { "options", "a{sv}" }),
> + NULL,
> + descriptor_write_value) },
> { }
> };
>
> @@ -837,7 +883,9 @@ static DBusMessage *characteristic_read_value(DBusConnection *conn,
> {
> struct characteristic *chrc = user_data;
> struct bt_gatt_client *gatt = chrc->service->client->gatt;
> + DBusMessageIter iter;
> struct async_dbus_op *op;
> + uint16_t offset = 0;
>
> if (!gatt)
> return btd_error_failed(msg, "Not connected");
> @@ -845,14 +893,17 @@ static DBusMessage *characteristic_read_value(DBusConnection *conn,
> if (chrc->read_id)
> return btd_error_in_progress(msg);
>
> + dbus_message_iter_init(msg, &iter);
> +
> + if (parse_options(&iter, &offset))
> + return btd_error_invalid_args(msg);
> +
> op = new0(struct async_dbus_op, 1);
> op->msg = dbus_message_ref(msg);
> op->data = chrc;
> + op->offset = offset;
>
> - chrc->read_id = bt_gatt_client_read_value(gatt, chrc->value_handle,
> - chrc_read_cb,
> - async_dbus_op_ref(op),
> - async_dbus_op_unref);
> + chrc->read_id = read_value(gatt, chrc->value_handle, chrc_read_cb, op);
> if (chrc->read_id)
> return NULL;
>
> @@ -879,9 +930,11 @@ static DBusMessage *characteristic_write_value(DBusConnection *conn,
> {
> struct characteristic *chrc = user_data;
> struct bt_gatt_client *gatt = chrc->service->client->gatt;
> + DBusMessageIter iter;
> uint8_t *value = NULL;
> - size_t value_len = 0;
> + int value_len = 0;
> bool supported = false;
> + uint16_t offset = 0;
>
> if (!gatt)
> return btd_error_failed(msg, "Not connected");
> @@ -889,7 +942,12 @@ static DBusMessage *characteristic_write_value(DBusConnection *conn,
> if (chrc->write_id)
> return btd_error_in_progress(msg);
>
> - if (!parse_value_arg(msg, &value, &value_len))
> + dbus_message_iter_init(msg, &iter);
> +
> + if (parse_value_arg(&iter, &value, &value_len))
> + return btd_error_invalid_args(msg);
> +
> + if (parse_options(&iter, &offset))
> return btd_error_invalid_args(msg);
>
> /*
> @@ -906,7 +964,7 @@ static DBusMessage *characteristic_write_value(DBusConnection *conn,
> if ((chrc->ext_props & BT_GATT_CHRC_EXT_PROP_RELIABLE_WRITE)) {
> supported = true;
> chrc->write_id = start_long_write(msg, chrc->value_handle, gatt,
> - true, value, value_len,
> + true, value, value_len, offset,
> chrc, chrc_write_complete);
> if (chrc->write_id)
> return NULL;
> @@ -920,7 +978,7 @@ static DBusMessage *characteristic_write_value(DBusConnection *conn,
> if (!mtu)
> return btd_error_failed(msg, "No ATT transport");
>
> - if (value_len <= (unsigned) mtu - 3)
> + if (value_len <= mtu - 3 && !offset)
> chrc->write_id = start_write_request(msg,
> chrc->value_handle,
> gatt, value, value_len,
> @@ -928,7 +986,7 @@ static DBusMessage *characteristic_write_value(DBusConnection *conn,
> else
> chrc->write_id = start_long_write(msg,
> chrc->value_handle, gatt,
> - false, value, value_len,
> + false, value, value_len, offset,
> chrc, chrc_write_complete);
>
> if (chrc->write_id)
> @@ -1242,17 +1300,19 @@ static const GDBusPropertyTable characteristic_properties[] = {
> };
>
> static const GDBusMethodTable characteristic_methods[] = {
> - { GDBUS_EXPERIMENTAL_ASYNC_METHOD("ReadValue", NULL,
> - GDBUS_ARGS({ "value", "ay" }),
> - characteristic_read_value) },
> + { GDBUS_EXPERIMENTAL_ASYNC_METHOD("ReadValue",
> + GDBUS_ARGS({ "options", "a{sv}" }),
> + GDBUS_ARGS({ "value", "ay" }),
> + characteristic_read_value) },
> { GDBUS_EXPERIMENTAL_ASYNC_METHOD("WriteValue",
> - GDBUS_ARGS({ "value", "ay" }),
> - NULL,
> - characteristic_write_value) },
> + GDBUS_ARGS({ "value", "ay" },
> + { "options", "a{sv}" }),
> + NULL,
> + characteristic_write_value) },
> { GDBUS_EXPERIMENTAL_ASYNC_METHOD("StartNotify", NULL, NULL,
> - characteristic_start_notify) },
> + characteristic_start_notify) },
> { GDBUS_EXPERIMENTAL_METHOD("StopNotify", NULL, NULL,
> - characteristic_stop_notify) },
> + characteristic_stop_notify) },
> { }
> };
>
> diff --git a/src/gatt-database.c b/src/gatt-database.c
> index b8da955..99d084d 100644
> --- a/src/gatt-database.c
> +++ b/src/gatt-database.c
> @@ -135,6 +135,7 @@ struct external_desc {
> };
>
> struct pending_op {
> + struct btd_device *device;
> unsigned int id;
> struct gatt_db_attribute *attrib;
> struct queue *owner_queue;
> @@ -1592,7 +1593,8 @@ static void pending_op_free(void *data)
> free(op);
> }
>
> -static struct pending_op *pending_read_new(struct queue *owner_queue,
> +static struct pending_op *pending_read_new(struct btd_device *device,
> + struct queue *owner_queue,
> struct gatt_db_attribute *attrib,
> unsigned int id)
> {
> @@ -1601,6 +1603,7 @@ static struct pending_op *pending_read_new(struct queue *owner_queue,
> op = new0(struct pending_op, 1);
>
> op->owner_queue = owner_queue;
> + op->device = device;
> op->attrib = attrib;
> op->id = id;
> queue_push_tail(owner_queue, op);
> @@ -1608,33 +1611,75 @@ static struct pending_op *pending_read_new(struct queue *owner_queue,
> return op;
> }
>
> -static void send_read(struct gatt_db_attribute *attrib, GDBusProxy *proxy,
> - struct queue *owner_queue,
> - unsigned int id)
> +static void append_options(DBusMessageIter *iter, void *user_data)
> +{
> + struct pending_op *op = user_data;
> + const char *path = device_get_path(op->device);
> +
> + dict_append_entry(iter, "device", DBUS_TYPE_OBJECT_PATH, &path);
> +}
> +
> +static void read_setup_cb(DBusMessageIter *iter, void *user_data)
> +{
> + struct pending_op *op = user_data;
> + DBusMessageIter dict;
> +
> + 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);
> +
> + append_options(&dict, op);
> +
> + dbus_message_iter_close_container(iter, &dict);
> +}
> +
> +static struct pending_op *send_read(struct btd_device *device,
> + struct gatt_db_attribute *attrib,
> + GDBusProxy *proxy,
> + struct queue *owner_queue,
> + unsigned int id)
> {
> struct pending_op *op;
> - uint8_t ecode = BT_ATT_ERROR_UNLIKELY;
>
> - op = pending_read_new(owner_queue, attrib, id);
> + op = pending_read_new(device, owner_queue, attrib, id);
>
> - if (g_dbus_proxy_method_call(proxy, "ReadValue", NULL, read_reply_cb,
> - op, pending_op_free) == TRUE)
> - return;
> + if (g_dbus_proxy_method_call(proxy, "ReadValue", read_setup_cb,
> + read_reply_cb, op, pending_op_free) == TRUE)
> + return op;
>
> pending_op_free(op);
>
> - gatt_db_attribute_read_result(attrib, id, ecode, NULL, 0);
> + return NULL;
> }
>
> static void write_setup_cb(DBusMessageIter *iter, void *user_data)
> {
> struct pending_op *op = user_data;
> - DBusMessageIter array;
> + DBusMessageIter array, dict;
>
> dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "y", &array);
> dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
> &op->data.iov_base, op->data.iov_len);
> dbus_message_iter_close_container(iter, &array);
> +
> + 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);
> +
> + append_options(&dict, op);
> +
> + dbus_message_iter_close_container(iter, &dict);
> +
> + if (!op->owner_queue) {
> + gatt_db_attribute_write_result(op->attrib, op->id, 0);
> + pending_op_free(op);
> + }
> }
>
> static void write_reply_cb(DBusMessage *message, void *user_data)
> @@ -1673,7 +1718,8 @@ done:
> gatt_db_attribute_write_result(op->attrib, op->id, ecode);
> }
>
> -static struct pending_op *pending_write_new(struct queue *owner_queue,
> +static struct pending_op *pending_write_new(struct btd_device *device,
> + struct queue *owner_queue,
> struct gatt_db_attribute *attrib,
> unsigned int id,
> const uint8_t *value,
> @@ -1686,6 +1732,7 @@ static struct pending_op *pending_write_new(struct queue *owner_queue,
> op->data.iov_base = (uint8_t *) value;
> op->data.iov_len = len;
>
> + op->device = device;
> op->owner_queue = owner_queue;
> op->attrib = attrib;
> op->id = id;
> @@ -1694,24 +1741,25 @@ static struct pending_op *pending_write_new(struct queue *owner_queue,
> return op;
> }
>
> -static void send_write(struct gatt_db_attribute *attrib, GDBusProxy *proxy,
> +static struct pending_op *send_write(struct btd_device *device,
> + struct gatt_db_attribute *attrib,
> + GDBusProxy *proxy,
> struct queue *owner_queue,
> unsigned int id,
> const uint8_t *value, size_t len)
> {
> struct pending_op *op;
> - uint8_t ecode = BT_ATT_ERROR_UNLIKELY;
>
> - op = pending_write_new(owner_queue, attrib, id, value, len);
> + op = pending_write_new(device, owner_queue, attrib, id, value, len);
>
> if (g_dbus_proxy_method_call(proxy, "WriteValue", write_setup_cb,
> - write_reply_cb, op,
> - pending_op_free) == TRUE)
> - return;
> + owner_queue ? write_reply_cb : NULL,
> + op, pending_op_free) == TRUE)
> + return op;
>
> pending_op_free(op);
>
> - gatt_db_attribute_write_result(attrib, id, ecode);
> + return NULL;
> }
>
> static uint32_t permissions_from_props(uint8_t props, uint8_t ext_props)
> @@ -1895,19 +1943,65 @@ static bool database_add_cep(struct external_service *service,
> return true;
> }
>
> +static struct btd_device *att_get_device(struct bt_att *att)
> +{
> + GIOChannel *io = NULL;
> + GError *gerr = NULL;
> + bdaddr_t src, dst;
> + uint8_t dst_type;
> + struct btd_adapter *adapter;
> +
> + io = g_io_channel_unix_new(bt_att_get_fd(att));
> + if (!io)
> + return NULL;
> +
> + bt_io_get(io, &gerr, BT_IO_OPT_SOURCE_BDADDR, &src,
> + BT_IO_OPT_DEST_BDADDR, &dst,
> + BT_IO_OPT_DEST_TYPE, &dst_type,
> + BT_IO_OPT_INVALID);
> + if (gerr) {
> + error("bt_io_get: %s", gerr->message);
> + g_error_free(gerr);
> + g_io_channel_unref(io);
> + return NULL;
> + }
> +
> + g_io_channel_unref(io);
> +
> + adapter = adapter_find(&src);
> + if (!adapter) {
> + error("Unable to find adapter object");
> + return NULL;
> + }
> +
> + return btd_adapter_find_device(adapter, &dst, dst_type);
> +}
> +
> static void desc_read_cb(struct gatt_db_attribute *attrib,
> unsigned int id, uint16_t offset,
> uint8_t opcode, struct bt_att *att,
> void *user_data)
> {
> struct external_desc *desc = user_data;
> + struct btd_device *device;
>
> if (desc->attrib != attrib) {
> error("Read callback called with incorrect attribute");
> - return;
> + goto fail;
> }
>
> - send_read(attrib, desc->proxy, desc->pending_reads, id);
> + device = att_get_device(att);
> + if (!device) {
> + error("Unable to find device object");
> + goto fail;
> + }
> +
> + if (send_read(device, attrib, desc->proxy, desc->pending_reads, id))
> + return;
> +
> +fail:
> + gatt_db_attribute_read_result(attrib, id, BT_ATT_ERROR_UNLIKELY,
> + NULL, 0);
> }
>
> static void desc_write_cb(struct gatt_db_attribute *attrib,
> @@ -1917,13 +2011,26 @@ static void desc_write_cb(struct gatt_db_attribute *attrib,
> void *user_data)
> {
> struct external_desc *desc = user_data;
> + struct btd_device *device;
>
> if (desc->attrib != attrib) {
> error("Read callback called with incorrect attribute");
> - return;
> + goto fail;
> }
>
> - send_write(attrib, desc->proxy, desc->pending_writes, id, value, len);
> + device = att_get_device(att);
> + if (!device) {
> + error("Unable to find device object");
> + goto fail;
> + }
> +
> + if (send_write(device, attrib, desc->proxy, desc->pending_writes, id,
> + value, len))
> + return;
> +
> +fail:
> + gatt_db_attribute_read_result(attrib, id, BT_ATT_ERROR_UNLIKELY,
> + NULL, 0);
> }
>
> static bool database_add_desc(struct external_service *service,
> @@ -1956,43 +2063,25 @@ static void chrc_read_cb(struct gatt_db_attribute *attrib,
> void *user_data)
> {
> struct external_chrc *chrc = user_data;
> + struct btd_device *device;
>
> if (chrc->attrib != attrib) {
> error("Read callback called with incorrect attribute");
> - return;
> + goto fail;
> }
>
> - send_read(attrib, chrc->proxy, chrc->pending_reads, id);
> -}
> -
> -static void write_without_response_setup_cb(DBusMessageIter *iter,
> - void *user_data)
> -{
> - struct iovec *iov = user_data;
> - DBusMessageIter array;
> -
> - dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "y", &array);
> - dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
> - &iov->iov_base, iov->iov_len);
> - dbus_message_iter_close_container(iter, &array);
> -}
> -
> -static void send_write_without_response(struct gatt_db_attribute *attrib,
> - GDBusProxy *proxy, unsigned int id,
> - const uint8_t *value, size_t len)
> -{
> - struct iovec iov;
> - uint8_t ecode = 0;
> -
> - iov.iov_base = (uint8_t *) value;
> - iov.iov_len = len;
> + device = att_get_device(att);
> + if (!device) {
> + error("Unable to find device object");
> + goto fail;
> + }
>
> - if (!g_dbus_proxy_method_call(proxy, "WriteValue",
> - write_without_response_setup_cb,
> - NULL, &iov, NULL))
> - ecode = BT_ATT_ERROR_UNLIKELY;
> + if (send_read(device, attrib, chrc->proxy, chrc->pending_reads, id))
> + return;
>
> - gatt_db_attribute_write_result(attrib, id, ecode);
> +fail:
> + gatt_db_attribute_read_result(attrib, id, BT_ATT_ERROR_UNLIKELY,
> + NULL, 0);
> }
>
> static void chrc_write_cb(struct gatt_db_attribute *attrib,
> @@ -2002,19 +2091,31 @@ static void chrc_write_cb(struct gatt_db_attribute *attrib,
> void *user_data)
> {
> struct external_chrc *chrc = user_data;
> + struct btd_device *device;
> + struct queue *queue;
>
> if (chrc->attrib != attrib) {
> error("Write callback called with incorrect attribute");
> - return;
> + goto fail;
> }
>
> - if (chrc->props & BT_GATT_CHRC_PROP_WRITE_WITHOUT_RESP) {
> - send_write_without_response(attrib, chrc->proxy, id, value,
> - len);
> - return;
> + device = att_get_device(att);
> + if (!device) {
> + error("Unable to find device object");
> + goto fail;
> }
>
> - send_write(attrib, chrc->proxy, chrc->pending_writes, id, value, len);
> + if (!(chrc->props & BT_GATT_CHRC_PROP_WRITE_WITHOUT_RESP))
> + queue = chrc->pending_writes;
> + else
> + queue = NULL;
> +
> + if (send_write(device, attrib, chrc->proxy, queue, id, value, len))
> + return;
> +
> +fail:
> + gatt_db_attribute_read_result(attrib, id, BT_ATT_ERROR_UNLIKELY,
> + NULL, 0);
> }
>
> static bool database_add_chrc(struct external_service *service,
> --
> 2.5.5
>
> --
> 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