diff options
| -rw-r--r-- | audio/main.c | 8 | ||||
| -rw-r--r-- | common/dbus.c | 42 | ||||
| -rw-r--r-- | hcid/dbus-common.c | 2 | ||||
| -rw-r--r-- | hcid/dbus-database.c | 39 | ||||
| -rw-r--r-- | hcid/dbus-error.c | 6 | ||||
| -rw-r--r-- | hcid/dbus-error.h | 1 | ||||
| -rw-r--r-- | hcid/dbus-service.c | 705 | ||||
| -rw-r--r-- | hcid/dbus-service.h | 35 | ||||
| -rw-r--r-- | hcid/main.c | 2 | ||||
| -rw-r--r-- | hcid/manager.c | 29 | ||||
| -rw-r--r-- | input/main.c | 8 | ||||
| -rw-r--r-- | network/main.c | 8 | ||||
| -rw-r--r-- | serial/main.c | 5 | 
13 files changed, 151 insertions, 739 deletions
| diff --git a/audio/main.c b/audio/main.c index eaa04806..f54f74de 100644 --- a/audio/main.c +++ b/audio/main.c @@ -96,15 +96,19 @@ static int audio_init(void)  	g_key_file_free(config); -	register_uuids("audio", uuids); +	register_service("audio"); -	register_external_service(conn, "audio", "Audio service", ""); +	register_uuids("audio", uuids);  	return 0;  }  static void audio_exit(void)  { +	unregister_uuids("audio"); + +	unregister_service("audio"); +  	audio_manager_exit();  	unix_exit(); diff --git a/common/dbus.c b/common/dbus.c index 53e1046b..5a59f8f2 100644 --- a/common/dbus.c +++ b/common/dbus.c @@ -877,45 +877,3 @@ int set_nonblocking(int fd)  	return 0;  } - -static void external_reply(DBusPendingCall *call, void *user_data) -{ -	DBusMessage *reply; - -	debug("Service register reply"); - -	reply = dbus_pending_call_steal_reply(call); - -	dbus_message_unref(reply); -} - -void register_external_service(DBusConnection *conn, const char *identifier, -				const char *name, const char *description) -{ -	DBusMessage *msg; -	DBusPendingCall *call; - -	info("Registering service"); - -	msg = dbus_message_new_method_call("org.bluez", "/org/bluez", -				"org.bluez.Database", "RegisterService"); -	if (!msg) { -		error("Can't create service register method"); -		return; -	} - -	dbus_message_append_args(msg, DBUS_TYPE_STRING, &identifier, -			DBUS_TYPE_STRING, &name, -			DBUS_TYPE_STRING, &description, DBUS_TYPE_INVALID); - -	if (dbus_connection_send_with_reply(conn, msg, &call, -1) == FALSE) { -		error("Can't register service"); -		dbus_message_unref(msg); -		return; -	} - -	dbus_pending_call_set_notify(call, external_reply, NULL, NULL); -	dbus_pending_call_unref(call); - -	dbus_message_unref(msg); -} 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[] = { diff --git a/input/main.c b/input/main.c index d8236ada..a98bc72f 100644 --- a/input/main.c +++ b/input/main.c @@ -55,15 +55,19 @@ static int input_init(void)  		return -EIO;  	} -	register_uuids("input", uuids); +	register_service("input"); -	register_external_service(conn, "input", "Input service", ""); +	register_uuids("input", uuids);  	return 0;  }  static void input_exit(void)  { +	unregister_uuids("input"); + +	unregister_service("input"); +  	input_manager_exit();  	dbus_connection_unref(conn); diff --git a/network/main.c b/network/main.c index 037ee062..54bdf3d6 100644 --- a/network/main.c +++ b/network/main.c @@ -180,15 +180,19 @@ static int network_init(void)  		return -EIO;  	} -	register_uuids("network", uuids); +	register_service("network"); -	register_external_service(conn, "network", "Network service", ""); +	register_uuids("network", uuids);  	return 0;  }  static void network_exit(void)  { +	unregister_uuids("network"); + +	unregister_service("network"); +  	network_manager_exit();  	dbus_connection_unref(conn); diff --git a/serial/main.c b/serial/main.c index 9d094123..0916f760 100644 --- a/serial/main.c +++ b/serial/main.c @@ -34,6 +34,7 @@  #include "plugin.h"  #include "dbus.h" +#include "dbus-service.h"  #include "manager.h"  static DBusConnection *conn; @@ -49,13 +50,15 @@ static int serial_init(void)  		return -EIO;  	} -	register_external_service(conn, "serial", "Serial service", ""); +	register_service("serial");  	return 0;  }  static void serial_exit(void)  { +	unregister_service("serial"); +  	serial_manager_exit();  	dbus_connection_unref(conn); | 
