2018-04-26 12:31:57

by Grzegorz Kołodziejczyk

[permalink] [raw]
Subject: [PATCH BlueZ v3 1/4] tools/hcitool: Change connection handle condition for lecup

According to BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E
7.8.18 LE Connection Update Command, connection handle range is
0x0000-0x0EFF.
---
tools/hcitool.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/hcitool.c b/tools/hcitool.c
index 02c4ebe1b..945f675b0 100644
--- a/tools/hcitool.c
+++ b/tools/hcitool.c
@@ -3351,7 +3351,7 @@ static void cmd_lecup(int dev_id, int argc, char **argv)
timeout = strtoul(argv[4], NULL, 0);
}

- if (handle == 0) {
+ if (handle > 0x0EFF) {
printf("%s", lecup_help);
return;
}
--
2.13.6



2018-04-26 12:58:26

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH BlueZ v3 1/4] tools/hcitool: Change connection handle condition for lecup

Hi Grzegorz,

On Thu, Apr 26, 2018 at 3:31 PM, Grzegorz Kolodziejczyk
<[email protected]> wrote:
> According to BLUETOOTH SPECIFICATION Version 5.0 | Vol 2, Part E
> 7.8.18 LE Connection Update Command, connection handle range is
> 0x0000-0x0EFF.
> ---
> tools/hcitool.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tools/hcitool.c b/tools/hcitool.c
> index 02c4ebe1b..945f675b0 100644
> --- a/tools/hcitool.c
> +++ b/tools/hcitool.c
> @@ -3351,7 +3351,7 @@ static void cmd_lecup(int dev_id, int argc, char **argv)
> timeout = strtoul(argv[4], NULL, 0);
> }
>
> - if (handle == 0) {
> + if (handle > 0x0EFF) {
> printf("%s", lecup_help);
> return;
> }
> --
> 2.13.6

Applied, thanks.

--
Luiz Augusto von Dentz

2018-04-26 12:32:00

by Grzegorz Kołodziejczyk

[permalink] [raw]
Subject: [PATCH BlueZ v3 4/4] client: Add support for optional gatt write offset parameter

This patch extends missing optional gatt write offset parameter.
---
client/gatt.c | 34 ++++++++++++++++++++++++++--------
client/gatt.h | 2 +-
client/main.c | 4 ++--
3 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/client/gatt.c b/client/gatt.c
index a33a094e6..125d6034d 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -579,14 +579,20 @@ static void write_reply(DBusMessage *message, void *user_data)
return bt_shell_noninteractive_quit(EXIT_SUCCESS);
}

+struct write_attribute_data {
+ struct iovec *iov;
+ uint16_t offset;
+};
+
static void write_setup(DBusMessageIter *iter, void *user_data)
{
- struct iovec *iov = user_data;
+ struct write_attribute_data *wd = user_data;
DBusMessageIter array, dict;

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);
+ &wd->iov->iov_base,
+ wd->iov->iov_len);
dbus_message_iter_close_container(iter, &array);

dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
@@ -595,18 +601,22 @@ static void write_setup(DBusMessageIter *iter, void *user_data)
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
&dict);
- /* TODO: Add offset support */
+
+ g_dbus_dict_append_entry(&dict, "offset", DBUS_TYPE_UINT16,
+ &wd->offset);
+
dbus_message_iter_close_container(iter, &dict);
}

-static void write_attribute(GDBusProxy *proxy, char *arg)
+static void write_attribute(GDBusProxy *proxy, char *val_str, uint16_t offset)
{
struct iovec iov;
+ struct write_attribute_data wd;
uint8_t value[512];
char *entry;
unsigned int i;

- for (i = 0; (entry = strsep(&arg, " \t")) != NULL; i++) {
+ for (i = 0; (entry = strsep(&val_str, " \t")) != NULL; i++) {
long int val;
char *endptr = NULL;

@@ -642,8 +652,11 @@ static void write_attribute(GDBusProxy *proxy, char *arg)
return;
}

+ wd.iov = &iov;
+ wd.offset = offset;
+
if (g_dbus_proxy_method_call(proxy, "WriteValue", write_setup,
- write_reply, &iov, NULL) == FALSE) {
+ write_reply, &wd, NULL) == FALSE) {
bt_shell_printf("Failed to write\n");
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
@@ -652,14 +665,19 @@ static void write_attribute(GDBusProxy *proxy, char *arg)
g_dbus_proxy_get_path(proxy));
}

-void gatt_write_attribute(GDBusProxy *proxy, const char *arg)
+void gatt_write_attribute(GDBusProxy *proxy, int argc, char *argv[])
{
const char *iface;
+ uint16_t offset = 0;

iface = g_dbus_proxy_get_interface(proxy);
if (!strcmp(iface, "org.bluez.GattCharacteristic1") ||
!strcmp(iface, "org.bluez.GattDescriptor1")) {
- write_attribute(proxy, (char *) arg);
+
+ if (argc > 2)
+ offset = atoi(argv[2]);
+
+ write_attribute(proxy, argv[1], offset);
return;
}

diff --git a/client/gatt.h b/client/gatt.h
index 274c76b1f..957ae8003 100644
--- a/client/gatt.h
+++ b/client/gatt.h
@@ -35,7 +35,7 @@ GDBusProxy *gatt_select_attribute(GDBusProxy *parent, const char *path);
char *gatt_attribute_generator(const char *text, int state);

void gatt_read_attribute(GDBusProxy *proxy, int argc, char *argv[]);
-void gatt_write_attribute(GDBusProxy *proxy, const char *arg);
+void gatt_write_attribute(GDBusProxy *proxy, int argc, char *argv[]);
void gatt_notify_attribute(GDBusProxy *proxy, bool enable);

void gatt_acquire_write(GDBusProxy *proxy, const char *arg);
diff --git a/client/main.c b/client/main.c
index 57a85f1d5..dd85a1c85 100644
--- a/client/main.c
+++ b/client/main.c
@@ -1918,7 +1918,7 @@ static void cmd_write(int argc, char *argv[])
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}

- gatt_write_attribute(default_attr, argv[1]);
+ gatt_write_attribute(default_attr, argc, argv);
}

static void cmd_acquire_write(int argc, char *argv[])
@@ -2416,7 +2416,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 ...>", cmd_write,
+ { "write", "<data=xx xx ...> [offset]", cmd_write,
"Write attribute value" },
{ "acquire-write", NULL, cmd_acquire_write,
"Acquire Write file descriptor" },
--
2.13.6


2018-04-26 12:31:59

by Grzegorz Kołodziejczyk

[permalink] [raw]
Subject: [PATCH BlueZ v3 3/4] client: Add support for optional gatt read offset parameter

This patch extends missing optional gatt read offset parameter.
---
client/gatt.c | 18 +++++++++++++-----
client/gatt.h | 2 +-
client/main.c | 4 ++--
3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/client/gatt.c b/client/gatt.c
index b0ef7b9c0..a33a094e6 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -518,6 +518,7 @@ static void read_reply(DBusMessage *message, void *user_data)
static void read_setup(DBusMessageIter *iter, void *user_data)
{
DBusMessageIter dict;
+ uint16_t *offset = user_data;

dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
@@ -525,14 +526,16 @@ static void read_setup(DBusMessageIter *iter, void *user_data)
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
&dict);
- /* TODO: Add offset support */
+
+ g_dbus_dict_append_entry(&dict, "offset", DBUS_TYPE_UINT16, offset);
+
dbus_message_iter_close_container(iter, &dict);
}

-static void read_attribute(GDBusProxy *proxy)
+static void read_attribute(GDBusProxy *proxy, uint16_t offset)
{
if (g_dbus_proxy_method_call(proxy, "ReadValue", read_setup, read_reply,
- NULL, NULL) == FALSE) {
+ &offset, NULL) == FALSE) {
bt_shell_printf("Failed to read\n");
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
@@ -540,14 +543,19 @@ static void read_attribute(GDBusProxy *proxy)
bt_shell_printf("Attempting to read %s\n", g_dbus_proxy_get_path(proxy));
}

-void gatt_read_attribute(GDBusProxy *proxy)
+void gatt_read_attribute(GDBusProxy *proxy, int argc, char *argv[])
{
const char *iface;
+ uint16_t offset = 0;

iface = g_dbus_proxy_get_interface(proxy);
if (!strcmp(iface, "org.bluez.GattCharacteristic1") ||
!strcmp(iface, "org.bluez.GattDescriptor1")) {
- read_attribute(proxy);
+
+ if (argc == 2)
+ offset = atoi(argv[1]);
+
+ read_attribute(proxy, offset);
return;
}

diff --git a/client/gatt.h b/client/gatt.h
index f4c36b870..274c76b1f 100644
--- a/client/gatt.h
+++ b/client/gatt.h
@@ -34,7 +34,7 @@ void gatt_list_attributes(const char *device);
GDBusProxy *gatt_select_attribute(GDBusProxy *parent, const char *path);
char *gatt_attribute_generator(const char *text, int state);

-void gatt_read_attribute(GDBusProxy *proxy);
+void gatt_read_attribute(GDBusProxy *proxy, int argc, char *argv[]);
void gatt_write_attribute(GDBusProxy *proxy, const char *arg);
void gatt_notify_attribute(GDBusProxy *proxy, bool enable);

diff --git a/client/main.c b/client/main.c
index b96278d45..57a85f1d5 100644
--- a/client/main.c
+++ b/client/main.c
@@ -1908,7 +1908,7 @@ static void cmd_read(int argc, char *argv[])
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}

- gatt_read_attribute(default_attr);
+ gatt_read_attribute(default_attr, argc, argv);
}

static void cmd_write(int argc, char *argv[])
@@ -2415,7 +2415,7 @@ static const struct bt_shell_menu gatt_menu = {
"Select attribute", attribute_generator },
{ "attribute-info", "[attribute/UUID]", cmd_attribute_info,
"Select attribute", attribute_generator },
- { "read", NULL, cmd_read, "Read attribute value" },
+ { "read", "[offset]", cmd_read, "Read attribute value" },
{ "write", "<data=xx xx ...>", cmd_write,
"Write attribute value" },
{ "acquire-write", NULL, cmd_acquire_write,
--
2.13.6


2018-04-26 12:31:58

by Grzegorz Kołodziejczyk

[permalink] [raw]
Subject: [PATCH BlueZ v3 2/4] client: Fix writing attribute values

Attribute values is not copied with dbus_message_iter_get_fixed_array,
so gatt write callback needs to replace old value with reallocation and
copy.
---
client/gatt.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/client/gatt.c b/client/gatt.c
index 52a999dc9..b0ef7b9c0 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -1589,12 +1589,26 @@ static DBusMessage *chrc_read_value(DBusConnection *conn, DBusMessage *msg,
static int parse_value_arg(DBusMessageIter *iter, uint8_t **value, int *len)
{
DBusMessageIter array;
+ uint16_t offset = 0;
+ uint8_t *read_value;
+ int read_len;

if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
return -EINVAL;

dbus_message_iter_recurse(iter, &array);
- dbus_message_iter_get_fixed_array(&array, value, len);
+ dbus_message_iter_get_fixed_array(&array, &read_value, &read_len);
+
+ dbus_message_iter_next(iter);
+ if (parse_options(iter, &offset, NULL, NULL, NULL))
+ return -EINVAL;
+
+ if ((offset + read_len) > *len) {
+ *len = offset + read_len;
+ *value = g_realloc(*value, *len);
+ }
+
+ memcpy(*value + offset, read_value, read_len);

return 0;
}
--
2.13.6