* [PATCH BlueZ 01/12] client: Add support for GattService1
2015-02-06 11:03 [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
@ 2015-02-06 11:03 ` Luiz Augusto von Dentz
2015-02-06 11:03 ` [PATCH BlueZ 02/12] client: Add support for GattCharacteristic1 Luiz Augusto von Dentz
` (11 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2015-02-06 11:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This add support for GattService1 interface detection and prints when
they are added or removed
---
Makefile.tools | 1 +
client/gatt.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
client/gatt.h | 25 ++++++++++++++++
client/main.c | 30 ++++++++++++++++++++
4 files changed, 146 insertions(+)
create mode 100644 client/gatt.c
create mode 100644 client/gatt.h
diff --git a/Makefile.tools b/Makefile.tools
index e42e42d..64da54f 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -5,6 +5,7 @@ bin_PROGRAMS += client/bluetoothctl
client_bluetoothctl_SOURCES = client/main.c \
client/display.h client/display.c \
client/agent.h client/agent.c \
+ client/gatt.h client/gatt.c \
monitor/uuid.h monitor/uuid.c
client_bluetoothctl_LDADD = gdbus/libgdbus-internal.la @GLIB_LIBS@ @DBUS_LIBS@ \
-lreadline
diff --git a/client/gatt.c b/client/gatt.c
new file mode 100644
index 0000000..7de5c7b
--- /dev/null
+++ b/client/gatt.c
@@ -0,0 +1,90 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2014 Intel Corporation. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include <readline/readline.h>
+#include <readline/history.h>
+#include <glib.h>
+#include <gdbus.h>
+
+#include "monitor/uuid.h"
+#include "display.h"
+#include "gatt.h"
+
+/* String display constants */
+#define COLORED_NEW COLOR_GREEN "NEW" COLOR_OFF
+#define COLORED_CHG COLOR_YELLOW "CHG" COLOR_OFF
+#define COLORED_DEL COLOR_RED "DEL" COLOR_OFF
+
+static GList *services;
+
+static void print_service(GDBusProxy *proxy, const char *description)
+{
+ DBusMessageIter iter;
+ const char *uuid, *text;
+ dbus_bool_t primary;
+
+ if (g_dbus_proxy_get_property(proxy, "UUID", &iter) == FALSE)
+ return;
+
+ dbus_message_iter_get_basic(&iter, &uuid);
+
+ if (g_dbus_proxy_get_property(proxy, "Primary", &iter) == FALSE)
+ return;
+
+ dbus_message_iter_get_basic(&iter, &primary);
+
+ text = uuidstr_to_str(uuid);
+ if (!text)
+ text = uuid;
+
+ rl_printf("%s%s%sService %s %s %s\n",
+ description ? "[" : "",
+ description ? : "",
+ description ? "] " : "",
+ g_dbus_proxy_get_path(proxy),
+ text, primary ? "(Primary)" : "(Secondary)");
+}
+
+void gatt_add_service(GDBusProxy *proxy)
+{
+ services = g_list_append(services, proxy);
+
+ print_service(proxy, COLORED_NEW);
+}
+
+void gatt_remove_service(GDBusProxy *proxy)
+{
+ services = g_list_remove(services, proxy);
+
+ print_service(proxy, COLORED_DEL);
+}
diff --git a/client/gatt.h b/client/gatt.h
new file mode 100644
index 0000000..f049039
--- /dev/null
+++ b/client/gatt.h
@@ -0,0 +1,25 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2014 Intel Corporation. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+void gatt_add_service(GDBusProxy *proxy);
+void gatt_remove_service(GDBusProxy *proxy);
diff --git a/client/main.c b/client/main.c
index ea80ee7..ab644ba 100644
--- a/client/main.c
+++ b/client/main.c
@@ -41,6 +41,7 @@
#include "monitor/uuid.h"
#include "agent.h"
#include "display.h"
+#include "gatt.h"
/* String display constants */
#define COLORED_NEW COLOR_GREEN "NEW" COLOR_OFF
@@ -284,6 +285,29 @@ static gboolean device_is_child(GDBusProxy *device, GDBusProxy *master)
return FALSE;
}
+static gboolean service_is_child(GDBusProxy *service)
+{
+ GList *l;
+ DBusMessageIter iter;
+ const char *device, *path;
+
+ if (g_dbus_proxy_get_property(service, "Device", &iter) == FALSE)
+ return FALSE;
+
+ dbus_message_iter_get_basic(&iter, &device);
+
+ for (l = dev_list; l; l = g_list_next(l)) {
+ GDBusProxy *proxy = l->data;
+
+ path = g_dbus_proxy_get_path(proxy);
+
+ if (!strcmp(path, device))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static void proxy_added(GDBusProxy *proxy, void *user_data)
{
const char *interface;
@@ -311,6 +335,9 @@ static void proxy_added(GDBusProxy *proxy, void *user_data)
agent_register(dbus_conn, agent_manager,
auto_register_agent);
}
+ } else if (!strcmp(interface, "org.bluez.GattService1")) {
+ if (service_is_child(proxy))
+ gatt_add_service(proxy);
}
}
@@ -343,6 +370,9 @@ static void proxy_removed(GDBusProxy *proxy, void *user_data)
if (auto_register_agent)
agent_unregister(dbus_conn, NULL);
}
+ } else if (!strcmp(interface, "org.bluez.GattService1")) {
+ if (service_is_child(proxy))
+ gatt_remove_service(proxy);
}
}
--
2.1.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH BlueZ 02/12] client: Add support for GattCharacteristic1
2015-02-06 11:03 [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
2015-02-06 11:03 ` [PATCH BlueZ 01/12] client: Add support for GattService1 Luiz Augusto von Dentz
@ 2015-02-06 11:03 ` Luiz Augusto von Dentz
2015-02-06 11:03 ` [PATCH BlueZ 03/12] client: Add support for GattDescriptor1 Luiz Augusto von Dentz
` (10 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2015-02-06 11:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This add support for GattCharacteristici1 interface detection and
prints when they are added or removed
---
client/gatt.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
client/gatt.h | 3 +++
client/main.c | 4 ++++
3 files changed, 73 insertions(+)
diff --git a/client/gatt.c b/client/gatt.c
index 7de5c7b..8fd113f 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -46,6 +46,7 @@
#define COLORED_DEL COLOR_RED "DEL" COLOR_OFF
static GList *services;
+static GList *characteristics;
static void print_service(GDBusProxy *proxy, const char *description)
{
@@ -88,3 +89,68 @@ void gatt_remove_service(GDBusProxy *proxy)
print_service(proxy, COLORED_DEL);
}
+
+static void print_characteristic(GDBusProxy *proxy, const char *description)
+{
+ DBusMessageIter iter;
+ const char *uuid, *text;
+
+ if (g_dbus_proxy_get_property(proxy, "UUID", &iter) == FALSE)
+ return;
+
+ dbus_message_iter_get_basic(&iter, &uuid);
+
+ text = uuidstr_to_str(uuid);
+ if (!text)
+ text = uuid;
+
+ rl_printf("%s%s%sCharacteristic %s %s\n",
+ description ? "[" : "",
+ description ? : "",
+ description ? "] " : "",
+ g_dbus_proxy_get_path(proxy),
+ text);
+}
+
+static gboolean characteristic_is_child(GDBusProxy *characteristic)
+{
+ GList *l;
+ DBusMessageIter iter;
+ const char *service, *path;
+
+ if (!g_dbus_proxy_get_property(characteristic, "Service", &iter))
+ return FALSE;
+
+ dbus_message_iter_get_basic(&iter, &service);
+
+ for (l = services; l; l = g_list_next(l)) {
+ GDBusProxy *proxy = l->data;
+
+ path = g_dbus_proxy_get_path(proxy);
+
+ if (!strcmp(path, service))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void gatt_add_characteristic(GDBusProxy *proxy)
+{
+ if (!characteristic_is_child(proxy))
+ return;
+
+ characteristics = g_list_append(characteristics, proxy);
+
+ print_characteristic(proxy, COLORED_NEW);
+}
+
+void gatt_remove_characteristic(GDBusProxy *proxy)
+{
+ if (!characteristic_is_child(proxy))
+ return;
+
+ characteristics = g_list_remove(characteristics, proxy);
+
+ print_characteristic(proxy, COLORED_DEL);
+}
diff --git a/client/gatt.h b/client/gatt.h
index f049039..924c4d9 100644
--- a/client/gatt.h
+++ b/client/gatt.h
@@ -23,3 +23,6 @@
void gatt_add_service(GDBusProxy *proxy);
void gatt_remove_service(GDBusProxy *proxy);
+
+void gatt_add_characteristic(GDBusProxy *proxy);
+void gatt_remove_characteristic(GDBusProxy *proxy);
diff --git a/client/main.c b/client/main.c
index ab644ba..3db18af 100644
--- a/client/main.c
+++ b/client/main.c
@@ -338,6 +338,8 @@ static void proxy_added(GDBusProxy *proxy, void *user_data)
} else if (!strcmp(interface, "org.bluez.GattService1")) {
if (service_is_child(proxy))
gatt_add_service(proxy);
+ } else if (!strcmp(interface, "org.bluez.GattCharacteristic1")) {
+ gatt_add_characteristic(proxy);
}
}
@@ -373,6 +375,8 @@ static void proxy_removed(GDBusProxy *proxy, void *user_data)
} else if (!strcmp(interface, "org.bluez.GattService1")) {
if (service_is_child(proxy))
gatt_remove_service(proxy);
+ } else if (!strcmp(interface, "org.bluez.GattCharacteristic1")) {
+ gatt_remove_characteristic(proxy);
}
}
--
2.1.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH BlueZ 03/12] client: Add support for GattDescriptor1
2015-02-06 11:03 [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
2015-02-06 11:03 ` [PATCH BlueZ 01/12] client: Add support for GattService1 Luiz Augusto von Dentz
2015-02-06 11:03 ` [PATCH BlueZ 02/12] client: Add support for GattCharacteristic1 Luiz Augusto von Dentz
@ 2015-02-06 11:03 ` Luiz Augusto von Dentz
2015-02-06 11:03 ` [PATCH BlueZ 04/12] client: Make commands relative to device Luiz Augusto von Dentz
` (9 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2015-02-06 11:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This add support for GattDescriptor1 interface detection and
prints when they are added or removed.
---
client/gatt.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
client/gatt.h | 3 +++
client/main.c | 4 ++++
3 files changed, 73 insertions(+)
diff --git a/client/gatt.c b/client/gatt.c
index 8fd113f..47785a8 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -47,6 +47,7 @@
static GList *services;
static GList *characteristics;
+static GList *descriptors;
static void print_service(GDBusProxy *proxy, const char *description)
{
@@ -154,3 +155,68 @@ void gatt_remove_characteristic(GDBusProxy *proxy)
print_characteristic(proxy, COLORED_DEL);
}
+
+static void print_descriptor(GDBusProxy *proxy, const char *description)
+{
+ DBusMessageIter iter;
+ const char *uuid, *text;
+
+ if (g_dbus_proxy_get_property(proxy, "UUID", &iter) == FALSE)
+ return;
+
+ dbus_message_iter_get_basic(&iter, &uuid);
+
+ text = uuidstr_to_str(uuid);
+ if (!text)
+ text = uuid;
+
+ rl_printf("%s%s%sDescriptor %s %s\n",
+ description ? "[" : "",
+ description ? : "",
+ description ? "] " : "",
+ g_dbus_proxy_get_path(proxy),
+ text);
+}
+
+static gboolean descriptor_is_child(GDBusProxy *characteristic)
+{
+ GList *l;
+ DBusMessageIter iter;
+ const char *service, *path;
+
+ if (!g_dbus_proxy_get_property(characteristic, "Characteristic", &iter))
+ return FALSE;
+
+ dbus_message_iter_get_basic(&iter, &service);
+
+ for (l = characteristics; l; l = g_list_next(l)) {
+ GDBusProxy *proxy = l->data;
+
+ path = g_dbus_proxy_get_path(proxy);
+
+ if (!strcmp(path, service))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void gatt_add_descriptor(GDBusProxy *proxy)
+{
+ if (!descriptor_is_child(proxy))
+ return;
+
+ descriptors = g_list_append(descriptors, proxy);
+
+ print_descriptor(proxy, COLORED_NEW);
+}
+
+void gatt_remove_descriptor(GDBusProxy *proxy)
+{
+ if (!descriptor_is_child(proxy))
+ return;
+
+ descriptors = g_list_remove(descriptors, proxy);
+
+ print_descriptor(proxy, COLORED_DEL);
+}
diff --git a/client/gatt.h b/client/gatt.h
index 924c4d9..8b30668 100644
--- a/client/gatt.h
+++ b/client/gatt.h
@@ -26,3 +26,6 @@ void gatt_remove_service(GDBusProxy *proxy);
void gatt_add_characteristic(GDBusProxy *proxy);
void gatt_remove_characteristic(GDBusProxy *proxy);
+
+void gatt_add_descriptor(GDBusProxy *proxy);
+void gatt_remove_descriptor(GDBusProxy *proxy);
diff --git a/client/main.c b/client/main.c
index 3db18af..0590266 100644
--- a/client/main.c
+++ b/client/main.c
@@ -340,6 +340,8 @@ static void proxy_added(GDBusProxy *proxy, void *user_data)
gatt_add_service(proxy);
} else if (!strcmp(interface, "org.bluez.GattCharacteristic1")) {
gatt_add_characteristic(proxy);
+ } else if (!strcmp(interface, "org.bluez.GattDescriptor1")) {
+ gatt_add_descriptor(proxy);
}
}
@@ -377,6 +379,8 @@ static void proxy_removed(GDBusProxy *proxy, void *user_data)
gatt_remove_service(proxy);
} else if (!strcmp(interface, "org.bluez.GattCharacteristic1")) {
gatt_remove_characteristic(proxy);
+ } else if (!strcmp(interface, "org.bluez.GattDescriptor1")) {
+ gatt_remove_descriptor(proxy);
}
}
--
2.1.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH BlueZ 04/12] client: Make commands relative to device
2015-02-06 11:03 [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
` (2 preceding siblings ...)
2015-02-06 11:03 ` [PATCH BlueZ 03/12] client: Add support for GattDescriptor1 Luiz Augusto von Dentz
@ 2015-02-06 11:03 ` Luiz Augusto von Dentz
2015-02-06 11:03 ` [PATCH BlueZ 05/12] client: Add command list-attributes Luiz Augusto von Dentz
` (8 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2015-02-06 11:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
In case a device is connected make it the default and print to the
prompt, so the user don't have to type in its address.
---
client/main.c | 153 ++++++++++++++++++++++++++++++++--------------------------
1 file changed, 85 insertions(+), 68 deletions(-)
diff --git a/client/main.c b/client/main.c
index 0590266..72223d5 100644
--- a/client/main.c
+++ b/client/main.c
@@ -58,6 +58,7 @@ static GDBusProxy *agent_manager;
static char *auto_register_agent = NULL;
static GDBusProxy *default_ctrl;
+static GDBusProxy *default_dev;
static GList *ctrl_list;
static GList *dev_list;
@@ -345,6 +346,27 @@ static void proxy_added(GDBusProxy *proxy, void *user_data)
}
}
+static void set_default_device(GDBusProxy *proxy)
+{
+ char *desc = NULL;
+ DBusMessageIter iter;
+
+ default_dev = proxy;
+
+ if (!g_dbus_proxy_get_property(proxy, "Alias", &iter)) {
+ if (!g_dbus_proxy_get_property(proxy, "Address", &iter))
+ goto done;
+ }
+
+ dbus_message_iter_get_basic(&iter, &desc);
+ desc = g_strdup_printf(COLOR_BLUE "[%s]" COLOR_OFF "# ", desc);
+
+done:
+ rl_set_prompt(desc ? desc : PROMPT_ON);
+ rl_redisplay();
+ g_free(desc);
+}
+
static void proxy_removed(GDBusProxy *proxy, void *user_data)
{
const char *interface;
@@ -356,6 +378,9 @@ static void proxy_removed(GDBusProxy *proxy, void *user_data)
dev_list = g_list_remove(dev_list, proxy);
print_device(proxy, COLORED_DEL);
+
+ if (default_dev == proxy)
+ set_default_device(NULL);
}
} else if (!strcmp(interface, "org.bluez.Adapter1")) {
ctrl_list = g_list_remove(ctrl_list, proxy);
@@ -364,6 +389,7 @@ static void proxy_removed(GDBusProxy *proxy, void *user_data)
if (default_ctrl == proxy) {
default_ctrl = NULL;
+ set_default_device(NULL);
g_list_free(dev_list);
dev_list = NULL;
@@ -407,6 +433,17 @@ static void property_changed(GDBusProxy *proxy, const char *name,
} else
str = g_strdup("");
+ if (strcmp(name, "Connected") == 0) {
+ dbus_bool_t connected;
+
+ dbus_message_iter_get_basic(iter, &connected);
+
+ if (connected && default_dev == NULL)
+ set_default_device(proxy);
+ else if (!connected && default_dev == proxy)
+ set_default_device(NULL);
+ }
+
print_iter(str, name, iter);
g_free(str);
}
@@ -810,23 +847,36 @@ static void cmd_scan(const char *arg)
}
}
-static void cmd_info(const char *arg)
+static struct GDBusProxy *find_device(const char *arg)
{
GDBusProxy *proxy;
- DBusMessageIter iter;
- const char *address;
if (!arg || !strlen(arg)) {
+ if (default_dev)
+ return default_dev;
rl_printf("Missing device address argument\n");
- return;
+ return NULL;
}
proxy = find_proxy_by_address(dev_list, arg);
if (!proxy) {
rl_printf("Device %s not available\n", arg);
- return;
+ return NULL;
}
+ return proxy;
+}
+
+static void cmd_info(const char *arg)
+{
+ GDBusProxy *proxy;
+ DBusMessageIter iter;
+ const char *address;
+
+ proxy = find_device(arg);
+ if (!proxy)
+ return;
+
if (g_dbus_proxy_get_property(proxy, "Address", &iter) == FALSE)
return;
@@ -866,16 +916,9 @@ static void cmd_pair(const char *arg)
{
GDBusProxy *proxy;
- if (!arg || !strlen(arg)) {
- rl_printf("Missing device address argument\n");
+ proxy = find_device(arg);
+ if (!proxy)
return;
- }
-
- proxy = find_proxy_by_address(dev_list, arg);
- if (!proxy) {
- rl_printf("Device %s not available\n", arg);
- return;
- }
if (g_dbus_proxy_method_call(proxy, "Pair", NULL, pair_reply,
NULL, NULL) == FALSE) {
@@ -892,16 +935,9 @@ static void cmd_trust(const char *arg)
dbus_bool_t trusted;
char *str;
- if (!arg || !strlen(arg)) {
- rl_printf("Missing device address argument\n");
- return;
- }
-
- proxy = find_proxy_by_address(dev_list, arg);
- if (!proxy) {
- rl_printf("Device %s not available\n", arg);
+ proxy = find_device(arg);
+ if (!proxy)
return;
- }
trusted = TRUE;
@@ -921,16 +957,9 @@ static void cmd_untrust(const char *arg)
dbus_bool_t trusted;
char *str;
- if (!arg || !strlen(arg)) {
- rl_printf("Missing device address argument\n");
- return;
- }
-
- proxy = find_proxy_by_address(dev_list, arg);
- if (!proxy) {
- rl_printf("Device %s not available\n", arg);
+ proxy = find_device(arg);
+ if (!proxy)
return;
- }
trusted = FALSE;
@@ -950,16 +979,9 @@ static void cmd_block(const char *arg)
dbus_bool_t blocked;
char *str;
- if (!arg || !strlen(arg)) {
- rl_printf("Missing device address argument\n");
- return;
- }
-
- proxy = find_proxy_by_address(dev_list, arg);
- if (!proxy) {
- rl_printf("Device %s not available\n", arg);
+ proxy = find_device(arg);
+ if (!proxy)
return;
- }
blocked = TRUE;
@@ -979,16 +1001,9 @@ static void cmd_unblock(const char *arg)
dbus_bool_t blocked;
char *str;
- if (!arg || !strlen(arg)) {
- rl_printf("Missing device address argument\n");
- return;
- }
-
- proxy = find_proxy_by_address(dev_list, arg);
- if (!proxy) {
- rl_printf("Device %s not available\n", arg);
+ proxy = find_device(arg);
+ if (!proxy)
return;
- }
blocked = FALSE;
@@ -1057,6 +1072,7 @@ static void cmd_remove(const char *arg)
static void connect_reply(DBusMessage *message, void *user_data)
{
+ GDBusProxy *proxy = user_data;
DBusError error;
dbus_error_init(&error);
@@ -1068,6 +1084,8 @@ static void connect_reply(DBusMessage *message, void *user_data)
}
rl_printf("Connection successful\n");
+
+ set_default_device(proxy);
}
static void cmd_connect(const char *arg)
@@ -1086,7 +1104,7 @@ static void cmd_connect(const char *arg)
}
if (g_dbus_proxy_method_call(proxy, "Connect", NULL, connect_reply,
- NULL, NULL) == FALSE) {
+ proxy, NULL) == FALSE) {
rl_printf("Failed to connect\n");
return;
}
@@ -1096,6 +1114,7 @@ static void cmd_connect(const char *arg)
static void disconn_reply(DBusMessage *message, void *user_data)
{
+ GDBusProxy *proxy = user_data;
DBusError error;
dbus_error_init(&error);
@@ -1107,25 +1126,23 @@ static void disconn_reply(DBusMessage *message, void *user_data)
}
rl_printf("Successful disconnected\n");
+
+ if (proxy != default_dev)
+ return;
+
+ set_default_device(NULL);
}
static void cmd_disconn(const char *arg)
{
GDBusProxy *proxy;
- if (!arg || !strlen(arg)) {
- rl_printf("Missing device address argument\n");
+ proxy = find_device(arg);
+ if (!proxy)
return;
- }
-
- proxy = find_proxy_by_address(dev_list, arg);
- if (!proxy) {
- rl_printf("Device %s not available\n", arg);
- return;
- }
if (g_dbus_proxy_method_call(proxy, "Disconnect", NULL, disconn_reply,
- NULL, NULL) == FALSE) {
+ proxy, NULL) == FALSE) {
rl_printf("Failed to disconnect\n");
return;
}
@@ -1233,23 +1250,23 @@ static const struct {
{ "default-agent",NULL, cmd_default_agent,
"Set agent as the default one" },
{ "scan", "<on/off>", cmd_scan, "Scan for devices" },
- { "info", "<dev>", cmd_info, "Device information",
+ { "info", "[dev]", cmd_info, "Device information",
dev_generator },
- { "pair", "<dev>", cmd_pair, "Pair with device",
+ { "pair", "[dev]", cmd_pair, "Pair with device",
dev_generator },
- { "trust", "<dev>", cmd_trust, "Trust device",
+ { "trust", "[dev]", cmd_trust, "Trust device",
dev_generator },
- { "untrust", "<dev>", cmd_untrust, "Untrust device",
+ { "untrust", "[dev]", cmd_untrust, "Untrust device",
dev_generator },
- { "block", "<dev>", cmd_block, "Block device",
+ { "block", "[dev]", cmd_block, "Block device",
dev_generator },
- { "unblock", "<dev>", cmd_unblock, "Unblock device",
+ { "unblock", "[dev]", cmd_unblock, "Unblock device",
dev_generator },
{ "remove", "<dev>", cmd_remove, "Remove device",
dev_generator },
{ "connect", "<dev>", cmd_connect, "Connect device",
dev_generator },
- { "disconnect", "<dev>", cmd_disconn, "Disconnect device",
+ { "disconnect", "[dev]", cmd_disconn, "Disconnect device",
dev_generator },
{ "version", NULL, cmd_version, "Display version" },
{ "quit", NULL, cmd_quit, "Quit program" },
--
2.1.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH BlueZ 05/12] client: Add command list-attributes
2015-02-06 11:03 [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
` (3 preceding siblings ...)
2015-02-06 11:03 ` [PATCH BlueZ 04/12] client: Make commands relative to device Luiz Augusto von Dentz
@ 2015-02-06 11:03 ` Luiz Augusto von Dentz
2015-02-06 11:03 ` [PATCH BlueZ 06/12] client: Add command select-attribute Luiz Augusto von Dentz
` (7 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2015-02-06 11:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This command can be used to list service attributes of a device.
---
client/gatt.c | 29 +++++++++++++++++++++++++++++
client/gatt.h | 2 ++
client/main.c | 13 +++++++++++++
3 files changed, 44 insertions(+)
diff --git a/client/gatt.c b/client/gatt.c
index 47785a8..7c44a9f 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -220,3 +220,32 @@ void gatt_remove_descriptor(GDBusProxy *proxy)
print_descriptor(proxy, COLORED_DEL);
}
+
+static void list_attributes(const char *path, GList *source)
+{
+ GList *l;
+
+ for (l = source; l; l = g_list_next(l)) {
+ GDBusProxy *proxy = l->data;
+ const char *proxy_path;
+
+ proxy_path = g_dbus_proxy_get_path(proxy);
+
+ if (!g_str_has_prefix(proxy_path, path))
+ continue;
+
+ if (source == services) {
+ print_service(proxy, NULL);
+ list_attributes(proxy_path, characteristics);
+ } else if (source == characteristics) {
+ print_characteristic(proxy, NULL);
+ list_attributes(proxy_path, descriptors);
+ } else if (source == descriptors)
+ print_descriptor(proxy, NULL);
+ }
+}
+
+void gatt_list_attributes(const char *path)
+{
+ list_attributes(path, services);
+}
diff --git a/client/gatt.h b/client/gatt.h
index 8b30668..5785073 100644
--- a/client/gatt.h
+++ b/client/gatt.h
@@ -29,3 +29,5 @@ void gatt_remove_characteristic(GDBusProxy *proxy);
void gatt_add_descriptor(GDBusProxy *proxy);
void gatt_remove_descriptor(GDBusProxy *proxy);
+
+void gatt_list_attributes(const char *device);
diff --git a/client/main.c b/client/main.c
index 72223d5..7cdb19a 100644
--- a/client/main.c
+++ b/client/main.c
@@ -1150,6 +1150,17 @@ static void cmd_disconn(const char *arg)
rl_printf("Attempting to disconnect from %s\n", arg);
}
+static void cmd_list_attributes(const char *arg)
+{
+ GDBusProxy *proxy;
+
+ proxy = find_device(arg);
+ if (!proxy)
+ return;
+
+ gatt_list_attributes(g_dbus_proxy_get_path(proxy));
+}
+
static void cmd_version(const char *arg)
{
rl_printf("Version %s\n", VERSION);
@@ -1268,6 +1279,8 @@ static const struct {
dev_generator },
{ "disconnect", "[dev]", cmd_disconn, "Disconnect device",
dev_generator },
+ { "list-attributes", "[dev]", cmd_list_attributes, "List attributes",
+ dev_generator },
{ "version", NULL, cmd_version, "Display version" },
{ "quit", NULL, cmd_quit, "Quit program" },
{ "exit", NULL, cmd_quit },
--
2.1.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH BlueZ 06/12] client: Add command select-attribute
2015-02-06 11:03 [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
` (4 preceding siblings ...)
2015-02-06 11:03 ` [PATCH BlueZ 05/12] client: Add command list-attributes Luiz Augusto von Dentz
@ 2015-02-06 11:03 ` Luiz Augusto von Dentz
2015-02-06 11:03 ` [PATCH BlueZ 07/12] client: Add attribute-info command Luiz Augusto von Dentz
` (6 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2015-02-06 11:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Command select-attribute can be used to select a service attribute.
---
client/gatt.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
client/gatt.h | 2 ++
client/main.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 146 insertions(+), 9 deletions(-)
diff --git a/client/gatt.c b/client/gatt.c
index 7c44a9f..8fb3f62 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -249,3 +249,80 @@ void gatt_list_attributes(const char *path)
{
list_attributes(path, services);
}
+
+static GDBusProxy *select_proxy(const char *path, GList *source)
+{
+ GList *l;
+
+ for (l = source; l; l = g_list_next(l)) {
+ GDBusProxy *proxy = l->data;
+
+ if (strcmp(path, g_dbus_proxy_get_path(proxy)) == 0)
+ return proxy;
+ }
+
+ return NULL;
+}
+
+GDBusProxy *gatt_select_attribute(const char *path)
+{
+ GDBusProxy *proxy;
+
+ proxy = select_proxy(path, services);
+ if (proxy)
+ return proxy;
+
+ proxy = select_proxy(path, characteristics);
+ if (proxy)
+ return proxy;
+
+ return select_proxy(path, descriptors);
+}
+
+static char *attribute_generator(const char *text, int state, GList *source)
+{
+ static int index, len;
+ GList *list;
+
+ if (!state) {
+ index = 0;
+ len = strlen(text);
+ }
+
+ for (list = g_list_nth(source, index); list;
+ list = g_list_next(list)) {
+ GDBusProxy *proxy = list->data;
+ const char *path;
+
+ index++;
+
+ path = g_dbus_proxy_get_path(proxy);
+
+ if (!strncmp(path, text, len))
+ return strdup(path);
+ }
+
+ return NULL;
+}
+
+char *gatt_attribute_generator(const char *text, int state)
+{
+ static GList *list = NULL;
+
+ if (!state) {
+ GList *list1;
+
+ if (list) {
+ g_list_free(list);
+ list = NULL;
+ }
+
+ list1 = g_list_copy(characteristics);
+ list1 = g_list_concat(list1, g_list_copy(descriptors));
+
+ list = g_list_copy(services);
+ list = g_list_concat(list, list1);
+ }
+
+ return attribute_generator(text, state, list);
+}
diff --git a/client/gatt.h b/client/gatt.h
index 5785073..bb7cb1c 100644
--- a/client/gatt.h
+++ b/client/gatt.h
@@ -31,3 +31,5 @@ void gatt_add_descriptor(GDBusProxy *proxy);
void gatt_remove_descriptor(GDBusProxy *proxy);
void gatt_list_attributes(const char *device);
+GDBusProxy *gatt_select_attribute(const char *path);
+char *gatt_attribute_generator(const char *text, int state);
diff --git a/client/main.c b/client/main.c
index 7cdb19a..1481694 100644
--- a/client/main.c
+++ b/client/main.c
@@ -59,6 +59,7 @@ static char *auto_register_agent = NULL;
static GDBusProxy *default_ctrl;
static GDBusProxy *default_dev;
+static GDBusProxy *default_attr;
static GList *ctrl_list;
static GList *dev_list;
@@ -346,20 +347,30 @@ static void proxy_added(GDBusProxy *proxy, void *user_data)
}
}
-static void set_default_device(GDBusProxy *proxy)
+static void set_default_device(GDBusProxy *proxy, const char *attribute)
{
char *desc = NULL;
DBusMessageIter iter;
+ const char *path;
default_dev = proxy;
+ if (proxy == NULL) {
+ default_attr = NULL;
+ goto done;
+ }
+
if (!g_dbus_proxy_get_property(proxy, "Alias", &iter)) {
if (!g_dbus_proxy_get_property(proxy, "Address", &iter))
goto done;
}
+ path = g_dbus_proxy_get_path(proxy);
+
dbus_message_iter_get_basic(&iter, &desc);
- desc = g_strdup_printf(COLOR_BLUE "[%s]" COLOR_OFF "# ", desc);
+ desc = g_strdup_printf(COLOR_BLUE "[%s%s%s]" COLOR_OFF "# ", desc,
+ attribute ? ":" : "",
+ attribute ? attribute + strlen(path) : "");
done:
rl_set_prompt(desc ? desc : PROMPT_ON);
@@ -367,6 +378,17 @@ done:
g_free(desc);
}
+static void set_default_attribute(GDBusProxy *proxy)
+{
+ const char *path;
+
+ default_attr = proxy;
+
+ path = g_dbus_proxy_get_path(proxy);
+
+ set_default_device(default_dev, path);
+}
+
static void proxy_removed(GDBusProxy *proxy, void *user_data)
{
const char *interface;
@@ -380,7 +402,7 @@ static void proxy_removed(GDBusProxy *proxy, void *user_data)
print_device(proxy, COLORED_DEL);
if (default_dev == proxy)
- set_default_device(NULL);
+ set_default_device(NULL, NULL);
}
} else if (!strcmp(interface, "org.bluez.Adapter1")) {
ctrl_list = g_list_remove(ctrl_list, proxy);
@@ -389,7 +411,7 @@ static void proxy_removed(GDBusProxy *proxy, void *user_data)
if (default_ctrl == proxy) {
default_ctrl = NULL;
- set_default_device(NULL);
+ set_default_device(NULL, NULL);
g_list_free(dev_list);
dev_list = NULL;
@@ -401,12 +423,22 @@ static void proxy_removed(GDBusProxy *proxy, void *user_data)
agent_unregister(dbus_conn, NULL);
}
} else if (!strcmp(interface, "org.bluez.GattService1")) {
- if (service_is_child(proxy))
+ if (service_is_child(proxy)) {
gatt_remove_service(proxy);
+
+ if (default_attr == proxy)
+ set_default_attribute(NULL);
+ }
} else if (!strcmp(interface, "org.bluez.GattCharacteristic1")) {
gatt_remove_characteristic(proxy);
+
+ if (default_attr == proxy)
+ set_default_attribute(NULL);
} else if (!strcmp(interface, "org.bluez.GattDescriptor1")) {
gatt_remove_descriptor(proxy);
+
+ if (default_attr == proxy)
+ set_default_attribute(NULL);
}
}
@@ -439,9 +471,9 @@ static void property_changed(GDBusProxy *proxy, const char *name,
dbus_message_iter_get_basic(iter, &connected);
if (connected && default_dev == NULL)
- set_default_device(proxy);
+ set_default_device(proxy, NULL);
else if (!connected && default_dev == proxy)
- set_default_device(NULL);
+ set_default_device(NULL, NULL);
}
print_iter(str, name, iter);
@@ -1085,7 +1117,7 @@ static void connect_reply(DBusMessage *message, void *user_data)
rl_printf("Connection successful\n");
- set_default_device(proxy);
+ set_default_device(proxy, NULL);
}
static void cmd_connect(const char *arg)
@@ -1130,7 +1162,7 @@ static void disconn_reply(DBusMessage *message, void *user_data)
if (proxy != default_dev)
return;
- set_default_device(NULL);
+ set_default_device(NULL, NULL);
}
static void cmd_disconn(const char *arg)
@@ -1161,6 +1193,25 @@ static void cmd_list_attributes(const char *arg)
gatt_list_attributes(g_dbus_proxy_get_path(proxy));
}
+static void cmd_select_attribute(const char *arg)
+{
+ GDBusProxy *proxy;
+
+ if (!arg || !strlen(arg)) {
+ rl_printf("Missing attribute argument\n");
+ return;
+ }
+
+ if (!default_dev) {
+ rl_printf("No device connected\n");
+ return;
+ }
+
+ proxy = gatt_select_attribute(arg);
+ if (proxy)
+ set_default_attribute(proxy);
+}
+
static void cmd_version(const char *arg)
{
rl_printf("Version %s\n", VERSION);
@@ -1212,6 +1263,11 @@ static char *dev_generator(const char *text, int state)
return generic_generator(text, state, dev_list, "Address");
}
+static char *attribute_generator(const char *text, int state)
+{
+ return gatt_attribute_generator(text, state);
+}
+
static char *capability_generator(const char *text, int state)
{
static int index, len;
@@ -1281,6 +1337,8 @@ static const struct {
dev_generator },
{ "list-attributes", "[dev]", cmd_list_attributes, "List attributes",
dev_generator },
+ { "select-attribute", "<attribute>", cmd_select_attribute,
+ "Select attribute", attribute_generator },
{ "version", NULL, cmd_version, "Display version" },
{ "quit", NULL, cmd_quit, "Quit program" },
{ "exit", NULL, cmd_quit },
--
2.1.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH BlueZ 07/12] client: Add attribute-info command
2015-02-06 11:03 [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
` (5 preceding siblings ...)
2015-02-06 11:03 ` [PATCH BlueZ 06/12] client: Add command select-attribute Luiz Augusto von Dentz
@ 2015-02-06 11:03 ` Luiz Augusto von Dentz
2015-02-06 11:03 ` [PATCH BlueZ 08/12] client/display: Add rl_hexdump Luiz Augusto von Dentz
` (5 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2015-02-06 11:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
attribute-info can be used to print out attribute information.
---
client/main.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 81 insertions(+), 15 deletions(-)
diff --git a/client/main.c b/client/main.c
index 1481694..614efca 100644
--- a/client/main.c
+++ b/client/main.c
@@ -160,7 +160,6 @@ static void print_iter(const char *label, const char *name,
dbus_int16_t vals16;
const char *valstr;
DBusMessageIter subiter;
- int type;
if (iter == NULL) {
rl_printf("%s%s is nil\n", label, name);
@@ -193,23 +192,23 @@ static void print_iter(const char *label, const char *name,
dbus_message_iter_get_basic(iter, &vals16);
rl_printf("%s%s: %d\n", label, name, vals16);
break;
+ case DBUS_TYPE_VARIANT:
+ dbus_message_iter_recurse(iter, &subiter);
+ print_iter(label, name, &subiter);
+ break;
case DBUS_TYPE_ARRAY:
dbus_message_iter_recurse(iter, &subiter);
- rl_printf("%s%s:\n", label, name);
-
- do {
- type = dbus_message_iter_get_arg_type(&subiter);
- if (type == DBUS_TYPE_INVALID)
- break;
-
- if (type == DBUS_TYPE_STRING) {
- dbus_message_iter_get_basic(&subiter, &valstr);
- rl_printf("\t%s\n", valstr);
- }
-
+ while (dbus_message_iter_get_arg_type(&subiter) !=
+ DBUS_TYPE_INVALID) {
+ print_iter(label, name, &subiter);
dbus_message_iter_next(&subiter);
- } while(true);
-
+ }
+ break;
+ case DBUS_TYPE_DICT_ENTRY:
+ dbus_message_iter_recurse(iter, &subiter);
+ dbus_message_iter_get_basic(&subiter, &valstr);
+ dbus_message_iter_next(&subiter);
+ print_iter(label, valstr, &subiter);
break;
default:
rl_printf("%s%s has unsupported type\n", label, name);
@@ -1212,6 +1211,71 @@ static void cmd_select_attribute(const char *arg)
set_default_attribute(proxy);
}
+static struct GDBusProxy *find_attribute(const char *arg)
+{
+ GDBusProxy *proxy;
+
+ if (!arg || !strlen(arg)) {
+ if (default_attr)
+ return default_attr;
+ rl_printf("Missing attribute argument\n");
+ return NULL;
+ }
+
+ proxy = gatt_select_attribute(arg);
+ if (!proxy) {
+ rl_printf("Attribute %s not available\n", arg);
+ return NULL;
+ }
+
+ return proxy;
+}
+
+static void cmd_attribute_info(const char *arg)
+{
+ GDBusProxy *proxy;
+ DBusMessageIter iter;
+ const char *iface, *uuid, *text;
+
+ proxy = find_attribute(arg);
+ if (!proxy)
+ return;
+
+ if (g_dbus_proxy_get_property(proxy, "UUID", &iter) == FALSE)
+ return;
+
+ dbus_message_iter_get_basic(&iter, &uuid);
+
+ text = uuidstr_to_str(uuid);
+ if (!text)
+ text = g_dbus_proxy_get_path(proxy);
+
+ iface = g_dbus_proxy_get_interface(proxy);
+ if (!strcmp(iface, "org.bluez.GattService1")) {
+ rl_printf("Service - %s\n", text);
+
+ print_property(proxy, "UUID");
+ print_property(proxy, "Primary");
+ print_property(proxy, "Characteristics");
+ print_property(proxy, "Includes");
+ } else if (!strcmp(iface, "org.bluez.GattCharacteristic1")) {
+ rl_printf("Characteristic - %s\n", text);
+
+ print_property(proxy, "UUID");
+ print_property(proxy, "Service");
+ print_property(proxy, "Value");
+ print_property(proxy, "Notifying");
+ print_property(proxy, "Flags");
+ print_property(proxy, "Descriptors");
+ } else if (!strcmp(iface, "org.bluez.GattDescriptor1")) {
+ rl_printf("Descriptor - %s\n", text);
+
+ print_property(proxy, "UUID");
+ print_property(proxy, "Characteristic");
+ print_property(proxy, "Value");
+ }
+}
+
static void cmd_version(const char *arg)
{
rl_printf("Version %s\n", VERSION);
@@ -1339,6 +1403,8 @@ static const struct {
dev_generator },
{ "select-attribute", "<attribute>", cmd_select_attribute,
"Select attribute", attribute_generator },
+ { "attribute-info", "[attribute]", cmd_attribute_info,
+ "Select attribute", attribute_generator },
{ "version", NULL, cmd_version, "Display version" },
{ "quit", NULL, cmd_quit, "Quit program" },
{ "exit", NULL, cmd_quit },
--
2.1.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH BlueZ 08/12] client/display: Add rl_hexdump
2015-02-06 11:03 [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
` (6 preceding siblings ...)
2015-02-06 11:03 ` [PATCH BlueZ 07/12] client: Add attribute-info command Luiz Augusto von Dentz
@ 2015-02-06 11:03 ` Luiz Augusto von Dentz
2015-02-06 11:03 ` [PATCH BlueZ 09/12] client: Add read command Luiz Augusto von Dentz
` (4 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2015-02-06 11:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
client/display.c | 41 +++++++++++++++++++++++++++++++++++++++++
client/display.h | 1 +
2 files changed, 42 insertions(+)
diff --git a/client/display.c b/client/display.c
index 0f212b6..619973c 100644
--- a/client/display.c
+++ b/client/display.c
@@ -62,3 +62,44 @@ void rl_printf(const char *fmt, ...)
free(saved_line);
}
}
+
+void rl_hexdump(const unsigned char *buf, size_t len)
+{
+ static const char hexdigits[] = "0123456789abcdef";
+ char str[68];
+ size_t i;
+
+ if (!len)
+ return;
+
+ str[0] = ' ';
+
+ for (i = 0; i < len; i++) {
+ str[((i % 16) * 3) + 1] = ' ';
+ str[((i % 16) * 3) + 2] = hexdigits[buf[i] >> 4];
+ str[((i % 16) * 3) + 3] = hexdigits[buf[i] & 0xf];
+ str[(i % 16) + 51] = isprint(buf[i]) ? buf[i] : '.';
+
+ if ((i + 1) % 16 == 0) {
+ str[49] = ' ';
+ str[50] = ' ';
+ str[67] = '\0';
+ rl_printf("%s\n", str);
+ str[0] = ' ';
+ }
+ }
+
+ if (i % 16 > 0) {
+ size_t j;
+ for (j = (i % 16); j < 16; j++) {
+ str[(j * 3) + 1] = ' ';
+ str[(j * 3) + 2] = ' ';
+ str[(j * 3) + 3] = ' ';
+ str[j + 51] = ' ';
+ }
+ str[49] = ' ';
+ str[50] = ' ';
+ str[67] = '\0';
+ rl_printf("%s\n", str);
+ }
+}
diff --git a/client/display.h b/client/display.h
index 91a0be9..88dbbd0 100644
--- a/client/display.h
+++ b/client/display.h
@@ -30,3 +30,4 @@
#define COLOR_BOLDWHITE "\x1B[1;37m"
void rl_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
+void rl_hexdump(const unsigned char *buf, size_t len);
--
2.1.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH BlueZ 09/12] client: Add read command
2015-02-06 11:03 [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
` (7 preceding siblings ...)
2015-02-06 11:03 ` [PATCH BlueZ 08/12] client/display: Add rl_hexdump Luiz Augusto von Dentz
@ 2015-02-06 11:03 ` Luiz Augusto von Dentz
2015-02-06 11:03 ` [PATCH BlueZ 10/12] client: Add write command Luiz Augusto von Dentz
` (3 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2015-02-06 11:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This command can be used to read attributes, it only works if an
attribute has been selected with select-attribute.
---
client/gatt.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
client/gatt.h | 2 ++
client/main.c | 11 +++++++++++
3 files changed, 72 insertions(+)
diff --git a/client/gatt.c b/client/gatt.c
index 8fb3f62..ce709c8 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -326,3 +326,62 @@ char *gatt_attribute_generator(const char *text, int state)
return attribute_generator(text, state, list);
}
+
+static void read_reply(DBusMessage *message, void *user_data)
+{
+ DBusError error;
+ DBusMessageIter iter, array;
+ uint8_t *value;
+ int len;
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, message) == TRUE) {
+ rl_printf("Failed to read: %s\n", error.name);
+ dbus_error_free(&error);
+ return;
+ }
+
+ dbus_message_iter_init(message, &iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
+ rl_printf("Invalid response to read\n");
+ return;
+ }
+
+ dbus_message_iter_recurse(&iter, &array);
+ dbus_message_iter_get_fixed_array(&array, &value, &len);
+
+ if (len < 0) {
+ rl_printf("Unable to parse value\n");
+ return;
+ }
+
+ rl_hexdump(value, len);
+}
+
+static void read_attribute(GDBusProxy *proxy)
+{
+ if (g_dbus_proxy_method_call(proxy, "ReadValue", NULL, read_reply,
+ NULL, NULL) == FALSE) {
+ rl_printf("Failed to read\n");
+ return;
+ }
+
+ rl_printf("Attempting to read %s\n", g_dbus_proxy_get_path(proxy));
+}
+
+void gatt_read_attribute(GDBusProxy *proxy)
+{
+ const char *iface;
+
+ iface = g_dbus_proxy_get_interface(proxy);
+ if (!strcmp(iface, "org.bluez.GattCharacteristic1") ||
+ !strcmp(iface, "org.bluez.GattDescriptor1")) {
+ read_attribute(proxy);
+ return;
+ }
+
+ rl_printf("Unable to read attribute %s\n",
+ g_dbus_proxy_get_path(proxy));
+}
diff --git a/client/gatt.h b/client/gatt.h
index bb7cb1c..ac18a2a 100644
--- a/client/gatt.h
+++ b/client/gatt.h
@@ -33,3 +33,5 @@ void gatt_remove_descriptor(GDBusProxy *proxy);
void gatt_list_attributes(const char *device);
GDBusProxy *gatt_select_attribute(const char *path);
char *gatt_attribute_generator(const char *text, int state);
+
+void gatt_read_attribute(GDBusProxy *proxy);
diff --git a/client/main.c b/client/main.c
index 614efca..04cb51b 100644
--- a/client/main.c
+++ b/client/main.c
@@ -1276,6 +1276,16 @@ static void cmd_attribute_info(const char *arg)
}
}
+static void cmd_read(const char *arg)
+{
+ if (!default_attr) {
+ rl_printf("No attribute selected\n");
+ return;
+ }
+
+ gatt_read_attribute(default_attr);
+}
+
static void cmd_version(const char *arg)
{
rl_printf("Version %s\n", VERSION);
@@ -1405,6 +1415,7 @@ static const struct {
"Select attribute", attribute_generator },
{ "attribute-info", "[attribute]", cmd_attribute_info,
"Select attribute", attribute_generator },
+ { "read", NULL, cmd_read, "Read attribute value" },
{ "version", NULL, cmd_version, "Display version" },
{ "quit", NULL, cmd_quit, "Quit program" },
{ "exit", NULL, cmd_quit },
--
2.1.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH BlueZ 10/12] client: Add write command
2015-02-06 11:03 [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
` (8 preceding siblings ...)
2015-02-06 11:03 ` [PATCH BlueZ 09/12] client: Add read command Luiz Augusto von Dentz
@ 2015-02-06 11:03 ` Luiz Augusto von Dentz
2015-02-06 11:03 ` [PATCH BlueZ 11/12] client: Add notify command Luiz Augusto von Dentz
` (2 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2015-02-06 11:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This command can be used to write attributes, it only works if an
attribute has been selected with select-attribute.
The data argument should be passed hexdump format, %02x separated by
spaces, which is the same format used by read command.
---
client/gatt.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
client/gatt.h | 1 +
client/main.c | 17 +++++++++++++
3 files changed, 98 insertions(+)
diff --git a/client/gatt.c b/client/gatt.c
index ce709c8..207e049 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -30,6 +30,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
+#include <sys/uio.h>
#include <readline/readline.h>
#include <readline/history.h>
@@ -385,3 +386,82 @@ void gatt_read_attribute(GDBusProxy *proxy)
rl_printf("Unable to read attribute %s\n",
g_dbus_proxy_get_path(proxy));
}
+
+static void write_reply(DBusMessage *message, void *user_data)
+{
+ DBusError error;
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, message) == TRUE) {
+ rl_printf("Failed to write: %s\n", error.name);
+ dbus_error_free(&error);
+ return;
+ }
+}
+
+static void write_setup(DBusMessageIter *iter, void *user_data)
+{
+ struct iovec *iov = user_data;
+ DBusMessageIter array;
+
+ 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);
+ dbus_message_iter_close_container(iter, &array);
+}
+
+static void write_attribute(GDBusProxy *proxy, char *arg)
+{
+ struct iovec iov;
+ uint8_t value[512];
+ char *entry;
+ int i;
+
+ for (i = 0; (entry = strsep(&arg, " \t")) != NULL; i++) {
+ long int val;
+ char *endptr = NULL;
+
+ if (*entry == '\0')
+ continue;
+
+ if (i > 512) {
+ rl_printf("Too much data\n");
+ return;
+ }
+
+ val = strtol(entry, &endptr, 0);
+ if (!endptr || *endptr != '\0' || val > UINT8_MAX) {
+ rl_printf("Invalid value at index %d\n", i);
+ return;
+ }
+
+ value[i] = val;
+ }
+
+ iov.iov_base = value;
+ iov.iov_len = i;
+
+ if (g_dbus_proxy_method_call(proxy, "WriteValue", write_setup,
+ write_reply, &iov, NULL) == FALSE) {
+ rl_printf("Failed to write\n");
+ return;
+ }
+
+ rl_printf("Attempting to write %s\n", g_dbus_proxy_get_path(proxy));
+}
+
+void gatt_write_attribute(GDBusProxy *proxy, const char *arg)
+{
+ const char *iface;
+
+ iface = g_dbus_proxy_get_interface(proxy);
+ if (!strcmp(iface, "org.bluez.GattCharacteristic1") ||
+ !strcmp(iface, "org.bluez.GattDescriptor1")) {
+ write_attribute(proxy, (char *) arg);
+ return;
+ }
+
+ rl_printf("Unable to write attribute %s\n",
+ g_dbus_proxy_get_path(proxy));
+}
diff --git a/client/gatt.h b/client/gatt.h
index ac18a2a..b99f0f0 100644
--- a/client/gatt.h
+++ b/client/gatt.h
@@ -35,3 +35,4 @@ GDBusProxy *gatt_select_attribute(const char *path);
char *gatt_attribute_generator(const char *text, int state);
void gatt_read_attribute(GDBusProxy *proxy);
+void gatt_write_attribute(GDBusProxy *proxy, const char *arg);
diff --git a/client/main.c b/client/main.c
index 04cb51b..56d4750 100644
--- a/client/main.c
+++ b/client/main.c
@@ -1286,6 +1286,21 @@ static void cmd_read(const char *arg)
gatt_read_attribute(default_attr);
}
+static void cmd_write(const char *arg)
+{
+ if (!arg || !strlen(arg)) {
+ rl_printf("Missing data argument\n");
+ return;
+ }
+
+ if (!default_attr) {
+ rl_printf("No attribute selected\n");
+ return;
+ }
+
+ gatt_write_attribute(default_attr, arg);
+}
+
static void cmd_version(const char *arg)
{
rl_printf("Version %s\n", VERSION);
@@ -1416,6 +1431,8 @@ static const struct {
{ "attribute-info", "[attribute]", cmd_attribute_info,
"Select attribute", attribute_generator },
{ "read", NULL, cmd_read, "Read attribute value" },
+ { "write", "<data=[xx xx ...]>", cmd_write,
+ "Write attribute value" },
{ "version", NULL, cmd_version, "Display version" },
{ "quit", NULL, cmd_quit, "Quit program" },
{ "exit", NULL, cmd_quit },
--
2.1.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH BlueZ 11/12] client: Add notify command
2015-02-06 11:03 [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
` (9 preceding siblings ...)
2015-02-06 11:03 ` [PATCH BlueZ 10/12] client: Add write command Luiz Augusto von Dentz
@ 2015-02-06 11:03 ` Luiz Augusto von Dentz
2015-02-06 11:03 ` [PATCH BlueZ 12/12] client: Handle attribute notifications Luiz Augusto von Dentz
2015-02-10 11:42 ` [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
12 siblings, 0 replies; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2015-02-06 11:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This command can be used to start/stop changes on the attribute value,
it only works if an attribute has been selected with select-attribute.
---
client/gatt.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
client/gatt.h | 1 +
client/main.c | 16 ++++++++++++++++
3 files changed, 64 insertions(+)
diff --git a/client/gatt.c b/client/gatt.c
index 207e049..3785452 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -465,3 +465,50 @@ void gatt_write_attribute(GDBusProxy *proxy, const char *arg)
rl_printf("Unable to write attribute %s\n",
g_dbus_proxy_get_path(proxy));
}
+
+static void notify_reply(DBusMessage *message, void *user_data)
+{
+ bool enable = GPOINTER_TO_UINT(user_data);
+ DBusError error;
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, message) == TRUE) {
+ rl_printf("Failed to %s notify: %s\n",
+ enable ? "start" : "stop", error.name);
+ dbus_error_free(&error);
+ return;
+ }
+
+ rl_printf("Notify %s\n", enable == TRUE ? "started" : "stopped");
+}
+
+static void notify_attribute(GDBusProxy *proxy, bool enable)
+{
+ const char *method;
+
+ if (enable == TRUE)
+ method = "StartNotify";
+ else
+ method = "StopNotify";
+
+ if (g_dbus_proxy_method_call(proxy, method, NULL, notify_reply,
+ GUINT_TO_POINTER(enable), NULL) == FALSE) {
+ rl_printf("Failed to %s notify\n", enable ? "start" : "stop");
+ return;
+ }
+}
+
+void gatt_notify_attribute(GDBusProxy *proxy, bool enable)
+{
+ const char *iface;
+
+ iface = g_dbus_proxy_get_interface(proxy);
+ if (!strcmp(iface, "org.bluez.GattCharacteristic1")) {
+ notify_attribute(proxy, enable);
+ return;
+ }
+
+ rl_printf("Unable to notify attribute %s\n",
+ g_dbus_proxy_get_path(proxy));
+}
diff --git a/client/gatt.h b/client/gatt.h
index b99f0f0..effee5e 100644
--- a/client/gatt.h
+++ b/client/gatt.h
@@ -36,3 +36,4 @@ char *gatt_attribute_generator(const char *text, int state);
void gatt_read_attribute(GDBusProxy *proxy);
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 56d4750..57b1201 100644
--- a/client/main.c
+++ b/client/main.c
@@ -1301,6 +1301,21 @@ static void cmd_write(const char *arg)
gatt_write_attribute(default_attr, arg);
}
+static void cmd_notify(const char *arg)
+{
+ dbus_bool_t enable;
+
+ if (parse_argument_on_off(arg, &enable) == FALSE)
+ return;
+
+ if (!default_attr) {
+ rl_printf("No attribute selected\n");
+ return;
+ }
+
+ gatt_notify_attribute(default_attr, enable ? true : false);
+}
+
static void cmd_version(const char *arg)
{
rl_printf("Version %s\n", VERSION);
@@ -1433,6 +1448,7 @@ static const struct {
{ "read", NULL, cmd_read, "Read attribute value" },
{ "write", "<data=[xx xx ...]>", cmd_write,
"Write attribute value" },
+ { "notify", "<on/off>", cmd_notify, "Notify attribute value" },
{ "version", NULL, cmd_version, "Display version" },
{ "quit", NULL, cmd_quit, "Quit program" },
{ "exit", NULL, cmd_quit },
--
2.1.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH BlueZ 12/12] client: Handle attribute notifications
2015-02-06 11:03 [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
` (10 preceding siblings ...)
2015-02-06 11:03 ` [PATCH BlueZ 11/12] client: Add notify command Luiz Augusto von Dentz
@ 2015-02-06 11:03 ` Luiz Augusto von Dentz
2015-02-09 11:41 ` Gowtham Anandha Babu
2015-02-10 11:42 ` [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
12 siblings, 1 reply; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2015-02-06 11:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This enable printing properties changes to the current selected
attribute.
---
client/main.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/client/main.c b/client/main.c
index 57b1201..fbfd8c8 100644
--- a/client/main.c
+++ b/client/main.c
@@ -158,6 +158,7 @@ static void print_iter(const char *label, const char *name,
dbus_uint32_t valu32;
dbus_uint16_t valu16;
dbus_int16_t vals16;
+ unsigned char byte;
const char *valstr;
DBusMessageIter subiter;
@@ -192,6 +193,10 @@ static void print_iter(const char *label, const char *name,
dbus_message_iter_get_basic(iter, &vals16);
rl_printf("%s%s: %d\n", label, name, vals16);
break;
+ case DBUS_TYPE_BYTE:
+ dbus_message_iter_get_basic(iter, &byte);
+ rl_printf("%s%s: 0x%02x\n", label, name, byte);
+ break;
case DBUS_TYPE_VARIANT:
dbus_message_iter_recurse(iter, &subiter);
print_iter(label, name, &subiter);
@@ -494,6 +499,14 @@ static void property_changed(GDBusProxy *proxy, const char *name,
print_iter(str, name, iter);
g_free(str);
+ } else if (proxy == default_attr) {
+ char *str;
+
+ str = g_strdup_printf("[" COLORED_CHG "] Attribute %s ",
+ g_dbus_proxy_get_path(proxy));
+
+ print_iter(str, name, iter);
+ str = g_strdup("");
}
}
--
2.1.0
^ permalink raw reply related [flat|nested] 16+ messages in thread* RE: [PATCH BlueZ 12/12] client: Handle attribute notifications
2015-02-06 11:03 ` [PATCH BlueZ 12/12] client: Handle attribute notifications Luiz Augusto von Dentz
@ 2015-02-09 11:41 ` Gowtham Anandha Babu
2015-02-09 13:14 ` Luiz Augusto von Dentz
0 siblings, 1 reply; 16+ messages in thread
From: Gowtham Anandha Babu @ 2015-02-09 11:41 UTC (permalink / raw)
To: 'Luiz Augusto von Dentz', linux-bluetooth
Hi Luiz,
> -----Original Message-----
> From: linux-bluetooth-owner@vger.kernel.org [mailto:linux-bluetooth-
> owner@vger.kernel.org] On Behalf Of Luiz Augusto von Dentz
> Sent: Friday, February 06, 2015 4:34 PM
> To: linux-bluetooth@vger.kernel.org
> Subject: [PATCH BlueZ 12/12] client: Handle attribute notifications
>
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This enable printing properties changes to the current selected attribute.
> ---
> client/main.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/client/main.c b/client/main.c index 57b1201..fbfd8c8 100644
> --- a/client/main.c
> +++ b/client/main.c
> @@ -158,6 +158,7 @@ static void print_iter(const char *label, const char
> *name,
> dbus_uint32_t valu32;
> dbus_uint16_t valu16;
> dbus_int16_t vals16;
> + unsigned char byte;
> const char *valstr;
> DBusMessageIter subiter;
>
> @@ -192,6 +193,10 @@ static void print_iter(const char *label, const char
> *name,
> dbus_message_iter_get_basic(iter, &vals16);
> rl_printf("%s%s: %d\n", label, name, vals16);
> break;
> + case DBUS_TYPE_BYTE:
> + dbus_message_iter_get_basic(iter, &byte);
> + rl_printf("%s%s: 0x%02x\n", label, name, byte);
> + break;
> case DBUS_TYPE_VARIANT:
> dbus_message_iter_recurse(iter, &subiter);
> print_iter(label, name, &subiter);
> @@ -494,6 +499,14 @@ static void property_changed(GDBusProxy *proxy,
> const char *name,
>
> print_iter(str, name, iter);
> g_free(str);
> + } else if (proxy == default_attr) {
> + char *str;
> +
> + str = g_strdup_printf("[" COLORED_CHG "] Attribute %s ",
> +
> g_dbus_proxy_get_path(proxy));
> +
> + print_iter(str, name, iter);
Here I suppose, g_free(str) should come. Because the returned string (str)
should be freed when no longer needed.
And str = g_strdup(""); seems like Dead assignment. Other than that
everything applied cleanly with no warnings/errors.
Regards,
Gowtham Anandha Babu
> + str = g_strdup("");
> }
> }
>
> --
> 2.1.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth"
in
> the body of a message to majordomo@vger.kernel.org More majordomo
> info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH BlueZ 12/12] client: Handle attribute notifications
2015-02-09 11:41 ` Gowtham Anandha Babu
@ 2015-02-09 13:14 ` Luiz Augusto von Dentz
0 siblings, 0 replies; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2015-02-09 13:14 UTC (permalink / raw)
To: Gowtham Anandha Babu; +Cc: linux-bluetooth@vger.kernel.org
Hi Gowtham,
On Mon, Feb 9, 2015 at 1:41 PM, Gowtham Anandha Babu
<gowtham.ab@samsung.com> wrote:
> Hi Luiz,
>
>> -----Original Message-----
>> From: linux-bluetooth-owner@vger.kernel.org [mailto:linux-bluetooth-
>> owner@vger.kernel.org] On Behalf Of Luiz Augusto von Dentz
>> Sent: Friday, February 06, 2015 4:34 PM
>> To: linux-bluetooth@vger.kernel.org
>> Subject: [PATCH BlueZ 12/12] client: Handle attribute notifications
>>
>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>
>> This enable printing properties changes to the current selected attribute.
>> ---
>> client/main.c | 13 +++++++++++++
>> 1 file changed, 13 insertions(+)
>>
>> diff --git a/client/main.c b/client/main.c index 57b1201..fbfd8c8 100644
>> --- a/client/main.c
>> +++ b/client/main.c
>> @@ -158,6 +158,7 @@ static void print_iter(const char *label, const char
>> *name,
>> dbus_uint32_t valu32;
>> dbus_uint16_t valu16;
>> dbus_int16_t vals16;
>> + unsigned char byte;
>> const char *valstr;
>> DBusMessageIter subiter;
>>
>> @@ -192,6 +193,10 @@ static void print_iter(const char *label, const char
>> *name,
>> dbus_message_iter_get_basic(iter, &vals16);
>> rl_printf("%s%s: %d\n", label, name, vals16);
>> break;
>> + case DBUS_TYPE_BYTE:
>> + dbus_message_iter_get_basic(iter, &byte);
>> + rl_printf("%s%s: 0x%02x\n", label, name, byte);
>> + break;
>> case DBUS_TYPE_VARIANT:
>> dbus_message_iter_recurse(iter, &subiter);
>> print_iter(label, name, &subiter);
>> @@ -494,6 +499,14 @@ static void property_changed(GDBusProxy *proxy,
>> const char *name,
>>
>> print_iter(str, name, iter);
>> g_free(str);
>> + } else if (proxy == default_attr) {
>> + char *str;
>> +
>> + str = g_strdup_printf("[" COLORED_CHG "] Attribute %s ",
>> +
>> g_dbus_proxy_get_path(proxy));
>> +
>> + print_iter(str, name, iter);
>
> Here I suppose, g_free(str) should come. Because the returned string (str)
> should be freed when no longer needed.
> And str = g_strdup(""); seems like Dead assignment. Other than that
> everything applied cleanly with no warnings/errors.
>
> Regards,
> Gowtham Anandha Babu
>
>> + str = g_strdup("");
Indeed this is a dead assignment, not sure why it did not catch during
the build, perhaps that should be g_free not g_strdup.
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH BlueZ 00/12] client: Add support for GATT API
2015-02-06 11:03 [PATCH BlueZ 00/12] client: Add support for GATT API Luiz Augusto von Dentz
` (11 preceding siblings ...)
2015-02-06 11:03 ` [PATCH BlueZ 12/12] client: Handle attribute notifications Luiz Augusto von Dentz
@ 2015-02-10 11:42 ` Luiz Augusto von Dentz
12 siblings, 0 replies; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2015-02-10 11:42 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org
Hi,
On Fri, Feb 6, 2015 at 1:03 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This adds basic support for GATT API, the main idea is that one can
> navigate into the attributes and read and write values to them.
>
> Some of the output of the changes can be found bellow:
>
> [bluetooth]# connect XX:XX:XX:XX:XX:XX
> Attempting to connect to XX:XX:XX:XX:XX:XX
> [CHG] Device XX:XX:XX:XX:XX:XX Connected: yes
> Connection successful
> [CHG] Device XX:XX:XX:XX:XX:XX Paired: yes
> [NEW] Service /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011 Battery Service (Primary)
> [NEW] Characteristic /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012 Battery Level
> [NEW] Descriptor /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012/desc0014 Client Characteristic Configuration
> [Arc Touch Mouse SE]# select-attribute /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011
> /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011 /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012 /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012/desc0014
> [Arc Touch Mouse SE]# select-attribute /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011
> [Arc Touch Mouse SE:/service0011]# attribute-info
> Service - Battery Service
> UUID: 0000180f-0000-1000-8000-00805f9b34fb
> Primary: yes
> Characteristics: /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012
> [Arc Touch Mouse SE:/service0011]# select-attribute /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012
> [Arc Touch Mouse SE:/service0011/char0012]# attribute-info
> Characteristic - Battery Level
> UUID: 00002a19-0000-1000-8000-00805f9b34fb
> Service: /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011
> Notifying: no
> Flags: read
> Flags: notify
> Descriptors: /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012/desc0014
> [Arc Touch Mouse SE:/service0011/char0012]# read
> Attempting to read /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012
> [CHG] Attribute /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012 Value: 0x63
> 63 c
> [Arc Touch Mouse SE:/service0011/char0012]# write 00
> Attempting to write /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012
> Failed to write: org.bluez.Error.NotSupported
> [Arc Touch Mouse SE:/service0011/char0012]# notify on
> [CHG] Attribute /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012 Notifying: yes
> Notify started
> [CHG] Attribute /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012 Value: 0x55
> [CHG] Attribute /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012 Value: 0x56
> [CHG] Attribute /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012 Value: 0x57
> [CHG] Attribute /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012 Value: 0x58
> [Arc Touch Mouse SE:/service0011/char0012]# notify off
> [CHG] Attribute /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/service0011/char0012 Notifying: no
> Notify stopped
> [Arc Touch Mouse SE:/service0011/char0012]#
>
> Luiz Augusto von Dentz (12):
> client: Add support for GattService1
> client: Add support for GattCharacteristic1
> client: Add support for GattDescriptor1
> client: Make commands relative to device
> client: Add command list-attributes
> client: Add command select-attribute
> client: Add attribute-info command
> client/display: Add rl_hexdump
> client: Add read command
> client: Add write command
> client: Add notify command
> client: Handle attribute notifications
>
> Makefile.tools | 1 +
> client/display.c | 41 +++++
> client/display.h | 1 +
> client/gatt.c | 514 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> client/gatt.h | 39 +++++
> client/main.c | 409 ++++++++++++++++++++++++++++++++++---------
> 6 files changed, 925 insertions(+), 80 deletions(-)
> create mode 100644 client/gatt.c
> create mode 100644 client/gatt.h
>
> --
> 2.1.0
Pushed.
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 16+ messages in thread