2 #include "e_nm_private.h"
5 #include <Ecore_Data.h>
7 #define CHECK_SIGNATURE(msg, err, sig) \
8 if (dbus_error_is_set((err))) \
10 printf("Error: %s - %s\n", (err)->name, (err)->message); \
14 if (!dbus_message_has_signature((msg), (sig))) \
16 dbus_set_error((err), DBUS_ERROR_INVALID_SIGNATURE, ""); \
20 static E_NM_Property *property_string(DBusMessageIter *iter, const char *sig, void *value);
21 static E_NM_Property *property_basic(DBusMessageIter *iter, const char *sig, void *value);
22 static E_NM_Property *property_variant(DBusMessageIter *iter, const char *sig, void *value);
23 static E_NM_Property *property_array(DBusMessageIter *iter, const char *sig, void *value);
24 static void property_free(E_NM_Property *prop);
26 typedef E_NM_Property *(*Property_Cb)(DBusMessageIter *iter, const char *sig, void *value);
28 typedef struct Sig_Property Sig_Property;
35 static Sig_Property sigs[] = {
36 { .sig = "s", property_string },
37 { .sig = "o", property_string },
38 { .sig = "u", property_basic },
39 { .sig = "b", property_basic },
40 { .sig = "y", property_basic },
41 { .sig = "t", property_basic },
42 { .sig = "v", property_variant },
43 { .sig = "a", property_array },
44 { .sig = "as", property_array },
45 { .sig = "ao", property_array },
46 { .sig = "ay", property_array },
47 { .sig = "au", property_array },
48 { .sig = "aau", property_array },
53 find_property_cb(const char *sig)
57 if (!sig) return NULL;
59 for (t = sigs; t->sig; t++)
61 if (!strcmp(t->sig, sig))
64 fprintf(stderr, "Missing property parser for sig: %s\n", sig);
69 find_property(const char *name, Property *properties)
73 if (!name) return NULL;
75 for (p = properties; p->name; p++)
77 if (!strcmp(p->name, name))
83 static E_NM_Property *
84 property_string(DBusMessageIter *iter, const char *sig, void *value)
87 E_NM_Property *prop = NULL;
89 if ((value) && (!sig))
91 printf("Error: Can't have value and no sig\n");
94 dbus_message_iter_get_basic(iter, &str);
97 if (!check_arg_type(iter, sig[0])) return NULL;
98 if (!value) value = ∝
102 prop = malloc(sizeof(E_NM_Property));
103 prop->type = dbus_message_iter_get_arg_type(iter);
106 *((char **)value) = strdup(str);
111 static E_NM_Property *
112 property_basic(DBusMessageIter *iter, const char *sig, void *value)
114 E_NM_Property *prop = NULL;
116 if ((value) && (!sig))
118 printf("Error: Can't have value and no sig\n");
123 if (!check_arg_type(iter, sig[0])) return NULL;
126 // TODO: Only alloc right size
127 prop = malloc(sizeof(long long));
133 prop = malloc(sizeof(E_NM_Property));
134 prop->type = dbus_message_iter_get_arg_type(iter);
137 dbus_message_iter_get_basic(iter, value);
142 static E_NM_Property *
143 property_variant(DBusMessageIter *iter, const char *sig, void *value)
145 DBusMessageIter v_iter;
149 if (!check_arg_type(iter, 'v')) return NULL;
150 dbus_message_iter_recurse(iter, &v_iter);
151 tmp[0] = dbus_message_iter_get_arg_type(&v_iter);
153 func = find_property_cb(tmp);
154 if (!func) return NULL;
155 return (*func)(&v_iter, NULL, NULL);
158 static E_NM_Property *
159 property_array(DBusMessageIter *iter, const char *sig, void *value)
161 DBusMessageIter a_iter;
164 E_NM_Property *prop = NULL;
165 const char *subsig = NULL;
167 if ((value) && (!sig))
169 printf("Error: Can't have value and no sig\n");
173 dbus_message_iter_recurse(iter, &a_iter);
177 if (!check_arg_type(iter, sig[0])) return NULL;
179 func = find_property_cb(subsig);
180 if (!func) return NULL;
181 if (!value) value = ∝
182 list = (Ecore_List **)value;
183 *list = ecore_list_new();
184 if (subsig[0] == 'a')
185 ecore_list_free_cb_set(*list, ECORE_FREE_CB(ecore_list_destroy));
187 ecore_list_free_cb_set(*list, free);
191 char tmp[] = { dbus_message_iter_get_arg_type(&a_iter), 0 };
192 func = find_property_cb(tmp);
193 if (!func) return NULL;
194 prop = malloc(sizeof(E_NM_Property));
195 prop->type = dbus_message_iter_get_arg_type(iter);
196 list = (Ecore_List **)&prop->a;
197 *list = ecore_list_new();
198 ecore_list_free_cb_set(*list, ECORE_FREE_CB(property_free));
201 while (dbus_message_iter_get_arg_type(&a_iter) != DBUS_TYPE_INVALID)
205 subprop = (*func)(&a_iter, subsig, NULL);
206 if (subprop) ecore_list_append(*list, subprop);
207 dbus_message_iter_next(&a_iter);
214 property_free(E_NM_Property *prop)
217 if ((prop->type == 's') || (prop->type == 'o'))
219 else if (prop->type == 'a')
220 ecore_list_destroy(prop->a);
225 property(void *data, DBusMessage *msg, DBusError *err)
227 DBusMessageIter iter, v_iter;
230 Property_Cb func = NULL;
233 if (dbus_error_is_set(err))
235 printf("Error: %s - %s\n", err->name, err->message);
238 if (!dbus_message_has_signature(msg, "v")) goto error;
239 dbus_message_iter_init(msg, &iter);
240 dbus_message_iter_recurse(&iter, &v_iter);
241 if (d->property->func)
243 d->property->func(d, &v_iter);
247 value = ((char *)d->reply + d->property->offset);
248 func = find_property_cb(d->property->sig);
249 if (func) (*func)(&v_iter, d->property->sig, value);
252 if (d->property->name)
253 e_nm_device_properties_get(d->nmi->conn, d->object, d->property->name, property, d);
256 if (d->cb_func) d->cb_func(d->data, d->reply);
257 property_data_free(d);
262 if (d->reply) free(d->reply); /* TODO: Correct free for object */
263 if (d->cb_func) d->cb_func(d->data, NULL);
264 property_data_free(d);
268 parse_properties(void *data, Property *properties, DBusMessage *msg)
270 DBusMessageIter iter, a_iter;
272 if (!dbus_message_has_signature(msg, "a{sv}")) return;
274 dbus_message_iter_init(msg, &iter);
276 dbus_message_iter_recurse(&iter, &a_iter);
277 while (dbus_message_iter_get_arg_type(&a_iter) != DBUS_TYPE_INVALID)
279 DBusMessageIter d_iter, v_iter;
285 dbus_message_iter_recurse(&a_iter, &d_iter);
286 if (!check_arg_type(&d_iter, 's')) return;
287 dbus_message_iter_get_basic(&d_iter, &name);
289 dbus_message_iter_next(&d_iter);
290 if (!check_arg_type(&d_iter, 'v')) return;
291 dbus_message_iter_recurse(&d_iter, &v_iter);
293 p = find_property(name, properties);
295 value = ((char *)data + p->offset);
296 func = find_property_cb(p->sig);
297 if (!func) goto next;
298 func(&v_iter, p->sig, value);
301 dbus_message_iter_next(&a_iter);
307 * @brief Generic callback for methods that return nothing
310 cb_nm_generic(DBusMessage *msg, DBusError *err)
317 * @brief Generic free for methods
320 free_nm_generic(void *data)
328 * @brief Callback for methods that return DBUS_TYPE_INT32
331 cb_nm_int32(DBusMessage *msg, DBusError *err)
335 CHECK_SIGNATURE(msg, err, "i");
337 i = malloc(sizeof(dbus_int32_t));
338 /* Actually emit the integer */
339 dbus_message_get_args(msg, err,
348 * @brief Callback for methods that return DBUS_TYPE_UINT32
351 cb_nm_uint32(DBusMessage *msg, DBusError *err)
355 CHECK_SIGNATURE(msg, err, "u");
357 i = malloc(sizeof(dbus_uint32_t));
358 /* Actually emit the unsigned integer */
359 dbus_message_get_args(msg, err,
368 * @brief Callback for methods that return DBUS_TYPE_BOOLEAN
371 cb_nm_boolean(DBusMessage *msg, DBusError *err)
375 CHECK_SIGNATURE(msg, err, "b");
377 i = malloc(sizeof(dbus_bool_t));
378 /* Actually emit the unsigned integer */
379 dbus_message_get_args(msg, err,
380 DBUS_TYPE_BOOLEAN, i,
388 * @brief Callback for methods returning a single object path
391 cb_nm_object_path(DBusMessage *msg, DBusError *err)
395 CHECK_SIGNATURE(msg, err, "o");
397 /* Actually emit the object_path */
398 dbus_message_get_args(msg, err,
399 DBUS_TYPE_OBJECT_PATH, &str,
408 * @brief Callback for methods returning a list of object paths
411 cb_nm_object_path_list(DBusMessage *msg, DBusError *err)
414 DBusMessageIter iter, sub;
416 CHECK_SIGNATURE(msg, err, "ao");
418 dbus_message_iter_init(msg, &iter);
420 devices = ecore_list_new();
421 dbus_message_iter_recurse(&iter, &sub);
422 while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID)
426 if (!check_arg_type(&sub, 'o')) goto error;
427 dbus_message_iter_get_basic(&sub, &dev);
428 if (dev) ecore_list_append(devices, dev);
429 dbus_message_iter_next(&sub);
434 ecore_list_destroy(devices);
439 free_nm_object_path_list(void *data)
441 Ecore_List *list = data;
443 if (list) ecore_list_destroy(list);
447 cb_nm_settings(DBusMessage *msg, DBusError *err)
449 Ecore_Hash *settings;
450 DBusMessageIter iter, a_iter;
452 CHECK_SIGNATURE(msg, err, "a{sa{sv}}");
454 dbus_message_iter_init(msg, &iter);
456 settings = ecore_hash_new(ecore_str_hash, ecore_str_compare);
457 ecore_hash_free_key_cb_set(settings, free);
458 ecore_hash_free_value_cb_set(settings, ECORE_FREE_CB(ecore_hash_destroy));
459 dbus_message_iter_recurse(&iter, &a_iter);
460 while (dbus_message_iter_get_arg_type(&a_iter) != DBUS_TYPE_INVALID)
462 DBusMessageIter d_iter, a2_iter;
467 dbus_message_iter_recurse(&a_iter, &d_iter);
468 if (!check_arg_type(&d_iter, 's')) goto error;
469 dbus_message_iter_get_basic(&d_iter, &name);
471 dbus_message_iter_next(&d_iter);
472 if (!check_arg_type(&d_iter, 'a')) goto error;
473 dbus_message_iter_recurse(&d_iter, &a2_iter);
475 value = ecore_hash_new(ecore_str_hash, ecore_str_compare);
476 ecore_hash_free_key_cb_set(value, free);
477 ecore_hash_free_value_cb_set(value, ECORE_FREE_CB(property_free));
478 ecore_hash_set(settings, strdup(name), value);
479 while (dbus_message_iter_get_arg_type(&a2_iter) != DBUS_TYPE_INVALID)
481 dbus_message_iter_recurse(&a2_iter, &d_iter);
482 if (!check_arg_type(&d_iter, 's')) goto error;
483 dbus_message_iter_get_basic(&d_iter, &name);
484 dbus_message_iter_next(&d_iter);
485 if (!check_arg_type(&d_iter, 'v')) goto error;
486 prop = property_variant(&d_iter, NULL, NULL);
487 if (prop) ecore_hash_set(value, strdup(name), prop);
488 dbus_message_iter_next(&a2_iter);
491 dbus_message_iter_next(&a_iter);
496 ecore_hash_destroy(settings);
501 free_nm_settings(void *data)
503 Ecore_Hash *hash = data;
505 if (hash) ecore_hash_destroy(hash);
509 check_arg_type(DBusMessageIter *iter, char type)
513 sig = dbus_message_iter_get_arg_type(iter);
518 property_data_free(Property_Data *data)
520 if (data->object) free(data->object);
525 ip4_address2str(unsigned int address)
529 snprintf(buf, sizeof(buf), "%u.%u.%u.%u",
531 ((address >> 8 ) & 0xff),
532 ((address >> 16) & 0xff),
533 ((address >> 24) & 0xff));