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 * Licensed under the Academic Free License version 2.1
14 * LADI Session Handler is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * LADI Session Handler is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
26 * or write to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include "../common.h"
31 #include "object_path.h"
32 #include "../common/safety.h"
33 #include "introspection.h" /* g_dbus_interface_dtor_introspectable */
34 #include "error.h" /* lash_dbus_error() */
36 static DBusHandlerResult
37 object_path_handler(DBusConnection
*connection
,
42 object_path_handler_unregister(DBusConnection
*conn
,
45 struct dbus_object_path
*
46 dbus_object_path_new(const char *name
,
51 if (!name
|| !name
[0] || num_ifaces
< 0)
53 lash_error("Invalid arguments");
57 lash_debug("Creating object path");
59 struct dbus_object_path
*path
;
61 const interface_t
**iface_pptr
;
63 path
= lash_malloc(1, sizeof(struct dbus_object_path
));
64 path
->name
= lash_strdup(name
);
65 path
->interfaces
= lash_malloc(num_ifaces
+ 2, sizeof(interface_t
*));
67 va_start(argp
, num_ifaces
);
69 iface_pptr
= path
->interfaces
;
70 *iface_pptr
++ = &g_dbus_interface_dtor_introspectable
;
71 while (num_ifaces
> 0)
73 *iface_pptr
++ = va_arg(argp
, const interface_t
*);
80 if ((path
->introspection
= introspection_new(path
))) {
81 path
->context
= context
;
85 lash_error("Failed to create object path");
86 dbus_object_path_destroy(NULL
, path
);
92 dbus_object_path_register(DBusConnection
*conn
,
93 struct dbus_object_path
*path
)
95 if (!conn
|| !path
|| !path
->name
|| !path
->interfaces
) {
96 lash_debug("Invalid arguments");
100 lash_debug("Registering object path");
102 DBusObjectPathVTable vtable
=
104 object_path_handler_unregister
,
106 NULL
, NULL
, NULL
, NULL
109 dbus_connection_register_object_path(conn
, path
->name
,
110 &vtable
, (void *) path
);
115 void dbus_object_path_destroy(DBusConnection
* connection_ptr
, struct dbus_object_path
* path_ptr
)
117 lash_debug("Destroying object path");
121 if (connection_ptr
!= NULL
&& !dbus_connection_unregister_object_path(connection_ptr
, path_ptr
->name
))
123 lash_error("dbus_connection_unregister_object_path() failed.");
128 free(path_ptr
->name
);
129 path_ptr
->name
= NULL
;
132 if (path_ptr
->interfaces
)
134 free(path_ptr
->interfaces
);
135 path_ptr
->interfaces
= NULL
;
138 introspection_destroy(path_ptr
);
144 lash_debug("Nothing to destroy");
150 static DBusHandlerResult
151 object_path_handler(DBusConnection
*connection
,
152 DBusMessage
*message
,
155 const char *interface_name
;
156 const interface_t
**iface_pptr
;
159 /* Check if the message is a method call. If not, ignore it. */
160 if (dbus_message_get_type(message
) != DBUS_MESSAGE_TYPE_METHOD_CALL
) {
164 /* Get the invoked method's name and make sure it's non-NULL. */
165 if (!(call
.method_name
= dbus_message_get_member(message
))) {
166 lash_dbus_error(&call
, LASH_DBUS_ERROR_UNKNOWN_METHOD
,
167 "Received method call with empty method name");
171 /* Initialize our data. */
172 call
.connection
= connection
;
173 call
.message
= message
;
174 call
.interface
= NULL
; /* To be set by the default interface handler */
178 /* Check if there's an interface specified for this method call. */
179 if ((interface_name
= dbus_message_get_interface(message
)))
181 for (iface_pptr
= (const interface_t
**) ((struct dbus_object_path
*) data
)->interfaces
;
182 iface_pptr
&& *iface_pptr
;
185 if (strcmp(interface_name
, (*iface_pptr
)->name
) == 0)
187 if ((*iface_pptr
)->handler(*iface_pptr
, &call
))
198 /* No interface was specified so we have to try them all. This is
199 * dictated by the D-Bus specification which states that method calls
200 * omitting the interface must never be rejected.
203 for (iface_pptr
= (const interface_t
**) ((struct dbus_object_path
*) data
)->interfaces
;
204 iface_pptr
&& *iface_pptr
;
206 if ((*iface_pptr
)->handler(*iface_pptr
, &call
)) {
212 lash_dbus_error(&call
, LASH_DBUS_ERROR_UNKNOWN_METHOD
,
213 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist",
214 call
.method_name
, dbus_message_get_signature(message
), interface_name
);
217 method_return_send(&call
);
220 return DBUS_HANDLER_RESULT_HANDLED
;
224 object_path_handler_unregister(DBusConnection
*conn
,
228 struct dbus_object_path
*path
= data
;
229 lash_debug("Message handler of object path %s was unregistered",
230 (path
&& path
->name
) ? path
->name
: "<unknown>");
231 #endif /* LASH_DEBUG */