4 * Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
5 * Copyright (C) 2008 Nedko Arnaudov
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "dbus/object_path.h"
27 #include "common/safety.h"
28 #include "common/debug.h"
29 #include "dbus/introspection.h" /* g_dbus_interface_dtor_introspectable */
30 #include "dbus/error.h" /* lash_dbus_error() */
32 static DBusHandlerResult
33 object_path_handler(DBusConnection
*connection
,
38 object_path_handler_unregister(DBusConnection
*conn
,
42 object_path_new(const char *name
,
47 if (!name
|| !name
[0] || num_ifaces
< 1) {
48 lash_debug("Invalid arguments");
52 lash_debug("Creating object path");
56 const interface_t
**iface_pptr
;
58 path
= lash_malloc(1, sizeof(object_path_t
));
59 path
->name
= lash_strdup(name
);
60 path
->interfaces
= lash_malloc(num_ifaces
+ 2, sizeof(interface_t
*));
62 va_start(argp
, num_ifaces
);
64 iface_pptr
= path
->interfaces
;
65 *iface_pptr
= &g_dbus_interface_dtor_introspectable
;
67 (*iface_pptr
= va_arg(argp
, const interface_t
*));
72 if ((path
->introspection
= introspection_new(path
))) {
73 path
->context
= context
;
77 lash_error("Failed to create object path");
78 object_path_destroy(path
);
84 object_path_register(DBusConnection
*conn
,
87 if (!conn
|| !path
|| !path
->name
|| !path
->interfaces
) {
88 lash_debug("Invalid arguments");
92 lash_debug("Registering object path");
94 DBusObjectPathVTable vtable
=
96 object_path_handler_unregister
,
98 NULL
, NULL
, NULL
, NULL
101 dbus_connection_register_object_path(conn
, path
->name
,
102 &vtable
, (void *) path
);
108 object_path_destroy(object_path_t
*path
)
110 lash_debug("Destroying object path");
117 if (path
->interfaces
) {
118 free(path
->interfaces
);
119 path
->interfaces
= NULL
;
121 introspection_destroy(path
);
127 lash_debug("Nothing to destroy");
132 static DBusHandlerResult
133 object_path_handler(DBusConnection
*connection
,
134 DBusMessage
*message
,
137 const char *interface_name
;
138 const interface_t
**iface_pptr
;
141 /* Check if the message is a method call. If not, ignore it. */
142 if (dbus_message_get_type(message
) != DBUS_MESSAGE_TYPE_METHOD_CALL
) {
146 /* Get the invoked method's name and make sure it's non-NULL. */
147 if (!(call
.method_name
= dbus_message_get_member(message
))) {
148 lash_dbus_error(&call
, LASH_DBUS_ERROR_UNKNOWN_METHOD
,
149 "Received method call with empty method name");
153 /* Initialize our data. */
154 call
.connection
= connection
;
155 call
.message
= message
;
156 call
.interface
= NULL
; /* To be set by the default interface handler */
160 /* Check if there's an interface specified for this method call. */
161 if ((interface_name
= dbus_message_get_interface(message
))) {
162 for (iface_pptr
= (const interface_t
**) ((object_path_t
*) data
)->interfaces
;
163 iface_pptr
&& *iface_pptr
;
165 if (strcmp(interface_name
, (*iface_pptr
)->name
) == 0) {
166 if ((*iface_pptr
)->handler(*iface_pptr
, &call
)) {
176 /* No interface was specified so we have to try them all. This is
177 * dictated by the D-Bus specification which states that method calls
178 * omitting the interface must never be rejected.
181 for (iface_pptr
= (const interface_t
**) ((object_path_t
*) data
)->interfaces
;
182 iface_pptr
&& *iface_pptr
;
184 if ((*iface_pptr
)->handler(*iface_pptr
, &call
)) {
190 lash_dbus_error(&call
, LASH_DBUS_ERROR_UNKNOWN_METHOD
,
191 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist",
192 call
.method_name
, dbus_message_get_signature(message
), interface_name
);
195 method_return_send(&call
);
198 return DBUS_HANDLER_RESULT_HANDLED
;
202 object_path_handler_unregister(DBusConnection
*conn
,
206 object_path_t
*path
= data
;
207 lash_debug("Message handler of object path %s was unregistered",
208 (path
&& path
->name
) ? path
->name
: "<unknown>");
209 #endif /* LASH_DEBUG */