summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2007-01-24 05:38:40 +0000
committerMarcel Holtmann <marcel@holtmann.org>2007-01-24 05:38:40 +0000
commit3021d8e125537fd3b14a5d50e0710bce17f8d198 (patch)
treeb899e4e247deb92223bd11e986a6defb7fc50b1f
parentbf9a0168854c71faff3e67c42c6265069230f6ce (diff)
Add support for internal debug services
-rw-r--r--hcid/dbus-database.c30
-rw-r--r--hcid/dbus-service.c87
-rw-r--r--hcid/dbus-service.h6
3 files changed, 119 insertions, 4 deletions
diff --git a/hcid/dbus-database.c b/hcid/dbus-database.c
index 1e0cee3e..f0b13abb 100644
--- a/hcid/dbus-database.c
+++ b/hcid/dbus-database.c
@@ -43,6 +43,8 @@
#include "sdp-xml.h"
#include "dbus-common.h"
#include "dbus-error.h"
+#include "dbus-hci.h"
+#include "dbus-service.h"
#include "dbus-database.h"
static int sdp_server_enable = 0;
@@ -264,10 +266,38 @@ static DBusHandlerResult remove_service_record(DBusConnection *conn,
return send_message_and_unref(conn, reply);
}
+static DBusHandlerResult register_service(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ DBusMessage *reply;
+ const char *ident, *name, *desc;
+ const char *sender;
+
+ if (!hcid_dbus_use_experimental())
+ return error_unknown_method(conn, msg);
+
+ if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &ident,
+ DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &desc,
+ DBUS_TYPE_INVALID) == FALSE)
+ return error_invalid_arguments(conn, msg);
+
+ sender = dbus_message_get_sender(msg);
+
+ if (service_register(sender, ident, name, desc) < 0)
+ return error_failed(conn, msg, EIO);
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+ return send_message_and_unref(conn, reply);
+}
+
static struct service_data database_services[] = {
{ "AddServiceRecord", add_service_record },
{ "AddServiceRecordFromXML", add_service_record_from_xml },
{ "RemoveServiceRecord", remove_service_record },
+ { "RegisterService", register_service },
{ NULL, NULL }
};
diff --git a/hcid/dbus-service.c b/hcid/dbus-service.c
index 30456591..a09a056f 100644
--- a/hcid/dbus-service.c
+++ b/hcid/dbus-service.c
@@ -304,7 +304,6 @@ static void service_died(GPid pid, gint status, gpointer data)
}
}
-
static gboolean service_shutdown_timeout(gpointer data)
{
struct service *service = data;
@@ -397,7 +396,7 @@ static DBusHandlerResult start(DBusConnection *conn,
{
struct service *service = data;
- if (service->pid)
+ if (service->internal || service->pid)
return error_failed(conn, msg, EALREADY);
if (service_start(service, conn) < 0)
@@ -413,7 +412,7 @@ static DBusHandlerResult stop(DBusConnection *conn,
{
struct service *service = data;
- if (!service->bus_name)
+ if (service->internal || !service->bus_name)
return error_failed(conn, msg, EPERM);
stop_service(service, FALSE);
@@ -434,7 +433,7 @@ static DBusHandlerResult is_running(DBusConnection *conn,
if (!reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
- running = service->bus_name ? TRUE : FALSE;
+ running = (service->internal || service->bus_name) ? TRUE : FALSE;
dbus_message_append_args(reply,
DBUS_TYPE_BOOLEAN, &running,
@@ -718,6 +717,8 @@ static struct service *create_service(const char *file)
return NULL;
}
+ service->internal = FALSE;
+
keyfile = g_key_file_new();
if (!g_key_file_load_from_file(keyfile, file, 0, &err)) {
@@ -881,3 +882,81 @@ int init_services(const char *path)
return 0;
}
+
+static struct service *create_internal_service(const char *ident,
+ const char *name, const char *description)
+{
+ struct service *service;
+
+ service = g_try_new0(struct service, 1);
+ if (!service) {
+ error("OOM while allocating new internal service");
+ return NULL;
+ }
+
+ service->filename = g_strdup("internal.service");
+ service->name = g_strdup(name);
+ service->descr = g_strdup(description);
+ service->ident = g_strdup(ident);
+
+ service->internal = TRUE;
+
+ return service;
+}
+
+static void internal_service_exit(const char *name, struct service *service)
+{
+ DBusConnection *conn = get_dbus_connection();
+ DBusMessage *signal;
+
+ service_exit(name, service);
+
+ if (!conn)
+ return;
+
+ if (!dbus_connection_unregister_object_path(conn, service->object_path))
+ return;
+
+ signal = dbus_message_new_signal(BASE_PATH, MANAGER_INTERFACE,
+ "ServiceRemoved");
+ if (signal) {
+ dbus_message_append_args(signal,
+ DBUS_TYPE_STRING, &service->object_path,
+ DBUS_TYPE_INVALID);
+ send_message_and_unref(conn, signal);
+ }
+
+ services = g_slist_remove(services, service);
+ service_free(service);
+}
+
+int service_register(const char *bus_name, const char *ident,
+ const char *name, const char *description)
+{
+ DBusConnection *conn = get_dbus_connection();
+ DBusMessage *msg;
+ struct service *service;
+
+ if (!conn)
+ return -1;
+
+ service = create_internal_service(ident, name, description);
+ if (!service)
+ return -1;
+
+ service->bus_name = g_strdup(bus_name);
+
+ if (register_service(service) < 0) {
+ service_free(service);
+ return -1;
+ }
+
+ name_listener_add(conn, bus_name, (name_cb_t) internal_service_exit, service);
+
+ msg = dbus_message_new_signal(service->object_path,
+ SERVICE_INTERFACE, "Started");
+ if (msg)
+ send_message_and_unref(conn, msg);
+
+ return 0;
+}
diff --git a/hcid/dbus-service.h b/hcid/dbus-service.h
index 4d65b38e..33e7e056 100644
--- a/hcid/dbus-service.h
+++ b/hcid/dbus-service.h
@@ -45,6 +45,9 @@ struct service {
char *ident;
gboolean autostart;
+ /* Services without a *.service file */
+ gboolean internal;
+
GSList *trusted_devices;
};
@@ -58,4 +61,7 @@ int service_start(struct service *service, DBusConnection *conn);
int init_services(const char *path);
+int service_register(const char *bus_name, const char *ident,
+ const char *name, const char *description);
+
#endif /* __BLUEZ_DBUS_SERVICE_H */