Hi Vinicius, On Sat, May 7, 2016 at 11:08 PM, Vinicius Costa Gomes <vinicius.gomes@xxxxxxxxx> wrote: > Hi Luiz, > > Luiz Augusto von Dentz <luiz.dentz@xxxxxxxxx> writes: > >> 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. >> --- >> doc/gatt-api.txt | 20 ++++-- >> src/gatt-client.c | 135 +++++++++++++++++++++++++++++---------- >> src/gatt-database.c | 177 +++++++++++++++++++++++++++++++++++++--------------- >> 3 files changed, 245 insertions(+), 87 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..c51cdc8 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> >> >> @@ -390,12 +391,67 @@ fail: >> return; >> } >> >> +static int parse_options(DBusMessage *msg, uint16_t *offset) >> +{ >> + DBusMessageIter args, flags; >> + >> + if (!dbus_message_iter_init(msg, &args)) >> + return -EINVAL; >> + >> + if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) >> + return -EINVAL; >> + >> + dbus_message_iter_recurse(&args, &flags); >> + if (dbus_message_iter_get_arg_type(&flags) != DBUS_TYPE_DICT_ENTRY) >> + return -EINVAL; >> + >> + while (dbus_message_iter_get_arg_type(&flags) == DBUS_TYPE_DICT_ENTRY) { >> + const char *key; >> + DBusMessageIter value, entry; >> + int var; >> + >> + dbus_message_iter_recurse(&flags, &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); >> + } >> + } >> + >> + 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; >> struct async_dbus_op *op; >> + uint16_t offset = 0; >> + >> + if (parse_options(msg, &offset)) >> + return btd_error_invalid_args(msg); >> >> if (!gatt) >> return btd_error_failed(msg, "Not connected"); >> @@ -406,17 +462,16 @@ static DBusMessage *descriptor_read_value(DBusConnection *conn, >> 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; >> >> async_dbus_op_free(op); >> >> return btd_error_failed(msg, "Failed to send read request"); >> + > > Extra empty line. > >> } >> >> static void write_result_cb(bool success, bool reliable_error, >> @@ -459,7 +514,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 +525,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); >> >> @@ -524,6 +581,10 @@ static DBusMessage *descriptor_write_value(DBusConnection *conn, >> struct bt_gatt_client *gatt = desc->chrc->service->client->gatt; >> uint8_t *value = NULL; >> size_t value_len = 0; >> + uint16_t offset = 0; >> + >> + if (parse_options(msg, &offset)) >> + return btd_error_invalid_args(msg); >> >> if (!gatt) >> return btd_error_failed(msg, "Not connected"); >> @@ -546,15 +607,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 <= (unsigned) 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 +635,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) }, >> { } >> }; >> >> @@ -838,6 +901,10 @@ static DBusMessage *characteristic_read_value(DBusConnection *conn, >> struct characteristic *chrc = user_data; >> struct bt_gatt_client *gatt = chrc->service->client->gatt; >> struct async_dbus_op *op; >> + uint16_t offset = 0; >> + >> + if (parse_options(msg, &offset)) >> + return btd_error_invalid_args(msg); >> >> if (!gatt) >> return btd_error_failed(msg, "Not connected"); >> @@ -848,11 +915,9 @@ static DBusMessage *characteristic_read_value(DBusConnection *conn, >> 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; >> >> @@ -882,6 +947,10 @@ static DBusMessage *characteristic_write_value(DBusConnection *conn, >> uint8_t *value = NULL; >> size_t value_len = 0; >> bool supported = false; >> + uint16_t offset = 0; >> + >> + if (parse_options(msg, &offset)) >> + return btd_error_invalid_args(msg); >> >> if (!gatt) >> return btd_error_failed(msg, "Not connected"); >> @@ -906,7 +975,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 +989,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 <= (unsigned) mtu - 3 && !offset) >> chrc->write_id = start_write_request(msg, >> chrc->value_handle, >> gatt, value, value_len, >> @@ -928,7 +997,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 +1311,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..7f36ffd 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; > > Increase the device's reference counting? Actually this can be a weak reference since we only use it on append_options which is actually called synchronously so there is no chance the device would be freed in the meantime. >> op->attrib = attrib; >> op->id = id; >> queue_push_tail(owner_queue, op); >> @@ -1608,17 +1611,44 @@ 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 void 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) >> + if (g_dbus_proxy_method_call(proxy, "ReadValue", read_setup_cb, >> + read_reply_cb, op, pending_op_free) == TRUE) >> return; >> >> pending_op_free(op); >> @@ -1629,12 +1659,28 @@ static void send_read(struct gatt_db_attribute *attrib, GDBusProxy *proxy, >> 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 +1719,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 +1733,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,7 +1742,9 @@ 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 void 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) >> @@ -1702,11 +1752,11 @@ static void send_write(struct gatt_db_attribute *attrib, GDBusProxy *proxy, >> 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) >> + owner_queue ? write_reply_cb : NULL, >> + op, pending_op_free) == TRUE) >> return; >> >> pending_op_free(op); >> @@ -1895,19 +1945,58 @@ 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 false; > > return NULL? Yep, gonna fix these errors, thanks for the review. >> + >> + 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 false; > > also here. > >> + } >> + >> + g_io_channel_unref(io); >> + >> + adapter = adapter_find(&src); >> + if (!adapter) { >> + error("Unable to find adapter object"); >> + return false; > > and here. > >> + } >> + >> + 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; >> } >> >> - send_read(attrib, desc->proxy, desc->pending_reads, id); >> + device = att_get_device(att); >> + if (!device) >> + error("Unable to find device object"); >> + >> + send_read(device, attrib, desc->proxy, desc->pending_reads, id); >> } >> >> static void desc_write_cb(struct gatt_db_attribute *attrib, >> @@ -1917,13 +2006,19 @@ 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; >> } >> >> - send_write(attrib, desc->proxy, desc->pending_writes, id, value, len); >> + device = att_get_device(att); >> + if (!device) >> + error("Unable to find device object"); > > I guess you should return here. There are couple of places like this. If > this is not a mistake, I guess you could make append_options() not > append the NULL path, if there's no device associated. The idea is to skip the device but this in fact shall never fail since we do create the device once connected so perhaps returning here is fine. > >> + >> + send_write(device, attrib, desc->proxy, desc->pending_writes, id, >> + value, len); >> } >> >> static bool database_add_desc(struct external_service *service, >> @@ -1956,43 +2051,18 @@ 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; >> } >> >> - 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; >> - >> - if (!g_dbus_proxy_method_call(proxy, "WriteValue", >> - write_without_response_setup_cb, >> - NULL, &iov, NULL)) >> - ecode = BT_ATT_ERROR_UNLIKELY; >> + device = att_get_device(att); >> + if (!device) >> + error("Unable to find device object"); >> >> - gatt_db_attribute_write_result(attrib, id, ecode); >> + send_read(device, attrib, chrc->proxy, chrc->pending_reads, id); >> } >> >> static void chrc_write_cb(struct gatt_db_attribute *attrib, >> @@ -2002,19 +2072,24 @@ 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; >> } >> >> - if (chrc->props & BT_GATT_CHRC_PROP_WRITE_WITHOUT_RESP) { >> - send_write_without_response(attrib, chrc->proxy, id, value, >> - len); >> - return; >> - } >> + if (!(chrc->props & BT_GATT_CHRC_PROP_WRITE_WITHOUT_RESP)) >> + queue = chrc->pending_writes; >> + else >> + queue = NULL; >> + >> + device = att_get_device(att); >> + if (!device) >> + error("Unable to find device object"); >> >> - send_write(attrib, chrc->proxy, chrc->pending_writes, id, value, len); >> + send_write(device, attrib, chrc->proxy, queue, id, value, len); >> } >> >> 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 > > > Cheers, > -- > Vinicius -- Luiz Augusto von Dentz -- 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