From 1fe61cf829b89ee28c0ab716c993b70537fe2dac Mon Sep 17 00:00:00 2001 From: Andy Isaacson Date: Mon, 6 Feb 2017 16:15:56 -0800 Subject: [PATCH 1/4] bluepy-helper: have gatt_attr_data_from_string return -1 on error rather than 0 a zero-byte value is perfectly valid for a GATT write, so using 0 as the error value is suboptimal. --- bluepy/bluepy-helper.c | 2 +- bluez-5.29/attrib/utils.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bluepy/bluepy-helper.c b/bluepy/bluepy-helper.c index 548269e7..2e25615d 100644 --- a/bluepy/bluepy-helper.c +++ b/bluepy/bluepy-helper.c @@ -1016,7 +1016,7 @@ static void cmd_char_write_common(int argcp, char **argvp, int with_response) } plen = gatt_attr_data_from_string(argvp[2], &value); - if (plen == 0) { + if (plen == (size_t)-1) { resp_error(err_BAD_PARAM); return; } diff --git a/bluez-5.29/attrib/utils.c b/bluez-5.29/attrib/utils.c index 8e2fc1a4..41af11fb 100644 --- a/bluez-5.29/attrib/utils.c +++ b/bluez-5.29/attrib/utils.c @@ -110,7 +110,7 @@ size_t gatt_attr_data_from_string(const char *str, uint8_t **data) size = strlen(str) / 2; *data = g_try_malloc0(size); if (*data == NULL) - return 0; + return (size_t)-1; tmp[2] = '\0'; for (i = 0; i < size; i++) { From fc5efb06565e5ac33f9a6b301ceeea77f97aefce Mon Sep 17 00:00:00 2001 From: Andy Isaacson Date: Mon, 6 Feb 2017 16:25:08 -0800 Subject: [PATCH 2/4] bluepy-helper: teach "wr" and "wrr" commands to take quoted data strings To support zero-byte strings, teach gatt_attr_data_from_string to enforce single quotes around the data hex string. The return value for an empty string is a one-byte allocation with size=0, which works properly in the gatt.c helper routines and in the return path (via g_free). --- bluepy/btle.py | 2 +- bluez-5.29/attrib/utils.c | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/bluepy/btle.py b/bluepy/btle.py index 82f8aee6..d02b95b2 100755 --- a/bluepy/btle.py +++ b/bluepy/btle.py @@ -492,7 +492,7 @@ def writeCharacteristic(self, handle, val, withResponse=False): # Without response, a value too long for one packet will be truncated, # but with response, it will be sent as a queued write cmd = "wrr" if withResponse else "wr" - self._writeCmd("%s %X %s\n" % (cmd, handle, binascii.b2a_hex(val).decode('utf-8'))) + self._writeCmd("%s %X '%s'\n" % (cmd, handle, binascii.b2a_hex(val).decode('utf-8'))) return self._getResp('wr') def setSecurityLevel(self, level): diff --git a/bluez-5.29/attrib/utils.c b/bluez-5.29/attrib/utils.c index 41af11fb..862a677b 100644 --- a/bluez-5.29/attrib/utils.c +++ b/bluez-5.29/attrib/utils.c @@ -105,10 +105,21 @@ GIOChannel *gatt_connect(const char *src, const char *dst, size_t gatt_attr_data_from_string(const char *str, uint8_t **data) { char tmp[3]; - size_t size, i; + size_t size, len, i; - size = strlen(str) / 2; - *data = g_try_malloc0(size); + if (str[0] != '\'') + return (size_t)-1; + + len = strlen(str); + + if (str[len - 1] != '\'') + return (size_t)-1; + + str = str + 1; + len = len - 2; + + size = len / 2; + *data = g_try_malloc0(len == 0 ? 1 : size); if (*data == NULL) return (size_t)-1; From e513e55427ce2fc21e540207d3c95b817ebb6d55 Mon Sep 17 00:00:00 2001 From: Andy Isaacson Date: Mon, 6 Feb 2017 20:07:32 -0800 Subject: [PATCH 3/4] bluepy-helper: support unquoted hex strings, too for backwards compatibility, also parse the string if given in the old, bare hex, format as well. --- bluez-5.29/attrib/utils.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/bluez-5.29/attrib/utils.c b/bluez-5.29/attrib/utils.c index 862a677b..68104ab2 100644 --- a/bluez-5.29/attrib/utils.c +++ b/bluez-5.29/attrib/utils.c @@ -106,17 +106,20 @@ size_t gatt_attr_data_from_string(const char *str, uint8_t **data) { char tmp[3]; size_t size, len, i; + int is_quoted = 0; - if (str[0] != '\'') - return (size_t)-1; + if (str[0] == '\'') + is_quoted = 1; len = strlen(str); - if (str[len - 1] != '\'') - return (size_t)-1; + if (is_quoted) { + if (str[len - 1] != '\'') + return (size_t)-1; - str = str + 1; - len = len - 2; + str = str + 1; + len = len - 2; + } size = len / 2; *data = g_try_malloc0(len == 0 ? 1 : size); From 44250513b70f256cf6161d6bd75dc555bd0368a1 Mon Sep 17 00:00:00 2001 From: Andy Isaacson Date: Tue, 7 Feb 2017 12:32:49 -0800 Subject: [PATCH 4/4] bluepy-helper: document "wr" and "wrr" optional quotes --- bluepy/bluepy-helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bluepy/bluepy-helper.c b/bluepy/bluepy-helper.c index 2e25615d..8d264434 100644 --- a/bluepy/bluepy-helper.c +++ b/bluepy/bluepy-helper.c @@ -1397,9 +1397,9 @@ static struct { "Characteristics Value/Descriptor Read by handle" }, { "rdu", cmd_read_uuid, " [start hnd] [end hnd]", "Characteristics Value/Descriptor Read by UUID" }, - { "wrr", cmd_char_write_rsp, " ", + { "wrr", cmd_char_write_rsp, " [|'']", "Characteristic Value Write (Write Request)" }, - { "wr", cmd_char_write, " ", + { "wr", cmd_char_write, " [|'']", "Characteristic Value Write (No response)" }, { "secu", cmd_sec_level, "[low | medium | high]", "Set security level. Default: low" },