All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/7] Improve help messages in interactive gatttool
@ 2011-02-21 22:50 Sheldon Demario
  2011-02-21 22:50 ` [PATCH 2/7] Add Characteristics Discovery option to " Sheldon Demario
                   ` (14 more replies)
  0 siblings, 15 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-21 22:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

Includes the parameters info on help.
---
 attrib/interactive.c |   19 +++++++++++++------
 1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index edc465a..b491314 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -217,13 +217,19 @@ static void cmd_primary(int argcp, char **argvp)
 static struct {
 	const char *cmd;
 	void (*func)(int argcp, char **argvp);
+	const char *params;
 	const char *desc;
 } commands[] = {
-	{ "help",	cmd_help,	"Show this help"},
-	{ "exit",	cmd_exit,	"Exit interactive mode"},
-	{ "connect",	cmd_connect,	"Connect to a remote device"},
-	{ "disconnect",	cmd_disconnect,	"Disconnect from a remote device"},
-	{ "primary",	cmd_primary,	"Primary Service Discovery"},
+	{ "help",		cmd_help,	"",
+		"Show this help"},
+	{ "exit",		cmd_exit,	"",
+		"Exit interactive mode" },
+	{ "connect",		cmd_connect,	"[address]",
+		"Connect to a remote device" },
+	{ "disconnect",		cmd_disconnect,	"",
+		"Disconnect from a remote device" },
+	{ "primary",		cmd_primary,	"[UUID]",
+		"Primary Service Discovery" },
 	{ NULL, NULL, NULL}
 };
 
@@ -232,7 +238,8 @@ static void cmd_help(int argcp, char **argvp)
 	int i;
 
 	for (i = 0; commands[i].cmd; i++)
-		printf("%-12s\t%s\n", commands[i].cmd, commands[i].desc);
+		printf("%-15s %-25s %s\n", commands[i].cmd,
+				commands[i].params, commands[i].desc);
 }
 
 static void parse_line(char *line_read)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 2/7] Add Characteristics Discovery option to interactive gatttool
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
@ 2011-02-21 22:50 ` Sheldon Demario
  2011-02-21 22:50 ` [PATCH 3/7] Create helper functions to deal with handles on " Sheldon Demario
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-21 22:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

---
 attrib/interactive.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index b491314..7cc03bc 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -22,6 +22,7 @@
  */
 #include <string.h>
 #include <stdlib.h>
+#include <errno.h>
 #include <stdio.h>
 #include <glib.h>
 
@@ -145,6 +146,29 @@ static void primary_by_uuid_cb(GSList *ranges, guint8 status,
 	rl_forced_update_display();
 }
 
+static void char_cb(GSList *characteristics, guint8 status, gpointer user_data)
+{
+	GSList *l;
+
+	if (status) {
+		printf("Discover all characteristics failed: %s\n",
+							att_ecode2str(status));
+		return;
+	}
+
+	printf("\n");
+	for (l = characteristics; l; l = l->next) {
+		struct att_char *chars = l->data;
+
+		printf("handle: 0x%04x, char properties: 0x%02x, char value "
+				"handle: 0x%04x, uuid: %s\n", chars->handle,
+				chars->properties, chars->value_handle,
+				chars->uuid);
+	}
+
+	rl_forced_update_display();
+}
+
 static void cmd_exit(int argcp, char **argvp)
 {
 	rl_callback_handler_remove();
@@ -214,6 +238,41 @@ static void cmd_primary(int argcp, char **argvp)
 	gatt_discover_primary(attrib, &uuid, primary_by_uuid_cb, NULL);
 }
 
+static void cmd_char(int argcp, char **argvp)
+{
+	int start = 0x0001;
+	int end = 0xffff;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (argcp > 1) {
+		char *e;
+
+		start = strtoll(argvp[1], &e, 16);
+		if (errno != 0 || *e != '\0') {
+			printf("Invalid start handle: %s\n", argvp[1]);
+			return;
+		}
+	}
+
+	if (argcp > 2) {
+		char *e;
+
+		end = strtoll(argvp[2], &e, 16);
+		if (errno != 0 || *e != '\0') {
+			printf("Invalid end handle: %s\n", argvp[2]);
+			return;
+		}
+	}
+
+	gatt_discover_char(attrib, start, end, char_cb, NULL);
+
+	return;
+}
+
 static struct {
 	const char *cmd;
 	void (*func)(int argcp, char **argvp);
@@ -230,6 +289,8 @@ static struct {
 		"Disconnect from a remote device" },
 	{ "primary",		cmd_primary,	"[UUID]",
 		"Primary Service Discovery" },
+	{ "characteristics",	cmd_char,	"[start hnd] [end hnd]",
+		"Characteristics Discovery" },
 	{ NULL, NULL, NULL}
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 3/7] Create helper functions to deal with handles on interactive gatttool
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
  2011-02-21 22:50 ` [PATCH 2/7] Add Characteristics Discovery option to " Sheldon Demario
@ 2011-02-21 22:50 ` Sheldon Demario
  2011-02-21 22:50 ` [PATCH 4/7] Add Characteristics Descriptor Discovery option in " Sheldon Demario
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-21 22:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

---
 attrib/interactive.c |   46 ++++++++++++++++++++++++++++++----------------
 1 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index 7cc03bc..e9f6019 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -238,36 +238,50 @@ static void cmd_primary(int argcp, char **argvp)
 	gatt_discover_primary(attrib, &uuid, primary_by_uuid_cb, NULL);
 }
 
-static void cmd_char(int argcp, char **argvp)
+static int strtohandle(int *dst, const char *src)
 {
-	int start = 0x0001;
-	int end = 0xffff;
+	char *e;
 
-	if (conn_state != STATE_CONNECTED) {
-		printf("Command failed: disconnected\n");
-		return;
+	*dst = strtoll(src, &e, 16);
+	if (errno != 0 || *e != '\0') {
+		return -1;
 	}
 
-	if (argcp > 1) {
-		char *e;
+	return 0;
+}
 
-		start = strtoll(argvp[1], &e, 16);
-		if (errno != 0 || *e != '\0') {
+static int set_handles(int *start, int *end, int argcp, char **argvp)
+{
+	if (argcp > 1) {
+		if (strtohandle(start, argvp[1])) {
 			printf("Invalid start handle: %s\n", argvp[1]);
-			return;
+			return -1;
 		}
 	}
 
 	if (argcp > 2) {
-		char *e;
-
-		end = strtoll(argvp[2], &e, 16);
-		if (errno != 0 || *e != '\0') {
+		if (strtohandle(end, argvp[2])) {
 			printf("Invalid end handle: %s\n", argvp[2]);
-			return;
+			return -1;
 		}
 	}
 
+	return 0;
+}
+
+static void cmd_char(int argcp, char **argvp)
+{
+	int start = 0x0001;
+	int end = 0xffff;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (set_handles(&start, &end, argcp, argvp))
+		return;
+
 	gatt_discover_char(attrib, start, end, char_cb, NULL);
 
 	return;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 4/7] Add Characteristics Descriptor Discovery option in interactive gatttool
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
  2011-02-21 22:50 ` [PATCH 2/7] Add Characteristics Discovery option to " Sheldon Demario
  2011-02-21 22:50 ` [PATCH 3/7] Create helper functions to deal with handles on " Sheldon Demario
@ 2011-02-21 22:50 ` Sheldon Demario
  2011-02-21 22:50 ` [PATCH 5/7] Add characteristics read options " Sheldon Demario
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-21 22:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

---
 attrib/interactive.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index e9f6019..9389686 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -169,6 +169,47 @@ static void char_cb(GSList *characteristics, guint8 status, gpointer user_data)
 	rl_forced_update_display();
 }
 
+static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
+							gpointer user_data)
+{
+	struct att_data_list *list;
+	guint8 format;
+	int i;
+
+	if (status != 0) {
+		printf("Discover all characteristic descriptors failed: "
+						"%s\n", att_ecode2str(status));
+		return;
+	}
+
+	list = dec_find_info_resp(pdu, plen, &format);
+	if (list == NULL)
+		return;
+
+	printf("\n");
+	for (i = 0; i < list->num; i++) {
+		char uuidstr[MAX_LEN_UUID_STR];
+		uint16_t handle;
+		uint8_t *value;
+		uuid_t uuid;
+
+		value = list->data[i];
+		handle = att_get_u16(value);
+
+		if (format == 0x01)
+			sdp_uuid16_create(&uuid, att_get_u16(&value[2]));
+		else
+			sdp_uuid128_create(&uuid, &value[2]);
+
+		sdp_uuid2strn(&uuid, uuidstr, MAX_LEN_UUID_STR);
+		printf("handle: 0x%04x, uuid: %s\n", handle, uuidstr);
+	}
+
+	att_data_list_free(list);
+
+	rl_forced_update_display();
+}
+
 static void cmd_exit(int argcp, char **argvp)
 {
 	rl_callback_handler_remove();
@@ -287,6 +328,24 @@ static void cmd_char(int argcp, char **argvp)
 	return;
 }
 
+static void cmd_char_desc(int argcp, char **argvp)
+{
+	int start = 0x0001;
+	int end = 0xffff;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (set_handles(&start, &end, argcp, argvp))
+		return;
+
+	gatt_find_info(attrib, start, end, char_desc_cb, NULL);
+
+	return;
+}
+
 static struct {
 	const char *cmd;
 	void (*func)(int argcp, char **argvp);
@@ -305,6 +364,8 @@ static struct {
 		"Primary Service Discovery" },
 	{ "characteristics",	cmd_char,	"[start hnd] [end hnd]",
 		"Characteristics Discovery" },
+	{ "char-desc",		cmd_char_desc,	"[start hnd] [end hnd]",
+		"Characteristics Descriptor Discovery" },
 	{ NULL, NULL, NULL}
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 5/7] Add characteristics read options in interactive gatttool
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
                   ` (2 preceding siblings ...)
  2011-02-21 22:50 ` [PATCH 4/7] Add Characteristics Descriptor Discovery option in " Sheldon Demario
@ 2011-02-21 22:50 ` Sheldon Demario
  2011-02-21 22:50 ` [PATCH 6/7] Move attr_data_from_string() to utils.c Sheldon Demario
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-21 22:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

---
 attrib/interactive.c |  142 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 141 insertions(+), 1 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index 9389686..e9d74b9 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -50,6 +50,13 @@ static gchar *opt_sec_level = NULL;
 static int opt_psm = 0;
 static int opt_mtu = 0;
 
+struct characteristic_data {
+	uint16_t orig_start;
+	uint16_t start;
+	uint16_t end;
+	uuid_t uuid;
+};
+
 static void cmd_help(int argcp, char **argvp);
 
 enum state {
@@ -210,6 +217,79 @@ static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
 	rl_forced_update_display();
 }
 
+static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
+							gpointer user_data)
+{
+	uint8_t value[ATT_MAX_MTU];
+	int i, vlen;
+
+	if (status != 0) {
+		printf("Characteristic value/descriptor read failed: %s\n",
+							att_ecode2str(status));
+		return;
+	}
+
+	if (!dec_read_resp(pdu, plen, value, &vlen)) {
+		printf("Protocol error\n");
+		return;
+	}
+
+	printf("\nCharacteristic value/descriptor: ");
+	for (i = 0; i < vlen; i++)
+		printf("%02x ", value[i]);
+	printf("\n");
+
+	rl_forced_update_display();
+}
+
+static void char_read_by_uuid_cb(guint8 status, const guint8 *pdu,
+					guint16 plen, gpointer user_data)
+{
+	struct characteristic_data *char_data = user_data;
+	struct att_data_list *list;
+	int i;
+
+	if (status == ATT_ECODE_ATTR_NOT_FOUND &&
+				char_data->start != char_data->orig_start)
+		goto done;
+
+	if (status != 0) {
+		printf("Read characteristics by UUID failed: %s\n",
+							att_ecode2str(status));
+		goto done;
+	}
+
+	list = dec_read_by_type_resp(pdu, plen);
+	if (list == NULL)
+		goto done;
+
+	for (i = 0; i < list->num; i++) {
+		uint8_t *value = list->data[i];
+		int j;
+
+		char_data->start = att_get_u16(value) + 1;
+
+		printf("\nhandle: 0x%04x \t value: ", att_get_u16(value));
+		value += 2;
+		for (j = 0; j < list->len - 2; j++, value++)
+			printf("%02x ", *value);
+		printf("\n");
+	}
+
+	att_data_list_free(list);
+
+	gatt_read_char_by_uuid(attrib, char_data->start, char_data->end,
+					&char_data->uuid, char_read_by_uuid_cb,
+					char_data);
+
+	rl_forced_update_display();
+
+	return;
+
+done:
+	g_free(char_data);
+}
+
 static void cmd_exit(int argcp, char **argvp)
 {
 	rl_callback_handler_remove();
@@ -346,6 +426,62 @@ static void cmd_char_desc(int argcp, char **argvp)
 	return;
 }
 
+static void cmd_read_hnd(int argcp, char **argvp)
+{
+	int handle;
+
+	if (argcp < 2) {
+		printf("Missing argument: handle\n");
+		return;
+	}
+
+	if (strtohandle(&handle, argvp[1])) {
+		printf("Invalid handle: %s\n", argvp[1]);
+		return;
+	}
+
+	gatt_read_char(attrib, handle, char_read_cb, attrib);
+
+	return;
+}
+
+static void cmd_read_uuid(int argcp, char **argvp)
+{
+	struct characteristic_data *char_data;
+	int start = 0x0001;
+	int end = 0xffff;
+	uuid_t uuid;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (argcp < 2) {
+		printf("Missing argument: UUID\n");
+		return;
+	}
+
+	if (bt_string2uuid(&uuid, argvp[1]) < 0) {
+		printf("Invalid UUID\n");
+		return;
+	}
+
+	if (set_handles(&start, &end, argcp - 1, argvp + 1))
+		return;
+
+	char_data = g_new(struct characteristic_data, 1);
+	char_data->orig_start = start;
+	char_data->start = start;
+	char_data->end = end;
+	char_data->uuid = uuid;
+
+	gatt_read_char_by_uuid(attrib, start, end, &char_data->uuid,
+					char_read_by_uuid_cb, char_data);
+
+	return;
+}
+
 static struct {
 	const char *cmd;
 	void (*func)(int argcp, char **argvp);
@@ -366,6 +502,10 @@ static struct {
 		"Characteristics Discovery" },
 	{ "char-desc",		cmd_char_desc,	"[start hnd] [end hnd]",
 		"Characteristics Descriptor Discovery" },
+	{ "char-read-hnd",	cmd_read_hnd,	"<handle>",
+		"Characteristics Value/Descriptor Read by handle" },
+	{ "char-read-uuid",	cmd_read_uuid,	"<UUID> [start hnd] [end hnd]",
+		"Characteristics Value/Descriptor Read by UUID" },
 	{ NULL, NULL, NULL}
 };
 
@@ -374,7 +514,7 @@ static void cmd_help(int argcp, char **argvp)
 	int i;
 
 	for (i = 0; commands[i].cmd; i++)
-		printf("%-15s %-25s %s\n", commands[i].cmd,
+		printf("%-15s %-30s %s\n", commands[i].cmd,
 				commands[i].params, commands[i].desc);
 }
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 6/7] Move attr_data_from_string() to utils.c
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
                   ` (3 preceding siblings ...)
  2011-02-21 22:50 ` [PATCH 5/7] Add characteristics read options " Sheldon Demario
@ 2011-02-21 22:50 ` Sheldon Demario
  2011-02-21 22:50 ` [PATCH 7/7] Add Write Request in interactive gatttool Sheldon Demario
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-21 22:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Bruna Moreira

From: Bruna Moreira <bruna.moreira@openbossa.org>

The attr_data_from_string() function will be used in interactive and
usual gatttool so this function was moved to common file utils.c.
---
 attrib/gatttool.c |   23 ++---------------------
 attrib/gatttool.h |    1 +
 attrib/utils.c    |   19 +++++++++++++++++++
 3 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 7478043..d7887c6 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -313,25 +313,6 @@ static gboolean characteristics_read(gpointer user_data)
 	return FALSE;
 }
 
-static size_t attr_data_from_string(const char *str, uint8_t **data)
-{
-	char tmp[3];
-	size_t size, i;
-
-	size = strlen(str) / 2;
-	*data = g_try_malloc0(size);
-	if (*data == NULL)
-		return 0;
-
-	tmp[2] = '\0';
-	for (i = 0; i < size; i++) {
-		memcpy(tmp, str + (i * 2), 2);
-		(*data)[i] = (uint8_t) strtol(tmp, NULL, 16);
-	}
-
-	return size;
-}
-
 static void mainloop_quit(gpointer user_data)
 {
 	uint8_t *value = user_data;
@@ -356,7 +337,7 @@ static gboolean characteristics_write(gpointer user_data)
 		goto error;
 	}
 
-	len = attr_data_from_string(opt_value, &value);
+	len = gatt_attr_data_from_string(opt_value, &value);
 	if (len == 0) {
 		g_printerr("Invalid value\n");
 		goto error;
@@ -408,7 +389,7 @@ static gboolean characteristics_write_req(gpointer user_data)
 		goto error;
 	}
 
-	len = attr_data_from_string(opt_value, &value);
+	len = gatt_attr_data_from_string(opt_value, &value);
 	if (len == 0) {
 		g_printerr("Invalid value\n");
 		goto error;
diff --git a/attrib/gatttool.h b/attrib/gatttool.h
index 7eae18d..2fd4a46 100644
--- a/attrib/gatttool.h
+++ b/attrib/gatttool.h
@@ -25,3 +25,4 @@ int interactive(gchar *dst, gboolean le);
 GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
 			const gchar *sec_level, int psm, int mtu,
 			BtIOConnect connect_cb);
+size_t gatt_attr_data_from_string(const char *str, uint8_t **data);
diff --git a/attrib/utils.c b/attrib/utils.c
index 4d0000d..8d1ca74 100644
--- a/attrib/utils.c
+++ b/attrib/utils.c
@@ -104,3 +104,22 @@ GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
 
 	return chan;
 }
+
+size_t gatt_attr_data_from_string(const char *str, uint8_t **data)
+{
+	char tmp[3];
+	size_t size, i;
+
+	size = strlen(str) / 2;
+	*data = g_try_malloc0(size);
+	if (*data == NULL)
+		return 0;
+
+	tmp[2] = '\0';
+	for (i = 0; i < size; i++) {
+		memcpy(tmp, str + (i * 2), 2);
+		(*data)[i] = (uint8_t) strtol(tmp, NULL, 16);
+	}
+
+	return size;
+}
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 7/7] Add Write Request in interactive gatttool
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
                   ` (4 preceding siblings ...)
  2011-02-21 22:50 ` [PATCH 6/7] Move attr_data_from_string() to utils.c Sheldon Demario
@ 2011-02-21 22:50 ` Sheldon Demario
  2011-02-22 19:11 ` [PATCH v2 1/7] Improve help messages " Sheldon Demario
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-21 22:50 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Bruna Moreira

From: Bruna Moreira <bruna.moreira@openbossa.org>

---
 attrib/interactive.c |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index e9d74b9..30e9f60 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -482,6 +482,51 @@ static void cmd_read_uuid(int argcp, char **argvp)
 	return;
 }
 
+static void char_write_req_cb(guint8 status, const guint8 *pdu, guint16 plen,
+							gpointer user_data)
+{
+	if (status != 0) {
+		printf("Characteristic Write Request failed: "
+						"%s\n", att_ecode2str(status));
+		return;
+	}
+
+	if (!dec_write_resp(pdu, plen)) {
+		printf("Protocol error\n");
+		return;
+	}
+
+	printf("Characteristic value was written successfully\n");
+}
+
+static void cmd_char_write_req(int argcp, char **argvp)
+{
+	uint8_t *value;
+	size_t plen;
+	int handle;
+
+	if (argcp < 3) {
+		printf("Usage: char-write-req <handle> <new value>\n");
+		return;
+	}
+
+	handle = strtoll(argvp[1], NULL, 16);
+	if (errno != 0 || handle <= 0) {
+		printf("A valid handle is required\n");
+		return;
+	}
+
+	plen = gatt_attr_data_from_string(argvp[2], &value);
+	if (plen == 0) {
+		g_printerr("Invalid value\n");
+		return;
+	}
+
+	gatt_write_char(attrib, handle, value, plen, char_write_req_cb, NULL);
+
+	g_free(value);
+}
+
 static struct {
 	const char *cmd;
 	void (*func)(int argcp, char **argvp);
@@ -506,6 +551,8 @@ static struct {
 		"Characteristics Value/Descriptor Read by handle" },
 	{ "char-read-uuid",	cmd_read_uuid,	"<UUID> [start hnd] [end hnd]",
 		"Characteristics Value/Descriptor Read by UUID" },
+	{ "char-write-req",	cmd_char_write_req,	"<handle> <new value>",
+		"Characteristic Value Write (Write Request)"},
 	{ NULL, NULL, NULL}
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 1/7] Improve help messages in interactive gatttool
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
                   ` (5 preceding siblings ...)
  2011-02-21 22:50 ` [PATCH 7/7] Add Write Request in interactive gatttool Sheldon Demario
@ 2011-02-22 19:11 ` Sheldon Demario
  2011-02-22 19:11 ` [PATCH v2 2/7] Add Characteristics Discovery option to " Sheldon Demario
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-22 19:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

Includes the parameters info on help.
---
 attrib/interactive.c |   19 +++++++++++++------
 1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index edc465a..b491314 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -217,13 +217,19 @@ static void cmd_primary(int argcp, char **argvp)
 static struct {
 	const char *cmd;
 	void (*func)(int argcp, char **argvp);
+	const char *params;
 	const char *desc;
 } commands[] = {
-	{ "help",	cmd_help,	"Show this help"},
-	{ "exit",	cmd_exit,	"Exit interactive mode"},
-	{ "connect",	cmd_connect,	"Connect to a remote device"},
-	{ "disconnect",	cmd_disconnect,	"Disconnect from a remote device"},
-	{ "primary",	cmd_primary,	"Primary Service Discovery"},
+	{ "help",		cmd_help,	"",
+		"Show this help"},
+	{ "exit",		cmd_exit,	"",
+		"Exit interactive mode" },
+	{ "connect",		cmd_connect,	"[address]",
+		"Connect to a remote device" },
+	{ "disconnect",		cmd_disconnect,	"",
+		"Disconnect from a remote device" },
+	{ "primary",		cmd_primary,	"[UUID]",
+		"Primary Service Discovery" },
 	{ NULL, NULL, NULL}
 };
 
@@ -232,7 +238,8 @@ static void cmd_help(int argcp, char **argvp)
 	int i;
 
 	for (i = 0; commands[i].cmd; i++)
-		printf("%-12s\t%s\n", commands[i].cmd, commands[i].desc);
+		printf("%-15s %-25s %s\n", commands[i].cmd,
+				commands[i].params, commands[i].desc);
 }
 
 static void parse_line(char *line_read)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 2/7] Add Characteristics Discovery option to interactive gatttool
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
                   ` (6 preceding siblings ...)
  2011-02-22 19:11 ` [PATCH v2 1/7] Improve help messages " Sheldon Demario
@ 2011-02-22 19:11 ` Sheldon Demario
  2011-02-22 19:12 ` [PATCH v2 3/7] Create helper functions to deal with handles on " Sheldon Demario
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-22 19:11 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

---
 attrib/interactive.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index b491314..7cc03bc 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -22,6 +22,7 @@
  */
 #include <string.h>
 #include <stdlib.h>
+#include <errno.h>
 #include <stdio.h>
 #include <glib.h>
 
@@ -145,6 +146,29 @@ static void primary_by_uuid_cb(GSList *ranges, guint8 status,
 	rl_forced_update_display();
 }
 
+static void char_cb(GSList *characteristics, guint8 status, gpointer user_data)
+{
+	GSList *l;
+
+	if (status) {
+		printf("Discover all characteristics failed: %s\n",
+							att_ecode2str(status));
+		return;
+	}
+
+	printf("\n");
+	for (l = characteristics; l; l = l->next) {
+		struct att_char *chars = l->data;
+
+		printf("handle: 0x%04x, char properties: 0x%02x, char value "
+				"handle: 0x%04x, uuid: %s\n", chars->handle,
+				chars->properties, chars->value_handle,
+				chars->uuid);
+	}
+
+	rl_forced_update_display();
+}
+
 static void cmd_exit(int argcp, char **argvp)
 {
 	rl_callback_handler_remove();
@@ -214,6 +238,41 @@ static void cmd_primary(int argcp, char **argvp)
 	gatt_discover_primary(attrib, &uuid, primary_by_uuid_cb, NULL);
 }
 
+static void cmd_char(int argcp, char **argvp)
+{
+	int start = 0x0001;
+	int end = 0xffff;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (argcp > 1) {
+		char *e;
+
+		start = strtoll(argvp[1], &e, 16);
+		if (errno != 0 || *e != '\0') {
+			printf("Invalid start handle: %s\n", argvp[1]);
+			return;
+		}
+	}
+
+	if (argcp > 2) {
+		char *e;
+
+		end = strtoll(argvp[2], &e, 16);
+		if (errno != 0 || *e != '\0') {
+			printf("Invalid end handle: %s\n", argvp[2]);
+			return;
+		}
+	}
+
+	gatt_discover_char(attrib, start, end, char_cb, NULL);
+
+	return;
+}
+
 static struct {
 	const char *cmd;
 	void (*func)(int argcp, char **argvp);
@@ -230,6 +289,8 @@ static struct {
 		"Disconnect from a remote device" },
 	{ "primary",		cmd_primary,	"[UUID]",
 		"Primary Service Discovery" },
+	{ "characteristics",	cmd_char,	"[start hnd] [end hnd]",
+		"Characteristics Discovery" },
 	{ NULL, NULL, NULL}
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 3/7] Create helper functions to deal with handles on interactive gatttool
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
                   ` (7 preceding siblings ...)
  2011-02-22 19:11 ` [PATCH v2 2/7] Add Characteristics Discovery option to " Sheldon Demario
@ 2011-02-22 19:12 ` Sheldon Demario
  2011-02-23  3:09   ` Johan Hedberg
  2011-02-22 19:12 ` [PATCH v2 4/7] Add Characteristics Descriptor Discovery option in " Sheldon Demario
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 20+ messages in thread
From: Sheldon Demario @ 2011-02-22 19:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

---
 attrib/interactive.c |   46 ++++++++++++++++++++++++++++++----------------
 1 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index 7cc03bc..e9f6019 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -238,36 +238,50 @@ static void cmd_primary(int argcp, char **argvp)
 	gatt_discover_primary(attrib, &uuid, primary_by_uuid_cb, NULL);
 }
 
-static void cmd_char(int argcp, char **argvp)
+static int strtohandle(int *dst, const char *src)
 {
-	int start = 0x0001;
-	int end = 0xffff;
+	char *e;
 
-	if (conn_state != STATE_CONNECTED) {
-		printf("Command failed: disconnected\n");
-		return;
+	*dst = strtoll(src, &e, 16);
+	if (errno != 0 || *e != '\0') {
+		return -1;
 	}
 
-	if (argcp > 1) {
-		char *e;
+	return 0;
+}
 
-		start = strtoll(argvp[1], &e, 16);
-		if (errno != 0 || *e != '\0') {
+static int set_handles(int *start, int *end, int argcp, char **argvp)
+{
+	if (argcp > 1) {
+		if (strtohandle(start, argvp[1])) {
 			printf("Invalid start handle: %s\n", argvp[1]);
-			return;
+			return -1;
 		}
 	}
 
 	if (argcp > 2) {
-		char *e;
-
-		end = strtoll(argvp[2], &e, 16);
-		if (errno != 0 || *e != '\0') {
+		if (strtohandle(end, argvp[2])) {
 			printf("Invalid end handle: %s\n", argvp[2]);
-			return;
+			return -1;
 		}
 	}
 
+	return 0;
+}
+
+static void cmd_char(int argcp, char **argvp)
+{
+	int start = 0x0001;
+	int end = 0xffff;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (set_handles(&start, &end, argcp, argvp))
+		return;
+
 	gatt_discover_char(attrib, start, end, char_cb, NULL);
 
 	return;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 4/7] Add Characteristics Descriptor Discovery option in interactive gatttool
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
                   ` (8 preceding siblings ...)
  2011-02-22 19:12 ` [PATCH v2 3/7] Create helper functions to deal with handles on " Sheldon Demario
@ 2011-02-22 19:12 ` Sheldon Demario
  2011-02-22 19:12 ` [PATCH v2 5/7] Add characteristics read options " Sheldon Demario
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-22 19:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

---
 attrib/interactive.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index e9f6019..9389686 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -169,6 +169,47 @@ static void char_cb(GSList *characteristics, guint8 status, gpointer user_data)
 	rl_forced_update_display();
 }
 
+static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
+							gpointer user_data)
+{
+	struct att_data_list *list;
+	guint8 format;
+	int i;
+
+	if (status != 0) {
+		printf("Discover all characteristic descriptors failed: "
+						"%s\n", att_ecode2str(status));
+		return;
+	}
+
+	list = dec_find_info_resp(pdu, plen, &format);
+	if (list == NULL)
+		return;
+
+	printf("\n");
+	for (i = 0; i < list->num; i++) {
+		char uuidstr[MAX_LEN_UUID_STR];
+		uint16_t handle;
+		uint8_t *value;
+		uuid_t uuid;
+
+		value = list->data[i];
+		handle = att_get_u16(value);
+
+		if (format == 0x01)
+			sdp_uuid16_create(&uuid, att_get_u16(&value[2]));
+		else
+			sdp_uuid128_create(&uuid, &value[2]);
+
+		sdp_uuid2strn(&uuid, uuidstr, MAX_LEN_UUID_STR);
+		printf("handle: 0x%04x, uuid: %s\n", handle, uuidstr);
+	}
+
+	att_data_list_free(list);
+
+	rl_forced_update_display();
+}
+
 static void cmd_exit(int argcp, char **argvp)
 {
 	rl_callback_handler_remove();
@@ -287,6 +328,24 @@ static void cmd_char(int argcp, char **argvp)
 	return;
 }
 
+static void cmd_char_desc(int argcp, char **argvp)
+{
+	int start = 0x0001;
+	int end = 0xffff;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (set_handles(&start, &end, argcp, argvp))
+		return;
+
+	gatt_find_info(attrib, start, end, char_desc_cb, NULL);
+
+	return;
+}
+
 static struct {
 	const char *cmd;
 	void (*func)(int argcp, char **argvp);
@@ -305,6 +364,8 @@ static struct {
 		"Primary Service Discovery" },
 	{ "characteristics",	cmd_char,	"[start hnd] [end hnd]",
 		"Characteristics Discovery" },
+	{ "char-desc",		cmd_char_desc,	"[start hnd] [end hnd]",
+		"Characteristics Descriptor Discovery" },
 	{ NULL, NULL, NULL}
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 5/7] Add characteristics read options in interactive gatttool
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
                   ` (9 preceding siblings ...)
  2011-02-22 19:12 ` [PATCH v2 4/7] Add Characteristics Descriptor Discovery option in " Sheldon Demario
@ 2011-02-22 19:12 ` Sheldon Demario
  2011-02-22 19:12 ` [PATCH v2 6/7] Move attr_data_from_string() to utils.c Sheldon Demario
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-22 19:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

---

Add forgoten conn_state check on cmd_read_hnd()

 attrib/interactive.c |  147 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 146 insertions(+), 1 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index 9389686..a1c5671 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -50,6 +50,13 @@ static gchar *opt_sec_level = NULL;
 static int opt_psm = 0;
 static int opt_mtu = 0;
 
+struct characteristic_data {
+	uint16_t orig_start;
+	uint16_t start;
+	uint16_t end;
+	uuid_t uuid;
+};
+
 static void cmd_help(int argcp, char **argvp);
 
 enum state {
@@ -210,6 +217,79 @@ static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
 	rl_forced_update_display();
 }
 
+static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
+							gpointer user_data)
+{
+	uint8_t value[ATT_MAX_MTU];
+	int i, vlen;
+
+	if (status != 0) {
+		printf("Characteristic value/descriptor read failed: %s\n",
+							att_ecode2str(status));
+		return;
+	}
+
+	if (!dec_read_resp(pdu, plen, value, &vlen)) {
+		printf("Protocol error\n");
+		return;
+	}
+
+	printf("\nCharacteristic value/descriptor: ");
+	for (i = 0; i < vlen; i++)
+		printf("%02x ", value[i]);
+	printf("\n");
+
+	rl_forced_update_display();
+}
+
+static void char_read_by_uuid_cb(guint8 status, const guint8 *pdu,
+					guint16 plen, gpointer user_data)
+{
+	struct characteristic_data *char_data = user_data;
+	struct att_data_list *list;
+	int i;
+
+	if (status == ATT_ECODE_ATTR_NOT_FOUND &&
+				char_data->start != char_data->orig_start)
+		goto done;
+
+	if (status != 0) {
+		printf("Read characteristics by UUID failed: %s\n",
+							att_ecode2str(status));
+		goto done;
+	}
+
+	list = dec_read_by_type_resp(pdu, plen);
+	if (list == NULL)
+		goto done;
+
+	for (i = 0; i < list->num; i++) {
+		uint8_t *value = list->data[i];
+		int j;
+
+		char_data->start = att_get_u16(value) + 1;
+
+		printf("\nhandle: 0x%04x \t value: ", att_get_u16(value));
+		value += 2;
+		for (j = 0; j < list->len - 2; j++, value++)
+			printf("%02x ", *value);
+		printf("\n");
+	}
+
+	att_data_list_free(list);
+
+	gatt_read_char_by_uuid(attrib, char_data->start, char_data->end,
+					&char_data->uuid, char_read_by_uuid_cb,
+					char_data);
+
+	rl_forced_update_display();
+
+	return;
+
+done:
+	g_free(char_data);
+}
+
 static void cmd_exit(int argcp, char **argvp)
 {
 	rl_callback_handler_remove();
@@ -346,6 +426,67 @@ static void cmd_char_desc(int argcp, char **argvp)
 	return;
 }
 
+static void cmd_read_hnd(int argcp, char **argvp)
+{
+	int handle;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (argcp < 2) {
+		printf("Missing argument: handle\n");
+		return;
+	}
+
+	if (strtohandle(&handle, argvp[1])) {
+		printf("Invalid handle: %s\n", argvp[1]);
+		return;
+	}
+
+	gatt_read_char(attrib, handle, char_read_cb, attrib);
+
+	return;
+}
+
+static void cmd_read_uuid(int argcp, char **argvp)
+{
+	struct characteristic_data *char_data;
+	int start = 0x0001;
+	int end = 0xffff;
+	uuid_t uuid;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (argcp < 2) {
+		printf("Missing argument: UUID\n");
+		return;
+	}
+
+	if (bt_string2uuid(&uuid, argvp[1]) < 0) {
+		printf("Invalid UUID\n");
+		return;
+	}
+
+	if (set_handles(&start, &end, argcp - 1, argvp + 1))
+		return;
+
+	char_data = g_new(struct characteristic_data, 1);
+	char_data->orig_start = start;
+	char_data->start = start;
+	char_data->end = end;
+	char_data->uuid = uuid;
+
+	gatt_read_char_by_uuid(attrib, start, end, &char_data->uuid,
+					char_read_by_uuid_cb, char_data);
+
+	return;
+}
+
 static struct {
 	const char *cmd;
 	void (*func)(int argcp, char **argvp);
@@ -366,6 +507,10 @@ static struct {
 		"Characteristics Discovery" },
 	{ "char-desc",		cmd_char_desc,	"[start hnd] [end hnd]",
 		"Characteristics Descriptor Discovery" },
+	{ "char-read-hnd",	cmd_read_hnd,	"<handle>",
+		"Characteristics Value/Descriptor Read by handle" },
+	{ "char-read-uuid",	cmd_read_uuid,	"<UUID> [start hnd] [end hnd]",
+		"Characteristics Value/Descriptor Read by UUID" },
 	{ NULL, NULL, NULL}
 };
 
@@ -374,7 +519,7 @@ static void cmd_help(int argcp, char **argvp)
 	int i;
 
 	for (i = 0; commands[i].cmd; i++)
-		printf("%-15s %-25s %s\n", commands[i].cmd,
+		printf("%-15s %-30s %s\n", commands[i].cmd,
 				commands[i].params, commands[i].desc);
 }
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 6/7] Move attr_data_from_string() to utils.c
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
                   ` (10 preceding siblings ...)
  2011-02-22 19:12 ` [PATCH v2 5/7] Add characteristics read options " Sheldon Demario
@ 2011-02-22 19:12 ` Sheldon Demario
  2011-02-22 19:12 ` [PATCH v2 7/7] Add Write Request in interactive gatttool Sheldon Demario
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-22 19:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Bruna Moreira

From: Bruna Moreira <bruna.moreira@openbossa.org>

The attr_data_from_string() function will be used in interactive and
usual gatttool so this function was moved to common file utils.c.
---
 attrib/gatttool.c |   23 ++---------------------
 attrib/gatttool.h |    1 +
 attrib/utils.c    |   19 +++++++++++++++++++
 3 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 7478043..d7887c6 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -313,25 +313,6 @@ static gboolean characteristics_read(gpointer user_data)
 	return FALSE;
 }
 
-static size_t attr_data_from_string(const char *str, uint8_t **data)
-{
-	char tmp[3];
-	size_t size, i;
-
-	size = strlen(str) / 2;
-	*data = g_try_malloc0(size);
-	if (*data == NULL)
-		return 0;
-
-	tmp[2] = '\0';
-	for (i = 0; i < size; i++) {
-		memcpy(tmp, str + (i * 2), 2);
-		(*data)[i] = (uint8_t) strtol(tmp, NULL, 16);
-	}
-
-	return size;
-}
-
 static void mainloop_quit(gpointer user_data)
 {
 	uint8_t *value = user_data;
@@ -356,7 +337,7 @@ static gboolean characteristics_write(gpointer user_data)
 		goto error;
 	}
 
-	len = attr_data_from_string(opt_value, &value);
+	len = gatt_attr_data_from_string(opt_value, &value);
 	if (len == 0) {
 		g_printerr("Invalid value\n");
 		goto error;
@@ -408,7 +389,7 @@ static gboolean characteristics_write_req(gpointer user_data)
 		goto error;
 	}
 
-	len = attr_data_from_string(opt_value, &value);
+	len = gatt_attr_data_from_string(opt_value, &value);
 	if (len == 0) {
 		g_printerr("Invalid value\n");
 		goto error;
diff --git a/attrib/gatttool.h b/attrib/gatttool.h
index 7eae18d..2fd4a46 100644
--- a/attrib/gatttool.h
+++ b/attrib/gatttool.h
@@ -25,3 +25,4 @@ int interactive(gchar *dst, gboolean le);
 GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
 			const gchar *sec_level, int psm, int mtu,
 			BtIOConnect connect_cb);
+size_t gatt_attr_data_from_string(const char *str, uint8_t **data);
diff --git a/attrib/utils.c b/attrib/utils.c
index 4d0000d..8d1ca74 100644
--- a/attrib/utils.c
+++ b/attrib/utils.c
@@ -104,3 +104,22 @@ GIOChannel *gatt_connect(const gchar *src, const gchar *dst,
 
 	return chan;
 }
+
+size_t gatt_attr_data_from_string(const char *str, uint8_t **data)
+{
+	char tmp[3];
+	size_t size, i;
+
+	size = strlen(str) / 2;
+	*data = g_try_malloc0(size);
+	if (*data == NULL)
+		return 0;
+
+	tmp[2] = '\0';
+	for (i = 0; i < size; i++) {
+		memcpy(tmp, str + (i * 2), 2);
+		(*data)[i] = (uint8_t) strtol(tmp, NULL, 16);
+	}
+
+	return size;
+}
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 7/7] Add Write Request in interactive gatttool
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
                   ` (11 preceding siblings ...)
  2011-02-22 19:12 ` [PATCH v2 6/7] Move attr_data_from_string() to utils.c Sheldon Demario
@ 2011-02-22 19:12 ` Sheldon Demario
  2011-02-24 13:54 ` [PATCH v3 4/7] Add Characteristics Descriptor Discovery option " Sheldon Demario
  2011-02-24 13:55 ` [PATCH v3 5/7] Add characteristics read options " Sheldon Demario
  14 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-22 19:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Bruna Moreira

From: Bruna Moreira <bruna.moreira@openbossa.org>

---

Add forgoten conn_state check on cmd_char_write_req()

 attrib/interactive.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index a1c5671..9af3daa 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -487,6 +487,56 @@ static void cmd_read_uuid(int argcp, char **argvp)
 	return;
 }
 
+static void char_write_req_cb(guint8 status, const guint8 *pdu, guint16 plen,
+							gpointer user_data)
+{
+	if (status != 0) {
+		printf("Characteristic Write Request failed: "
+						"%s\n", att_ecode2str(status));
+		return;
+	}
+
+	if (!dec_write_resp(pdu, plen)) {
+		printf("Protocol error\n");
+		return;
+	}
+
+	printf("Characteristic value was written successfully\n");
+}
+
+static void cmd_char_write_req(int argcp, char **argvp)
+{
+	uint8_t *value;
+	size_t plen;
+	int handle;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (argcp < 3) {
+		printf("Usage: char-write-req <handle> <new value>\n");
+		return;
+	}
+
+	handle = strtoll(argvp[1], NULL, 16);
+	if (errno != 0 || handle <= 0) {
+		printf("A valid handle is required\n");
+		return;
+	}
+
+	plen = gatt_attr_data_from_string(argvp[2], &value);
+	if (plen == 0) {
+		g_printerr("Invalid value\n");
+		return;
+	}
+
+	gatt_write_char(attrib, handle, value, plen, char_write_req_cb, NULL);
+
+	g_free(value);
+}
+
 static struct {
 	const char *cmd;
 	void (*func)(int argcp, char **argvp);
@@ -511,6 +561,8 @@ static struct {
 		"Characteristics Value/Descriptor Read by handle" },
 	{ "char-read-uuid",	cmd_read_uuid,	"<UUID> [start hnd] [end hnd]",
 		"Characteristics Value/Descriptor Read by UUID" },
+	{ "char-write-req",	cmd_char_write_req,	"<handle> <new value>",
+		"Characteristic Value Write (Write Request)" },
 	{ NULL, NULL, NULL}
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 3/7] Create helper functions to deal with handles on interactive gatttool
  2011-02-22 19:12 ` [PATCH v2 3/7] Create helper functions to deal with handles on " Sheldon Demario
@ 2011-02-23  3:09   ` Johan Hedberg
  2011-02-23 12:21     ` Anderson Lizardo
                       ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Johan Hedberg @ 2011-02-23  3:09 UTC (permalink / raw)
  To: Sheldon Demario; +Cc: linux-bluetooth

Hi Sheldon,

On Tue, Feb 22, 2011, Sheldon Demario wrote:
> +	*dst = strtoll(src, &e, 16);
> +	if (errno != 0 || *e != '\0') {
> +		return -1;
>  	}

Firstly, you've got a coding style issue here: no {} for one-line
scopes. Secondly, are you sure that this is the right way to check for
strtoll failure? If there was some earlier libc function that failed
errno might be set to != 0 even if strtoll succeeds, right? Or are all
errno using libc functions guaranteed to set errno to 0 on success?
Reading the man-page of strtoll it seems you should be checking for
LLONG_MIN and LLONG_MAX return values.

I've pushed the first two patches since they were fine, but I'll stop
here until we get some clarification on this matter.

Johan

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 3/7] Create helper functions to deal with handles on interactive gatttool
  2011-02-23  3:09   ` Johan Hedberg
@ 2011-02-23 12:21     ` Anderson Lizardo
  2011-02-23 13:23     ` Sheldon Demario
  2011-02-23 14:20     ` [PATCH v3 " Sheldon Demario
  2 siblings, 0 replies; 20+ messages in thread
From: Anderson Lizardo @ 2011-02-23 12:21 UTC (permalink / raw)
  To: Sheldon Demario, linux-bluetooth; +Cc: Johan Hedberg

Hi Johan,

On Wed, Feb 23, 2011 at 12:09 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Sheldon,
>
> On Tue, Feb 22, 2011, Sheldon Demario wrote:
>> +     *dst = strtoll(src, &e, 16);
>> +     if (errno != 0 || *e != '\0') {
>> +             return -1;
>>       }
>
> Firstly, you've got a coding style issue here: no {} for one-line
> scopes. Secondly, are you sure that this is the right way to check for
> strtoll failure? If there was some earlier libc function that failed
> errno might be set to != 0 even if strtoll succeeds, right? Or are all
> errno using libc functions guaranteed to set errno to 0 on success?
> Reading the man-page of strtoll it seems you should be checking for
> LLONG_MIN and LLONG_MAX return values.

Looking at "man errno", it is not guaranteed for errno to be set to
zero on success, therefore the recommended way is to set it to zero
prior to calling the function to be checked.

The NOTES section from "man strtoll" recommends using errno when
checking for errors:

"Since strtol() can legitimately return 0, LONG_MAX, or LONG_MIN
(LLONG_MAX or LLONG_MIN for strtoll()) on both success and failure,
the calling program  should  set errno to 0 before the call, and then
determine if an error occurred by checking whether errno has a
non-zero value after the call."

So I think the only missing bit here it to set errno to zero prior to
calling strtoll()

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 3/7] Create helper functions to deal with handles on interactive gatttool
  2011-02-23  3:09   ` Johan Hedberg
  2011-02-23 12:21     ` Anderson Lizardo
@ 2011-02-23 13:23     ` Sheldon Demario
  2011-02-23 14:20     ` [PATCH v3 " Sheldon Demario
  2 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-23 13:23 UTC (permalink / raw)
  To: Sheldon Demario, linux-bluetooth; +Cc: Johan Hedberg

Hi Johan

On Wed, Feb 23, 2011 at 12:09 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Sheldon,
>
> On Tue, Feb 22, 2011, Sheldon Demario wrote:
>> +     *dst = strtoll(src, &e, 16);
>> +     if (errno != 0 || *e != '\0') {
>> +             return -1;
>>       }
>
> Firstly, you've got a coding style issue here: no {} for one-line
> scopes. Secondly, are you sure that this is the right way to check for
> strtoll failure? If there was some earlier libc function that failed
> errno might be set to != 0 even if strtoll succeeds, right? Or are all
> errno using libc functions guaranteed to set errno to 0 on success?
> Reading the man-page of strtoll it seems you should be checking for
> LLONG_MIN and LLONG_MAX return values.

If strtoll() returns LLONG_MIN or LLONG_MAX the errno is set to ERANGE
so it is not need to check for these returning values. However, as
Lizardo said, the errno must be set to 0 before strtoll() be called,
so will send this fix.

Sheldon.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v3 3/7] Create helper functions to deal with handles on interactive gatttool
  2011-02-23  3:09   ` Johan Hedberg
  2011-02-23 12:21     ` Anderson Lizardo
  2011-02-23 13:23     ` Sheldon Demario
@ 2011-02-23 14:20     ` Sheldon Demario
  2 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-23 14:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

---
 attrib/interactive.c |   48 +++++++++++++++++++++++++++++++-----------------
 1 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index 7cc03bc..ed45894 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -238,36 +238,50 @@ static void cmd_primary(int argcp, char **argvp)
 	gatt_discover_primary(attrib, &uuid, primary_by_uuid_cb, NULL);
 }
 
-static void cmd_char(int argcp, char **argvp)
+static int strtohandle(int *dst, const char *src)
 {
-	int start = 0x0001;
-	int end = 0xffff;
+	char *e;
 
-	if (conn_state != STATE_CONNECTED) {
-		printf("Command failed: disconnected\n");
-		return;
-	}
+	errno = 0;
+	*dst = strtoll(src, &e, 16);
+	if (errno != 0 || *e != '\0')
+		return -1;
 
-	if (argcp > 1) {
-		char *e;
+	return 0;
+}
 
-		start = strtoll(argvp[1], &e, 16);
-		if (errno != 0 || *e != '\0') {
+static int set_handles(int *start, int *end, int argcp, char **argvp)
+{
+	if (argcp > 1) {
+		if (strtohandle(start, argvp[1])) {
 			printf("Invalid start handle: %s\n", argvp[1]);
-			return;
+			return -1;
 		}
 	}
 
 	if (argcp > 2) {
-		char *e;
-
-		end = strtoll(argvp[2], &e, 16);
-		if (errno != 0 || *e != '\0') {
+		if (strtohandle(end, argvp[2])) {
 			printf("Invalid end handle: %s\n", argvp[2]);
-			return;
+			return -1;
 		}
 	}
 
+	return 0;
+}
+
+static void cmd_char(int argcp, char **argvp)
+{
+	int start = 0x0001;
+	int end = 0xffff;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (set_handles(&start, &end, argcp, argvp))
+		return;
+
 	gatt_discover_char(attrib, start, end, char_cb, NULL);
 
 	return;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 4/7] Add Characteristics Descriptor Discovery option in interactive gatttool
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
                   ` (12 preceding siblings ...)
  2011-02-22 19:12 ` [PATCH v2 7/7] Add Write Request in interactive gatttool Sheldon Demario
@ 2011-02-24 13:54 ` Sheldon Demario
  2011-02-24 13:55 ` [PATCH v3 5/7] Add characteristics read options " Sheldon Demario
  14 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-24 13:54 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

---

Remove return statements at the end of void functions.

 attrib/interactive.c |   59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index ed45894..b00d0bc 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -169,6 +169,47 @@ static void char_cb(GSList *characteristics, guint8 status, gpointer user_data)
 	rl_forced_update_display();
 }
 
+static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
+							gpointer user_data)
+{
+	struct att_data_list *list;
+	guint8 format;
+	int i;
+
+	if (status != 0) {
+		printf("Discover all characteristic descriptors failed: "
+						"%s\n", att_ecode2str(status));
+		return;
+	}
+
+	list = dec_find_info_resp(pdu, plen, &format);
+	if (list == NULL)
+		return;
+
+	printf("\n");
+	for (i = 0; i < list->num; i++) {
+		char uuidstr[MAX_LEN_UUID_STR];
+		uint16_t handle;
+		uint8_t *value;
+		uuid_t uuid;
+
+		value = list->data[i];
+		handle = att_get_u16(value);
+
+		if (format == 0x01)
+			sdp_uuid16_create(&uuid, att_get_u16(&value[2]));
+		else
+			sdp_uuid128_create(&uuid, &value[2]);
+
+		sdp_uuid2strn(&uuid, uuidstr, MAX_LEN_UUID_STR);
+		printf("handle: 0x%04x, uuid: %s\n", handle, uuidstr);
+	}
+
+	att_data_list_free(list);
+
+	rl_forced_update_display();
+}
+
 static void cmd_exit(int argcp, char **argvp)
 {
 	rl_callback_handler_remove();
@@ -287,6 +328,22 @@ static void cmd_char(int argcp, char **argvp)
 	return;
 }
 
+static void cmd_char_desc(int argcp, char **argvp)
+{
+	int start = 0x0001;
+	int end = 0xffff;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (set_handles(&start, &end, argcp, argvp))
+		return;
+
+	gatt_find_info(attrib, start, end, char_desc_cb, NULL);
+}
+
 static struct {
 	const char *cmd;
 	void (*func)(int argcp, char **argvp);
@@ -305,6 +362,8 @@ static struct {
 		"Primary Service Discovery" },
 	{ "characteristics",	cmd_char,	"[start hnd] [end hnd]",
 		"Characteristics Discovery" },
+	{ "char-desc",		cmd_char_desc,	"[start hnd] [end hnd]",
+		"Characteristics Descriptor Discovery" },
 	{ NULL, NULL, NULL}
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 5/7] Add characteristics read options in interactive gatttool
  2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
                   ` (13 preceding siblings ...)
  2011-02-24 13:54 ` [PATCH v3 4/7] Add Characteristics Descriptor Discovery option " Sheldon Demario
@ 2011-02-24 13:55 ` Sheldon Demario
  14 siblings, 0 replies; 20+ messages in thread
From: Sheldon Demario @ 2011-02-24 13:55 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sheldon Demario

---

Remove return statements at the end of void functions

 attrib/interactive.c |  143 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 142 insertions(+), 1 deletions(-)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index b00d0bc..7f3f658 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -50,6 +50,13 @@ static gchar *opt_sec_level = NULL;
 static int opt_psm = 0;
 static int opt_mtu = 0;
 
+struct characteristic_data {
+	uint16_t orig_start;
+	uint16_t start;
+	uint16_t end;
+	uuid_t uuid;
+};
+
 static void cmd_help(int argcp, char **argvp);
 
 enum state {
@@ -210,6 +217,79 @@ static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
 	rl_forced_update_display();
 }
 
+static void char_read_cb(guint8 status, const guint8 *pdu, guint16 plen,
+							gpointer user_data)
+{
+	uint8_t value[ATT_MAX_MTU];
+	int i, vlen;
+
+	if (status != 0) {
+		printf("Characteristic value/descriptor read failed: %s\n",
+							att_ecode2str(status));
+		return;
+	}
+
+	if (!dec_read_resp(pdu, plen, value, &vlen)) {
+		printf("Protocol error\n");
+		return;
+	}
+
+	printf("\nCharacteristic value/descriptor: ");
+	for (i = 0; i < vlen; i++)
+		printf("%02x ", value[i]);
+	printf("\n");
+
+	rl_forced_update_display();
+}
+
+static void char_read_by_uuid_cb(guint8 status, const guint8 *pdu,
+					guint16 plen, gpointer user_data)
+{
+	struct characteristic_data *char_data = user_data;
+	struct att_data_list *list;
+	int i;
+
+	if (status == ATT_ECODE_ATTR_NOT_FOUND &&
+				char_data->start != char_data->orig_start)
+		goto done;
+
+	if (status != 0) {
+		printf("Read characteristics by UUID failed: %s\n",
+							att_ecode2str(status));
+		goto done;
+	}
+
+	list = dec_read_by_type_resp(pdu, plen);
+	if (list == NULL)
+		goto done;
+
+	for (i = 0; i < list->num; i++) {
+		uint8_t *value = list->data[i];
+		int j;
+
+		char_data->start = att_get_u16(value) + 1;
+
+		printf("\nhandle: 0x%04x \t value: ", att_get_u16(value));
+		value += 2;
+		for (j = 0; j < list->len - 2; j++, value++)
+			printf("%02x ", *value);
+		printf("\n");
+	}
+
+	att_data_list_free(list);
+
+	gatt_read_char_by_uuid(attrib, char_data->start, char_data->end,
+					&char_data->uuid, char_read_by_uuid_cb,
+					char_data);
+
+	rl_forced_update_display();
+
+	return;
+
+done:
+	g_free(char_data);
+}
+
 static void cmd_exit(int argcp, char **argvp)
 {
 	rl_callback_handler_remove();
@@ -344,6 +424,63 @@ static void cmd_char_desc(int argcp, char **argvp)
 	gatt_find_info(attrib, start, end, char_desc_cb, NULL);
 }
 
+static void cmd_read_hnd(int argcp, char **argvp)
+{
+	int handle;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (argcp < 2) {
+		printf("Missing argument: handle\n");
+		return;
+	}
+
+	if (strtohandle(&handle, argvp[1])) {
+		printf("Invalid handle: %s\n", argvp[1]);
+		return;
+	}
+
+	gatt_read_char(attrib, handle, char_read_cb, attrib);
+}
+
+static void cmd_read_uuid(int argcp, char **argvp)
+{
+	struct characteristic_data *char_data;
+	int start = 0x0001;
+	int end = 0xffff;
+	uuid_t uuid;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (argcp < 2) {
+		printf("Missing argument: UUID\n");
+		return;
+	}
+
+	if (bt_string2uuid(&uuid, argvp[1]) < 0) {
+		printf("Invalid UUID\n");
+		return;
+	}
+
+	if (set_handles(&start, &end, argcp - 1, argvp + 1))
+		return;
+
+	char_data = g_new(struct characteristic_data, 1);
+	char_data->orig_start = start;
+	char_data->start = start;
+	char_data->end = end;
+	char_data->uuid = uuid;
+
+	gatt_read_char_by_uuid(attrib, start, end, &char_data->uuid,
+					char_read_by_uuid_cb, char_data);
+}
+
 static struct {
 	const char *cmd;
 	void (*func)(int argcp, char **argvp);
@@ -364,6 +501,10 @@ static struct {
 		"Characteristics Discovery" },
 	{ "char-desc",		cmd_char_desc,	"[start hnd] [end hnd]",
 		"Characteristics Descriptor Discovery" },
+	{ "char-read-hnd",	cmd_read_hnd,	"<handle>",
+		"Characteristics Value/Descriptor Read by handle" },
+	{ "char-read-uuid",	cmd_read_uuid,	"<UUID> [start hnd] [end hnd]",
+		"Characteristics Value/Descriptor Read by UUID" },
 	{ NULL, NULL, NULL}
 };
 
@@ -372,7 +513,7 @@ static void cmd_help(int argcp, char **argvp)
 	int i;
 
 	for (i = 0; commands[i].cmd; i++)
-		printf("%-15s %-25s %s\n", commands[i].cmd,
+		printf("%-15s %-30s %s\n", commands[i].cmd,
 				commands[i].params, commands[i].desc);
 }
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2011-02-24 13:55 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-21 22:50 [PATCH 1/7] Improve help messages in interactive gatttool Sheldon Demario
2011-02-21 22:50 ` [PATCH 2/7] Add Characteristics Discovery option to " Sheldon Demario
2011-02-21 22:50 ` [PATCH 3/7] Create helper functions to deal with handles on " Sheldon Demario
2011-02-21 22:50 ` [PATCH 4/7] Add Characteristics Descriptor Discovery option in " Sheldon Demario
2011-02-21 22:50 ` [PATCH 5/7] Add characteristics read options " Sheldon Demario
2011-02-21 22:50 ` [PATCH 6/7] Move attr_data_from_string() to utils.c Sheldon Demario
2011-02-21 22:50 ` [PATCH 7/7] Add Write Request in interactive gatttool Sheldon Demario
2011-02-22 19:11 ` [PATCH v2 1/7] Improve help messages " Sheldon Demario
2011-02-22 19:11 ` [PATCH v2 2/7] Add Characteristics Discovery option to " Sheldon Demario
2011-02-22 19:12 ` [PATCH v2 3/7] Create helper functions to deal with handles on " Sheldon Demario
2011-02-23  3:09   ` Johan Hedberg
2011-02-23 12:21     ` Anderson Lizardo
2011-02-23 13:23     ` Sheldon Demario
2011-02-23 14:20     ` [PATCH v3 " Sheldon Demario
2011-02-22 19:12 ` [PATCH v2 4/7] Add Characteristics Descriptor Discovery option in " Sheldon Demario
2011-02-22 19:12 ` [PATCH v2 5/7] Add characteristics read options " Sheldon Demario
2011-02-22 19:12 ` [PATCH v2 6/7] Move attr_data_from_string() to utils.c Sheldon Demario
2011-02-22 19:12 ` [PATCH v2 7/7] Add Write Request in interactive gatttool Sheldon Demario
2011-02-24 13:54 ` [PATCH v3 4/7] Add Characteristics Descriptor Discovery option " Sheldon Demario
2011-02-24 13:55 ` [PATCH v3 5/7] Add characteristics read options " Sheldon Demario

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.