summaryrefslogtreecommitdiffstats
path: root/hcid
diff options
context:
space:
mode:
Diffstat (limited to 'hcid')
-rw-r--r--hcid/dbus-common.c2
-rw-r--r--hcid/dbus-database.c39
-rw-r--r--hcid/dbus-error.c6
-rw-r--r--hcid/dbus-error.h1
-rw-r--r--hcid/dbus-service.c705
-rw-r--r--hcid/dbus-service.h35
-rw-r--r--hcid/main.c2
-rw-r--r--hcid/manager.c29
8 files changed, 129 insertions, 690 deletions
diff --git a/hcid/dbus-common.c b/hcid/dbus-common.c
index 0094c11e..20453c82 100644
--- a/hcid/dbus-common.c
+++ b/hcid/dbus-common.c
@@ -244,8 +244,6 @@ static gboolean system_bus_reconnect(void *data)
if (hcid_dbus_init() < 0)
return TRUE;
- init_services(CONFIGDIR);
-
/* Create and bind HCI socket */
sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (sk < 0) {
diff --git a/hcid/dbus-database.c b/hcid/dbus-database.c
index d37b4d97..9519975e 100644
--- a/hcid/dbus-database.c
+++ b/hcid/dbus-database.c
@@ -353,57 +353,34 @@ static DBusHandlerResult remove_service_record(DBusConnection *conn,
return send_message_and_unref(conn, reply);
}
-static DBusHandlerResult register_service(DBusConnection *conn,
+static DBusHandlerResult register_service_old(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- DBusMessage *reply;
- const char *sender, *ident, *name, *desc;
+ const char *ident, *name, *desc;
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, NULL);
- sender = dbus_message_get_sender(msg);
-
- if (service_register(conn, sender, ident, name, desc) < 0)
- return error_failed_errno(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);
+ return error_failed_errno(conn, msg, EIO);
}
-static DBusHandlerResult unregister_service(DBusConnection *conn,
+static DBusHandlerResult unregister_service_old(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- DBusMessage *reply;
- const char *sender, *ident;
struct service *service;
+ const char *ident;
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &ident,
DBUS_TYPE_INVALID) == FALSE)
return error_invalid_arguments(conn, msg, NULL);
- sender = dbus_message_get_sender(msg);
-
service = search_service(ident);
if (!service)
return error_service_does_not_exist(conn, msg);
- if (!service->external || strcmp(sender, service->bus_name))
- return error_not_authorized(conn, msg);
-
- if (service_unregister(conn, service) < 0)
- return error_failed_errno(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);
+ return error_failed_errno(conn, msg, EIO);
}
static DBusHandlerResult request_authorization_old(DBusConnection *conn,
@@ -486,8 +463,8 @@ static DBusMethodVTable database_methods[] = {
{ "UpdateServiceRecord", update_service_record, "uay", "" },
{ "UpdateServiceRecordFromXML", update_service_record_from_xml, "us", "" },
{ "RemoveServiceRecord", remove_service_record, "u", "" },
- { "RegisterService", register_service, "sss", "" },
- { "UnregisterService", unregister_service, "s", "" },
+ { "RegisterService", register_service_old, "sss", "" },
+ { "UnregisterService", unregister_service_old, "s", "" },
{ "RequestAuthorization", request_authorization_old, "ss", "" },
{ "CancelAuthorizationRequest", cancel_authorization_request, "ss", "" },
{ NULL, NULL, NULL, NULL }
diff --git a/hcid/dbus-error.c b/hcid/dbus-error.c
index 66fb2490..20a55c5c 100644
--- a/hcid/dbus-error.c
+++ b/hcid/dbus-error.c
@@ -170,12 +170,6 @@ DBusHandlerResult error_disconnect_in_progress(DBusConnection *conn, DBusMessage
return error_in_progress(conn, msg, "Disconnection in progress");
}
-DBusHandlerResult error_service_start_in_progress(DBusConnection *conn,
- DBusMessage *msg)
-{
- return error_in_progress(conn, msg, "Service start in progress");
-}
-
static const char *strsdperror(int err)
{
switch (err) {
diff --git a/hcid/dbus-error.h b/hcid/dbus-error.h
index b50c4772..2cdabdde 100644
--- a/hcid/dbus-error.h
+++ b/hcid/dbus-error.h
@@ -51,4 +51,3 @@ DBusHandlerResult error_service_search_in_progress(DBusConnection *conn, DBusMes
DBusHandlerResult error_sdp_failed(DBusConnection *conn, DBusMessage *msg, int err);
DBusHandlerResult error_audit_already_exists(DBusConnection *conn, DBusMessage *msg);
DBusHandlerResult error_disconnect_in_progress(DBusConnection *conn, DBusMessage *msg);
-DBusHandlerResult error_service_start_in_progress(DBusConnection *conn, DBusMessage *msg);
diff --git a/hcid/dbus-service.c b/hcid/dbus-service.c
index 01f07b2f..5282ffd1 100644
--- a/hcid/dbus-service.c
+++ b/hcid/dbus-service.c
@@ -61,14 +61,6 @@
#define SERVICE_INTERFACE "org.bluez.Service"
-#define STARTUP_TIMEOUT (10 * 1000) /* 10 seconds */
-#define SHUTDOWN_TIMEOUT (2 * 1000) /* 2 seconds */
-
-#define SERVICE_SUFFIX ".service"
-#define SERVICE_GROUP "Bluetooth Service"
-
-#define NAME_MATCH "interface=" DBUS_INTERFACE_DBUS ",member=NameOwnerChanged"
-
struct service_uuids {
char *name;
char **uuids;
@@ -81,69 +73,19 @@ struct service_auth {
static GSList *services = NULL;
static GSList *services_uuids = NULL;
-static GSList *removed = NULL;
static void service_free(struct service *service)
{
if (!service)
return;
- if (service->action)
- dbus_message_unref(service->action);
-
- g_free(service->bus_name);
- g_free(service->filename);
g_free(service->object_path);
- g_free(service->name);
- g_free(service->descr);
g_free(service->ident);
+ g_free(service->name);
g_free(service);
}
-static void service_exit(const char *name, struct service *service)
-{
- DBusConnection *conn = get_dbus_connection();
-
- debug("Service owner exited: %s", name);
-
- dbus_connection_emit_signal(conn, service->object_path,
- SERVICE_INTERFACE, "Stopped",
- DBUS_TYPE_INVALID);
-
- if (service->action) {
- DBusMessage *reply;
- reply = dbus_message_new_method_return(service->action);
- send_message_and_unref(conn, reply);
- dbus_message_unref(service->action);
- service->action = NULL;
- }
-
- g_free(service->bus_name);
- service->bus_name = NULL;
-}
-
-static void external_service_exit(const char *name, struct service *service)
-{
- DBusConnection *conn = get_dbus_connection();
-
- if (!conn)
- return;
-
- service_exit(name, service);
-
- dbus_connection_emit_signal(conn, BASE_PATH, MANAGER_INTERFACE,
- "ServiceRemoved",
- DBUS_TYPE_STRING, &service->object_path,
- DBUS_TYPE_INVALID);
-
- if (!dbus_connection_destroy_object_path(conn, service->object_path))
- return;
-
- services = g_slist_remove(services, service);
- service_free(service);
-}
-
static DBusHandlerResult get_info(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -151,7 +93,6 @@ static DBusHandlerResult get_info(DBusConnection *conn,
DBusMessage *reply;
DBusMessageIter iter;
DBusMessageIter dict;
- dbus_bool_t running;
reply = dbus_message_new_method_return(msg);
if (!reply)
@@ -170,14 +111,6 @@ static DBusHandlerResult get_info(DBusConnection *conn,
dbus_message_iter_append_dict_entry(&dict, "name",
DBUS_TYPE_STRING, &service->name);
- dbus_message_iter_append_dict_entry(&dict, "description",
- DBUS_TYPE_STRING, &service->descr);
-
- running = (service->external || service->bus_name) ? TRUE : FALSE;
-
- dbus_message_iter_append_dict_entry(&dict, "running",
- DBUS_TYPE_BOOLEAN, &running);
-
dbus_message_iter_close_container(&iter, &dict);
return send_message_and_unref(conn, reply);
@@ -198,9 +131,8 @@ static DBusHandlerResult get_identifier(DBusConnection *conn,
if (service->ident)
identifier = service->ident;
- dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &identifier,
- DBUS_TYPE_INVALID);
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &identifier,
+ DBUS_TYPE_INVALID);
return send_message_and_unref(conn, reply);
}
@@ -220,9 +152,8 @@ static DBusHandlerResult get_name(DBusConnection *conn,
if (service->name)
name = service->name;
- dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &name,
- DBUS_TYPE_INVALID);
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_INVALID);
return send_message_and_unref(conn, reply);
}
@@ -230,7 +161,6 @@ static DBusHandlerResult get_name(DBusConnection *conn,
static DBusHandlerResult get_description(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- struct service *service = data;
DBusMessage *reply;
const char *description = "";
@@ -238,12 +168,8 @@ static DBusHandlerResult get_description(DBusConnection *conn,
if (!reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
- if (service->descr)
- description = service->descr;
-
- dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &description,
- DBUS_TYPE_INVALID);
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &description,
+ DBUS_TYPE_INVALID);
return send_message_and_unref(conn, reply);
}
@@ -251,291 +177,41 @@ static DBusHandlerResult get_description(DBusConnection *conn,
static DBusHandlerResult get_bus_name(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- struct service *service = data;
DBusMessage *reply;
-
- if (!service->bus_name)
- return error_not_available(conn, msg);
+ const char *busname = "org.bluez";
reply = dbus_message_new_method_return(msg);
if (!reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
- dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &service->bus_name,
- DBUS_TYPE_INVALID);
-
- return send_message_and_unref(conn, reply);
-}
-
-static void service_setup(gpointer data)
-{
- /* struct service *service = data; */
-}
-
-static DBusHandlerResult service_filter(DBusConnection *conn,
- DBusMessage *msg, void *data)
-{
- DBusError err;
- struct service *service = data;
- const char *name, *old, *new;
- unsigned long pid;
-
- if (!dbus_message_is_signal(msg, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &old,
- DBUS_TYPE_STRING, &new, DBUS_TYPE_INVALID)) {
- error("Invalid arguments for NameOwnerChanged signal");
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
-
- if (*new == '\0' || *old != '\0' || *new != ':')
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- if (!dbus_bus_get_unix_process_id(conn, new, &pid)) {
- error("Could not get PID of %s", new);
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
-
- if ((GPid) pid != service->pid)
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- debug("Child PID %d got the unique bus name %s", service->pid, new);
-
- service->bus_name = g_strdup(new);
-
- dbus_error_init(&err);
- dbus_bus_remove_match(conn, NAME_MATCH, &err);
- if (dbus_error_is_set(&err)) {
- error("Remove match \"%s\" failed: %s" NAME_MATCH, err.message);
- dbus_error_free(&err);
- }
- dbus_connection_remove_filter(conn, service_filter, service);
-
- if (service->action) {
- msg = dbus_message_new_method_return(service->action);
- if (msg) {
- if (dbus_message_is_method_call(service->action, MANAGER_INTERFACE,
- "ActivateService"))
- dbus_message_append_args(msg, DBUS_TYPE_STRING, &new,
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &busname,
DBUS_TYPE_INVALID);
- send_message_and_unref(conn, msg);
- }
- dbus_message_unref(service->action);
- service->action = NULL;
- }
-
- if (service->startup_timer) {
- g_source_remove(service->startup_timer);
- service->startup_timer = 0;
- } else
- debug("service_filter: timeout was already removed!");
-
- name_listener_add(conn, new, (name_cb_t) service_exit, service);
-
- dbus_connection_emit_signal(conn, service->object_path,
- SERVICE_INTERFACE, "Started",
- DBUS_TYPE_INVALID);
-
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-static void abort_startup(struct service *service, DBusConnection *conn, int ecode)
-{
- DBusError err;
-
- if (conn) {
- dbus_error_init(&err);
- dbus_bus_remove_match(conn, NAME_MATCH, &err);
- if (dbus_error_is_set(&err)) {
- error("Remove match \"%s\" failed: %s" NAME_MATCH, err.message);
- dbus_error_free(&err);
- }
-
- dbus_connection_remove_filter(conn, service_filter, service);
- }
-
- g_source_remove(service->startup_timer);
- service->startup_timer = 0;
-
- if (service->action) {
- if (conn)
- error_failed_errno(conn, service->action, ecode);
- dbus_message_unref(service->action);
- service->action = NULL;
- }
-
- if (service->pid > 0 && kill(service->pid, SIGKILL) < 0)
- error("kill(%d, SIGKILL): %s (%d)", service->pid,
- strerror(errno), errno);
-}
-
-static void service_died(GPid pid, gint status, gpointer data)
-{
- struct service *service = data;
-
- if (WIFEXITED(status))
- debug("%s (%s) exited with status %d", service->name,
- service->ident, WEXITSTATUS(status));
- else
- debug("%s (%s) was killed by signal %d", service->name,
- service->ident, WTERMSIG(status));
-
- g_spawn_close_pid(pid);
- service->pid = 0;
-
- if (service->startup_timer)
- abort_startup(service, get_dbus_connection(), ECANCELED);
-
- if (service->shutdown_timer) {
- g_source_remove(service->shutdown_timer);
- service->shutdown_timer = 0;
- }
-
- if (g_slist_find(removed, service)) {
- removed = g_slist_remove(removed, service);
- service_free(service);
- }
-}
-
-static gboolean service_shutdown_timeout(gpointer data)
-{
- struct service *service = data;
-
- if (service->pid > 0) {
- debug("SIGKILL for \"%s\" (PID %d) since it didn't exit yet",
- service->name, service->pid);
-
- if (kill(service->pid, SIGKILL) < 0)
- error("kill(%d, SIGKILL): %s (%d)", service->pid,
- strerror(errno), errno);
- }
-
- service->shutdown_timer = 0;
-
- return FALSE;
-}
-
-static void stop_service(struct service *service, gboolean remove)
-{
- if (service->pid > 0 && kill(service->pid, SIGTERM) < 0)
- error("kill(%d, SIGTERM): %s (%d)", service->pid,
- strerror(errno), errno);
-
- service->shutdown_timer = g_timeout_add(SHUTDOWN_TIMEOUT,
- service_shutdown_timeout,
- service);
-
- if (remove) {
- services = g_slist_remove(services, service);
- removed = g_slist_append(removed, service);
- }
-}
-
-static gboolean service_startup_timeout(gpointer data)
-{
- struct service *service = data;
-
- debug("Killing \"%s\" (PID %d) because it did not connect to D-Bus in time",
- service->name, service->pid);
-
- abort_startup(service, get_dbus_connection(), ETIME);
-
- return FALSE;
-}
-
-int service_start(struct service *service, DBusConnection *conn)
-{
- DBusError derr;
- char *argv[2], *envp[1], command[PATH_MAX];
-
- if (!dbus_connection_add_filter(conn, service_filter, service, NULL)) {
- error("Unable to add signal filter");
- return -1;
- }
-
- dbus_error_init(&derr);
- dbus_bus_add_match(conn, NAME_MATCH, &derr);
- if (dbus_error_is_set(&derr)) {
- error("Add match \"%s\" failed: %s", NAME_MATCH, derr.message);
- dbus_error_free(&derr);
- dbus_connection_remove_filter(conn, service_filter, service);
- return -1;
- }
-
- snprintf(command, sizeof(command) - 1, "%s/bluetoothd-service-%s",
- SERVICEDIR, service->ident);
- argv[0] = command;
- argv[1] = NULL;
-
- envp[0] = NULL;
-
- if (!g_spawn_async(SERVICEDIR, argv, envp, G_SPAWN_DO_NOT_REAP_CHILD,
- service_setup, service, &service->pid, NULL)) {
- error("Unable to execute %s", argv[0]);
- dbus_connection_remove_filter(conn, service_filter, service);
- dbus_bus_remove_match(conn, NAME_MATCH, NULL);
- return -1;
- }
-
- g_child_watch_add(service->pid, service_died, service);
-
- debug("%s executed with PID %d", argv[0], service->pid);
-
- service->startup_timer = g_timeout_add(STARTUP_TIMEOUT,
- service_startup_timeout,
- service);
-
- return 0;
+ return send_message_and_unref(conn, reply);
}
static DBusHandlerResult start(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- struct service *service = data;
-
- if (service->external || service->pid)
- return error_failed_errno(conn, msg, EALREADY);
-
- if (service_start(service, conn) < 0)
- return error_failed_errno(conn, msg, ENOEXEC);
-
- service->action = dbus_message_ref(msg);
-
- return DBUS_HANDLER_RESULT_HANDLED;
+ return error_failed_errno(conn, msg, EALREADY);
}
static DBusHandlerResult stop(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- struct service *service = data;
-
- if (service->external || !service->bus_name)
- return error_failed_errno(conn, msg, EPERM);
-
- stop_service(service, FALSE);
-
- service->action = dbus_message_ref(msg);
-
- return DBUS_HANDLER_RESULT_HANDLED;
+ return error_failed_errno(conn, msg, EPERM);
}
static DBusHandlerResult is_running(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- struct service *service = data;
DBusMessage *reply;
- dbus_bool_t running;
+ dbus_bool_t running = TRUE;
reply = dbus_message_new_method_return(msg);
if (!reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
- running = (service->external || service->bus_name) ? TRUE : FALSE;
-
dbus_message_append_args(reply,
DBUS_TYPE_BOOLEAN, &running,
DBUS_TYPE_INVALID);
@@ -546,15 +222,15 @@ static DBusHandlerResult is_running(DBusConnection *conn,
static DBusHandlerResult is_external(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- struct service *service = data;
DBusMessage *reply;
+ dbus_bool_t external = TRUE;
reply = dbus_message_new_method_return(msg);
if (!reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
dbus_message_append_args(reply,
- DBUS_TYPE_BOOLEAN, &service->external,
+ DBUS_TYPE_BOOLEAN, &external,
DBUS_TYPE_INVALID);
return send_message_and_unref(conn, reply);
@@ -590,34 +266,34 @@ static DBusHandlerResult set_trusted(DBusConnection *conn,
}
static DBusHandlerResult list_trusted(DBusConnection *conn,
- DBusMessage *msg, void *data)
+ DBusMessage *msg, void *data)
{
- struct service *service = data;
- DBusMessage *reply;
- GSList *trusts, *l;
- char **addrs;
- int len;
+ struct service *service = data;
+ DBusMessage *reply;
+ GSList *trusts, *l;
+ char **addrs;
+ int len;
- reply = dbus_message_new_method_return(msg);
- if (!reply)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
- trusts = list_trusts(BDADDR_ANY, service->ident);
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
- addrs = g_new(char *, g_slist_length(trusts));
+ trusts = list_trusts(BDADDR_ANY, service->ident);
- for (l = trusts, len = 0; l; l = l->next, len++)
- addrs[len] = l->data;
+ addrs = g_new(char *, g_slist_length(trusts));
- dbus_message_append_args(reply,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
- &addrs, len,
- DBUS_TYPE_INVALID);
+ for (l = trusts, len = 0; l; l = l->next, len++)
+ addrs[len] = l->data;
+
+ dbus_message_append_args(reply,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
+ &addrs, len, DBUS_TYPE_INVALID);
- g_free(addrs);
- g_slist_foreach(trusts, (GFunc) g_free, NULL);
- g_slist_free(trusts);
+ g_free(addrs);
+ g_slist_foreach(trusts, (GFunc) g_free, NULL);
+ g_slist_free(trusts);
- return send_message_and_unref(conn, reply);
+ return send_message_and_unref(conn, reply);
}
static DBusHandlerResult is_trusted(DBusConnection *conn,
@@ -720,66 +396,6 @@ static int service_cmp_ident(struct service *service, const char *ident)
return strcmp(service->ident, ident);
}
-static int register_service(struct service *service)
-{
- char obj_path[PATH_MAX], *suffix;
- DBusConnection *conn = get_dbus_connection();
- int i;
-
- if (g_slist_find_custom(services, service->ident,
- (GCompareFunc) service_cmp_ident)
- || !strcmp(service->ident, GLOBAL_TRUST))
- return -EADDRINUSE;
-
- if (service->external) {
- snprintf(obj_path, sizeof(obj_path) - 1,
- "/org/bluez/external_%s", service->ident);
- } else {
- snprintf(obj_path, sizeof(obj_path) - 1,
- "/org/bluez/service_%s", service->filename);
-
- /* Don't include the .service part in the path */
- suffix = strstr(obj_path, SERVICE_SUFFIX);
- *suffix = '\0';
- }
-
- /* Make the path valid for D-Bus */
- for (i = strlen("/org/bluez/"); obj_path[i]; i++) {
- if (!isalnum(obj_path[i]))
- obj_path[i] = '_';
- }
-
- if (g_slist_find_custom(services, obj_path,
- (GCompareFunc) service_cmp_path))
- return -EADDRINUSE;
-
- debug("Registering service object: ident=%s, name=%s (%s)",
- service->ident, service->name, obj_path);
-
-
- if (!dbus_connection_create_object_path(conn, obj_path,
- service, NULL)) {
- error("D-Bus failed to register %s object", obj_path);
- return -1;
- }
-
- if (!service_init(conn, obj_path)) {
- error("Service init failed");
- return -1;
- }
-
- service->object_path = g_strdup(obj_path);
-
- services = g_slist_append(services, service);
-
- dbus_connection_emit_signal(conn, BASE_PATH, MANAGER_INTERFACE,
- "ServiceAdded",
- DBUS_TYPE_STRING, &service->object_path,
- DBUS_TYPE_INVALID);
-
- return 0;
-}
-
static int unregister_service_for_connection(DBusConnection *connection,
struct service *service)
{
@@ -790,13 +406,6 @@ static int unregister_service_for_connection(DBusConnection *connection,
if (!conn)
goto cleanup;
- if (service->bus_name) {
- name_cb_t cb = (name_cb_t) (service->external ?
- external_service_exit : service_exit);
- name_listener_remove(connection, service->bus_name,
- cb, service);
- }
-
dbus_connection_emit_signal(conn, service->object_path,
SERVICE_INTERFACE,
"Stopped", DBUS_TYPE_INVALID);
@@ -807,36 +416,30 @@ static int unregister_service_for_connection(DBusConnection *connection,
DBUS_TYPE_INVALID);
if (!dbus_connection_destroy_object_path(conn, service->object_path)) {
- error("D-Bus failed to unregister %s object", service->object_path);
+ error("D-Bus failed to unregister %s object",
+ service->object_path);
return -1;
}
cleanup:
- if (service->pid) {
- if (service->startup_timer) {
- abort_startup(service, conn, ECANCELED);
- services = g_slist_remove(services, service);
- removed = g_slist_append(removed, service);
- } else if (!service->shutdown_timer)
- stop_service(service, TRUE);
- } else {
- services = g_slist_remove(services, service);
- service_free(service);
- }
+ services = g_slist_remove(services, service);
+ service_free(service);
return 0;
}
-static int unregister_service(struct service *service)
+static int do_unregister(struct service *service)
{
- return unregister_service_for_connection(get_dbus_connection(), service);
+ DBusConnection *conn = get_dbus_connection();
+
+ return unregister_service_for_connection(conn, service);
}
void release_services(DBusConnection *conn)
{
debug("release_services");
- g_slist_foreach(services, (GFunc) unregister_service, NULL);
+ g_slist_foreach(services, (GFunc) do_unregister, NULL);
g_slist_free(services);
services = NULL;
}
@@ -856,9 +459,6 @@ struct service *search_service(const char *pattern)
if (service->ident && !strcmp(service->ident, pattern))
return service;
-
- if (service->bus_name && !strcmp(service->bus_name, pattern))
- return service;
}
return NULL;
@@ -876,188 +476,97 @@ void append_available_services(DBusMessageIter *array_iter)
}
}
-static struct service *create_service(const char *file)
+int service_unregister(DBusConnection *conn, struct service *service)
+{
+ return unregister_service_for_connection(conn, service);
+}
+
+static struct service *create_external_service(const char *ident)
{
- GKeyFile *keyfile;
- GError *err = NULL;
struct service *service;
- gboolean autostart;
- const char *slash;
+ const char *name;
service = g_try_new0(struct service, 1);
if (!service) {
- error("OOM while allocating new service");
+ error("OOM while allocating new external service");
return NULL;
}
- service->external = FALSE;
-
- keyfile = g_key_file_new();
-
- if (!g_key_file_load_from_file(keyfile, file, 0, &err)) {
- error("Parsing %s failed: %s", file, err->message);
- g_error_free(err);
- goto failed;
- }
-
- service->ident = g_key_file_get_string(keyfile, SERVICE_GROUP,
- "Identifier", &err);
- if (err) {
- debug("%s: %s", file, err->message);
- g_error_free(err);
- goto failed;
- }
-
- service->name = g_key_file_get_string(keyfile, SERVICE_GROUP,
- "Name", &err);
- if (!service->name) {
- error("%s: %s", file, err->message);
- g_error_free(err);
- goto failed;
- }
-
- slash = strrchr(file, '/');
- if (!slash) {
- error("No slash in service file path!?");
- goto failed;
- }
-
- service->filename = g_strdup(slash + 1);
-
- service->descr = g_key_file_get_string(keyfile, SERVICE_GROUP,
- "Description", &err);
- if (err) {
- debug("%s: %s", file, err->message);
- g_error_free(err);
- err = NULL;
- }
-
- autostart = g_key_file_get_boolean(keyfile, SERVICE_GROUP,
- "Autostart", &err);
- if (err) {
- debug("%s: %s", file, err->message);
- g_error_free(err);
- err = NULL;
- } else
- service->autostart = autostart;
+ if (!strcmp(ident, "input"))
+ name = "Input service";
+ else if (!strcmp(ident, "audio"))
+ name = "Audio service";
+ else if (!strcmp(ident, "network"))
+ name = "Network service";
+ else if (!strcmp(ident, "serial"))
+ name = "Serial service";
+ else
+ name = "";
- g_key_file_free(keyfile);
+ service->ident = g_strdup(ident);
+ service->name = g_strdup(name);
return service;
-
-failed:
- g_key_file_free(keyfile);
- service_free(service);
- return NULL;
-}
-
-static gint service_filename_cmp(struct service *service, const char *filename)
-{
- return strcmp(service->filename, filename);
}
-int init_services(const char *path)
+int register_service(const char *ident)
{
- DIR *d;
- struct dirent *e;
-
- d = opendir(path);
- if (!d) {
- error("Unable to open service dir %s: %s", path, strerror(errno));
- return -1;
- }
-
- while ((e = readdir(d)) != NULL) {
- char full_path[PATH_MAX];
- struct service *service;
- size_t len = strlen(e->d_name);
-
- if (len < (strlen(SERVICE_SUFFIX) + 1))
- continue;
-
- /* Skip if the file doesn't end in .service */
- if (strcmp(&e->d_name[len - strlen(SERVICE_SUFFIX)], SERVICE_SUFFIX))
- continue;
-
- snprintf(full_path, sizeof(full_path) - 1, "%s/%s", path, e->d_name);
+ DBusConnection *conn = get_dbus_connection();
+ struct service *service;
+ char obj_path[PATH_MAX];
+ int i;
- service = create_service(full_path);
- if (!service) {
- error("Unable to read %s", full_path);
- continue;
- }
+ if (g_slist_find_custom(services, ident,
+ (GCompareFunc) service_cmp_ident))
+ return -EADDRINUSE;
- if (register_service(service) < 0) {
- error("Unable to register service");
- service_free(service);
- continue;
- }
+ snprintf(obj_path, sizeof(obj_path) - 1,
+ "/org/bluez/service_%s", ident);
- if (service->autostart)
- service_start(service, get_dbus_connection());
+ /* Make the path valid for D-Bus */
+ for (i = strlen("/org/bluez/"); obj_path[i]; i++) {
+ if (!isalnum(obj_path[i]))
+ obj_path[i] = '_';
}
- closedir(d);
+ if (g_slist_find_custom(services, obj_path,
+ (GCompareFunc) service_cmp_path))
+ return -EADDRINUSE;
- return 0;
-}
+ service = create_external_service(ident);
-static struct service *create_external_service(const char *ident,
- const char *name, const char *description)
-{
- struct service *service;
+ debug("Registering service object: %s (%s)",
+ service->ident, obj_path);
- service = g_try_new0(struct service, 1);
- if (!service) {
- error("OOM while allocating new external service");
- return NULL;
+ if (!dbus_connection_create_object_path(conn, obj_path,
+ service, NULL)) {
+ error("D-Bus failed to register %s object", obj_path);
+ return -1;
}
- service->filename = NULL;
- service->name = g_strdup(name);
- service->descr = g_strdup(description);
- service->ident = g_strdup(ident);
-
- service->external = TRUE;
-
- return service;
-}
-
-int service_register(DBusConnection *conn, const char *bus_name, const char *ident,
- const char *name, const char *description)
-{
- struct service *service;
- const char *sender;
-
- service = create_external_service(ident, name, description);
- if (!service)
+ if (!service_init(conn, obj_path)) {
+ error("Service init failed");
return -1;
+ }
- if (!bus_name) {
- sender = dbus_bus_get_unique_name(get_dbus_connection());
- service->bus_name = g_strdup(sender);
- } else
- service->bus_name = g_strdup(bus_name);
+ service->object_path = g_strdup(obj_path);
- if (register_service(service) < 0) {
- service_free(service);
- return -1;
- }
+ services = g_slist_append(services, service);
- if (conn && bus_name)
- name_listener_add(conn, bus_name, (name_cb_t) external_service_exit,
- service);
+ dbus_connection_emit_signal(conn, BASE_PATH, MANAGER_INTERFACE,
+ "ServiceAdded",
+ DBUS_TYPE_STRING, &service->object_path,
+ DBUS_TYPE_INVALID);
- dbus_connection_emit_signal(get_dbus_connection(), service->object_path,
- SERVICE_INTERFACE, "Started",
- DBUS_TYPE_INVALID);
+ dbus_connection_emit_signal(conn, service->object_path,
+ SERVICE_INTERFACE,
+ "Started", DBUS_TYPE_INVALID);
return 0;
}
-int service_unregister(DBusConnection *conn, struct service *service)
+void unregister_service(const char *ident)
{
- return unregister_service_for_connection(conn, service);
}
static gint name_cmp(struct service_uuids *su, const char *name)
@@ -1098,16 +607,16 @@ struct service *search_service_by_uuid(const char *uuid)
return service;
}
-void register_uuids(const char *name, const char **uuids)
+void register_uuids(const char *ident, const char **uuids)
{
struct service_uuids *su;
int i;
- if (!name)
+ if (!ident)
return;
su = g_new0(struct service_uuids, 1);
- su->name = g_strdup(name);
+ su->name = g_strdup(ident);
for (i = 0; uuids[i]; i++);
@@ -1134,7 +643,7 @@ static void service_uuids_free(struct service_uuids *su)
g_free(su);
}
-void unregister_uuids(const char *name)
+void unregister_uuids(const char *ident)
{
struct service_uuids *su;
GSList *l;
@@ -1142,7 +651,7 @@ void unregister_uuids(const char *name)
if (!services_uuids)
return;
- l = g_slist_find_custom(services_uuids, name, (GCompareFunc) name_cmp);
+ l = g_slist_find_custom(services_uuids, ident, (GCompareFunc) name_cmp);
if (!l)
return;
diff --git a/hcid/dbus-service.h b/hcid/dbus-service.h
index 72a23f25..c96179ea 100644
--- a/hcid/dbus-service.h
+++ b/hcid/dbus-service.h
@@ -22,29 +22,10 @@
*
*/
-#define START_REPLY_TIMEOUT 5000
-
struct service {
- char *filename;
char *object_path;
-
- DBusMessage *action; /* Either Start or Stop method call */
-
- guint startup_timer;
- guint shutdown_timer;
-
- /* These are set when the service is running */
- GPid pid; /* Process id */
- char *bus_name; /* D-Bus unique name */
-
- /* Information parsed from the service file */
- char *name;
- char *descr;
char *ident;
- gboolean autostart;
-
- /* Services without a *.service file */
- gboolean external;
+ char *name;
};
void release_services(DBusConnection *conn);
@@ -55,17 +36,13 @@ struct service *search_service(const char *pattern);
struct service *search_service_by_uuid(const char *uuid);
-int service_start(struct service *service, DBusConnection *conn);
-
-int init_services(const char *path);
-
-int service_register(DBusConnection *conn, const char *bus_name, const char *ident,
- const char *name, const char *description);
-
int service_unregister(DBusConnection *conn, struct service *service);
-void register_uuids(const char *name, const char **uuids);
-void unregister_uuids(const char *name);
+int register_service(const char *ident);
+void unregister_service(const char *ident);
+
+void register_uuids(const char *ident, const char **uuids);
+void unregister_uuids(const char *ident);
typedef void (*service_auth_cb) (DBusError *derr, void *user_data);
int service_req_auth(bdaddr_t *src, bdaddr_t *dst,
diff --git a/hcid/main.c b/hcid/main.c
index 9980cc4e..980afec2 100644
--- a/hcid/main.c
+++ b/hcid/main.c
@@ -922,8 +922,6 @@ int main(int argc, char *argv[])
* daemon needs to be re-worked. */
plugin_init();
- init_services(CONFIGDIR);
-
/* Start event processor */
g_main_loop_run(event_loop);
diff --git a/hcid/manager.c b/hcid/manager.c
index d470e53b..c4288278 100644
--- a/hcid/manager.c
+++ b/hcid/manager.c
@@ -312,8 +312,10 @@ static DBusHandlerResult list_services(DBusConnection *conn,
static DBusHandlerResult activate_service(DBusConnection *conn,
DBusMessage *msg, void *data)
{
+ DBusMessage *reply;
const char *pattern;
struct service *service;
+ const char *busname = "org.bluez";
if (!dbus_message_get_args(msg, NULL,
DBUS_TYPE_STRING, &pattern,
@@ -324,29 +326,14 @@ static DBusHandlerResult activate_service(DBusConnection *conn,
if (!service)
return error_no_such_service(conn, msg);
- if (service->bus_name) {
- DBusMessage *reply;
-
- reply = dbus_message_new_method_return(msg);
- if (!reply)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
-
- dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &service->bus_name,
- DBUS_TYPE_INVALID);
-
- return send_message_and_unref(conn, reply);
- }
-
- if (service->pid)
- return error_service_start_in_progress(conn, msg);
-
- if (service_start(service, conn) < 0)
- return error_failed_errno(conn, msg, ENOEXEC);
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
- service->action = dbus_message_ref(msg);
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &busname,
+ DBUS_TYPE_INVALID);
- return DBUS_HANDLER_RESULT_HANDLED;
+ return send_message_and_unref(conn, reply);
}
static DBusMethodVTable old_manager_methods[] = {