[PATCH BlueZ 2/4] core/gatt-database: Implement Application API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>

This implements RegisterApplication/UnregisterApplication that allow
multiple services to be registered at once.
---
 src/gatt-database.c | 446 ++++++++++++++++++++++++++++++++--------------------
 1 file changed, 273 insertions(+), 173 deletions(-)

diff --git a/src/gatt-database.c b/src/gatt-database.c
index e8ce7d5..ac0d92e 100644
--- a/src/gatt-database.c
+++ b/src/gatt-database.c
@@ -77,17 +77,23 @@ struct btd_gatt_database {
 	struct queue *ccc_callbacks;
 	struct gatt_db_attribute *svc_chngd;
 	struct gatt_db_attribute *svc_chngd_ccc;
-	struct queue *services;
+	struct queue *apps;
 	struct queue *profiles;
 };
 
-struct external_service {
+struct gatt_app {
 	struct btd_gatt_database *database;
-	bool failed;
 	char *owner;
-	char *path;	/* Path to GattService1 */
+	char *path;
 	DBusMessage *reg;
 	GDBusClient *client;
+	bool failed;
+	struct queue *services;
+};
+
+struct external_service {
+	struct gatt_app *app;
+	char *path;	/* Path to GattService1 */
 	GDBusProxy *proxy;
 	struct gatt_db_attribute *attrib;
 	uint16_t attr_cnt;
@@ -342,26 +348,41 @@ static void service_free(void *data)
 	queue_destroy(service->chrcs, chrc_free);
 	queue_destroy(service->descs, desc_free);
 
-	gatt_db_remove_service(service->database->db, service->attrib);
+	if (service->attrib)
+		gatt_db_remove_service(service->app->database->db,
+							service->attrib);
 
-	if (service->client) {
-		g_dbus_client_set_disconnect_watch(service->client, NULL, NULL);
-		g_dbus_client_set_proxy_handlers(service->client, NULL, NULL,
-								NULL, NULL);
-		g_dbus_client_set_ready_watch(service->client, NULL, NULL);
+	if (service->app->client)
 		g_dbus_proxy_unref(service->proxy);
-		g_dbus_client_unref(service->client);
-	}
-
-	if (service->reg)
-		dbus_message_unref(service->reg);
 
-	g_free(service->owner);
 	g_free(service->path);
 
 	free(service);
 }
 
+static void app_free(void *data)
+{
+	struct gatt_app *app = data;
+
+	queue_destroy(app->services, service_free);
+
+	if (app->client) {
+		g_dbus_client_set_disconnect_watch(app->client, NULL, NULL);
+		g_dbus_client_set_proxy_handlers(app->client, NULL, NULL,
+								NULL, NULL);
+		g_dbus_client_set_ready_watch(app->client, NULL, NULL);
+		g_dbus_client_unref(app->client);
+	}
+
+	if (app->reg)
+		dbus_message_unref(app->reg);
+
+	g_free(app->owner);
+	g_free(app->path);
+
+	free(app);
+}
+
 static void profile_remove(void *data)
 {
 	struct btd_profile *p = data;
@@ -434,7 +455,7 @@ static void gatt_database_free(void *data)
 	gatt_db_unregister(database->db, database->db_id);
 
 	queue_destroy(database->device_states, device_state_free);
-	queue_destroy(database->services, service_free);
+	queue_destroy(database->apps, app_free);
 	queue_destroy(database->profiles, profile_free);
 	queue_destroy(database->ccc_callbacks, ccc_cb_free);
 	database->device_states = NULL;
@@ -1012,67 +1033,101 @@ struct svc_match_data {
 	const char *sender;
 };
 
-static bool match_service(const void *a, const void *b)
+static bool match_app(const void *a, const void *b)
 {
-	const struct external_service *service = a;
+	const struct gatt_app *app = a;
 	const struct svc_match_data *data = b;
 
-	return g_strcmp0(service->path, data->path) == 0 &&
-				g_strcmp0(service->owner, data->sender) == 0;
+	return g_strcmp0(app->path, data->path) == 0 &&
+				g_strcmp0(app->owner, data->sender) == 0;
 }
 
-static gboolean service_free_idle_cb(void *data)
+static gboolean app_free_idle_cb(void *data)
 {
-	service_free(data);
+	app_free(data);
 
 	return FALSE;
 }
 
-static void service_remove_helper(void *data)
-{
-	struct external_service *service = data;
-
-	queue_remove(service->database->services, service);
-
-	/*
-	 * Do not run in the same loop, this may be a disconnect
-	 * watch call and GDBusClient should not be destroyed.
-	 */
-	g_idle_add(service_free_idle_cb, service);
-}
-
 static void client_disconnect_cb(DBusConnection *conn, void *user_data)
 {
+	struct gatt_app *app = user_data;
+	struct btd_gatt_database *database = app->database;
+
 	DBG("Client disconnected");
 
-	service_remove_helper(user_data);
+	if (queue_remove(database->apps, app))
+		app_free(app);
 }
 
-static void remove_service(void *data)
+static void remove_app(void *data)
 {
-	struct external_service *service = data;
+	struct gatt_app *app = data;
 
 	/*
 	 * Set callback to NULL to avoid potential race condition
-	 * when calling remove_service and GDBusClient unref.
+	 * when calling remove_app and GDBusClient unref.
 	 */
-	g_dbus_client_set_disconnect_watch(service->client, NULL, NULL);
+	g_dbus_client_set_disconnect_watch(app->client, NULL, NULL);
 
 	/*
 	 * Set proxy handlers to NULL, so that this gets called only once when
 	 * the first proxy that belongs to this service gets removed.
 	 */
-	g_dbus_client_set_proxy_handlers(service->client, NULL, NULL,
-								NULL, NULL);
+	g_dbus_client_set_proxy_handlers(app->client, NULL, NULL, NULL, NULL);
+
+
+	queue_remove(app->database->apps, app);
+
+	/*
+	 * Do not run in the same loop, this may be a disconnect
+	 * watch call and GDBusClient should not be destroyed.
+	 */
+	g_idle_add(app_free_idle_cb, app);
+}
+
+static bool match_service_by_path(const void *a, const void *b)
+{
+	const struct external_service *service = a;
+	const char *path = b;
 
-	service_remove_helper(service);
+	return strcmp(service->path, path) == 0;
 }
 
-static struct external_chrc *chrc_create(struct external_service *service,
+static bool parse_path(GDBusProxy *proxy, const char *name, const char **path)
+{
+	DBusMessageIter iter;
+
+	if (!g_dbus_proxy_get_property(proxy, name, &iter))
+		return false;
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH)
+		return false;
+
+	dbus_message_iter_get_basic(&iter, path);
+
+	return true;
+}
+
+static struct external_chrc *chrc_create(struct gatt_app *app,
 							GDBusProxy *proxy,
 							const char *path)
 {
+	struct external_service *service;
 	struct external_chrc *chrc;
+	const char *service_path;
+
+	if (!parse_path(proxy, "Service", &service_path)) {
+		error("Failed to obtain service path for characteristic");
+		return NULL;
+	}
+
+	service = queue_find(app->services, match_service_by_path,
+								service_path);
+	if (!service) {
+		error("Unable to find service for characteristic: %s", path);
+		return NULL;
+	}
 
 	chrc = new0(struct external_chrc, 1);
 	chrc->pending_reads = queue_new();
@@ -1092,11 +1147,40 @@ static struct external_chrc *chrc_create(struct external_service *service,
 	return chrc;
 }
 
-static struct external_desc *desc_create(struct external_service *service,
-							GDBusProxy *proxy,
-							const char *chrc_path)
+static bool match_chrc(const void *a, const void *b)
+{
+	const struct external_chrc *chrc = a;
+	const char *path = b;
+
+	return strcmp(chrc->path, path) == 0;
+}
+
+static bool match_service_by_chrc(const void *a, const void *b)
+{
+	const struct external_service *service = a;
+	const char *path = b;
+
+	return queue_find(service->chrcs, match_chrc, path);
+}
+
+static struct external_desc *desc_create(struct gatt_app *app,
+							GDBusProxy *proxy)
 {
+	struct external_service *service;
 	struct external_desc *desc;
+	const char *chrc_path;
+
+	if (!parse_path(proxy, "Characteristic", &chrc_path)) {
+		error("Failed to obtain characteristic path for descriptor");
+		return NULL;
+	}
+
+	service = queue_find(app->services, match_service_by_chrc, chrc_path);
+	if (!service) {
+		error("Unable to find service for characteristic: %s",
+								chrc_path);
+		return NULL;
+	}
 
 	desc = new0(struct external_desc, 1);
 	desc->pending_reads = queue_new();
@@ -1126,21 +1210,6 @@ static bool incr_attr_count(struct external_service *service, uint16_t incr)
 	return true;
 }
 
-static bool parse_path(GDBusProxy *proxy, const char *name, const char **path)
-{
-	DBusMessageIter iter;
-
-	if (!g_dbus_proxy_get_property(proxy, name, &iter))
-		return false;
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH)
-		return false;
-
-	dbus_message_iter_get_basic(&iter, path);
-
-	return true;
-}
-
 static bool check_service_path(GDBusProxy *proxy,
 					struct external_service *service)
 {
@@ -1259,54 +1328,74 @@ static bool parse_flags(GDBusProxy *proxy, uint8_t *props, uint8_t *ext_props,
 	return parse_chrc_flags(&array, props, ext_props);
 }
 
+static struct external_service *create_service(struct gatt_app *app,
+						GDBusProxy *proxy,
+						const char *path)
+{
+	struct external_service *service;
+
+	if (!path || !g_str_has_prefix(path, "/"))
+		return NULL;
+
+	service = queue_find(app->services, match_service_by_path, path);
+	if (service) {
+		error("Duplicated service: %s", path);
+		return NULL;
+	}
+
+	service = new0(struct external_service, 1);
+
+	service->app = app;
+
+	service->path = g_strdup(path);
+	if (!service->path)
+		goto fail;
+
+	service->proxy = g_dbus_proxy_ref(proxy);
+	service->chrcs = queue_new();
+	service->descs = queue_new();
+
+	return service;
+
+fail:
+	service_free(service);
+	return NULL;
+}
+
 static void proxy_added_cb(GDBusProxy *proxy, void *user_data)
 {
-	struct external_service *service = user_data;
+	struct gatt_app *app = user_data;
 	const char *iface, *path;
 
-	if (service->failed || service->attrib)
+	if (app->failed)
 		return;
 
 	iface = g_dbus_proxy_get_interface(proxy);
 	path = g_dbus_proxy_get_path(proxy);
 
-	if (!g_str_has_prefix(path, service->path))
-		return;
-
 	if (g_strcmp0(iface, GATT_SERVICE_IFACE) == 0) {
-		if (service->proxy)
-			return;
+		struct external_service *service;
 
-		/*
-		 * TODO: We may want to support adding included services in a
-		 * single hierarchy.
-		 */
-		if (g_strcmp0(path, service->path) != 0) {
-			error("Multiple services added within hierarchy");
-			service->failed = true;
+		service = create_service(app, proxy, path);
+		if (!service) {
+			app->failed = true;
 			return;
 		}
 
 		/* Add 1 for the service declaration */
 		if (!incr_attr_count(service, 1)) {
 			error("Failed to increment attribute count");
-			service->failed = true;
+			app->failed = true;
 			return;
 		}
 
-		service->proxy = g_dbus_proxy_ref(proxy);
+		queue_push_tail(app->services, service);
 	} else if (g_strcmp0(iface, GATT_CHRC_IFACE) == 0) {
 		struct external_chrc *chrc;
 
-		if (g_strcmp0(path, service->path) == 0) {
-			error("Characteristic path same as service path");
-			service->failed = true;
-			return;
-		}
-
-		chrc = chrc_create(service, proxy, path);
+		chrc = chrc_create(app, proxy, path);
 		if (!chrc) {
-			service->failed = true;
+			app->failed = true;
 			return;
 		}
 
@@ -1314,9 +1403,9 @@ static void proxy_added_cb(GDBusProxy *proxy, void *user_data)
 		 * Add 2 for the characteristic declaration and the value
 		 * attribute.
 		 */
-		if (!incr_attr_count(service, 2)) {
+		if (!incr_attr_count(chrc->service, 2)) {
 			error("Failed to increment attribute count");
-			service->failed = true;
+			app->failed = true;
 			return;
 		}
 
@@ -1327,46 +1416,38 @@ static void proxy_added_cb(GDBusProxy *proxy, void *user_data)
 		 */
 		if (!parse_flags(proxy, &chrc->props, &chrc->ext_props, NULL)) {
 			error("Failed to parse characteristic properties");
-			service->failed = true;
+			app->failed = true;
 			return;
 		}
 
 		if ((chrc->props & BT_GATT_CHRC_PROP_NOTIFY ||
 				chrc->props & BT_GATT_CHRC_PROP_INDICATE) &&
-				!incr_attr_count(service, 1)) {
+				!incr_attr_count(chrc->service, 1)) {
 			error("Failed to increment attribute count for CCC");
-			service->failed = true;
+			app->failed = true;
 			return;
 		}
 
-		if (chrc->ext_props && !incr_attr_count(service, 1)) {
+		if (chrc->ext_props && !incr_attr_count(chrc->service, 1)) {
 			error("Failed to increment attribute count for CEP");
-			service->failed = true;
+			app->failed = true;
 			return;
 		}
 
-		queue_push_tail(service->chrcs, chrc);
+		queue_push_tail(chrc->service->chrcs, chrc);
 	} else if (g_strcmp0(iface, GATT_DESC_IFACE) == 0) {
 		struct external_desc *desc;
-		const char *chrc_path;
 
-		if (!parse_path(proxy, "Characteristic", &chrc_path)) {
-			error("Failed to obtain characteristic path for "
-								"descriptor");
-			service->failed = true;
-			return;
-		}
-
-		desc = desc_create(service, proxy, chrc_path);
+		desc = desc_create(app, proxy);
 		if (!desc) {
-			service->failed = true;
+			app->failed = true;
 			return;
 		}
 
 		/* Add 1 for the descriptor attribute */
-		if (!incr_attr_count(service, 1)) {
+		if (!incr_attr_count(desc->service, 1)) {
 			error("Failed to increment attribute count");
-			service->failed = true;
+			app->failed = true;
 			return;
 		}
 
@@ -1376,32 +1457,35 @@ static void proxy_added_cb(GDBusProxy *proxy, void *user_data)
 		 */
 		if (!parse_flags(proxy, NULL, NULL, &desc->perm)) {
 			error("Failed to parse characteristic properties");
-			service->failed = true;
+			app->failed = true;
 			return;
 		}
 
-		queue_push_tail(service->descs, desc);
+		queue_push_tail(desc->service->descs, desc);
 	} else {
 		DBG("Ignoring unrelated interface: %s", iface);
 		return;
 	}
 
-	DBG("Object added to service - path: %s, iface: %s", path, iface);
+	DBG("Object added: path: %s, iface: %s", path, iface);
 }
 
 static void proxy_removed_cb(GDBusProxy *proxy, void *user_data)
 {
-	struct external_service *service = user_data;
+	struct gatt_app *app = user_data;
+	struct external_service *service;
 	const char *path;
 
 	path = g_dbus_proxy_get_path(proxy);
 
-	if (!g_str_has_prefix(path, service->path))
+	service = queue_remove_if(app->services, match_service_by_path,
+							(void *) path);
+	if (!service)
 		return;
 
 	DBG("Proxy removed - removing service: %s", service->path);
 
-	remove_service(service);
+	service_free(service);
 }
 
 static bool parse_uuid(GDBusProxy *proxy, bt_uuid_t *uuid)
@@ -1769,7 +1853,7 @@ static void property_changed_cb(GDBusProxy *proxy, const char *name,
 	len = MIN(BT_ATT_MAX_VALUE_LEN, len);
 	value = len ? value : NULL;
 
-	send_notification_to_devices(chrc->service->database,
+	send_notification_to_devices(chrc->service->app->database,
 				gatt_db_attribute_get_handle(chrc->attrib),
 				value, len,
 				gatt_db_attribute_get_handle(chrc->ccc),
@@ -1783,7 +1867,7 @@ static bool database_add_ccc(struct external_service *service,
 				!(chrc->props & BT_GATT_CHRC_PROP_INDICATE))
 		return true;
 
-	chrc->ccc = service_add_ccc(service->attrib, service->database,
+	chrc->ccc = service_add_ccc(service->attrib, service->app->database,
 						ccc_write_cb, chrc, NULL);
 	if (!chrc->ccc) {
 		error("Failed to create CCC entry for characteristic");
@@ -1992,7 +2076,7 @@ static bool match_desc_unhandled(const void *a, const void *b)
 	return !desc->handled;
 }
 
-static bool create_service_entry(struct external_service *service)
+static bool database_add_service(struct external_service *service)
 {
 	bt_uuid_t uuid;
 	bool primary;
@@ -2008,7 +2092,7 @@ static bool create_service_entry(struct external_service *service)
 		return false;
 	}
 
-	service->attrib = gatt_db_add_service(service->database->db, &uuid,
+	service->attrib = gatt_db_add_service(service->app->database->db, &uuid,
 						primary, service->attr_cnt);
 	if (!service->attrib)
 		return false;
@@ -2036,98 +2120,114 @@ static bool create_service_entry(struct external_service *service)
 	return true;
 
 fail:
-	gatt_db_remove_service(service->database->db, service->attrib);
+	gatt_db_remove_service(service->app->database->db, service->attrib);
 	service->attrib = NULL;
 
 	return false;
 }
 
+static bool database_add_app(struct gatt_app *app)
+{
+	const struct queue_entry *entry;
+
+	if (queue_isempty(app->services))
+		return false;
+
+	entry = queue_get_entries(app->services);
+	while (entry) {
+		if (!database_add_service(entry->data)) {
+			error("Failed to add service");
+			return false;
+		}
+
+		entry = entry->next;
+	}
+
+	return true;
+}
+
 static void client_ready_cb(GDBusClient *client, void *user_data)
 {
-	struct external_service *service = user_data;
+	struct gatt_app *app = user_data;
 	DBusMessage *reply;
 	bool fail = false;
 
-	if (!service->proxy || service->failed) {
+	if (!app->services || app->failed) {
 		error("No valid external GATT objects found");
 		fail = true;
-		reply = btd_error_failed(service->reg,
+		reply = btd_error_failed(app->reg,
 					"No valid service object found");
 		goto reply;
 	}
 
-	if (!create_service_entry(service)) {
+	if (!database_add_app(app)) {
 		error("Failed to create GATT service entry in local database");
 		fail = true;
-		reply = btd_error_failed(service->reg,
+		reply = btd_error_failed(app->reg,
 					"Failed to create entry in database");
 		goto reply;
 	}
 
-	DBG("GATT service registered: %s", service->path);
+	DBG("GATT application registered: %s:%s", app->owner, app->path);
 
-	reply = dbus_message_new_method_return(service->reg);
+	reply = dbus_message_new_method_return(app->reg);
 
 reply:
 	g_dbus_send_message(btd_get_dbus_connection(), reply);
-	dbus_message_unref(service->reg);
-	service->reg = NULL;
+	dbus_message_unref(app->reg);
+	app->reg = NULL;
 
 	if (fail)
-		remove_service(service);
+		remove_app(app);
 }
 
-static struct external_service *create_service(DBusConnection *conn,
-					DBusMessage *msg, const char *path)
+static struct gatt_app *create_app(DBusConnection *conn, DBusMessage *msg,
+							const char *path)
 {
-	struct external_service *service;
+	struct gatt_app *app;
 	const char *sender = dbus_message_get_sender(msg);
 
 	if (!path || !g_str_has_prefix(path, "/"))
 		return NULL;
 
-	service = new0(struct external_service, 1);
+	app = new0(struct gatt_app, 1);
 
-	service->client = g_dbus_client_new_full(conn, sender, path, path);
-	if (!service->client)
+	app->client = g_dbus_client_new_full(conn, sender, path, path);
+	if (!app->client)
 		goto fail;
 
-	service->owner = g_strdup(sender);
-	if (!service->owner)
+	app->owner = g_strdup(sender);
+	if (!app->owner)
 		goto fail;
 
-	service->path = g_strdup(path);
-	if (!service->path)
+	app->path = g_strdup(path);
+	if (!app->path)
 		goto fail;
 
-	service->chrcs = queue_new();
-	service->descs = queue_new();
-
-	service->reg = dbus_message_ref(msg);
+	app->services = queue_new();
+	app->reg = dbus_message_ref(msg);
 
-	g_dbus_client_set_disconnect_watch(service->client,
-						client_disconnect_cb, service);
-	g_dbus_client_set_proxy_handlers(service->client, proxy_added_cb,
-							proxy_removed_cb, NULL,
-							service);
-	g_dbus_client_set_ready_watch(service->client, client_ready_cb,
-								service);
+	g_dbus_client_set_disconnect_watch(app->client, client_disconnect_cb,
+									app);
+	g_dbus_client_set_proxy_handlers(app->client, proxy_added_cb,
+					proxy_removed_cb, NULL, app);
+	g_dbus_client_set_ready_watch(app->client, client_ready_cb, app);
 
-	return service;
+	return app;
 
 fail:
-	service_free(service);
+	app_free(app);
 	return NULL;
 }
 
-static DBusMessage *manager_register_service(DBusConnection *conn,
+static DBusMessage *manager_register_app(DBusConnection *conn,
 					DBusMessage *msg, void *user_data)
 {
 	struct btd_gatt_database *database = user_data;
 	const char *sender = dbus_message_get_sender(msg);
 	DBusMessageIter args;
 	const char *path;
-	struct external_service *service;
+	struct gatt_app *app;
 	struct svc_match_data match_data;
 
 	if (!dbus_message_iter_init(msg, &args))
@@ -2141,33 +2241,33 @@ static DBusMessage *manager_register_service(DBusConnection *conn,
 	match_data.path = path;
 	match_data.sender = sender;
 
-	if (queue_find(database->services, match_service, &match_data))
+	if (queue_find(database->apps, match_app, &match_data))
 		return btd_error_already_exists(msg);
 
 	dbus_message_iter_next(&args);
 	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
 		return btd_error_invalid_args(msg);
 
-	service = create_service(conn, msg, path);
-	if (!service)
-		return btd_error_failed(msg, "Failed to register service");
+	app = create_app(conn, msg, path);
+	if (!app)
+		return btd_error_failed(msg, "Failed to register application");
 
-	DBG("Registering service - path: %s", path);
+	DBG("Registering application: %s:%s", sender, path);
 
-	service->database = database;
-	queue_push_tail(database->services, service);
+	app->database = database;
+	queue_push_tail(database->apps, app);
 
 	return NULL;
 }
 
-static DBusMessage *manager_unregister_service(DBusConnection *conn,
+static DBusMessage *manager_unregister_app(DBusConnection *conn,
 					DBusMessage *msg, void *user_data)
 {
 	struct btd_gatt_database *database = user_data;
 	const char *sender = dbus_message_get_sender(msg);
 	const char *path;
 	DBusMessageIter args;
-	struct external_service *service;
+	struct gatt_app *app;
 	struct svc_match_data match_data;
 
 	if (!dbus_message_iter_init(msg, &args))
@@ -2181,12 +2281,11 @@ static DBusMessage *manager_unregister_service(DBusConnection *conn,
 	match_data.path = path;
 	match_data.sender = sender;
 
-	service = queue_remove_if(database->services, match_service,
-								&match_data);
-	if (!service)
+	app = queue_remove_if(database->apps, match_app, &match_data);
+	if (!app)
 		return btd_error_does_not_exist(msg);
 
-	service_free(service);
+	app_free(app);
 
 	return dbus_message_new_method_return(msg);
 }
@@ -2389,12 +2488,13 @@ static DBusMessage *manager_unregister_profile(DBusConnection *conn,
 }
 
 static const GDBusMethodTable manager_methods[] = {
-	{ GDBUS_EXPERIMENTAL_ASYNC_METHOD("RegisterService",
-			GDBUS_ARGS({ "service", "o" }, { "options", "a{sv}" }),
-			NULL, manager_register_service) },
-	{ GDBUS_EXPERIMENTAL_ASYNC_METHOD("UnregisterService",
-					GDBUS_ARGS({ "service", "o" }),
-					NULL, manager_unregister_service) },
+	{ GDBUS_EXPERIMENTAL_ASYNC_METHOD("RegisterApplication",
+			GDBUS_ARGS({ "application", "o" },
+			{ "options", "a{sv}" }), NULL,
+			manager_register_app) },
+	{ GDBUS_EXPERIMENTAL_ASYNC_METHOD("UnregisterApplication",
+					GDBUS_ARGS({ "application", "o" }),
+					NULL, manager_unregister_app) },
 	{ GDBUS_EXPERIMENTAL_ASYNC_METHOD("RegisterProfile",
 			GDBUS_ARGS({ "profile", "o" }, { "UUIDs", "as" },
 			{ "options", "a{sv}" }), NULL,
@@ -2418,7 +2518,7 @@ struct btd_gatt_database *btd_gatt_database_new(struct btd_adapter *adapter)
 	database->adapter = btd_adapter_ref(adapter);
 	database->db = gatt_db_new();
 	database->device_states = queue_new();
-	database->services = queue_new();
+	database->apps = queue_new();
 	database->profiles = queue_new();
 	database->ccc_callbacks = queue_new();
 
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux