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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



*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
<luiz.dentz@xxxxxxxxx> wrote:
>
> From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>
>
> 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 majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux