From 7ddb6d998cf56da8e3d21c4c879cfdb0b4b20150 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Sun, 5 Jan 2014 19:08:29 +0200 Subject: [PATCH 02/12] plugins/service: Add initial code Add initial code that creates service objects data. --- plugins/service.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 131 insertions(+), 1 deletion(-) diff --git a/plugins/service.c b/plugins/service.c index e63d8a8..0c22d79 100644 --- a/plugins/service.c +++ b/plugins/service.c @@ -25,19 +25,149 @@ #include #endif -#include "src/plugin.h" +#include +#include +#include + +#include +#include + +#include "lib/uuid.h" #include "src/log.h" +#include "src/plugin.h" +#include "src/dbus-common.h" +#include "src/error.h" +#include "src/adapter.h" +#include "src/device.h" +#include "src/service.h" +#include "src/profile.h" + +#define SERVICE_INTERFACE "org.bluez.Service1" + +static unsigned int service_id = 0; +static GSList *services = NULL; + +struct service_data { + struct btd_service *service; + char *path; +}; + +static struct service_data *find_data(struct btd_service *service) +{ + GSList *l; + + for (l = services; l; l = l->next) { + struct service_data *data = l->data; + + if (data->service == service) + return data; + } + + return NULL; +} + +static void data_free(void *user_data) +{ + struct service_data *data = user_data; + + g_free(data->path); + g_free(data); +} + +static void data_remove(struct service_data *data) +{ + services = g_slist_remove(services, data); + g_dbus_unregister_interface(btd_get_dbus_connection(), data->path, + SERVICE_INTERFACE); +} + +static DBusMessage *service_disconnect(DBusConnection *conn, DBusMessage *msg, + void *user_data) +{ + return btd_error_not_available(msg); +} + +static DBusMessage *service_connect(DBusConnection *conn, DBusMessage *msg, + void *user_data) +{ + return btd_error_not_available(msg); +} + +static const GDBusMethodTable service_methods[] = { + { GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, service_disconnect) }, + { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, service_connect) }, + {} +}; + +static struct service_data *service_get_data(struct btd_service *service) +{ + struct btd_device *dev = btd_service_get_device(service); + struct btd_profile *p = btd_service_get_profile(service); + struct service_data *data; + + data = find_data(service); + if (data != NULL) + return data; + + data = g_new0(struct service_data, 1); + data->path = g_strdup_printf("%s/%s", btd_device_get_path(dev), + p->remote_uuid); + data->path = g_strdelimit(data->path, "-", '_'); + data->service = service; + if (g_dbus_register_interface(btd_get_dbus_connection(), + data->path, SERVICE_INTERFACE, + service_methods, NULL, + NULL, data, + data_free) == FALSE) { + error("Unable to register service interface for %s", + data->path); + data_free(data); + return NULL; + } + + services = g_slist_prepend(services, data); + + DBG("%s", data->path); + + return data; +} + +static void service_cb(struct btd_service *service, + btd_service_state_t old_state, + btd_service_state_t new_state, + void *user_data) +{ + struct service_data *data; + + data = service_get_data(service); + if (!data) + return; + + switch (new_state) { + case BTD_SERVICE_STATE_UNAVAILABLE: + data_remove(data); + break; + default: + return; + } +} static int service_init(void) { DBG(""); + service_id = btd_service_add_state_cb(service_cb, NULL); + return 0; } static void service_exit(void) { DBG(""); + + btd_service_remove_state_cb(service_id); + + g_slist_free_full(services, data_free); } BLUETOOTH_PLUGIN_DEFINE(service, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, -- 2.2.0