From 6c2395632a10784491faf95fec00c3d2d9726a48 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 11 Feb 2019 11:29:21 +0200 Subject: [PATCH] client: Add type to write command This enables setting the write type as optional third parameter: write [offset] [type] The type can be used to force a specific procedure to be used, for example to force reliable writes one can enter: > write 00 0 reliable Change-Id: I4e74cff3cd2a38f07b36e09716023810e641c136 Signed-off-by: himanshu --- client/gatt.c | 124 ++++++++++++++++++++++++---------------------------------- client/main.c | 2 +- 2 files changed, 53 insertions(+), 73 deletions(-) diff --git a/client/gatt.c b/client/gatt.c index 2059677..ca63c23 100755 --- a/client/gatt.c +++ b/client/gatt.c @@ -65,7 +65,7 @@ struct desc { uint16_t handle; char *uuid; char **flags; - int value_len; + size_t value_len; unsigned int max_val_len; uint8_t *value; }; @@ -79,7 +79,7 @@ struct chrc { char **flags; bool notifying; GList *descs; - int value_len; + size_t value_len; unsigned int max_val_len; uint8_t *value; uint16_t mtu; @@ -697,7 +697,8 @@ static void write_reply(DBusMessage *message, void *user_data) struct write_attribute_data { DBusMessage *msg; - struct iovec *iov; + struct iovec iov; + char *type; uint16_t offset; }; @@ -708,8 +709,8 @@ static void write_setup(DBusMessageIter *iter, void *user_data) dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "y", &array); dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE, - &wd->iov->iov_base, - wd->iov->iov_len); + &wd->iov.iov_base, + wd->iov.iov_len); dbus_message_iter_close_container(iter, &array); dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, @@ -719,6 +720,10 @@ static void write_setup(DBusMessageIter *iter, void *user_data) DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); + if (wd->type) + g_dbus_dict_append_entry(&dict, "type", DBUS_TYPE_STRING, + &wd->type); + g_dbus_dict_append_entry(&dict, "offset", DBUS_TYPE_UINT16, &wd->offset); @@ -743,15 +748,38 @@ static int sock_send(struct io *io, struct iovec *iov, size_t iovlen) return ret; } -static void write_attribute(GDBusProxy *proxy, char *val_str, uint16_t offset) +static void write_attribute(GDBusProxy *proxy, + struct write_attribute_data *data) +{ + /* Write using the fd if it has been acquired and fit the MTU */ + if (proxy == write_io.proxy && + (write_io.io && write_io.mtu >= data->iov.iov_len)) { + bt_shell_printf("Attempting to write fd %d\n", + io_get_fd(write_io.io)); + if (sock_send(write_io.io, &data->iov, 1) < 0) { + bt_shell_printf("Failed to write: %s", strerror(errno)); + return bt_shell_noninteractive_quit(EXIT_FAILURE); + } + return; + } + + if (g_dbus_proxy_method_call(proxy, "WriteValue", write_setup, + write_reply, data, NULL) == FALSE) { + bt_shell_printf("Failed to write\n"); + return bt_shell_noninteractive_quit(EXIT_FAILURE); + } + + bt_shell_printf("Attempting to write %s\n", + g_dbus_proxy_get_path(proxy)); +} + +static uint8_t *str2bytearray(char *arg, size_t *val_len) { - struct iovec iov; - struct write_attribute_data wd; uint8_t value[MAX_ATTR_VAL_LEN]; char *entry; unsigned int i; - for (i = 0; (entry = strsep(&val_str, " \t")) != NULL; i++) { + for (i = 0; (entry = strsep(&arg, " \t")) != NULL; i++) { long int val; char *endptr = NULL; @@ -760,58 +788,42 @@ static void write_attribute(GDBusProxy *proxy, char *val_str, uint16_t offset) if (i >= G_N_ELEMENTS(value)) { bt_shell_printf("Too much data\n"); - return bt_shell_noninteractive_quit(EXIT_FAILURE); + return NULL; } val = strtol(entry, &endptr, 0); if (!endptr || *endptr != '\0' || val > UINT8_MAX) { bt_shell_printf("Invalid value at index %d\n", i); - return bt_shell_noninteractive_quit(EXIT_FAILURE); + return NULL; } value[i] = val; } - iov.iov_base = value; - iov.iov_len = i; - - /* Write using the fd if it has been acquired and fit the MTU */ - if (proxy == write_io.proxy && (write_io.io && write_io.mtu >= i)) { - bt_shell_printf("Attempting to write fd %d\n", - io_get_fd(write_io.io)); - if (sock_send(write_io.io, &iov, 1) < 0) { - bt_shell_printf("Failed to write: %s", strerror(errno)); - return bt_shell_noninteractive_quit(EXIT_FAILURE); - } - return; - } - - wd.iov = &iov; - wd.offset = offset; - - if (g_dbus_proxy_method_call(proxy, "WriteValue", write_setup, - write_reply, &wd, NULL) == FALSE) { - bt_shell_printf("Failed to write\n"); - return bt_shell_noninteractive_quit(EXIT_FAILURE); - } + *val_len = i; - bt_shell_printf("Attempting to write %s\n", - g_dbus_proxy_get_path(proxy)); + return g_memdup(value, i); } void gatt_write_attribute(GDBusProxy *proxy, int argc, char *argv[]) { const char *iface; - uint16_t offset = 0; + struct write_attribute_data data; + + memset(&data, 0, sizeof(data)); iface = g_dbus_proxy_get_interface(proxy); if (!strcmp(iface, "org.bluez.GattCharacteristic1") || !strcmp(iface, "org.bluez.GattDescriptor1")) { + data.iov.iov_base = str2bytearray(argv[1], &data.iov.iov_len); if (argc > 2) - offset = atoi(argv[2]); + data.offset = atoi(argv[2]); - write_attribute(proxy, argv[1], offset); + if (argc > 3) + data.type = argv[3]; + + write_attribute(proxy, &data); return; } @@ -2081,8 +2093,8 @@ static int parse_value_arg(DBusMessageIter *iter, uint8_t **value, int *len) return 0; } -static int write_value(int *dst_len, uint8_t **dst_value, uint8_t *src_val, - int src_len, uint16_t offset, uint16_t max_len) +static int write_value(size_t *dst_len, uint8_t **dst_value, uint8_t *src_val, + size_t src_len, uint16_t offset, uint16_t max_len) { if ((offset + src_len) > max_len) return -EOVERFLOW; @@ -2511,38 +2523,6 @@ static const GDBusMethodTable chrc_methods[] = { { } }; -static uint8_t *str2bytearray(char *arg, int *val_len) -{ - uint8_t value[MAX_ATTR_VAL_LEN]; - char *entry; - unsigned int i; - - for (i = 0; (entry = strsep(&arg, " \t")) != NULL; i++) { - long int val; - char *endptr = NULL; - - if (*entry == '\0') - continue; - - if (i >= G_N_ELEMENTS(value)) { - bt_shell_printf("Too much data\n"); - return NULL; - } - - val = strtol(entry, &endptr, 0); - if (!endptr || *endptr != '\0' || val > UINT8_MAX) { - bt_shell_printf("Invalid value at index %d\n", i); - return NULL; - } - - value[i] = val; - } - - *val_len = i; - - return g_memdup(value, i); -} - static void chrc_set_value(const char *input, void *user_data) { struct chrc *chrc = user_data; diff --git a/client/main.c b/client/main.c index c530dc9..2c6a350 100644 --- a/client/main.c +++ b/client/main.c @@ -2664,7 +2664,7 @@ static const struct bt_shell_menu gatt_menu = { { "attribute-info", "[attribute/UUID]", cmd_attribute_info, "Select attribute", attribute_generator }, { "read", "[offset]", cmd_read, "Read attribute value" }, - { "write", " [offset]", cmd_write, + { "write", " [offset] [type]", cmd_write, "Write attribute value" }, { "acquire-write", NULL, cmd_acquire_write, "Acquire Write file descriptor" }, -- 2.7.4