All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ v2] core/gatt-client: Add support for Includes property
@ 2017-04-26  9:51 Marcin Kraglak
  0 siblings, 0 replies; 3+ messages in thread
From: Marcin Kraglak @ 2017-04-26  9:51 UTC (permalink / raw)
  To: linux-bluetooth

Add implementation of Includes property in GATT service interface.
Include services are updated after exporting all services, when new service
has been added or service was removed.
---
 src/gatt-client.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 105 insertions(+), 7 deletions(-)

diff --git a/src/gatt-client.c b/src/gatt-client.c
index 114981c..00f9d6a 100644
--- a/src/gatt-client.c
+++ b/src/gatt-client.c
@@ -72,6 +72,7 @@ struct service {
 	bt_uuid_t uuid;
 	char *path;
 	struct queue *chrcs;
+	struct queue *incl_services;
 };
 
 typedef bool (*async_dbus_op_complete_t)(void *data);
@@ -1398,10 +1399,36 @@ static gboolean service_get_primary(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
+static void append_incl_service_path(void *data, void *user_data)
+{
+	struct service *incl_service = data;
+	DBusMessageIter *array = user_data;
+
+	dbus_message_iter_append_basic(array, DBUS_TYPE_OBJECT_PATH,
+					&incl_service->path);
+}
+
+static gboolean service_get_includes(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct service *service = data;
+	DBusMessageIter array;
+
+	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{o}", &array);
+
+	queue_foreach(service->incl_services, append_incl_service_path, &array);
+
+	dbus_message_iter_close_container(iter, &array);
+
+	return TRUE;
+
+}
+
 static const GDBusPropertyTable service_properties[] = {
 	{ "UUID", "s", service_get_uuid },
 	{ "Device", "o", service_get_device },
 	{ "Primary", "b", service_get_primary },
+	{ "Includes", "ao", service_get_includes },
 	{ }
 };
 
@@ -1410,6 +1437,7 @@ static void service_free(void *data)
 	struct service *service = data;
 
 	queue_destroy(service->chrcs, NULL);  /* List should be empty here */
+	queue_destroy(service->incl_services, NULL);
 	g_free(service->path);
 	free(service);
 }
@@ -1423,6 +1451,7 @@ static struct service *service_create(struct gatt_db_attribute *attr,
 
 	service = new0(struct service, 1);
 	service->chrcs = queue_new();
+	service->incl_services = queue_new();
 	service->client = client;
 
 	gatt_db_attribute_get_service_data(attr, &service->start_handle,
@@ -1459,13 +1488,29 @@ static struct service *service_create(struct gatt_db_attribute *attr,
 	return service;
 }
 
+static void on_service_removed(void *data, void *user_data)
+{
+	struct service *service = data;
+	struct service *removed_service = user_data;
+
+	if (queue_remove(service->incl_services, removed_service))
+		g_dbus_emit_property_changed(btd_get_dbus_connection(),
+							service->path,
+							GATT_SERVICE_IFACE,
+							"Includes");
+}
+
 static void unregister_service(void *data)
 {
 	struct service *service = data;
+	struct btd_gatt_client *client = service->client;
 
 	DBG("Removing GATT service: %s", service->path);
 
 	queue_remove_all(service->chrcs, NULL, NULL, unregister_characteristic);
+	queue_remove_all(service->incl_services, NULL, NULL, NULL);
+
+	queue_foreach(client->services, on_service_removed, service);
 
 	g_dbus_unregister_interface(btd_get_dbus_connection(), service->path,
 							GATT_SERVICE_IFACE);
@@ -1567,11 +1612,70 @@ static void export_service(struct gatt_db_attribute *attr, void *user_data)
 	queue_push_tail(client->services, service);
 }
 
+static bool match_service_handle(const void *a, const void *b)
+{
+	const struct service *service = a;
+	uint16_t start_handle = PTR_TO_UINT(b);
+
+	return service->start_handle == start_handle;
+}
+
+struct update_incl_data {
+	struct service *service;
+	bool changed;
+};
+
+static void update_included_service(struct gatt_db_attribute *attrib,
+							void *user_data)
+{
+	struct update_incl_data *update_data = user_data;
+	struct btd_gatt_client *client = update_data->service->client;
+	struct service *service = update_data->service;
+	struct service *incl_service;
+	uint16_t start_handle;
+
+	gatt_db_attribute_get_incl_data(attrib, NULL, &start_handle, NULL);
+
+	incl_service = queue_find(client->services, match_service_handle,
+						UINT_TO_PTR(start_handle));
+
+	if (!incl_service)
+		return;
+
+	/* Check if service is already on list */
+	if (queue_find(service->incl_services, NULL, incl_service))
+		return;
+
+	queue_push_tail(service->incl_services, incl_service);
+	update_data->changed = true;
+}
+static void update_included_services(void *data, void *user_data)
+{
+	struct btd_gatt_client *client = user_data;
+	struct service *service = data;
+	struct gatt_db_attribute *attr;
+	struct update_incl_data inc_data = {
+		.changed = false,
+		.service = service,
+	};
+
+	attr = gatt_db_get_attribute(client->db, service->start_handle);
+	gatt_db_service_foreach_incl(attr, update_included_service, &inc_data);
+
+	if (inc_data.changed)
+		g_dbus_emit_property_changed(btd_get_dbus_connection(),
+							service->path,
+							GATT_SERVICE_IFACE,
+							"Includes");
+}
+
 static void create_services(struct btd_gatt_client *client)
 {
 	DBG("Exporting objects for GATT services: %s", client->devaddr);
 
 	gatt_db_foreach_service(client->db, NULL, export_service, client);
+
+	queue_foreach(client->services, update_included_services, client);
 }
 
 struct btd_gatt_client *btd_gatt_client_new(struct btd_device *device)
@@ -1689,14 +1793,8 @@ void btd_gatt_client_service_added(struct btd_gatt_client *client,
 		return;
 
 	export_service(attrib, client);
-}
 
-static bool match_service_handle(const void *a, const void *b)
-{
-	const struct service *service = a;
-	uint16_t start_handle = PTR_TO_UINT(b);
-
-	return service->start_handle == start_handle;
+	queue_foreach(client->services, update_included_services, client);
 }
 
 void btd_gatt_client_service_removed(struct btd_gatt_client *client,
-- 
2.4.3


^ permalink raw reply related	[flat|nested] 3+ messages in thread
* [PATCH BlueZ v2] core/gatt-client: Add support for Includes property
@ 2017-04-26 12:32 Marcin Kraglak
  2017-05-02 15:36 ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 3+ messages in thread
From: Marcin Kraglak @ 2017-04-26 12:32 UTC (permalink / raw)
  To: linux-bluetooth

Add implementation of Includes property in GATT service interface.
Include services are updated after exporting all services, when new service
has been added or service was removed.
---
 src/gatt-client.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 106 insertions(+), 7 deletions(-)

diff --git a/src/gatt-client.c b/src/gatt-client.c
index 114981c..b86bfe6 100644
--- a/src/gatt-client.c
+++ b/src/gatt-client.c
@@ -72,6 +72,7 @@ struct service {
 	bt_uuid_t uuid;
 	char *path;
 	struct queue *chrcs;
+	struct queue *incl_services;
 };
 
 typedef bool (*async_dbus_op_complete_t)(void *data);
@@ -1398,10 +1399,36 @@ static gboolean service_get_primary(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
+static void append_incl_service_path(void *data, void *user_data)
+{
+	struct service *incl_service = data;
+	DBusMessageIter *array = user_data;
+
+	dbus_message_iter_append_basic(array, DBUS_TYPE_OBJECT_PATH,
+					&incl_service->path);
+}
+
+static gboolean service_get_includes(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct service *service = data;
+	DBusMessageIter array;
+
+	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{o}", &array);
+
+	queue_foreach(service->incl_services, append_incl_service_path, &array);
+
+	dbus_message_iter_close_container(iter, &array);
+
+	return TRUE;
+
+}
+
 static const GDBusPropertyTable service_properties[] = {
 	{ "UUID", "s", service_get_uuid },
 	{ "Device", "o", service_get_device },
 	{ "Primary", "b", service_get_primary },
+	{ "Includes", "ao", service_get_includes },
 	{ }
 };
 
@@ -1410,6 +1437,7 @@ static void service_free(void *data)
 	struct service *service = data;
 
 	queue_destroy(service->chrcs, NULL);  /* List should be empty here */
+	queue_destroy(service->incl_services, NULL);
 	g_free(service->path);
 	free(service);
 }
@@ -1423,6 +1451,7 @@ static struct service *service_create(struct gatt_db_attribute *attr,
 
 	service = new0(struct service, 1);
 	service->chrcs = queue_new();
+	service->incl_services = queue_new();
 	service->client = client;
 
 	gatt_db_attribute_get_service_data(attr, &service->start_handle,
@@ -1459,13 +1488,29 @@ static struct service *service_create(struct gatt_db_attribute *attr,
 	return service;
 }
 
+static void on_service_removed(void *data, void *user_data)
+{
+	struct service *service = data;
+	struct service *removed_service = user_data;
+
+	if (queue_remove(service->incl_services, removed_service))
+		g_dbus_emit_property_changed(btd_get_dbus_connection(),
+							service->path,
+							GATT_SERVICE_IFACE,
+							"Includes");
+}
+
 static void unregister_service(void *data)
 {
 	struct service *service = data;
+	struct btd_gatt_client *client = service->client;
 
 	DBG("Removing GATT service: %s", service->path);
 
 	queue_remove_all(service->chrcs, NULL, NULL, unregister_characteristic);
+	queue_remove_all(service->incl_services, NULL, NULL, NULL);
+
+	queue_foreach(client->services, on_service_removed, service);
 
 	g_dbus_unregister_interface(btd_get_dbus_connection(), service->path,
 							GATT_SERVICE_IFACE);
@@ -1567,11 +1612,71 @@ static void export_service(struct gatt_db_attribute *attr, void *user_data)
 	queue_push_tail(client->services, service);
 }
 
+static bool match_service_handle(const void *a, const void *b)
+{
+	const struct service *service = a;
+	uint16_t start_handle = PTR_TO_UINT(b);
+
+	return service->start_handle == start_handle;
+}
+
+struct update_incl_data {
+	struct service *service;
+	bool changed;
+};
+
+static void update_included_service(struct gatt_db_attribute *attrib,
+							void *user_data)
+{
+	struct update_incl_data *update_data = user_data;
+	struct btd_gatt_client *client = update_data->service->client;
+	struct service *service = update_data->service;
+	struct service *incl_service;
+	uint16_t start_handle;
+
+	gatt_db_attribute_get_incl_data(attrib, NULL, &start_handle, NULL);
+
+	incl_service = queue_find(client->services, match_service_handle,
+						UINT_TO_PTR(start_handle));
+
+	if (!incl_service)
+		return;
+
+	/* Check if service is already on list */
+	if (queue_find(service->incl_services, NULL, incl_service))
+		return;
+
+	queue_push_tail(service->incl_services, incl_service);
+	update_data->changed = true;
+}
+
+static void update_included_services(void *data, void *user_data)
+{
+	struct btd_gatt_client *client = user_data;
+	struct service *service = data;
+	struct gatt_db_attribute *attr;
+	struct update_incl_data inc_data = {
+		.changed = false,
+		.service = service,
+	};
+
+	attr = gatt_db_get_attribute(client->db, service->start_handle);
+	gatt_db_service_foreach_incl(attr, update_included_service, &inc_data);
+
+	if (inc_data.changed)
+		g_dbus_emit_property_changed(btd_get_dbus_connection(),
+							service->path,
+							GATT_SERVICE_IFACE,
+							"Includes");
+}
+
 static void create_services(struct btd_gatt_client *client)
 {
 	DBG("Exporting objects for GATT services: %s", client->devaddr);
 
 	gatt_db_foreach_service(client->db, NULL, export_service, client);
+
+	queue_foreach(client->services, update_included_services, client);
 }
 
 struct btd_gatt_client *btd_gatt_client_new(struct btd_device *device)
@@ -1689,14 +1794,8 @@ void btd_gatt_client_service_added(struct btd_gatt_client *client,
 		return;
 
 	export_service(attrib, client);
-}
-
-static bool match_service_handle(const void *a, const void *b)
-{
-	const struct service *service = a;
-	uint16_t start_handle = PTR_TO_UINT(b);
 
-	return service->start_handle == start_handle;
+	queue_foreach(client->services, update_included_services, client);
 }
 
 void btd_gatt_client_service_removed(struct btd_gatt_client *client,
-- 
2.4.3


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

end of thread, other threads:[~2017-05-02 15:36 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-26  9:51 [PATCH BlueZ v2] core/gatt-client: Add support for Includes property Marcin Kraglak
2017-04-26 12:32 Marcin Kraglak
2017-05-02 15:36 ` Luiz Augusto von Dentz

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.