Commit ee1133de authored by Anders Carlsson's avatar Anders Carlsson

2003-01-27 Anders Carlsson <andersca@codefactory.se>

	* bus/dispatch.c: (bus_dispatch_message_handler):
	Dispatch messages sent to services.

	* bus/driver.c: (bus_driver_send_service_deleted),
	(bus_driver_send_service_created), (bus_driver_send_service_lost),
	(bus_driver_send_service_acquired):
	Add helper functions for sending service related messages.

	(bus_driver_send_welcome_message):
	Send HELLO_REPLY instead of WELCOME.

	(bus_driver_handle_list_services):
	Send LIST_SERVICES_REPLY instead of SERVICES.

	(bus_driver_handle_own_service),
	(bus_driver_handle_service_exists):
	New message handlers.

	(bus_driver_handle_message):
	Invoke new message handlers.

	(bus_driver_remove_connection):
	Don't remove any services here since that's done automatically
	by bus_service_remove_owner now.

	* bus/driver.h:
	New function signatures.

	* bus/services.c: (bus_service_add_owner):
	Send ServiceAcquired message if we're the only primary owner.

	(bus_service_remove_owner):
	Send ServiceAcquired/ServiceLost messages.

	(bus_service_set_prohibit_replacement),
	(bus_service_get_prohibit_replacement):
	Functions for setting prohibit replacement.

	(bus_service_has_owner):
	New function that checks if a connection is in the owner queue of
	a certain service.

	* bus/services.h:
	Add new function signatures.

	* dbus/dbus-list.c: (_dbus_list_test):
	Add tests for _dbus_list_remove_last and traversing the list backwards.

	* dbus/dbus-list.h:
	Fix a typo in _dbus_list_get_prev_link, if we're at the first element we can't
	go any further, so return NULL then.

	* dbus/dbus-protocol.h:
	Add new messages, service flags and service replies.
parent 2f440457
2003-01-27 Anders Carlsson <andersca@codefactory.se>
* bus/dispatch.c: (bus_dispatch_message_handler):
Dispatch messages sent to services.
* bus/driver.c: (bus_driver_send_service_deleted),
(bus_driver_send_service_created), (bus_driver_send_service_lost),
(bus_driver_send_service_acquired):
Add helper functions for sending service related messages.
(bus_driver_send_welcome_message):
Send HELLO_REPLY instead of WELCOME.
(bus_driver_handle_list_services):
Send LIST_SERVICES_REPLY instead of SERVICES.
(bus_driver_handle_own_service),
(bus_driver_handle_service_exists):
New message handlers.
(bus_driver_handle_message):
Invoke new message handlers.
(bus_driver_remove_connection):
Don't remove any services here since that's done automatically
by bus_service_remove_owner now.
* bus/driver.h:
New function signatures.
* bus/services.c: (bus_service_add_owner):
Send ServiceAcquired message if we're the only primary owner.
(bus_service_remove_owner):
Send ServiceAcquired/ServiceLost messages.
(bus_service_set_prohibit_replacement),
(bus_service_get_prohibit_replacement):
Functions for setting prohibit replacement.
(bus_service_has_owner):
New function that checks if a connection is in the owner queue of
a certain service.
* bus/services.h:
Add new function signatures.
* dbus/dbus-list.c: (_dbus_list_test):
Add tests for _dbus_list_remove_last and traversing the list backwards.
* dbus/dbus-list.h:
Fix a typo in _dbus_list_get_prev_link, if we're at the first element we can't
go any further, so return NULL then.
* dbus/dbus-protocol.h:
Add new messages, service flags and service replies.
2003-01-26 Havoc Pennington <hp@pobox.com>
* dbus/dbus-message-builder.c: implement, completely untested.
......
......@@ -50,16 +50,16 @@ bus_dispatch_message_handler (DBusMessageHandler *handler,
DBusMessage *message,
void *user_data)
{
const char *sender, *service;
const char *sender, *service_name;
/* Assign a sender to the message */
sender = bus_connection_get_name (connection);
_DBUS_HANDLE_OOM (dbus_message_set_sender (message, sender));
service = dbus_message_get_service (message);
service_name = dbus_message_get_service (message);
/* See if the message is to the driver */
if (strcmp (service, DBUS_SERVICE_DBUS) == 0)
if (strcmp (service_name, DBUS_SERVICE_DBUS) == 0)
{
bus_driver_handle_message (connection, message);
}
......@@ -68,13 +68,23 @@ bus_dispatch_message_handler (DBusMessageHandler *handler,
_dbus_verbose ("Received message from non-registered client. Disconnecting.\n");
dbus_connection_disconnect (connection);
}
else if (strcmp (service, DBUS_SERVICE_BROADCAST) == 0)
else if (strcmp (service_name, DBUS_SERVICE_BROADCAST) == 0)
{
bus_dispatch_broadcast_message (message);
}
else
{
DBusString service_string;
BusService *service;
_dbus_string_init_const (&service_string, service_name);
service = bus_service_lookup (&service_string, FALSE);
_dbus_assert (bus_service_get_primary_owner (service) != NULL);
/* Dispatch the message */
_DBUS_HANDLE_OOM (dbus_connection_send_message (bus_service_get_primary_owner (service),
message, NULL, NULL));
}
return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
......@@ -118,7 +128,7 @@ bus_dispatch_remove_connection (DBusConnection *connection)
{
/* Here we tell the bus driver that we want to get off. */
bus_driver_remove_connection (connection);
dbus_connection_set_data (connection,
message_handler_slot,
NULL, NULL);
......
......@@ -32,12 +32,12 @@
static void bus_driver_send_welcome_message (DBusConnection *connection,
DBusMessage *hello_message);
static void
bus_driver_send_service_deleted (DBusConnection *connection, const char *name)
void
bus_driver_send_service_deleted (const char *service_name)
{
DBusMessage *message;
_dbus_verbose ("sending service deleted: %s\n", name);
_dbus_verbose ("sending service deleted: %s\n", service_name);
_DBUS_HANDLE_OOM (message = dbus_message_new (DBUS_SERVICE_BROADCAST,
DBUS_MESSAGE_SERVICE_DELETED));
......@@ -45,14 +45,14 @@ bus_driver_send_service_deleted (DBusConnection *connection, const char *name)
_DBUS_HANDLE_OOM (dbus_message_set_sender (message, DBUS_SERVICE_DBUS));
_DBUS_HANDLE_OOM (dbus_message_append_fields (message,
DBUS_TYPE_STRING, name,
DBUS_TYPE_STRING, service_name,
0));
bus_dispatch_broadcast_message (message);
dbus_message_unref (message);
}
static void
bus_driver_send_service_created (DBusConnection *connection, const char *name)
bus_driver_send_service_created (const char *service_name)
{
DBusMessage *message;
......@@ -62,12 +62,48 @@ bus_driver_send_service_created (DBusConnection *connection, const char *name)
_DBUS_HANDLE_OOM (dbus_message_set_sender (message, DBUS_SERVICE_DBUS));
_DBUS_HANDLE_OOM (dbus_message_append_fields (message,
DBUS_TYPE_STRING, name,
DBUS_TYPE_STRING, service_name,
0));
bus_dispatch_broadcast_message (message);
dbus_message_unref (message);
}
void
bus_driver_send_service_lost (DBusConnection *connection,
const char *service_name)
{
DBusMessage *message;
_DBUS_HANDLE_OOM (message = dbus_message_new (DBUS_SERVICE_BROADCAST,
DBUS_MESSAGE_SERVICE_LOST));
_DBUS_HANDLE_OOM (dbus_message_set_sender (message, DBUS_SERVICE_DBUS));
_DBUS_HANDLE_OOM (dbus_message_append_fields (message,
DBUS_TYPE_STRING, service_name,
0));
_DBUS_HANDLE_OOM (dbus_connection_send_message (connection, message, NULL, NULL));
dbus_message_unref (message);
}
void
bus_driver_send_service_acquired (DBusConnection *connection,
const char *service_name)
{
DBusMessage *message;
_DBUS_HANDLE_OOM (message = dbus_message_new (DBUS_SERVICE_BROADCAST,
DBUS_MESSAGE_SERVICE_ACQUIRED));
_DBUS_HANDLE_OOM (dbus_message_set_sender (message, DBUS_SERVICE_DBUS));
_DBUS_HANDLE_OOM (dbus_message_append_fields (message,
DBUS_TYPE_STRING, service_name,
0));
_DBUS_HANDLE_OOM (dbus_connection_send_message (connection, message, NULL, NULL));
dbus_message_unref (message);
}
static dbus_bool_t
create_unique_client_name (const char *name,
DBusString *str)
......@@ -158,7 +194,8 @@ bus_driver_handle_hello (DBusConnection *connection,
/* Create the service */
_DBUS_HANDLE_OOM (service = bus_service_lookup (&unique_name, TRUE));
bus_service_set_prohibit_replacement (service, TRUE);
/* Add the connection as the owner */
_DBUS_HANDLE_OOM (bus_service_add_owner (service, connection));
_DBUS_HANDLE_OOM (bus_connection_set_name (connection, &unique_name));
......@@ -171,7 +208,7 @@ bus_driver_handle_hello (DBusConnection *connection,
_DBUS_HANDLE_OOM (bus_driver_send_welcome_message (connection, message));
/* Broadcast a service created message */
bus_driver_send_service_created (connection, bus_service_get_name (service));
bus_driver_send_service_created (bus_service_get_name (service));
}
static void
......@@ -184,7 +221,7 @@ bus_driver_send_welcome_message (DBusConnection *connection,
name = bus_connection_get_name (connection);
_dbus_assert (name != NULL);
_DBUS_HANDLE_OOM (welcome = dbus_message_new_reply (DBUS_MESSAGE_WELCOME,
_DBUS_HANDLE_OOM (welcome = dbus_message_new_reply (DBUS_MESSAGE_HELLO_REPLY,
hello_message));
_DBUS_HANDLE_OOM (dbus_message_set_sender (welcome, DBUS_SERVICE_DBUS));
......@@ -206,7 +243,7 @@ bus_driver_handle_list_services (DBusConnection *connection,
int len, i;
char **services;
_DBUS_HANDLE_OOM (reply = dbus_message_new_reply (DBUS_MESSAGE_SERVICES, message));
_DBUS_HANDLE_OOM (reply = dbus_message_new_reply (DBUS_MESSAGE_LIST_SERVICES_REPLY, message));
_DBUS_HANDLE_OOM (services = bus_services_list (&len));
......@@ -226,26 +263,125 @@ bus_driver_handle_list_services (DBusConnection *connection,
}
}
void
bus_driver_remove_connection (DBusConnection *connection)
static void
bus_driver_handle_own_service (DBusConnection *connection,
DBusMessage *message)
{
BusService *service;
DBusMessage *reply;
DBusResultCode result;
DBusString service_name;
const char *name;
BusService *service;
char *name;
int service_reply;
int flags;
_DBUS_HANDLE_OOM ((result = dbus_message_get_fields (message,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_UINT32, &flags,
0)) != DBUS_RESULT_NO_MEMORY);
if (result != DBUS_RESULT_SUCCESS)
{
dbus_free (name);
dbus_connection_disconnect (connection);
return;
}
name = bus_connection_get_name (connection);
_dbus_verbose ("Trying to own service %s with flags %d\n", name, flags);
if (name == NULL)
return;
_dbus_string_init_const (&service_name, name);
service = bus_service_lookup (&service_name, TRUE);
_DBUS_HANDLE_OOM ((reply = dbus_message_new_reply (DBUS_MESSAGE_ACQUIRE_SERVICE_REPLY, message)));
service = bus_service_lookup (&service_name, FALSE);
/*
* Check if the service already has an owner
*/
if (bus_service_get_primary_owner (service) != NULL)
{
if (bus_service_has_owner (service, connection))
service_reply = DBUS_SERVICE_REPLY_ALREADY_OWNER;
else if (!(flags & DBUS_SERVICE_FLAG_REPLACE_EXISTING))
service_reply = DBUS_SERVICE_REPLY_SERVICE_EXISTS;
else
{
if (bus_service_get_prohibit_replacement (service))
{
/* Queue the connection */
_DBUS_HANDLE_OOM (bus_service_add_owner (service, connection));
service_reply = DBUS_SERVICE_REPLY_IN_QUEUE;
}
else
{
DBusConnection *owner;
/* We can replace the primary owner */
owner = bus_service_get_primary_owner (service);
/* We enqueue the new owner and remove the first one because
* that will cause ServiceAcquired and ServiceLost messages to
* be sent.
*/
_DBUS_HANDLE_OOM (bus_service_add_owner (service, connection));
bus_service_remove_owner (service, owner);
_dbus_assert (connection == bus_service_get_primary_owner (service));
}
}
}
else
{
bus_service_set_prohibit_replacement (service,
(flags & DBUS_SERVICE_FLAG_PROHIBIT_REPLACEMENT));
/* Broadcast service created message */
bus_driver_send_service_created (bus_service_get_name (service));
_DBUS_HANDLE_OOM (bus_service_add_owner (service, connection));
service_reply = DBUS_SERVICE_REPLY_PRIMARY_OWNER;
}
/* Send service reply */
_DBUS_HANDLE_OOM (dbus_connection_send_message (connection, reply, NULL, NULL));
dbus_free (name);
dbus_message_unref (reply);
}
bus_driver_send_service_deleted (connection, name);
static void
bus_driver_handle_service_exists (DBusConnection *connection,
DBusMessage *message)
{
DBusMessage *reply;
DBusResultCode result;
DBusString service_name;
BusService *service;
char *name;
if (service)
bus_service_free (service);
_DBUS_HANDLE_OOM ((result = dbus_message_get_fields (message,
DBUS_TYPE_STRING, &name,
0)) != DBUS_RESULT_NO_MEMORY);
if (result != DBUS_RESULT_SUCCESS)
{
dbus_free (name);
dbus_connection_disconnect (connection);
return;
}
_dbus_string_init_const (&service_name, name);
service = bus_service_lookup (&service_name, FALSE);
_DBUS_HANDLE_OOM ((reply = dbus_message_new_reply (DBUS_MESSAGE_ACQUIRE_SERVICE_REPLY, message)));
_DBUS_HANDLE_OOM (dbus_message_set_sender (message, DBUS_SERVICE_DBUS));
_DBUS_HANDLE_OOM (dbus_message_append_fields (message,
DBUS_TYPE_UINT32, (service != NULL ? 1 : 0),
0));
_DBUS_HANDLE_OOM (dbus_connection_send_message (connection, message, NULL, NULL));
dbus_message_unref (message);
dbus_free (name);
}
void
......@@ -272,4 +408,15 @@ bus_driver_handle_message (DBusConnection *connection,
bus_driver_handle_hello (connection, message);
else if (strcmp (name, DBUS_MESSAGE_LIST_SERVICES) == 0)
bus_driver_handle_list_services (connection, message);
else if (strcmp (name, DBUS_MESSAGE_ACQUIRE_SERVICE) == 0)
bus_driver_handle_own_service (connection, message);
else if (strcmp (name, DBUS_MESSAGE_SERVICE_EXISTS) == 0)
bus_driver_handle_service_exists (connection, message);
}
void
bus_driver_remove_connection (DBusConnection *connection)
{
/* Does nothing for now */
}
......@@ -26,8 +26,15 @@
#include <dbus/dbus.h>
void bus_driver_handle_message (DBusConnection *connection,
DBusMessage *message);
void bus_driver_remove_connection (DBusConnection *connection);
void bus_driver_remove_connection (DBusConnection *connection);
void bus_driver_handle_message (DBusConnection *connection,
DBusMessage *message);
void bus_driver_send_service_deleted (const char *service_name);
void bus_driver_send_service_lost (DBusConnection *connection,
const char *service_name);
void bus_driver_send_service_acquired (DBusConnection *connection,
const char *service_name);
#endif /* BUS_DRIVER_H */
......@@ -2,6 +2,7 @@
/* services.c Service management
*
* Copyright (C) 2003 Red Hat, Inc.
* Copyright (C) 2003 CodeFactory AB
*
* Licensed under the Academic Free License version 1.2
*
......@@ -20,6 +21,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "driver.h"
#include "services.h"
#include "connection.h"
#include <dbus/dbus-hash.h>
......@@ -30,6 +32,8 @@ struct BusService
{
char *name;
DBusList *owners;
unsigned int prohibit_replacement:1;
};
static DBusHashTable *service_hash = NULL;
......@@ -98,17 +102,6 @@ bus_service_lookup (const DBusString *service_name,
return service;
}
void
bus_service_free (BusService *service)
{
_dbus_assert (service->owners == NULL);
_dbus_hash_table_remove_string (service_hash, service->name);
dbus_free (service->name);
_dbus_mem_pool_dealloc (service_pool, service);
}
dbus_bool_t
bus_service_add_owner (BusService *service,
DBusConnection *owner)
......@@ -123,6 +116,10 @@ bus_service_add_owner (BusService *service,
return FALSE;
}
/* Send service acquired message */
if (bus_service_get_primary_owner (service) == owner)
bus_driver_send_service_acquired (owner, service->name);
return TRUE;
}
......@@ -130,8 +127,29 @@ void
bus_service_remove_owner (BusService *service,
DBusConnection *owner)
{
/* Send service lost message */
if (bus_service_get_primary_owner (service) == owner)
bus_driver_send_service_lost (owner, service->name);
_dbus_list_remove_last (&service->owners, owner);
bus_connection_remove_owned_service (owner, service);
if (service->owners == NULL)
{
/* Delete service */
bus_driver_send_service_deleted (service->name);
_dbus_hash_table_remove_string (service_hash, service->name);
dbus_free (service->name);
_dbus_mem_pool_dealloc (service_pool, service);
}
else
{
/* Send service acquired to the new owner */
bus_driver_send_service_acquired (bus_service_get_primary_owner (service),
service->name);
}
}
DBusConnection*
......@@ -202,3 +220,37 @@ bus_services_list (int *array_len)
return NULL;
}
void
bus_service_set_prohibit_replacement (BusService *service,
dbus_bool_t prohibit_replacement)
{
_dbus_assert (service->owners == NULL);
service->prohibit_replacement = prohibit_replacement != FALSE;
}
dbus_bool_t
bus_service_get_prohibit_replacement (BusService *service)
{
return service->prohibit_replacement;
}
dbus_bool_t
bus_service_has_owner (BusService *service,
DBusConnection *owner)
{
DBusList *link;
link = _dbus_list_get_first_link (&service->owners);
while (link != NULL)
{
if (link->data == owner)
return TRUE;
link = _dbus_list_get_next_link (&service->owners, link);
}
return FALSE;
}
......@@ -38,17 +38,22 @@ typedef struct BusService BusService;
typedef void (* BusServiceForeachFunction) (BusService *service,
void *data);
BusService* bus_service_lookup (const DBusString *service_name,
dbus_bool_t create_if_not_found);
void bus_service_free (BusService *service);
dbus_bool_t bus_service_add_owner (BusService *service,
DBusConnection *owner);
void bus_service_remove_owner (BusService *service,
DBusConnection *owner);
DBusConnection* bus_service_get_primary_owner (BusService *service);
const char* bus_service_get_name (BusService *service);
void bus_service_foreach (BusServiceForeachFunction function,
void *data);
BusService* bus_service_lookup (const DBusString *service_name,
dbus_bool_t create_if_not_found);
dbus_bool_t bus_service_add_owner (BusService *service,
DBusConnection *owner);
void bus_service_remove_owner (BusService *service,
DBusConnection *owner);
dbus_bool_t bus_service_has_owner (BusService *service,
DBusConnection *owner);
DBusConnection* bus_service_get_primary_owner (BusService *service);
void bus_service_set_prohibit_replacement (BusService *service,
dbus_bool_t prohibit_replacement);
dbus_bool_t bus_service_get_prohibit_replacement (BusService *service);
const char* bus_service_get_name (BusService *service);
void bus_service_foreach (BusServiceForeachFunction function,
void *data);
char **bus_services_list (int *array_len);
......
......@@ -341,6 +341,7 @@ _dbus_list_remove_last (DBusList **list,
DBusList *link;
link = _dbus_list_get_last_link (list);
while (link != NULL)
{
if (link->data == data)
......@@ -884,10 +885,22 @@ _dbus_list_test (void)
link1 = _dbus_list_get_next_link (&list1, link1);
++i;
}
--i;
link1 = _dbus_list_get_last_link (&list1);
while (link1 != NULL)
{
verify_list (&link1); /* pretend this link is the head */
_dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i);
link1 = _dbus_list_get_prev_link (&list1, link1);
--i;
}
_dbus_list_clear (&list1);
_dbus_list_clear (&list2);
/* Test remove */
i = 0;
......@@ -1106,6 +1119,18 @@ _dbus_list_test (void)
_dbus_list_clear (&list1);
/* using remove_last */
_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (2));
_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (1));
_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (3));
_dbus_list_remove_last (&list1, _DBUS_INT_TO_POINTER (2));
verify_list (&list1);
_dbus_assert (is_ascending_sequence (&list1));
_dbus_list_clear (&list1);
return TRUE;
}
......
......@@ -71,7 +71,7 @@ void _dbus_list_foreach (DBusList **list,
void *data);
#define _dbus_list_get_next_link(list, link) ((link)->next == *(list) ? NULL : (link)->next)
#define _dbus_list_get_prev_link(list, link) ((link)->prev == *(list) ? NULL : (link)->prev)
#define _dbus_list_get_prev_link(list, link) ((link) == *(list) ? NULL : (link)->prev)
DBUS_END_DECLS;
......
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-protocol.h D-Bus protocol constants
*
* Copyright (C) 2002 CodeFactory AB
* Copyright (C) 2002, 2003 CodeFactory AB
*
* Licensed under the Academic Free License version 1.2
*
......@@ -59,14 +59,31 @@ extern "C" {
/* Services */
#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
#define DBUS_SERVICE_BROADCAST "org.freedesktop.DBus.Broadcast"
/* Service owner flags */
#define DBUS_SERVICE_FLAG_PROHIBIT_REPLACEMENT 0x1
#define DBUS_SERVICE_FLAG_REPLACE_EXISTING 0x2
/* Service replies */
#define DBUS_SERVICE_REPLY_PRIMARY_OWNER 0x1
#define DBUS_SERVICE_REPLY_IN_QUEUE 0x2
#define DBUS_SERVICE_REPLY_SERVICE_EXISTS 0x3
#define DBUS_SERVICE_REPLY_ALREADY_OWNER 0x4
/* Messages */
#define DBUS_MESSAGE_HELLO "org.freedesktop.DBus.Hello"
#define DBUS_MESSAGE_LIST_SERVICES "org.freedesktop.DBus.ListServices"
#define DBUS_MESSAGE_SERVICE_CREATED "org.freedesktop.DBus.ServiceCreated"
#define DBUS_MESSAGE_SERVICE_DELETED "org.freedesktop.DBus.ServiceDeleted"
#define DBUS_MESSAGE_SERVICES "org.freedesktop.DBus.Services"
#define DBUS_MESSAGE_WELCOME "org.freedesktop.DBus.Welcome"
#define DBUS_MESSAGE_SERVICE_EXISTS "org.freedesktop.DBus.ServiceExists"
#define DBUS_MESSAGE_SERVICE_EXISTS_REPLY "org.freedesktop.DBus.ServiceExists:Reply"
#define DBUS_MESSAGE_HELLO "org.freedesktop.DBus.Hello"
#define DBUS_MESSAGE_HELLO_REPLY "org.freedesktop.DBus.Hello:Reply"
#define DBUS_MESSAGE_LIST_SERVICES "org.freedesktop.DBus.ListServices"
#define DBUS_MESSAGE_LIST_SERVICES_REPLY "org.freedesktop.DBus.ListServices:Reply"
#define DBUS_MESSAGE_ACQUIRE_SERVICE "org.freedesktop.DBus.OwnService"
#define DBUS_MESSAGE_ACQUIRE_SERVICE_REPLY "org.freedesktop.DBus.OwnService:Reply"
#define DBUS_MESSAGE_SERVICE_ACQUIRED "org.freedesktop.DBus.ServiceAcquired"
#define DBUS_MESSAGE_SERVICE_CREATED "org.freedesktop.DBus.ServiceCreated"
#define DBUS_MESSAGE_SERVICE_DELETED "org.freedesktop.DBus.ServiceDeleted"
#define DBUS_MESSAGE_SERVICE_LOST "org.freedesktop.DBus.ServiceLost"
#ifdef __cplusplus
}
......