All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ v0 0/9] GATT API: Add Register Services Async
@ 2014-02-28 17:05 Claudio Takahasi
  2014-02-28 17:05 ` [PATCH BlueZ v0 1/9] gdbus: Add g_dbus_client_set_proxies_ready_watch() Claudio Takahasi
                   ` (8 more replies)
  0 siblings, 9 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-02-28 17:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patchset is an extension of "[PATCH BlueZ v7 00/11] GATT API:
External Services". It adds the following features:
  * new gdbus helper to allow notifying the clients when
    GetManagedObjects() reply is received and all proxies reported.
  * reply for RegisterService() after validating the fetched objects
  * adds the service declaration to the local GATT database

Claudio Takahasi (9):
  gdbus: Add g_dbus_client_set_proxies_ready_watch()
  gatt: Add proxy added handler
  gatt: Add proxy removed handler
  gatt: Add GATT service to the local database
  gatt: Make RegisterService() async
  test: Add external service GATT skeleton
  test: Add signal handling for gatt-service
  test: Add registering external service
  bluetooth.conf: Add ObjectManager interface

 .gitignore          |   1 +
 Makefile.tools      |   5 +
 gdbus/client.c      |  18 ++++
 gdbus/gdbus.h       |   4 +
 src/bluetooth.conf  |   1 +
 src/gatt-dbus.c     | 135 +++++++++++++++++++++++++-
 test/gatt-service.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 427 insertions(+), 4 deletions(-)
 create mode 100644 test/gatt-service.c

-- 
1.8.3.1


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

* [PATCH BlueZ v0 1/9] gdbus: Add g_dbus_client_set_proxies_ready_watch()
  2014-02-28 17:05 [PATCH BlueZ v0 0/9] GATT API: Add Register Services Async Claudio Takahasi
@ 2014-02-28 17:05 ` Claudio Takahasi
  2014-03-05  6:37   ` Marcel Holtmann
  2014-02-28 17:05 ` [PATCH BlueZ v0 2/9] gatt: Add proxy added handler Claudio Takahasi
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 24+ messages in thread
From: Claudio Takahasi @ 2014-02-28 17:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch adds a new gdbus helper to notify the clients that
GetManagedObjects reply was received and the last proxy has been
informed previously by the proxy_added callback.
---
 gdbus/client.c | 18 ++++++++++++++++++
 gdbus/gdbus.h  |  4 ++++
 2 files changed, 22 insertions(+)

diff --git a/gdbus/client.c b/gdbus/client.c
index be8cc29..f479742 100644
--- a/gdbus/client.c
+++ b/gdbus/client.c
@@ -56,6 +56,8 @@ struct GDBusClient {
 	void *signal_data;
 	GDBusProxyFunction proxy_added;
 	GDBusProxyFunction proxy_removed;
+	GDBusClientReadyFunction ready;
+	void *ready_data;
 	GDBusPropertyFunction property_changed;
 	void *user_data;
 	GList *proxy_list;
@@ -982,6 +984,9 @@ static void parse_managed_objects(GDBusClient *client, DBusMessage *msg)
 
 		dbus_message_iter_next(&dict);
 	}
+
+	if (client->ready)
+		client->ready(client->ready_data);
 }
 
 static void get_managed_objects_reply(DBusPendingCall *call, void *user_data)
@@ -1261,3 +1266,16 @@ gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
 
 	return TRUE;
 }
+
+gboolean g_dbus_client_set_proxies_ready_watch(GDBusClient *client,
+						GDBusClientReadyFunction ready,
+						void *user_data)
+{
+	if (client == NULL)
+		return FALSE;
+
+	client->ready = ready;
+	client->ready_data = user_data;
+
+	return TRUE;
+}
diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index 9542109..aa407aa 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -337,6 +337,7 @@ gboolean g_dbus_proxy_method_call(GDBusProxy *proxy, const char *method,
 				GDBusReturnFunction function, void *user_data,
 				GDBusDestroyFunction destroy);
 
+typedef void (* GDBusClientReadyFunction) (void *user_data);
 typedef void (* GDBusProxyFunction) (GDBusProxy *proxy, void *user_data);
 typedef void (* GDBusPropertyFunction) (GDBusProxy *proxy, const char *name,
 					DBusMessageIter *iter, void *user_data);
@@ -365,6 +366,9 @@ gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
 					GDBusProxyFunction proxy_removed,
 					GDBusPropertyFunction property_changed,
 					void *user_data);
+gboolean g_dbus_client_set_proxies_ready_watch(GDBusClient *client,
+						GDBusClientReadyFunction ready,
+						void *user_data);
 
 #ifdef __cplusplus
 }
-- 
1.8.3.1


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

* [PATCH BlueZ v0 2/9] gatt: Add proxy added handler
  2014-02-28 17:05 [PATCH BlueZ v0 0/9] GATT API: Add Register Services Async Claudio Takahasi
  2014-02-28 17:05 ` [PATCH BlueZ v0 1/9] gdbus: Add g_dbus_client_set_proxies_ready_watch() Claudio Takahasi
@ 2014-02-28 17:05 ` Claudio Takahasi
  2014-02-28 17:05 ` [PATCH BlueZ v0 3/9] gatt: Add proxy removed handler Claudio Takahasi
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-02-28 17:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch creates a list of GATT objects sorting the entries based on
the object path to allow inserting the attributes following hierarchical
association.
---
 src/gatt-dbus.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
index fd614f9..f8486f3 100644
--- a/src/gatt-dbus.c
+++ b/src/gatt-dbus.c
@@ -42,11 +42,15 @@
 #include "gatt-dbus.h"
 
 #define GATT_MGR_IFACE			"org.bluez.GattManager1"
+#define GATT_SERVICE_IFACE		"org.bluez.GattService1"
+#define GATT_CHR_IFACE			"org.bluez.GattCharacteristic1"
+#define GATT_DESCRIPTOR_IFACE		"org.bluez.GattDescriptor1"
 
 struct external_app {
 	char *owner;
 	char *path;
 	GDBusClient *client;
+	GSList *proxies;
 	unsigned int watch;
 };
 
@@ -75,6 +79,43 @@ static void external_app_watch_destroy(gpointer user_data)
 	g_free(eapp);
 }
 
+static int proxy_path_cmp(gconstpointer a, gconstpointer b)
+{
+	GDBusProxy *proxy1 = (GDBusProxy *) a;
+	GDBusProxy *proxy2 = (GDBusProxy *) b;
+	const char *path1 = g_dbus_proxy_get_path(proxy1);
+	const char *path2 = g_dbus_proxy_get_path(proxy2);
+
+	return g_strcmp0(path1, path2);
+}
+
+static void proxy_added(GDBusProxy *proxy, void *user_data)
+{
+	struct external_app *eapp = user_data;
+	const char *interface, *path;
+
+	interface = g_dbus_proxy_get_interface(proxy);
+	path = g_dbus_proxy_get_path(proxy);
+
+	if (!g_str_has_prefix(path, eapp->path))
+		return;
+
+	if (g_strcmp0(interface, GATT_CHR_IFACE) != 0 &&
+			g_strcmp0(interface, GATT_SERVICE_IFACE) != 0 &&
+			g_strcmp0(interface, GATT_DESCRIPTOR_IFACE) != 0)
+		return;
+
+	DBG("path %s iface %s", path, interface);
+
+	/*
+	 * Object path follows a hierarchical organization. Add the
+	 * proxies sorted by path helps the logic to register the
+	 * object path later.
+	 */
+	eapp->proxies = g_slist_insert_sorted(eapp->proxies, proxy,
+							proxy_path_cmp);
+}
+
 static struct external_app *new_external_app(DBusConnection *conn,
 					const char *sender, const char *path)
 {
@@ -99,6 +140,9 @@ static struct external_app *new_external_app(DBusConnection *conn,
 	eapp->client = client;
 	eapp->path = g_strdup(path);
 
+	g_dbus_client_set_proxy_handlers(client, proxy_added, NULL, NULL,
+								eapp);
+
 	return eapp;
 }
 
-- 
1.8.3.1


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

* [PATCH BlueZ v0 3/9] gatt: Add proxy removed handler
  2014-02-28 17:05 [PATCH BlueZ v0 0/9] GATT API: Add Register Services Async Claudio Takahasi
  2014-02-28 17:05 ` [PATCH BlueZ v0 1/9] gdbus: Add g_dbus_client_set_proxies_ready_watch() Claudio Takahasi
  2014-02-28 17:05 ` [PATCH BlueZ v0 2/9] gatt: Add proxy added handler Claudio Takahasi
@ 2014-02-28 17:05 ` Claudio Takahasi
  2014-02-28 17:05 ` [PATCH BlueZ v0 4/9] gatt: Add GATT service to the local database Claudio Takahasi
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-02-28 17:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 src/gatt-dbus.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
index f8486f3..28d7f78 100644
--- a/src/gatt-dbus.c
+++ b/src/gatt-dbus.c
@@ -116,6 +116,19 @@ static void proxy_added(GDBusProxy *proxy, void *user_data)
 							proxy_path_cmp);
 }
 
+static void proxy_removed(GDBusProxy *proxy, void *user_data)
+{
+	struct external_app *eapp = user_data;
+	const char *interface, *path;
+
+	interface = g_dbus_proxy_get_interface(proxy);
+	path = g_dbus_proxy_get_path(proxy);
+
+	DBG("path %s iface %s", path, interface);
+
+	eapp->proxies = g_slist_remove(eapp->proxies, proxy);
+}
+
 static struct external_app *new_external_app(DBusConnection *conn,
 					const char *sender, const char *path)
 {
@@ -140,8 +153,8 @@ static struct external_app *new_external_app(DBusConnection *conn,
 	eapp->client = client;
 	eapp->path = g_strdup(path);
 
-	g_dbus_client_set_proxy_handlers(client, proxy_added, NULL, NULL,
-								eapp);
+	g_dbus_client_set_proxy_handlers(client, proxy_added, proxy_removed,
+								NULL, eapp);
 
 	return eapp;
 }
-- 
1.8.3.1


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

* [PATCH BlueZ v0 4/9] gatt: Add GATT service to the local database
  2014-02-28 17:05 [PATCH BlueZ v0 0/9] GATT API: Add Register Services Async Claudio Takahasi
                   ` (2 preceding siblings ...)
  2014-02-28 17:05 ` [PATCH BlueZ v0 3/9] gatt: Add proxy removed handler Claudio Takahasi
@ 2014-02-28 17:05 ` Claudio Takahasi
  2014-02-28 17:05 ` [PATCH BlueZ v0 5/9] gatt: Make RegisterService() async Claudio Takahasi
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-02-28 17:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch creates GATT service attribute based on its GDBusProxy
object, and inserts the declaration to the local database.
---
 src/gatt-dbus.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
index 28d7f78..93d5b7c 100644
--- a/src/gatt-dbus.c
+++ b/src/gatt-dbus.c
@@ -39,6 +39,7 @@
 #include "log.h"
 
 #include "error.h"
+#include "gatt.h"
 #include "gatt-dbus.h"
 
 #define GATT_MGR_IFACE			"org.bluez.GattManager1"
@@ -129,6 +130,56 @@ static void proxy_removed(GDBusProxy *proxy, void *user_data)
 	eapp->proxies = g_slist_remove(eapp->proxies, proxy);
 }
 
+static int register_external_service(const struct external_app *eapp,
+							GDBusProxy *proxy)
+{
+	DBusMessageIter iter;
+	const char *str, *path, *iface;
+	bt_uuid_t uuid;
+
+	path = g_dbus_proxy_get_path(proxy);
+	iface = g_dbus_proxy_get_interface(proxy);
+	if (g_strcmp0(eapp->path, path) != 0 ||
+			g_strcmp0(iface, GATT_SERVICE_IFACE) != 0)
+		return -EINVAL;
+
+	if (!g_dbus_proxy_get_property(proxy, "UUID", &iter))
+		return -EINVAL;
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+		return -EINVAL;
+
+	dbus_message_iter_get_basic(&iter, &str);
+
+	if (bt_string_to_uuid(&uuid, str) < 0)
+		return -EINVAL;
+
+	if (btd_gatt_add_service(&uuid) == NULL)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void client_ready(void *user_data)
+{
+	struct external_app *eapp = user_data;
+	GDBusProxy *proxy;
+
+	if (eapp->proxies == NULL)
+		goto fail;
+
+	proxy = eapp->proxies->data;
+	if (register_external_service(eapp, proxy) < 0)
+		goto fail;
+
+	DBG("Added GATT service %s", eapp->path);
+
+	return;
+
+fail:
+	DBG("No proxies: inconsistent service (%s)!", eapp->path);
+}
+
 static struct external_app *new_external_app(DBusConnection *conn,
 					const char *sender, const char *path)
 {
@@ -156,6 +207,8 @@ static struct external_app *new_external_app(DBusConnection *conn,
 	g_dbus_client_set_proxy_handlers(client, proxy_added, proxy_removed,
 								NULL, eapp);
 
+	g_dbus_client_set_proxies_ready_watch(client, client_ready, eapp);
+
 	return eapp;
 }
 
-- 
1.8.3.1


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

* [PATCH BlueZ v0 5/9] gatt: Make RegisterService() async
  2014-02-28 17:05 [PATCH BlueZ v0 0/9] GATT API: Add Register Services Async Claudio Takahasi
                   ` (3 preceding siblings ...)
  2014-02-28 17:05 ` [PATCH BlueZ v0 4/9] gatt: Add GATT service to the local database Claudio Takahasi
@ 2014-02-28 17:05 ` Claudio Takahasi
  2014-02-28 17:05 ` [PATCH BlueZ v0 6/9] test: Add external service GATT skeleton Claudio Takahasi
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-02-28 17:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

GDBus proxy objects consistency should be checked, and attributes
declaration inserted in the local GATT database before replying
the caller.
---
 src/gatt-dbus.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
index 93d5b7c..b8c7b17 100644
--- a/src/gatt-dbus.c
+++ b/src/gatt-dbus.c
@@ -50,6 +50,7 @@
 struct external_app {
 	char *owner;
 	char *path;
+	DBusMessage *reg;
 	GDBusClient *client;
 	GSList *proxies;
 	unsigned int watch;
@@ -74,6 +75,8 @@ static void external_app_watch_destroy(gpointer user_data)
 	external_apps = g_slist_remove(external_apps, eapp);
 
 	g_dbus_client_unref(eapp->client);
+	if (eapp->reg)
+		dbus_message_unref(eapp->reg);
 
 	g_free(eapp->owner);
 	g_free(eapp->path);
@@ -164,6 +167,8 @@ static void client_ready(void *user_data)
 {
 	struct external_app *eapp = user_data;
 	GDBusProxy *proxy;
+	DBusConnection *conn = btd_get_dbus_connection();
+	DBusMessage *reply;
 
 	if (eapp->proxies == NULL)
 		goto fail;
@@ -174,17 +179,28 @@ static void client_ready(void *user_data)
 
 	DBG("Added GATT service %s", eapp->path);
 
-	return;
+	reply = dbus_message_new_method_return(eapp->reg);
+	goto reply;
 
 fail:
-	DBG("No proxies: inconsistent service (%s)!", eapp->path);
+	error("Could not register external service: %s", eapp->path);
+
+	reply = btd_error_invalid_args(eapp->reg);
+	/* TODO: missing eapp cleanup */
+
+reply:
+	dbus_message_unref(eapp->reg);
+	eapp->reg = NULL;
+
+	g_dbus_send_message(conn, reply);
 }
 
 static struct external_app *new_external_app(DBusConnection *conn,
-					const char *sender, const char *path)
+					DBusMessage *msg, const char *path)
 {
 	struct external_app *eapp;
 	GDBusClient *client;
+	const char *sender = dbus_message_get_sender(msg);
 
 	client = g_dbus_client_new(conn, sender, "/");
 	if (client == NULL)
@@ -201,6 +217,7 @@ static struct external_app *new_external_app(DBusConnection *conn,
 	}
 
 	eapp->owner = g_strdup(sender);
+	eapp->reg = dbus_message_ref(msg);
 	eapp->client = client;
 	eapp->path = g_strdup(path);
 
@@ -230,7 +247,7 @@ static DBusMessage *register_service(DBusConnection *conn,
 	if (g_slist_find_custom(external_apps, path, external_app_path_cmp))
 		return btd_error_already_exists(msg);
 
-	eapp = new_external_app(conn, dbus_message_get_sender(msg), path);
+	eapp = new_external_app(conn, msg, path);
 	if (eapp == NULL)
 		return btd_error_failed(msg, "Not enough resources");
 
@@ -238,7 +255,7 @@ static DBusMessage *register_service(DBusConnection *conn,
 
 	DBG("New app %p: %s", eapp, path);
 
-	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+	return NULL;
 }
 
 static DBusMessage *unregister_service(DBusConnection *conn,
@@ -248,7 +265,7 @@ static DBusMessage *unregister_service(DBusConnection *conn,
 }
 
 static const GDBusMethodTable methods[] = {
-	{ GDBUS_EXPERIMENTAL_METHOD("RegisterService",
+	{ GDBUS_EXPERIMENTAL_ASYNC_METHOD("RegisterService",
 				GDBUS_ARGS({ "service", "o"},
 						{ "options", "a{sv}"}),
 				NULL, register_service) },
-- 
1.8.3.1


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

* [PATCH BlueZ v0 6/9] test: Add external service GATT skeleton
  2014-02-28 17:05 [PATCH BlueZ v0 0/9] GATT API: Add Register Services Async Claudio Takahasi
                   ` (4 preceding siblings ...)
  2014-02-28 17:05 ` [PATCH BlueZ v0 5/9] gatt: Make RegisterService() async Claudio Takahasi
@ 2014-02-28 17:05 ` Claudio Takahasi
  2014-02-28 17:05 ` [PATCH BlueZ v0 7/9] test: Add signal handling for gatt-service Claudio Takahasi
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-02-28 17:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch adds the initial code for an external GATT service example.
It implements the API defined at doc/gatt-api.txt
---
 .gitignore          |   1 +
 Makefile.tools      |   5 +++
 test/gatt-service.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 127 insertions(+)
 create mode 100644 test/gatt-service.c

diff --git a/.gitignore b/.gitignore
index 94c0c78..d8e06ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -76,6 +76,7 @@ test/sap_client.pyc
 test/bluezutils.pyc
 unit/test-ringbuf
 unit/test-queue
+test/gatt-service
 unit/test-eir
 unit/test-uuid
 unit/test-crc
diff --git a/Makefile.tools b/Makefile.tools
index 9f7ba9f..cf800da 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -392,3 +392,8 @@ test_scripts += test/sap_client.py test/bluezutils.py \
 		test/test-heartrate test/test-alert test/test-hfp \
 		test/test-cyclingspeed test/opp-client test/ftp-client \
 		test/pbap-client test/map-client
+
+noinst_PROGRAMS += test/gatt-service
+
+test_gatt_service_SOURCES = test/gatt-service.c
+test_gatt_service_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ gdbus/libgdbus-internal.la
diff --git a/test/gatt-service.c b/test/gatt-service.c
new file mode 100644
index 0000000..18ab7da
--- /dev/null
+++ b/test/gatt-service.c
@@ -0,0 +1,121 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2014  Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ *  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 <errno.h>
+#include <stdio.h>
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <gdbus/gdbus.h>
+
+#define GATT_SERVICE_IFACE		"org.bluez.GattService1"
+
+/* Immediate Alert Service UUID */
+#define IAS_UUID			"00001802-0000-1000-8000-00805f9b34fb"
+
+static GMainLoop *main_loop;
+static GSList *services;
+
+static gboolean service_get_uuid(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *user_data)
+{
+	const char *uuid = user_data;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &uuid);
+
+	return TRUE;
+}
+
+static gboolean service_get_includes(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *user_data)
+{
+	return TRUE;
+}
+
+static gboolean service_exist_includes(const GDBusPropertyTable *property,
+							void *user_data)
+{
+	return FALSE;
+}
+
+static const GDBusPropertyTable service_properties[] = {
+	{ "UUID", "s", service_get_uuid },
+	{ "Includes", "ao", service_get_includes, NULL,
+					service_exist_includes },
+	{ }
+};
+
+static char *register_service(DBusConnection *conn, const char *uuid)
+{
+	static int id = 1;
+	char *path;
+
+	path = g_strdup_printf("/service%d", id++);
+	if (g_dbus_register_interface(conn, path, GATT_SERVICE_IFACE,
+				NULL, NULL, service_properties,
+				g_strdup(uuid), g_free) == FALSE) {
+		printf("Couldn't register service interface\n");
+		g_free(path);
+		return NULL;
+	}
+
+	return path;
+}
+
+static void create_services(DBusConnection *conn)
+{
+	char *service_path;
+
+	service_path = register_service(conn, IAS_UUID);
+
+	services = g_slist_prepend(services, service_path);
+
+	printf("Registered service: %s\n", service_path);
+}
+
+int main(int argc, char *argv[])
+{
+	DBusConnection *dbus_conn;
+
+	dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
+
+	main_loop = g_main_loop_new(NULL, FALSE);
+
+	g_dbus_attach_object_manager(dbus_conn);
+
+	printf("gatt-service unique name: %s\n",
+				dbus_bus_get_unique_name(dbus_conn));
+
+	create_services(dbus_conn);
+
+	g_main_loop_run(main_loop);
+
+	g_slist_free_full(services, g_free);
+	dbus_connection_unref(dbus_conn);
+
+	return 0;
+}
-- 
1.8.3.1


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

* [PATCH BlueZ v0 7/9] test: Add signal handling for gatt-service
  2014-02-28 17:05 [PATCH BlueZ v0 0/9] GATT API: Add Register Services Async Claudio Takahasi
                   ` (5 preceding siblings ...)
  2014-02-28 17:05 ` [PATCH BlueZ v0 6/9] test: Add external service GATT skeleton Claudio Takahasi
@ 2014-02-28 17:05 ` Claudio Takahasi
  2014-02-28 17:05 ` [PATCH BlueZ v0 8/9] test: Add registering external service Claudio Takahasi
  2014-02-28 17:05 ` [PATCH BlueZ v0 9/9] bluetooth.conf: Add ObjectManager interface Claudio Takahasi
  8 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-02-28 17:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch implements signal handling to run cleanup tasks before
exiting.
---
 test/gatt-service.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/test/gatt-service.c b/test/gatt-service.c
index 18ab7da..ecb5cc3 100644
--- a/test/gatt-service.c
+++ b/test/gatt-service.c
@@ -27,6 +27,9 @@
 
 #include <errno.h>
 #include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/signalfd.h>
 
 #include <glib.h>
 #include <dbus/dbus.h>
@@ -97,9 +100,83 @@ static void create_services(DBusConnection *conn)
 	printf("Registered service: %s\n", service_path);
 }
 
+static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
+							gpointer user_data)
+{
+	static bool __terminated = false;
+	struct signalfd_siginfo si;
+	ssize_t result;
+	int fd;
+
+	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP))
+		return FALSE;
+
+	fd = g_io_channel_unix_get_fd(channel);
+
+	result = read(fd, &si, sizeof(si));
+	if (result != sizeof(si))
+		return FALSE;
+
+	switch (si.ssi_signo) {
+	case SIGINT:
+	case SIGTERM:
+		if (!__terminated) {
+			printf("Terminating\n");
+			g_main_loop_quit(main_loop);
+		}
+
+		__terminated = true;
+		break;
+	}
+
+	return TRUE;
+}
+
+static guint setup_signalfd(void)
+{
+	GIOChannel *channel;
+	guint source;
+	sigset_t mask;
+	int fd;
+
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGINT);
+	sigaddset(&mask, SIGTERM);
+
+	if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
+		perror("Failed to set signal mask");
+		return 0;
+	}
+
+	fd = signalfd(-1, &mask, 0);
+	if (fd < 0) {
+		perror("Failed to create signal descriptor");
+		return 0;
+	}
+
+	channel = g_io_channel_unix_new(fd);
+
+	g_io_channel_set_close_on_unref(channel, TRUE);
+	g_io_channel_set_encoding(channel, NULL, NULL);
+	g_io_channel_set_buffered(channel, FALSE);
+
+	source = g_io_add_watch(channel,
+				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				signal_handler, NULL);
+
+	g_io_channel_unref(channel);
+
+	return source;
+}
+
 int main(int argc, char *argv[])
 {
 	DBusConnection *dbus_conn;
+	guint signal;
+
+	signal = setup_signalfd();
+	if (signal == 0)
+		return -errno;
 
 	dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
 
@@ -114,6 +191,8 @@ int main(int argc, char *argv[])
 
 	g_main_loop_run(main_loop);
 
+	g_source_remove(signal);
+
 	g_slist_free_full(services, g_free);
 	dbus_connection_unref(dbus_conn);
 
-- 
1.8.3.1


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

* [PATCH BlueZ v0 8/9] test: Add registering external service
  2014-02-28 17:05 [PATCH BlueZ v0 0/9] GATT API: Add Register Services Async Claudio Takahasi
                   ` (6 preceding siblings ...)
  2014-02-28 17:05 ` [PATCH BlueZ v0 7/9] test: Add signal handling for gatt-service Claudio Takahasi
@ 2014-02-28 17:05 ` Claudio Takahasi
  2014-02-28 17:05 ` [PATCH BlueZ v0 9/9] bluetooth.conf: Add ObjectManager interface Claudio Takahasi
  8 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-02-28 17:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch extends gatt-service to call RegisterService() when org.bluez
service gets connected to the system bus.
---
 test/gatt-service.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/test/gatt-service.c b/test/gatt-service.c
index ecb5cc3..f8ae7cc 100644
--- a/test/gatt-service.c
+++ b/test/gatt-service.c
@@ -35,6 +35,7 @@
 #include <dbus/dbus.h>
 #include <gdbus/gdbus.h>
 
+#define GATT_MGR_IFACE			"org.bluez.GattManager1"
 #define GATT_SERVICE_IFACE		"org.bluez.GattService1"
 
 /* Immediate Alert Service UUID */
@@ -100,6 +101,65 @@ static void create_services(DBusConnection *conn)
 	printf("Registered service: %s\n", service_path);
 }
 
+static void register_external_service_reply(DBusPendingCall *call,
+							void *user_data)
+{
+	DBusMessage *reply = dbus_pending_call_steal_reply(call);
+	DBusError derr;
+
+	dbus_error_init(&derr);
+	dbus_set_error_from_message(&derr, reply);
+
+	if (dbus_error_is_set(&derr))
+		printf("RegisterService: %s\n", derr.message);
+	else
+		printf("RegisterService: OK\n");
+
+	dbus_message_unref(reply);
+	dbus_error_free(&derr);
+}
+
+static void register_external_service(gpointer a, gpointer b)
+{
+	DBusConnection *conn = b;
+	const char *path = a;
+	DBusMessage *msg;
+	DBusPendingCall *call;
+	DBusMessageIter iter, dict;
+
+	msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
+					GATT_MGR_IFACE, "RegisterService");
+	if (msg == NULL) {
+		printf("Couldn't allocate D-Bus message\n");
+		return;
+	}
+
+	dbus_message_iter_init_append(msg, &iter);
+
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &dict);
+
+	/* TODO: Add options dictionary */
+
+	dbus_message_iter_close_container(&iter, &dict);
+
+	if (g_dbus_send_message_with_reply(conn, msg, &call, -1) == FALSE) {
+		dbus_message_unref(msg);
+		return;
+	}
+
+	dbus_pending_call_set_notify(call, register_external_service_reply,
+								NULL, NULL);
+
+	dbus_pending_call_unref(call);
+}
+
+static void connect_handler(DBusConnection *conn, void *user_data)
+{
+	g_slist_foreach(services, register_external_service, conn);
+}
+
 static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
 							gpointer user_data)
 {
@@ -171,6 +231,7 @@ static guint setup_signalfd(void)
 
 int main(int argc, char *argv[])
 {
+	GDBusClient *client;
 	DBusConnection *dbus_conn;
 	guint signal;
 
@@ -189,8 +250,14 @@ int main(int argc, char *argv[])
 
 	create_services(dbus_conn);
 
+	client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");
+
+	g_dbus_client_set_connect_watch(client, connect_handler, NULL);
+
 	g_main_loop_run(main_loop);
 
+	g_dbus_client_unref(client);
+
 	g_source_remove(signal);
 
 	g_slist_free_full(services, g_free);
-- 
1.8.3.1


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

* [PATCH BlueZ v0 9/9] bluetooth.conf: Add ObjectManager interface
  2014-02-28 17:05 [PATCH BlueZ v0 0/9] GATT API: Add Register Services Async Claudio Takahasi
                   ` (7 preceding siblings ...)
  2014-02-28 17:05 ` [PATCH BlueZ v0 8/9] test: Add registering external service Claudio Takahasi
@ 2014-02-28 17:05 ` Claudio Takahasi
  8 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-02-28 17:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 src/bluetooth.conf | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/bluetooth.conf b/src/bluetooth.conf
index 0495200..ad8891a 100644
--- a/src/bluetooth.conf
+++ b/src/bluetooth.conf
@@ -18,6 +18,7 @@
     <allow send_interface="org.bluez.Profile1"/>
     <allow send_interface="org.bluez.HeartRateWatcher1"/>
     <allow send_interface="org.bluez.CyclingSpeedWatcher1"/>
+    <allow send_interface="org.freedesktop.DBus.ObjectManager"/>
   </policy>
 
   <policy at_console="true">
-- 
1.8.3.1


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

* Re: [PATCH BlueZ v0 1/9] gdbus: Add g_dbus_client_set_proxies_ready_watch()
  2014-02-28 17:05 ` [PATCH BlueZ v0 1/9] gdbus: Add g_dbus_client_set_proxies_ready_watch() Claudio Takahasi
@ 2014-03-05  6:37   ` Marcel Holtmann
  2014-03-06 12:24     ` Claudio Takahasi
  0 siblings, 1 reply; 24+ messages in thread
From: Marcel Holtmann @ 2014-03-05  6:37 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth

Hi Claudio,

> This patch adds a new gdbus helper to notify the clients that
> GetManagedObjects reply was received and the last proxy has been
> informed previously by the proxy_added callback.
> ---
> gdbus/client.c | 18 ++++++++++++++++++
> gdbus/gdbus.h  |  4 ++++
> 2 files changed, 22 insertions(+)
> 
> diff --git a/gdbus/client.c b/gdbus/client.c
> index be8cc29..f479742 100644
> --- a/gdbus/client.c
> +++ b/gdbus/client.c
> @@ -56,6 +56,8 @@ struct GDBusClient {
> 	void *signal_data;
> 	GDBusProxyFunction proxy_added;
> 	GDBusProxyFunction proxy_removed;
> +	GDBusClientReadyFunction ready;
> +	void *ready_data;
> 	GDBusPropertyFunction property_changed;
> 	void *user_data;
> 	GList *proxy_list;
> @@ -982,6 +984,9 @@ static void parse_managed_objects(GDBusClient *client, DBusMessage *msg)
> 
> 		dbus_message_iter_next(&dict);
> 	}
> +
> +	if (client->ready)
> +		client->ready(client->ready_data);
> }
> 
> static void get_managed_objects_reply(DBusPendingCall *call, void *user_data)
> @@ -1261,3 +1266,16 @@ gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
> 
> 	return TRUE;
> }
> +
> +gboolean g_dbus_client_set_proxies_ready_watch(GDBusClient *client,
> +						GDBusClientReadyFunction ready,
> +						void *user_data)
> +{
> +	if (client == NULL)
> +		return FALSE;
> +
> +	client->ready = ready;
> +	client->ready_data = user_data;
> +
> +	return TRUE;
> +}
> diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
> index 9542109..aa407aa 100644
> --- a/gdbus/gdbus.h
> +++ b/gdbus/gdbus.h
> @@ -337,6 +337,7 @@ gboolean g_dbus_proxy_method_call(GDBusProxy *proxy, const char *method,
> 				GDBusReturnFunction function, void *user_data,
> 				GDBusDestroyFunction destroy);
> 
> +typedef void (* GDBusClientReadyFunction) (void *user_data);
> typedef void (* GDBusProxyFunction) (GDBusProxy *proxy, void *user_data);
> typedef void (* GDBusPropertyFunction) (GDBusProxy *proxy, const char *name,
> 					DBusMessageIter *iter, void *user_data);
> @@ -365,6 +366,9 @@ gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
> 					GDBusProxyFunction proxy_removed,
> 					GDBusPropertyFunction property_changed,
> 					void *user_data);
> +gboolean g_dbus_client_set_proxies_ready_watch(GDBusClient *client,
> +						GDBusClientReadyFunction ready,
> +						void *user_data);

this names is a bit confusing. On one hand it is proxies ready on the other it is client ready. We need to be a bit specific here.

My initial thinking is this should be

	g_dbus_client_set_ready_watch()

and then use GDBusClientFunction(GDBusClient, user_data) as callback function.

Regards

Marcel


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

* Re: [PATCH BlueZ v0 1/9] gdbus: Add g_dbus_client_set_proxies_ready_watch()
  2014-03-05  6:37   ` Marcel Holtmann
@ 2014-03-06 12:24     ` Claudio Takahasi
  2014-03-06 13:44       ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Claudio Takahasi
  0 siblings, 1 reply; 24+ messages in thread
From: Claudio Takahasi @ 2014-03-06 12:24 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: BlueZ development

Hi Marcel,

On Wed, Mar 5, 2014 at 3:37 AM, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi Claudio,
>
>> This patch adds a new gdbus helper to notify the clients that
>> GetManagedObjects reply was received and the last proxy has been
>> informed previously by the proxy_added callback.
>> ---
>> gdbus/client.c | 18 ++++++++++++++++++
>> gdbus/gdbus.h  |  4 ++++
>> 2 files changed, 22 insertions(+)
>>
>> diff --git a/gdbus/client.c b/gdbus/client.c
>> index be8cc29..f479742 100644
>> --- a/gdbus/client.c
>> +++ b/gdbus/client.c
>> @@ -56,6 +56,8 @@ struct GDBusClient {
>>       void *signal_data;
>>       GDBusProxyFunction proxy_added;
>>       GDBusProxyFunction proxy_removed;
>> +     GDBusClientReadyFunction ready;
>> +     void *ready_data;
>>       GDBusPropertyFunction property_changed;
>>       void *user_data;
>>       GList *proxy_list;
>> @@ -982,6 +984,9 @@ static void parse_managed_objects(GDBusClient *client, DBusMessage *msg)
>>
>>               dbus_message_iter_next(&dict);
>>       }
>> +
>> +     if (client->ready)
>> +             client->ready(client->ready_data);
>> }
>>
>> static void get_managed_objects_reply(DBusPendingCall *call, void *user_data)
>> @@ -1261,3 +1266,16 @@ gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
>>
>>       return TRUE;
>> }
>> +
>> +gboolean g_dbus_client_set_proxies_ready_watch(GDBusClient *client,
>> +                                             GDBusClientReadyFunction ready,
>> +                                             void *user_data)
>> +{
>> +     if (client == NULL)
>> +             return FALSE;
>> +
>> +     client->ready = ready;
>> +     client->ready_data = user_data;
>> +
>> +     return TRUE;
>> +}
>> diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
>> index 9542109..aa407aa 100644
>> --- a/gdbus/gdbus.h
>> +++ b/gdbus/gdbus.h
>> @@ -337,6 +337,7 @@ gboolean g_dbus_proxy_method_call(GDBusProxy *proxy, const char *method,
>>                               GDBusReturnFunction function, void *user_data,
>>                               GDBusDestroyFunction destroy);
>>
>> +typedef void (* GDBusClientReadyFunction) (void *user_data);
>> typedef void (* GDBusProxyFunction) (GDBusProxy *proxy, void *user_data);
>> typedef void (* GDBusPropertyFunction) (GDBusProxy *proxy, const char *name,
>>                                       DBusMessageIter *iter, void *user_data);
>> @@ -365,6 +366,9 @@ gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
>>                                       GDBusProxyFunction proxy_removed,
>>                                       GDBusPropertyFunction property_changed,
>>                                       void *user_data);
>> +gboolean g_dbus_client_set_proxies_ready_watch(GDBusClient *client,
>> +                                             GDBusClientReadyFunction ready,
>> +                                             void *user_data);
>
> this names is a bit confusing. On one hand it is proxies ready on the other it is client ready. We need to be a bit specific here.
>
> My initial thinking is this should be
>
>         g_dbus_client_set_ready_watch()
>
> and then use GDBusClientFunction(GDBusClient, user_data) as callback function.
>
> Regards
>
> Marcel

Ok. I will send another patchset renaming the function.

For our use case, the GDBus Proxy order is important, for others maybe
it is not relevant. Another possible implementation could be detect if
the reported proxy is the last. ProxyAdded callback could be extended
to report some sort of index x/y or create a new helper
g_dbus_client_get_proxy_last().


Regards,
Claudio

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

* [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async
  2014-03-06 12:24     ` Claudio Takahasi
@ 2014-03-06 13:44       ` Claudio Takahasi
  2014-03-06 13:44         ` [PATCH BlueZ v1 1/9] gdbus: Add g_dbus_client_set_ready_watch() Claudio Takahasi
                           ` (9 more replies)
  0 siblings, 10 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-03-06 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patchset is an extension of "[PATCH BlueZ v7 00/11] GATT API:
External Services". It adds the following features:
  * new gdbus helper to allow notifying the clients when
    GetManagedObjects() reply is received and all proxies reported to
    upper-layer.
  * reply for RegisterService() after validating fetched objects
  * adds the service declaration to the local GATT database

* Changes from v0 to v1:
  - renames g_dbus_client_set_proxies_ready_watch() to
    g_dbus_client_set_ready_watch()

Claudio Takahasi (9):
  gdbus: Add g_dbus_client_set_ready_watch()
  gatt: Add proxy added handler
  gatt: Add proxy removed handler
  gatt: Add GATT service to the local database
  gatt: Make RegisterService() async
  test: Add external service GATT skeleton
  test: Add signal handling for gatt-service
  test: Add registering external service
  bluetooth.conf: Add ObjectManager interface

 .gitignore          |   1 +
 Makefile.tools      |   5 +
 gdbus/client.c      |  17 ++++
 gdbus/gdbus.h       |   4 +-
 src/bluetooth.conf  |   1 +
 src/gatt-dbus.c     | 135 +++++++++++++++++++++++++-
 test/gatt-service.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 425 insertions(+), 5 deletions(-)
 create mode 100644 test/gatt-service.c

-- 
1.8.3.1


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

* [PATCH BlueZ v1 1/9] gdbus: Add g_dbus_client_set_ready_watch()
  2014-03-06 13:44       ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Claudio Takahasi
@ 2014-03-06 13:44         ` Claudio Takahasi
  2014-03-06 13:56           ` Luiz Augusto von Dentz
  2014-03-06 13:44         ` [PATCH BlueZ v1 2/9] gatt: Add proxy added handler Claudio Takahasi
                           ` (8 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: Claudio Takahasi @ 2014-03-06 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch adds a new gdbus helper to notify the clients that
GetManagedObjects reply was received and the last proxy has been
informed previously by the proxy_added callback.
---
 gdbus/client.c | 17 +++++++++++++++++
 gdbus/gdbus.h  |  4 +++-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/gdbus/client.c b/gdbus/client.c
index be8cc29..5193b6c 100644
--- a/gdbus/client.c
+++ b/gdbus/client.c
@@ -56,6 +56,8 @@ struct GDBusClient {
 	void *signal_data;
 	GDBusProxyFunction proxy_added;
 	GDBusProxyFunction proxy_removed;
+	GDBusClientFunction ready;
+	void *ready_data;
 	GDBusPropertyFunction property_changed;
 	void *user_data;
 	GList *proxy_list;
@@ -982,6 +984,9 @@ static void parse_managed_objects(GDBusClient *client, DBusMessage *msg)
 
 		dbus_message_iter_next(&dict);
 	}
+
+	if (client->ready)
+		client->ready(client, client->ready_data);
 }
 
 static void get_managed_objects_reply(DBusPendingCall *call, void *user_data)
@@ -1243,6 +1248,18 @@ gboolean g_dbus_client_set_signal_watch(GDBusClient *client,
 	return TRUE;
 }
 
+gboolean g_dbus_client_set_ready_watch(GDBusClient *client,
+				GDBusClientFunction ready, void *user_data)
+{
+	if (client == NULL)
+		return FALSE;
+
+	client->ready = ready;
+	client->ready_data = user_data;
+
+	return TRUE;
+}
+
 gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
 					GDBusProxyFunction proxy_added,
 					GDBusProxyFunction proxy_removed,
diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index 9542109..8ada200 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -337,6 +337,7 @@ gboolean g_dbus_proxy_method_call(GDBusProxy *proxy, const char *method,
 				GDBusReturnFunction function, void *user_data,
 				GDBusDestroyFunction destroy);
 
+typedef void (* GDBusClientFunction) (GDBusClient *client, void *user_data);
 typedef void (* GDBusProxyFunction) (GDBusProxy *proxy, void *user_data);
 typedef void (* GDBusPropertyFunction) (GDBusProxy *proxy, const char *name,
 					DBusMessageIter *iter, void *user_data);
@@ -359,7 +360,8 @@ gboolean g_dbus_client_set_disconnect_watch(GDBusClient *client,
 				GDBusWatchFunction function, void *user_data);
 gboolean g_dbus_client_set_signal_watch(GDBusClient *client,
 				GDBusMessageFunction function, void *user_data);
-
+gboolean g_dbus_client_set_ready_watch(GDBusClient *client,
+				GDBusClientFunction ready, void *user_data);
 gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
 					GDBusProxyFunction proxy_added,
 					GDBusProxyFunction proxy_removed,
-- 
1.8.3.1


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

* [PATCH BlueZ v1 2/9] gatt: Add proxy added handler
  2014-03-06 13:44       ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Claudio Takahasi
  2014-03-06 13:44         ` [PATCH BlueZ v1 1/9] gdbus: Add g_dbus_client_set_ready_watch() Claudio Takahasi
@ 2014-03-06 13:44         ` Claudio Takahasi
  2014-03-06 13:44         ` [PATCH BlueZ v1 3/9] gatt: Add proxy removed handler Claudio Takahasi
                           ` (7 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-03-06 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch creates a list of GATT objects sorting the entries based on
the object path to allow inserting the attributes following hierarchical
association.
---
 src/gatt-dbus.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
index fd614f9..f8486f3 100644
--- a/src/gatt-dbus.c
+++ b/src/gatt-dbus.c
@@ -42,11 +42,15 @@
 #include "gatt-dbus.h"
 
 #define GATT_MGR_IFACE			"org.bluez.GattManager1"
+#define GATT_SERVICE_IFACE		"org.bluez.GattService1"
+#define GATT_CHR_IFACE			"org.bluez.GattCharacteristic1"
+#define GATT_DESCRIPTOR_IFACE		"org.bluez.GattDescriptor1"
 
 struct external_app {
 	char *owner;
 	char *path;
 	GDBusClient *client;
+	GSList *proxies;
 	unsigned int watch;
 };
 
@@ -75,6 +79,43 @@ static void external_app_watch_destroy(gpointer user_data)
 	g_free(eapp);
 }
 
+static int proxy_path_cmp(gconstpointer a, gconstpointer b)
+{
+	GDBusProxy *proxy1 = (GDBusProxy *) a;
+	GDBusProxy *proxy2 = (GDBusProxy *) b;
+	const char *path1 = g_dbus_proxy_get_path(proxy1);
+	const char *path2 = g_dbus_proxy_get_path(proxy2);
+
+	return g_strcmp0(path1, path2);
+}
+
+static void proxy_added(GDBusProxy *proxy, void *user_data)
+{
+	struct external_app *eapp = user_data;
+	const char *interface, *path;
+
+	interface = g_dbus_proxy_get_interface(proxy);
+	path = g_dbus_proxy_get_path(proxy);
+
+	if (!g_str_has_prefix(path, eapp->path))
+		return;
+
+	if (g_strcmp0(interface, GATT_CHR_IFACE) != 0 &&
+			g_strcmp0(interface, GATT_SERVICE_IFACE) != 0 &&
+			g_strcmp0(interface, GATT_DESCRIPTOR_IFACE) != 0)
+		return;
+
+	DBG("path %s iface %s", path, interface);
+
+	/*
+	 * Object path follows a hierarchical organization. Add the
+	 * proxies sorted by path helps the logic to register the
+	 * object path later.
+	 */
+	eapp->proxies = g_slist_insert_sorted(eapp->proxies, proxy,
+							proxy_path_cmp);
+}
+
 static struct external_app *new_external_app(DBusConnection *conn,
 					const char *sender, const char *path)
 {
@@ -99,6 +140,9 @@ static struct external_app *new_external_app(DBusConnection *conn,
 	eapp->client = client;
 	eapp->path = g_strdup(path);
 
+	g_dbus_client_set_proxy_handlers(client, proxy_added, NULL, NULL,
+								eapp);
+
 	return eapp;
 }
 
-- 
1.8.3.1


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

* [PATCH BlueZ v1 3/9] gatt: Add proxy removed handler
  2014-03-06 13:44       ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Claudio Takahasi
  2014-03-06 13:44         ` [PATCH BlueZ v1 1/9] gdbus: Add g_dbus_client_set_ready_watch() Claudio Takahasi
  2014-03-06 13:44         ` [PATCH BlueZ v1 2/9] gatt: Add proxy added handler Claudio Takahasi
@ 2014-03-06 13:44         ` Claudio Takahasi
  2014-03-06 13:44         ` [PATCH BlueZ v1 4/9] gatt: Add GATT service to the local database Claudio Takahasi
                           ` (6 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-03-06 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 src/gatt-dbus.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
index f8486f3..28d7f78 100644
--- a/src/gatt-dbus.c
+++ b/src/gatt-dbus.c
@@ -116,6 +116,19 @@ static void proxy_added(GDBusProxy *proxy, void *user_data)
 							proxy_path_cmp);
 }
 
+static void proxy_removed(GDBusProxy *proxy, void *user_data)
+{
+	struct external_app *eapp = user_data;
+	const char *interface, *path;
+
+	interface = g_dbus_proxy_get_interface(proxy);
+	path = g_dbus_proxy_get_path(proxy);
+
+	DBG("path %s iface %s", path, interface);
+
+	eapp->proxies = g_slist_remove(eapp->proxies, proxy);
+}
+
 static struct external_app *new_external_app(DBusConnection *conn,
 					const char *sender, const char *path)
 {
@@ -140,8 +153,8 @@ static struct external_app *new_external_app(DBusConnection *conn,
 	eapp->client = client;
 	eapp->path = g_strdup(path);
 
-	g_dbus_client_set_proxy_handlers(client, proxy_added, NULL, NULL,
-								eapp);
+	g_dbus_client_set_proxy_handlers(client, proxy_added, proxy_removed,
+								NULL, eapp);
 
 	return eapp;
 }
-- 
1.8.3.1


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

* [PATCH BlueZ v1 4/9] gatt: Add GATT service to the local database
  2014-03-06 13:44       ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Claudio Takahasi
                           ` (2 preceding siblings ...)
  2014-03-06 13:44         ` [PATCH BlueZ v1 3/9] gatt: Add proxy removed handler Claudio Takahasi
@ 2014-03-06 13:44         ` Claudio Takahasi
  2014-03-06 13:44         ` [PATCH BlueZ v1 5/9] gatt: Make RegisterService() async Claudio Takahasi
                           ` (5 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-03-06 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch creates GATT service attribute based on its GDBusProxy
object, and inserts the declaration to the local database.
---
 src/gatt-dbus.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
index 28d7f78..d62e2cf 100644
--- a/src/gatt-dbus.c
+++ b/src/gatt-dbus.c
@@ -39,6 +39,7 @@
 #include "log.h"
 
 #include "error.h"
+#include "gatt.h"
 #include "gatt-dbus.h"
 
 #define GATT_MGR_IFACE			"org.bluez.GattManager1"
@@ -129,6 +130,56 @@ static void proxy_removed(GDBusProxy *proxy, void *user_data)
 	eapp->proxies = g_slist_remove(eapp->proxies, proxy);
 }
 
+static int register_external_service(const struct external_app *eapp,
+							GDBusProxy *proxy)
+{
+	DBusMessageIter iter;
+	const char *str, *path, *iface;
+	bt_uuid_t uuid;
+
+	path = g_dbus_proxy_get_path(proxy);
+	iface = g_dbus_proxy_get_interface(proxy);
+	if (g_strcmp0(eapp->path, path) != 0 ||
+			g_strcmp0(iface, GATT_SERVICE_IFACE) != 0)
+		return -EINVAL;
+
+	if (!g_dbus_proxy_get_property(proxy, "UUID", &iter))
+		return -EINVAL;
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+		return -EINVAL;
+
+	dbus_message_iter_get_basic(&iter, &str);
+
+	if (bt_string_to_uuid(&uuid, str) < 0)
+		return -EINVAL;
+
+	if (btd_gatt_add_service(&uuid) == NULL)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void client_ready(GDBusClient *client, void *user_data)
+{
+	struct external_app *eapp = user_data;
+	GDBusProxy *proxy;
+
+	if (eapp->proxies == NULL)
+		goto fail;
+
+	proxy = eapp->proxies->data;
+	if (register_external_service(eapp, proxy) < 0)
+		goto fail;
+
+	DBG("Added GATT service %s", eapp->path);
+
+	return;
+
+fail:
+	error("Could not register external service: %s", eapp->path);
+}
+
 static struct external_app *new_external_app(DBusConnection *conn,
 					const char *sender, const char *path)
 {
@@ -156,6 +207,8 @@ static struct external_app *new_external_app(DBusConnection *conn,
 	g_dbus_client_set_proxy_handlers(client, proxy_added, proxy_removed,
 								NULL, eapp);
 
+	g_dbus_client_set_ready_watch(client, client_ready, eapp);
+
 	return eapp;
 }
 
-- 
1.8.3.1


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

* [PATCH BlueZ v1 5/9] gatt: Make RegisterService() async
  2014-03-06 13:44       ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Claudio Takahasi
                           ` (3 preceding siblings ...)
  2014-03-06 13:44         ` [PATCH BlueZ v1 4/9] gatt: Add GATT service to the local database Claudio Takahasi
@ 2014-03-06 13:44         ` Claudio Takahasi
  2014-03-06 13:44         ` [PATCH BlueZ v1 6/9] test: Add external service GATT skeleton Claudio Takahasi
                           ` (4 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-03-06 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

GDBusProxy objects consistency should be checked, and attributes
declaration inserted in the local GATT database before replying
the caller.
---
 src/gatt-dbus.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
index d62e2cf..3fbff87 100644
--- a/src/gatt-dbus.c
+++ b/src/gatt-dbus.c
@@ -50,6 +50,7 @@
 struct external_app {
 	char *owner;
 	char *path;
+	DBusMessage *reg;
 	GDBusClient *client;
 	GSList *proxies;
 	unsigned int watch;
@@ -74,6 +75,8 @@ static void external_app_watch_destroy(gpointer user_data)
 	external_apps = g_slist_remove(external_apps, eapp);
 
 	g_dbus_client_unref(eapp->client);
+	if (eapp->reg)
+		dbus_message_unref(eapp->reg);
 
 	g_free(eapp->owner);
 	g_free(eapp->path);
@@ -164,6 +167,8 @@ static void client_ready(GDBusClient *client, void *user_data)
 {
 	struct external_app *eapp = user_data;
 	GDBusProxy *proxy;
+	DBusConnection *conn = btd_get_dbus_connection();
+	DBusMessage *reply;
 
 	if (eapp->proxies == NULL)
 		goto fail;
@@ -174,17 +179,28 @@ static void client_ready(GDBusClient *client, void *user_data)
 
 	DBG("Added GATT service %s", eapp->path);
 
-	return;
+	reply = dbus_message_new_method_return(eapp->reg);
+	goto reply;
 
 fail:
 	error("Could not register external service: %s", eapp->path);
+
+	reply = btd_error_invalid_args(eapp->reg);
+	/* TODO: missing eapp cleanup */
+
+reply:
+	dbus_message_unref(eapp->reg);
+	eapp->reg = NULL;
+
+	g_dbus_send_message(conn, reply);
 }
 
 static struct external_app *new_external_app(DBusConnection *conn,
-					const char *sender, const char *path)
+					DBusMessage *msg, const char *path)
 {
 	struct external_app *eapp;
 	GDBusClient *client;
+	const char *sender = dbus_message_get_sender(msg);
 
 	client = g_dbus_client_new(conn, sender, "/");
 	if (client == NULL)
@@ -201,6 +217,7 @@ static struct external_app *new_external_app(DBusConnection *conn,
 	}
 
 	eapp->owner = g_strdup(sender);
+	eapp->reg = dbus_message_ref(msg);
 	eapp->client = client;
 	eapp->path = g_strdup(path);
 
@@ -230,7 +247,7 @@ static DBusMessage *register_service(DBusConnection *conn,
 	if (g_slist_find_custom(external_apps, path, external_app_path_cmp))
 		return btd_error_already_exists(msg);
 
-	eapp = new_external_app(conn, dbus_message_get_sender(msg), path);
+	eapp = new_external_app(conn, msg, path);
 	if (eapp == NULL)
 		return btd_error_failed(msg, "Not enough resources");
 
@@ -238,7 +255,7 @@ static DBusMessage *register_service(DBusConnection *conn,
 
 	DBG("New app %p: %s", eapp, path);
 
-	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+	return NULL;
 }
 
 static DBusMessage *unregister_service(DBusConnection *conn,
@@ -248,7 +265,7 @@ static DBusMessage *unregister_service(DBusConnection *conn,
 }
 
 static const GDBusMethodTable methods[] = {
-	{ GDBUS_EXPERIMENTAL_METHOD("RegisterService",
+	{ GDBUS_EXPERIMENTAL_ASYNC_METHOD("RegisterService",
 				GDBUS_ARGS({ "service", "o"},
 						{ "options", "a{sv}"}),
 				NULL, register_service) },
-- 
1.8.3.1


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

* [PATCH BlueZ v1 6/9] test: Add external service GATT skeleton
  2014-03-06 13:44       ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Claudio Takahasi
                           ` (4 preceding siblings ...)
  2014-03-06 13:44         ` [PATCH BlueZ v1 5/9] gatt: Make RegisterService() async Claudio Takahasi
@ 2014-03-06 13:44         ` Claudio Takahasi
  2014-03-06 13:44         ` [PATCH BlueZ v1 7/9] test: Add signal handling for gatt-service Claudio Takahasi
                           ` (3 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-03-06 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch adds the initial code for an external GATT service example.
It implements the API defined at doc/gatt-api.txt
---
 .gitignore          |   1 +
 Makefile.tools      |   5 +++
 test/gatt-service.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 127 insertions(+)
 create mode 100644 test/gatt-service.c

diff --git a/.gitignore b/.gitignore
index 47ba9b8..f323080 100644
--- a/.gitignore
+++ b/.gitignore
@@ -76,6 +76,7 @@ test/sap_client.pyc
 test/bluezutils.pyc
 unit/test-ringbuf
 unit/test-queue
+test/gatt-service
 unit/test-eir
 unit/test-uuid
 unit/test-crc
diff --git a/Makefile.tools b/Makefile.tools
index 31e1093..c589199 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -393,3 +393,8 @@ test_scripts += test/sap_client.py test/bluezutils.py \
 		test/test-heartrate test/test-alert test/test-hfp \
 		test/test-cyclingspeed test/opp-client test/ftp-client \
 		test/pbap-client test/map-client
+
+noinst_PROGRAMS += test/gatt-service
+
+test_gatt_service_SOURCES = test/gatt-service.c
+test_gatt_service_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ gdbus/libgdbus-internal.la
diff --git a/test/gatt-service.c b/test/gatt-service.c
new file mode 100644
index 0000000..18ab7da
--- /dev/null
+++ b/test/gatt-service.c
@@ -0,0 +1,121 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2014  Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ *  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 <errno.h>
+#include <stdio.h>
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <gdbus/gdbus.h>
+
+#define GATT_SERVICE_IFACE		"org.bluez.GattService1"
+
+/* Immediate Alert Service UUID */
+#define IAS_UUID			"00001802-0000-1000-8000-00805f9b34fb"
+
+static GMainLoop *main_loop;
+static GSList *services;
+
+static gboolean service_get_uuid(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *user_data)
+{
+	const char *uuid = user_data;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &uuid);
+
+	return TRUE;
+}
+
+static gboolean service_get_includes(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *user_data)
+{
+	return TRUE;
+}
+
+static gboolean service_exist_includes(const GDBusPropertyTable *property,
+							void *user_data)
+{
+	return FALSE;
+}
+
+static const GDBusPropertyTable service_properties[] = {
+	{ "UUID", "s", service_get_uuid },
+	{ "Includes", "ao", service_get_includes, NULL,
+					service_exist_includes },
+	{ }
+};
+
+static char *register_service(DBusConnection *conn, const char *uuid)
+{
+	static int id = 1;
+	char *path;
+
+	path = g_strdup_printf("/service%d", id++);
+	if (g_dbus_register_interface(conn, path, GATT_SERVICE_IFACE,
+				NULL, NULL, service_properties,
+				g_strdup(uuid), g_free) == FALSE) {
+		printf("Couldn't register service interface\n");
+		g_free(path);
+		return NULL;
+	}
+
+	return path;
+}
+
+static void create_services(DBusConnection *conn)
+{
+	char *service_path;
+
+	service_path = register_service(conn, IAS_UUID);
+
+	services = g_slist_prepend(services, service_path);
+
+	printf("Registered service: %s\n", service_path);
+}
+
+int main(int argc, char *argv[])
+{
+	DBusConnection *dbus_conn;
+
+	dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
+
+	main_loop = g_main_loop_new(NULL, FALSE);
+
+	g_dbus_attach_object_manager(dbus_conn);
+
+	printf("gatt-service unique name: %s\n",
+				dbus_bus_get_unique_name(dbus_conn));
+
+	create_services(dbus_conn);
+
+	g_main_loop_run(main_loop);
+
+	g_slist_free_full(services, g_free);
+	dbus_connection_unref(dbus_conn);
+
+	return 0;
+}
-- 
1.8.3.1


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

* [PATCH BlueZ v1 7/9] test: Add signal handling for gatt-service
  2014-03-06 13:44       ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Claudio Takahasi
                           ` (5 preceding siblings ...)
  2014-03-06 13:44         ` [PATCH BlueZ v1 6/9] test: Add external service GATT skeleton Claudio Takahasi
@ 2014-03-06 13:44         ` Claudio Takahasi
  2014-03-06 13:44         ` [PATCH BlueZ v1 8/9] test: Add registering external service Claudio Takahasi
                           ` (2 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-03-06 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch implements signal handling to run cleanup tasks before
exiting.
---
 test/gatt-service.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/test/gatt-service.c b/test/gatt-service.c
index 18ab7da..ecb5cc3 100644
--- a/test/gatt-service.c
+++ b/test/gatt-service.c
@@ -27,6 +27,9 @@
 
 #include <errno.h>
 #include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/signalfd.h>
 
 #include <glib.h>
 #include <dbus/dbus.h>
@@ -97,9 +100,83 @@ static void create_services(DBusConnection *conn)
 	printf("Registered service: %s\n", service_path);
 }
 
+static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
+							gpointer user_data)
+{
+	static bool __terminated = false;
+	struct signalfd_siginfo si;
+	ssize_t result;
+	int fd;
+
+	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP))
+		return FALSE;
+
+	fd = g_io_channel_unix_get_fd(channel);
+
+	result = read(fd, &si, sizeof(si));
+	if (result != sizeof(si))
+		return FALSE;
+
+	switch (si.ssi_signo) {
+	case SIGINT:
+	case SIGTERM:
+		if (!__terminated) {
+			printf("Terminating\n");
+			g_main_loop_quit(main_loop);
+		}
+
+		__terminated = true;
+		break;
+	}
+
+	return TRUE;
+}
+
+static guint setup_signalfd(void)
+{
+	GIOChannel *channel;
+	guint source;
+	sigset_t mask;
+	int fd;
+
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGINT);
+	sigaddset(&mask, SIGTERM);
+
+	if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) {
+		perror("Failed to set signal mask");
+		return 0;
+	}
+
+	fd = signalfd(-1, &mask, 0);
+	if (fd < 0) {
+		perror("Failed to create signal descriptor");
+		return 0;
+	}
+
+	channel = g_io_channel_unix_new(fd);
+
+	g_io_channel_set_close_on_unref(channel, TRUE);
+	g_io_channel_set_encoding(channel, NULL, NULL);
+	g_io_channel_set_buffered(channel, FALSE);
+
+	source = g_io_add_watch(channel,
+				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				signal_handler, NULL);
+
+	g_io_channel_unref(channel);
+
+	return source;
+}
+
 int main(int argc, char *argv[])
 {
 	DBusConnection *dbus_conn;
+	guint signal;
+
+	signal = setup_signalfd();
+	if (signal == 0)
+		return -errno;
 
 	dbus_conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
 
@@ -114,6 +191,8 @@ int main(int argc, char *argv[])
 
 	g_main_loop_run(main_loop);
 
+	g_source_remove(signal);
+
 	g_slist_free_full(services, g_free);
 	dbus_connection_unref(dbus_conn);
 
-- 
1.8.3.1


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

* [PATCH BlueZ v1 8/9] test: Add registering external service
  2014-03-06 13:44       ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Claudio Takahasi
                           ` (6 preceding siblings ...)
  2014-03-06 13:44         ` [PATCH BlueZ v1 7/9] test: Add signal handling for gatt-service Claudio Takahasi
@ 2014-03-06 13:44         ` Claudio Takahasi
  2014-03-06 13:44         ` [PATCH BlueZ v1 9/9] bluetooth.conf: Add ObjectManager interface Claudio Takahasi
  2014-03-06 14:54         ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Johan Hedberg
  9 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-03-06 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch extends gatt-service to call RegisterService() when org.bluez
service gets connected to the system bus.
---
 test/gatt-service.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/test/gatt-service.c b/test/gatt-service.c
index ecb5cc3..f8ae7cc 100644
--- a/test/gatt-service.c
+++ b/test/gatt-service.c
@@ -35,6 +35,7 @@
 #include <dbus/dbus.h>
 #include <gdbus/gdbus.h>
 
+#define GATT_MGR_IFACE			"org.bluez.GattManager1"
 #define GATT_SERVICE_IFACE		"org.bluez.GattService1"
 
 /* Immediate Alert Service UUID */
@@ -100,6 +101,65 @@ static void create_services(DBusConnection *conn)
 	printf("Registered service: %s\n", service_path);
 }
 
+static void register_external_service_reply(DBusPendingCall *call,
+							void *user_data)
+{
+	DBusMessage *reply = dbus_pending_call_steal_reply(call);
+	DBusError derr;
+
+	dbus_error_init(&derr);
+	dbus_set_error_from_message(&derr, reply);
+
+	if (dbus_error_is_set(&derr))
+		printf("RegisterService: %s\n", derr.message);
+	else
+		printf("RegisterService: OK\n");
+
+	dbus_message_unref(reply);
+	dbus_error_free(&derr);
+}
+
+static void register_external_service(gpointer a, gpointer b)
+{
+	DBusConnection *conn = b;
+	const char *path = a;
+	DBusMessage *msg;
+	DBusPendingCall *call;
+	DBusMessageIter iter, dict;
+
+	msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
+					GATT_MGR_IFACE, "RegisterService");
+	if (msg == NULL) {
+		printf("Couldn't allocate D-Bus message\n");
+		return;
+	}
+
+	dbus_message_iter_init_append(msg, &iter);
+
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &dict);
+
+	/* TODO: Add options dictionary */
+
+	dbus_message_iter_close_container(&iter, &dict);
+
+	if (g_dbus_send_message_with_reply(conn, msg, &call, -1) == FALSE) {
+		dbus_message_unref(msg);
+		return;
+	}
+
+	dbus_pending_call_set_notify(call, register_external_service_reply,
+								NULL, NULL);
+
+	dbus_pending_call_unref(call);
+}
+
+static void connect_handler(DBusConnection *conn, void *user_data)
+{
+	g_slist_foreach(services, register_external_service, conn);
+}
+
 static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
 							gpointer user_data)
 {
@@ -171,6 +231,7 @@ static guint setup_signalfd(void)
 
 int main(int argc, char *argv[])
 {
+	GDBusClient *client;
 	DBusConnection *dbus_conn;
 	guint signal;
 
@@ -189,8 +250,14 @@ int main(int argc, char *argv[])
 
 	create_services(dbus_conn);
 
+	client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");
+
+	g_dbus_client_set_connect_watch(client, connect_handler, NULL);
+
 	g_main_loop_run(main_loop);
 
+	g_dbus_client_unref(client);
+
 	g_source_remove(signal);
 
 	g_slist_free_full(services, g_free);
-- 
1.8.3.1


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

* [PATCH BlueZ v1 9/9] bluetooth.conf: Add ObjectManager interface
  2014-03-06 13:44       ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Claudio Takahasi
                           ` (7 preceding siblings ...)
  2014-03-06 13:44         ` [PATCH BlueZ v1 8/9] test: Add registering external service Claudio Takahasi
@ 2014-03-06 13:44         ` Claudio Takahasi
  2014-03-06 14:54         ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Johan Hedberg
  9 siblings, 0 replies; 24+ messages in thread
From: Claudio Takahasi @ 2014-03-06 13:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 src/bluetooth.conf | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/bluetooth.conf b/src/bluetooth.conf
index 0495200..ad8891a 100644
--- a/src/bluetooth.conf
+++ b/src/bluetooth.conf
@@ -18,6 +18,7 @@
     <allow send_interface="org.bluez.Profile1"/>
     <allow send_interface="org.bluez.HeartRateWatcher1"/>
     <allow send_interface="org.bluez.CyclingSpeedWatcher1"/>
+    <allow send_interface="org.freedesktop.DBus.ObjectManager"/>
   </policy>
 
   <policy at_console="true">
-- 
1.8.3.1


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

* Re: [PATCH BlueZ v1 1/9] gdbus: Add g_dbus_client_set_ready_watch()
  2014-03-06 13:44         ` [PATCH BlueZ v1 1/9] gdbus: Add g_dbus_client_set_ready_watch() Claudio Takahasi
@ 2014-03-06 13:56           ` Luiz Augusto von Dentz
  0 siblings, 0 replies; 24+ messages in thread
From: Luiz Augusto von Dentz @ 2014-03-06 13:56 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth

Hi Claudio,

On Thu, Mar 6, 2014 at 3:44 PM, Claudio Takahasi
<claudio.takahasi@openbossa.org> wrote:
> This patch adds a new gdbus helper to notify the clients that
> GetManagedObjects reply was received and the last proxy has been
> informed previously by the proxy_added callback.
> ---
>  gdbus/client.c | 17 +++++++++++++++++
>  gdbus/gdbus.h  |  4 +++-
>  2 files changed, 20 insertions(+), 1 deletion(-)
>
> diff --git a/gdbus/client.c b/gdbus/client.c
> index be8cc29..5193b6c 100644
> --- a/gdbus/client.c
> +++ b/gdbus/client.c
> @@ -56,6 +56,8 @@ struct GDBusClient {
>         void *signal_data;
>         GDBusProxyFunction proxy_added;
>         GDBusProxyFunction proxy_removed;
> +       GDBusClientFunction ready;
> +       void *ready_data;
>         GDBusPropertyFunction property_changed;
>         void *user_data;
>         GList *proxy_list;
> @@ -982,6 +984,9 @@ static void parse_managed_objects(GDBusClient *client, DBusMessage *msg)
>
>                 dbus_message_iter_next(&dict);
>         }
> +
> +       if (client->ready)
> +               client->ready(client, client->ready_data);
>  }
>
>  static void get_managed_objects_reply(DBusPendingCall *call, void *user_data)
> @@ -1243,6 +1248,18 @@ gboolean g_dbus_client_set_signal_watch(GDBusClient *client,
>         return TRUE;
>  }
>
> +gboolean g_dbus_client_set_ready_watch(GDBusClient *client,
> +                               GDBusClientFunction ready, void *user_data)
> +{
> +       if (client == NULL)
> +               return FALSE;
> +
> +       client->ready = ready;
> +       client->ready_data = user_data;
> +
> +       return TRUE;
> +}
> +
>  gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
>                                         GDBusProxyFunction proxy_added,
>                                         GDBusProxyFunction proxy_removed,
> diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
> index 9542109..8ada200 100644
> --- a/gdbus/gdbus.h
> +++ b/gdbus/gdbus.h
> @@ -337,6 +337,7 @@ gboolean g_dbus_proxy_method_call(GDBusProxy *proxy, const char *method,
>                                 GDBusReturnFunction function, void *user_data,
>                                 GDBusDestroyFunction destroy);
>
> +typedef void (* GDBusClientFunction) (GDBusClient *client, void *user_data);
>  typedef void (* GDBusProxyFunction) (GDBusProxy *proxy, void *user_data);
>  typedef void (* GDBusPropertyFunction) (GDBusProxy *proxy, const char *name,
>                                         DBusMessageIter *iter, void *user_data);
> @@ -359,7 +360,8 @@ gboolean g_dbus_client_set_disconnect_watch(GDBusClient *client,
>                                 GDBusWatchFunction function, void *user_data);
>  gboolean g_dbus_client_set_signal_watch(GDBusClient *client,
>                                 GDBusMessageFunction function, void *user_data);
> -
> +gboolean g_dbus_client_set_ready_watch(GDBusClient *client,
> +                               GDBusClientFunction ready, void *user_data);
>  gboolean g_dbus_client_set_proxy_handlers(GDBusClient *client,
>                                         GDBusProxyFunction proxy_added,
>                                         GDBusProxyFunction proxy_removed,
> --
> 1.8.3.1

It should be relatively simple to add a unit for it, doesn't need to
be in the same patch-set since I don't want to slow down the set just
because of the lack of it.


-- 
Luiz Augusto von Dentz

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

* Re: [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async
  2014-03-06 13:44       ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Claudio Takahasi
                           ` (8 preceding siblings ...)
  2014-03-06 13:44         ` [PATCH BlueZ v1 9/9] bluetooth.conf: Add ObjectManager interface Claudio Takahasi
@ 2014-03-06 14:54         ` Johan Hedberg
  9 siblings, 0 replies; 24+ messages in thread
From: Johan Hedberg @ 2014-03-06 14:54 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth

Hi Claudio,

On Thu, Mar 06, 2014, Claudio Takahasi wrote:
> This patchset is an extension of "[PATCH BlueZ v7 00/11] GATT API:
> External Services". It adds the following features:
>   * new gdbus helper to allow notifying the clients when
>     GetManagedObjects() reply is received and all proxies reported to
>     upper-layer.
>   * reply for RegisterService() after validating fetched objects
>   * adds the service declaration to the local GATT database
> 
> * Changes from v0 to v1:
>   - renames g_dbus_client_set_proxies_ready_watch() to
>     g_dbus_client_set_ready_watch()
> 
> Claudio Takahasi (9):
>   gdbus: Add g_dbus_client_set_ready_watch()
>   gatt: Add proxy added handler
>   gatt: Add proxy removed handler
>   gatt: Add GATT service to the local database
>   gatt: Make RegisterService() async
>   test: Add external service GATT skeleton
>   test: Add signal handling for gatt-service
>   test: Add registering external service
>   bluetooth.conf: Add ObjectManager interface
> 
>  .gitignore          |   1 +
>  Makefile.tools      |   5 +
>  gdbus/client.c      |  17 ++++
>  gdbus/gdbus.h       |   4 +-
>  src/bluetooth.conf  |   1 +
>  src/gatt-dbus.c     | 135 +++++++++++++++++++++++++-
>  test/gatt-service.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  7 files changed, 425 insertions(+), 5 deletions(-)
>  create mode 100644 test/gatt-service.c

All patches in the set have been applied. Thanks.

Johan

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

end of thread, other threads:[~2014-03-06 14:54 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-28 17:05 [PATCH BlueZ v0 0/9] GATT API: Add Register Services Async Claudio Takahasi
2014-02-28 17:05 ` [PATCH BlueZ v0 1/9] gdbus: Add g_dbus_client_set_proxies_ready_watch() Claudio Takahasi
2014-03-05  6:37   ` Marcel Holtmann
2014-03-06 12:24     ` Claudio Takahasi
2014-03-06 13:44       ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Claudio Takahasi
2014-03-06 13:44         ` [PATCH BlueZ v1 1/9] gdbus: Add g_dbus_client_set_ready_watch() Claudio Takahasi
2014-03-06 13:56           ` Luiz Augusto von Dentz
2014-03-06 13:44         ` [PATCH BlueZ v1 2/9] gatt: Add proxy added handler Claudio Takahasi
2014-03-06 13:44         ` [PATCH BlueZ v1 3/9] gatt: Add proxy removed handler Claudio Takahasi
2014-03-06 13:44         ` [PATCH BlueZ v1 4/9] gatt: Add GATT service to the local database Claudio Takahasi
2014-03-06 13:44         ` [PATCH BlueZ v1 5/9] gatt: Make RegisterService() async Claudio Takahasi
2014-03-06 13:44         ` [PATCH BlueZ v1 6/9] test: Add external service GATT skeleton Claudio Takahasi
2014-03-06 13:44         ` [PATCH BlueZ v1 7/9] test: Add signal handling for gatt-service Claudio Takahasi
2014-03-06 13:44         ` [PATCH BlueZ v1 8/9] test: Add registering external service Claudio Takahasi
2014-03-06 13:44         ` [PATCH BlueZ v1 9/9] bluetooth.conf: Add ObjectManager interface Claudio Takahasi
2014-03-06 14:54         ` [PATCH BlueZ v1 0/9] GATT API: Add Register Services Async Johan Hedberg
2014-02-28 17:05 ` [PATCH BlueZ v0 2/9] gatt: Add proxy added handler Claudio Takahasi
2014-02-28 17:05 ` [PATCH BlueZ v0 3/9] gatt: Add proxy removed handler Claudio Takahasi
2014-02-28 17:05 ` [PATCH BlueZ v0 4/9] gatt: Add GATT service to the local database Claudio Takahasi
2014-02-28 17:05 ` [PATCH BlueZ v0 5/9] gatt: Make RegisterService() async Claudio Takahasi
2014-02-28 17:05 ` [PATCH BlueZ v0 6/9] test: Add external service GATT skeleton Claudio Takahasi
2014-02-28 17:05 ` [PATCH BlueZ v0 7/9] test: Add signal handling for gatt-service Claudio Takahasi
2014-02-28 17:05 ` [PATCH BlueZ v0 8/9] test: Add registering external service Claudio Takahasi
2014-02-28 17:05 ` [PATCH BlueZ v0 9/9] bluetooth.conf: Add ObjectManager interface Claudio Takahasi

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.