summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2019-02-11 11:29:21 +0200
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2019-02-11 11:29:21 +0200
commitdb15160d5ca3f8234137dc3083f5cb8795827b98 (patch)
tree20eb604840e5fe1e78a50b0d67e78dc97331cf81 /client
parentaa9f9b193c51d371b5d2a863f35a034ee0377b22 (diff)
downloadbluez-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.c124
-rw-r--r--client/main.c2
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" },