summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2014-01-05 19:08:29 +0200
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2016-01-28 14:04:42 +0200
commitbf63c41568e71afa0508028e73cef3994a767432 (patch)
tree8c64dee17b78dc5b7637a3e0575f2b32122ce55a
parent20928920cb0c14d9b05862a712eabbf4ba58ae01 (diff)
downloadbluez-bf63c41568e71afa0508028e73cef3994a767432.tar.gz
plugins/service: Add initial code
Add initial code that creates service objects data.
-rw-r--r--plugins/service.c129
1 files changed, 128 insertions, 1 deletions
diff --git a/plugins/service.c b/plugins/service.c
index e63d8a829..ffa941f90 100644
--- a/plugins/service.c
+++ b/plugins/service.c
@@ -25,19 +25,146 @@
#include <config.h>
#endif
-#include "src/plugin.h"
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <gdbus/gdbus.h>
+
+#include "lib/bluetooth.h"
+#include "lib/sdp.h"
+#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 || new_state != BTD_SERVICE_STATE_UNAVAILABLE)
+ return;
+
+ data_remove(data);
+}
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);
+
+ while (services)
+ data_remove(services->data);
}
BLUETOOTH_PLUGIN_DEFINE(service, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,