diff options
| author | Marcel Holtmann <marcel@holtmann.org> | 2007-01-24 05:38:40 +0000 | 
|---|---|---|
| committer | Marcel Holtmann <marcel@holtmann.org> | 2007-01-24 05:38:40 +0000 | 
| commit | 3021d8e125537fd3b14a5d50e0710bce17f8d198 (patch) | |
| tree | b899e4e247deb92223bd11e986a6defb7fc50b1f | |
| parent | bf9a0168854c71faff3e67c42c6265069230f6ce (diff) | |
Add support for internal debug services
| -rw-r--r-- | hcid/dbus-database.c | 30 | ||||
| -rw-r--r-- | hcid/dbus-service.c | 87 | ||||
| -rw-r--r-- | hcid/dbus-service.h | 6 | 
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 */ | 
