diff options
author | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2019-02-11 11:29:21 +0200 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2019-02-11 11:29:21 +0200 |
commit | db15160d5ca3f8234137dc3083f5cb8795827b98 (patch) | |
tree | 20eb604840e5fe1e78a50b0d67e78dc97331cf81 /client | |
parent | aa9f9b193c51d371b5d2a863f35a034ee0377b22 (diff) | |
download | bluez-db15160d5ca3f8234137dc3083f5cb8795827b98.tar.gz |
client: Add type to write command
This enables setting the write type as optional third parameter:
write <data=xx xx ...> [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
Diffstat (limited to 'client')
-rw-r--r-- | client/gatt.c | 124 | ||||
-rw-r--r-- | client/main.c | 2 |
2 files changed, 53 insertions, 73 deletions
diff --git a/client/gatt.c b/client/gatt.c index 06364a820..cbcff30da 100644 --- 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; }; @@ -78,7 +78,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; @@ -669,7 +669,8 @@ static void write_reply(DBusMessage *message, void *user_data) } struct write_attribute_data { - struct iovec *iov; + struct iovec iov; + char *type; uint16_t offset; }; @@ -680,8 +681,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, @@ -691,6 +692,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); @@ -715,15 +720,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; @@ -732,58 +760,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; } @@ -1952,8 +1964,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; @@ -2255,38 +2267,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 16433f96d..e91794504 100644 --- a/client/main.c +++ b/client/main.c @@ -2612,7 +2612,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", "<data=xx xx ...> [offset]", cmd_write, + { "write", "<data=xx xx ...> [offset] [type]", cmd_write, "Write attribute value" }, { "acquire-write", NULL, cmd_acquire_write, "Acquire Write file descriptor" }, |