1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2008, 2009 Nedko Arnaudov <nedko@arnaudov.name>
6 * Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
8 **************************************************************************
9 * This file contains D-Bus object path helpers
10 **************************************************************************
12 * LADI Session Handler is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * LADI Session Handler is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
24 * or write to the Free Software Foundation, Inc.,
25 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include "object_path.h"
33 #include "../common/safety.h"
34 #include "../common/debug.h"
35 #include "introspection.h" /* g_dbus_interface_dtor_introspectable */
36 #include "error.h" /* lash_dbus_error() */
38 static DBusHandlerResult
39 object_path_handler(DBusConnection
*connection
,
44 object_path_handler_unregister(DBusConnection
*conn
,
48 object_path_new(const char *name
,
53 if (!name
|| !name
[0] || num_ifaces
< 0)
55 lash_error("Invalid arguments");
59 lash_debug("Creating object path");
63 const interface_t
**iface_pptr
;
65 path
= lash_malloc(1, sizeof(object_path_t
));
66 path
->name
= lash_strdup(name
);
67 path
->interfaces
= lash_malloc(num_ifaces
+ 2, sizeof(interface_t
*));
69 va_start(argp
, num_ifaces
);
71 iface_pptr
= path
->interfaces
;
72 *iface_pptr
++ = &g_dbus_interface_dtor_introspectable
;
73 while (num_ifaces
> 0)
75 *iface_pptr
++ = va_arg(argp
, const interface_t
*);
82 if ((path
->introspection
= introspection_new(path
))) {
83 path
->context
= context
;
87 lash_error("Failed to create object path");
88 object_path_destroy(NULL
, path
);
94 object_path_register(DBusConnection
*conn
,
97 if (!conn
|| !path
|| !path
->name
|| !path
->interfaces
) {
98 lash_debug("Invalid arguments");
102 lash_debug("Registering object path");
104 DBusObjectPathVTable vtable
=
106 object_path_handler_unregister
,
108 NULL
, NULL
, NULL
, NULL
111 dbus_connection_register_object_path(conn
, path
->name
,
112 &vtable
, (void *) path
);
117 void object_path_destroy(DBusConnection
* connection_ptr
, object_path_t
* path_ptr
)
119 lash_debug("Destroying object path");
123 if (connection_ptr
!= NULL
&& !dbus_connection_unregister_object_path(connection_ptr
, path_ptr
->name
))
125 lash_error("dbus_connection_unregister_object_path() failed.");
130 free(path_ptr
->name
);
131 path_ptr
->name
= NULL
;
134 if (path_ptr
->interfaces
)
136 free(path_ptr
->interfaces
);
137 path_ptr
->interfaces
= NULL
;
140 introspection_destroy(path_ptr
);
146 lash_debug("Nothing to destroy");
152 static DBusHandlerResult
153 object_path_handler(DBusConnection
*connection
,
154 DBusMessage
*message
,
157 const char *interface_name
;
158 const interface_t
**iface_pptr
;
161 /* Check if the message is a method call. If not, ignore it. */
162 if (dbus_message_get_type(message
) != DBUS_MESSAGE_TYPE_METHOD_CALL
) {
166 /* Get the invoked method's name and make sure it's non-NULL. */
167 if (!(call
.method_name
= dbus_message_get_member(message
))) {
168 lash_dbus_error(&call
, LASH_DBUS_ERROR_UNKNOWN_METHOD
,
169 "Received method call with empty method name");
173 /* Initialize our data. */
174 call
.connection
= connection
;
175 call
.message
= message
;
176 call
.interface
= NULL
; /* To be set by the default interface handler */
180 /* Check if there's an interface specified for this method call. */
181 if ((interface_name
= dbus_message_get_interface(message
))) {
182 for (iface_pptr
= (const interface_t
**) ((object_path_t
*) data
)->interfaces
;
183 iface_pptr
&& *iface_pptr
;
185 if (strcmp(interface_name
, (*iface_pptr
)->name
) == 0) {
186 if ((*iface_pptr
)->handler(*iface_pptr
, &call
)) {
196 /* No interface was specified so we have to try them all. This is
197 * dictated by the D-Bus specification which states that method calls
198 * omitting the interface must never be rejected.
201 for (iface_pptr
= (const interface_t
**) ((object_path_t
*) data
)->interfaces
;
202 iface_pptr
&& *iface_pptr
;
204 if ((*iface_pptr
)->handler(*iface_pptr
, &call
)) {
210 lash_dbus_error(&call
, LASH_DBUS_ERROR_UNKNOWN_METHOD
,
211 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist",
212 call
.method_name
, dbus_message_get_signature(message
), interface_name
);
215 method_return_send(&call
);
218 return DBUS_HANDLER_RESULT_HANDLED
;
222 object_path_handler_unregister(DBusConnection
*conn
,
226 object_path_t
*path
= data
;
227 lash_debug("Message handler of object path %s was unregistered",
228 (path
&& path
->name
) ? path
->name
: "<unknown>");
229 #endif /* LASH_DEBUG */