aboutsummaryrefslogtreecommitdiff
path: root/src/lib/common/gnunet_dbus_lib_interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/common/gnunet_dbus_lib_interface.c')
-rw-r--r--src/lib/common/gnunet_dbus_lib_interface.c275
1 files changed, 275 insertions, 0 deletions
diff --git a/src/lib/common/gnunet_dbus_lib_interface.c b/src/lib/common/gnunet_dbus_lib_interface.c
new file mode 100644
index 0000000..bbc3467
--- /dev/null
+++ b/src/lib/common/gnunet_dbus_lib_interface.c
@@ -0,0 +1,275 @@
1#include "config.h"
2
3#include <dbus/dbus.h>
4
5#include <gnunet/platform.h>
6#include <gnunet/gnunet_common.h>
7#include <gnunet/gnunet_container_lib.h>
8
9#include "gnunet_dbus_lib.h"
10
11#define LOG(kind, ...) GNUNET_log_from (kind, "dbus-interface", __VA_ARGS__)
12
13struct GNUNET_DBUS_Interface
14{
15 struct GNUNET_DBUS_MethodIterator *methods_front;
16 struct GNUNET_DBUS_MethodIterator *methods_back;
17
18 struct GNUNET_DBUS_SignalIterator *signals_front;
19 struct GNUNET_DBUS_SignalIterator *signals_back;
20
21 char *name;
22 unsigned ref_count;
23};
24
25struct GNUNET_DBUS_Interface *
26GNUNET_DBUS_interface_create (
27 const char *name)
28{
29 LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating interface %s\n", name);
30
31 struct GNUNET_DBUS_Interface *interface = GNUNET_new (struct GNUNET_DBUS_Interface);
32
33 interface->methods_front = NULL;
34 interface->methods_back = NULL;
35 interface->name = GNUNET_strdup (name);
36 interface->ref_count = 1;
37
38 return interface;
39};
40
41void
42GNUNET_DBUS_interface_ref (
43 struct GNUNET_DBUS_Interface *interface)
44{
45 interface->ref_count++;
46};
47
48void
49GNUNET_DBUS_interface_unref (
50 struct GNUNET_DBUS_Interface *interface)
51{
52 if (interface->ref_count == 0)
53 {
54 LOG (GNUNET_ERROR_TYPE_ERROR, "Tried to unreference interface with ref count 0\n");
55 GNUNET_abort_ ();
56 };
57 if (0 == --(interface->ref_count))
58 {
59 LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying interface %s\n", interface->name);
60
61 struct GNUNET_DBUS_MethodIterator *methods_iter = interface->methods_front;
62 while (methods_iter)
63 {
64 struct GNUNET_DBUS_MethodIterator *next = methods_iter->next;
65 GNUNET_DBUS_method_unref (methods_iter->method);
66 GNUNET_free (methods_iter);
67 methods_iter = next;
68 };
69
70 GNUNET_free (interface->name);
71 GNUNET_free (interface);
72 }
73};
74
75void
76GNUNET_DBUS_interface_add_method (
77 struct GNUNET_DBUS_Interface *interface,
78 struct GNUNET_DBUS_Method *method)
79{
80 struct GNUNET_DBUS_MethodIterator *meth_it = GNUNET_new (struct GNUNET_DBUS_MethodIterator);
81 meth_it->method = method;
82 GNUNET_DBUS_method_ref (method);
83
84 GNUNET_CONTAINER_DLL_insert (interface->methods_front,
85 interface->methods_back,
86 meth_it);
87};
88
89void
90GNUNET_DBUS_interface_add_signal (
91 struct GNUNET_DBUS_Interface *interface,
92 struct GNUNET_DBUS_Signal *signal)
93{
94 struct GNUNET_DBUS_SignalIterator *sig_it = GNUNET_new (struct GNUNET_DBUS_SignalIterator);
95 sig_it->signal = signal;
96 GNUNET_DBUS_signal_ref (signal);
97
98 GNUNET_CONTAINER_DLL_insert (interface->signals_front,
99 interface->signals_back,
100 sig_it);
101};
102
103const char *
104GNUNET_DBUS_interface_get_name (
105 const struct GNUNET_DBUS_Interface *interface)
106{
107 return interface->name;
108};
109
110const struct GNUNET_DBUS_MethodIterator *
111GNUNET_DBUS_interface_iterate_methods (
112 const struct GNUNET_DBUS_Interface *interface)
113{
114 return interface->methods_front;
115};
116
117const struct GNUNET_DBUS_SignalIterator *
118GNUNET_DBUS_interface_iterate_signals (
119 const struct GNUNET_DBUS_Interface *interface)
120{
121 return interface->signals_front;
122}
123
124static void
125introspectable_introspect (
126 struct GNUNET_DBUS_MethodContext *mc)
127{
128 char *data = NULL;
129 char *new_data = NULL;
130
131 LOG (GNUNET_ERROR_TYPE_DEBUG, "Introspecting\n");
132 struct GNUNET_DBUS_Object *object = mc->object;
133
134 GNUNET_asprintf (&data, "%s", DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE);
135 GNUNET_asprintf (&new_data, "%s<node>\n", data);
136 GNUNET_free (data); data = new_data;
137
138 const struct GNUNET_DBUS_InterfaceIterator *int_it = GNUNET_DBUS_object_iterate_interfaces (object);
139 while (int_it)
140 {
141 struct GNUNET_DBUS_Interface *interface = int_it->interface;
142 const char *interface_name = GNUNET_DBUS_interface_get_name (interface);
143 GNUNET_asprintf (&new_data, "%s <interface name='%s'>\n", data, interface_name);
144 GNUNET_free (data); data = new_data;
145 const struct GNUNET_DBUS_MethodIterator *meth_it = GNUNET_DBUS_interface_iterate_methods (interface);
146 while (meth_it)
147 {
148 struct GNUNET_DBUS_Method *method = meth_it->method;
149 const char *method_name = GNUNET_DBUS_method_get_name (method);
150 GNUNET_asprintf (&new_data, "%s <method name='%s'>\n", data, method_name);
151 GNUNET_free (data); data = new_data;
152 const struct GNUNET_DBUS_ArgIterator *arg_it = GNUNET_DBUS_method_iterate_args (method);
153 while (arg_it)
154 {
155 struct GNUNET_DBUS_Arg *arg = arg_it->arg;
156 const char *arg_name = GNUNET_DBUS_arg_get_name (arg);
157 const char *signature = GNUNET_DBUS_arg_get_signature (arg);
158 GNUNET_asprintf (
159 &new_data,
160 "%s <arg name='%s' type='%s' direction='in'/>\n",
161 data,
162 arg_name,
163 signature);
164 GNUNET_free (data); data = new_data;
165 arg_it = arg_it->next;
166 };
167
168 arg_it = GNUNET_DBUS_method_iterate_return_args (method);
169 while (arg_it)
170 {
171 struct GNUNET_DBUS_Arg *arg = arg_it->arg;
172 const char *arg_name = GNUNET_DBUS_arg_get_name (arg);
173 const char *signature = GNUNET_DBUS_arg_get_signature (arg);
174 GNUNET_asprintf (
175 &new_data,
176 "%s <arg name='%s' type='%s' direction='out'/>\n",
177 data,
178 arg_name,
179 signature);
180 GNUNET_free (data); data = new_data;
181 arg_it = arg_it->next;
182 };
183 GNUNET_asprintf (&new_data, "%s </method>\n", data);
184 GNUNET_free (data); data = new_data;
185 meth_it = meth_it->next;
186 };
187 const struct GNUNET_DBUS_SignalIterator *sig_it = GNUNET_DBUS_interface_iterate_signals (interface);
188 while (sig_it)
189 {
190 struct GNUNET_DBUS_Signal *signal = sig_it->signal;
191 const char *signal_name = GNUNET_DBUS_signal_get_name (signal);
192 GNUNET_asprintf (&new_data, "%s <signal name='%s'>\n", data, signal_name);
193 GNUNET_free (data); data = new_data;
194 const struct GNUNET_DBUS_ArgIterator *arg_it = GNUNET_DBUS_signal_iterate_args (signal);
195 while (arg_it)
196 {
197 struct GNUNET_DBUS_Arg *arg = arg_it->arg;
198 const char *arg_name = GNUNET_DBUS_arg_get_name (arg);
199 const char *signature = GNUNET_DBUS_arg_get_signature (arg);
200 GNUNET_asprintf (
201 &new_data,
202 "%s <arg name='%s' type='%s'/>\n",
203 data,
204 arg_name,
205 signature);
206 GNUNET_free (data); data = new_data;
207 arg_it = arg_it->next;
208 }
209 GNUNET_asprintf (&new_data, "%s </signal>\n", data);
210 GNUNET_free (data); data = new_data;
211 sig_it = sig_it->next;
212 };
213 GNUNET_asprintf (&new_data, "%s </interface>\n", data);
214 GNUNET_free (data); data = new_data;
215 int_it = int_it->next;
216 };
217 const struct GNUNET_DBUS_ObjectIterator *obj_it = GNUNET_DBUS_object_iterate_subobjects (object);
218 while (obj_it)
219 {
220 const char *obj_name = GNUNET_DBUS_object_get_name (obj_it->object);
221 GNUNET_asprintf (&new_data, "%s <node name='%s'/>\n", data, obj_name);
222 GNUNET_free (data); data = new_data;
223 obj_it = obj_it->next;
224 }
225 GNUNET_asprintf (&new_data, "%s</node>\n", data);
226 GNUNET_free (data); data = new_data;
227
228 DBusMessage *reply = GNUNET_DBUS_method_context_create_reply (mc);
229 DBusMessageIter reply_iter;
230 dbus_message_iter_init_append (reply, &reply_iter);
231 GNUNET_DBUS_push_string (reply, &reply_iter, (const char *const *)&data);
232 GNUNET_DBUS_method_context_send_reply (mc, reply);
233 GNUNET_free (data);
234};
235
236struct GNUNET_DBUS_Interface *interface_introspectable;
237
238static void construct_interface_introspectable ()
239 __attribute__((constructor));
240
241static void destruct_interface_introspectable ()
242 __attribute__((destructor));
243
244static void construct_interface_introspectable ()
245{
246 interface_introspectable = GNUNET_DBUS_interface_create ("org.freedesktop.DBus.Introspectable");
247 struct GNUNET_DBUS_Method *introspect = GNUNET_DBUS_method_create ("Introspect", introspectable_introspect);
248 GNUNET_DBUS_method_add_return_arg (introspect, "data", GNUNET_DBUS_SIGNATURE_STRING);
249 GNUNET_DBUS_interface_add_method (interface_introspectable, introspect);
250}
251
252static void destruct_interface_introspectable ()
253{
254 GNUNET_DBUS_interface_unref (interface_introspectable);
255}
256
257struct GNUNET_DBUS_Interface *
258GNUNET_DBUS_interface_introspectable ()
259{
260 return interface_introspectable;
261};
262
263const struct GNUNET_DBUS_InterfaceIterator *
264GNUNET_DBUS_interface_find (
265 const struct GNUNET_DBUS_InterfaceIterator *int_it,
266 const char *name)
267{
268 for (; int_it; int_it = int_it->next)
269 {
270 if (! strcmp (name, int_it->interface->name))
271 return int_it;
272 }
273 return NULL;
274}
275