dbus: Rename old D-Bus API files to include "_old"
[hostap-gosc2009.git] / wpa_supplicant / dbus / dbus_dict_helpers.c
blob82f6be88c73d15b054da4e3ff5d9de51b74e744d
1 /*
2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
12 * See README and COPYING for more details.
15 #include "includes.h"
16 #include <dbus/dbus.h>
18 #include "common.h"
19 #include "dbus_dict_helpers.h"
22 /**
23 * Start a dict in a dbus message. Should be paired with a call to
24 * wpa_dbus_dict_close_write().
26 * @param iter A valid dbus message iterator
27 * @param iter_dict (out) A dict iterator to pass to further dict functions
28 * @return TRUE on success, FALSE on failure
31 dbus_bool_t wpa_dbus_dict_open_write(DBusMessageIter *iter,
32 DBusMessageIter *iter_dict)
34 dbus_bool_t result;
36 if (!iter || !iter_dict)
37 return FALSE;
39 result = dbus_message_iter_open_container(
40 iter,
41 DBUS_TYPE_ARRAY,
42 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
43 DBUS_TYPE_STRING_AS_STRING
44 DBUS_TYPE_VARIANT_AS_STRING
45 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
46 iter_dict);
47 return result;
51 /**
52 * End a dict element in a dbus message. Should be paired with
53 * a call to wpa_dbus_dict_open_write().
55 * @param iter valid dbus message iterator, same as passed to
56 * wpa_dbus_dict_open_write()
57 * @param iter_dict a dbus dict iterator returned from
58 * wpa_dbus_dict_open_write()
59 * @return TRUE on success, FALSE on failure
62 dbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter,
63 DBusMessageIter *iter_dict)
65 if (!iter || !iter_dict)
66 return FALSE;
68 return dbus_message_iter_close_container(iter, iter_dict);
72 static const char * _wpa_get_type_as_string_from_type(const int type)
74 switch(type) {
75 case DBUS_TYPE_BYTE:
76 return DBUS_TYPE_BYTE_AS_STRING;
77 case DBUS_TYPE_BOOLEAN:
78 return DBUS_TYPE_BOOLEAN_AS_STRING;
79 case DBUS_TYPE_INT16:
80 return DBUS_TYPE_INT16_AS_STRING;
81 case DBUS_TYPE_UINT16:
82 return DBUS_TYPE_UINT16_AS_STRING;
83 case DBUS_TYPE_INT32:
84 return DBUS_TYPE_INT32_AS_STRING;
85 case DBUS_TYPE_UINT32:
86 return DBUS_TYPE_UINT32_AS_STRING;
87 case DBUS_TYPE_INT64:
88 return DBUS_TYPE_INT64_AS_STRING;
89 case DBUS_TYPE_UINT64:
90 return DBUS_TYPE_UINT64_AS_STRING;
91 case DBUS_TYPE_DOUBLE:
92 return DBUS_TYPE_DOUBLE_AS_STRING;
93 case DBUS_TYPE_STRING:
94 return DBUS_TYPE_STRING_AS_STRING;
95 case DBUS_TYPE_OBJECT_PATH:
96 return DBUS_TYPE_OBJECT_PATH_AS_STRING;
97 case DBUS_TYPE_ARRAY:
98 return DBUS_TYPE_ARRAY_AS_STRING;
99 default:
100 return NULL;
105 static dbus_bool_t _wpa_dbus_add_dict_entry_start(
106 DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
107 const char *key, const int value_type)
109 if (!dbus_message_iter_open_container(iter_dict,
110 DBUS_TYPE_DICT_ENTRY, NULL,
111 iter_dict_entry))
112 return FALSE;
114 if (!dbus_message_iter_append_basic(iter_dict_entry, DBUS_TYPE_STRING,
115 &key))
116 return FALSE;
118 return TRUE;
122 static dbus_bool_t _wpa_dbus_add_dict_entry_end(
123 DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
124 DBusMessageIter *iter_dict_val)
126 if (!dbus_message_iter_close_container(iter_dict_entry, iter_dict_val))
127 return FALSE;
128 if (!dbus_message_iter_close_container(iter_dict, iter_dict_entry))
129 return FALSE;
131 return TRUE;
135 static dbus_bool_t _wpa_dbus_add_dict_entry_basic(DBusMessageIter *iter_dict,
136 const char *key,
137 const int value_type,
138 const void *value)
140 DBusMessageIter iter_dict_entry, iter_dict_val;
141 const char *type_as_string = NULL;
143 type_as_string = _wpa_get_type_as_string_from_type(value_type);
144 if (!type_as_string)
145 return FALSE;
147 if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
148 key, value_type))
149 return FALSE;
151 if (!dbus_message_iter_open_container(&iter_dict_entry,
152 DBUS_TYPE_VARIANT,
153 type_as_string, &iter_dict_val))
154 return FALSE;
156 if (!dbus_message_iter_append_basic(&iter_dict_val, value_type, value))
157 return FALSE;
159 if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
160 &iter_dict_val))
161 return FALSE;
163 return TRUE;
167 static dbus_bool_t _wpa_dbus_add_dict_entry_byte_array(
168 DBusMessageIter *iter_dict, const char *key,
169 const char *value, const dbus_uint32_t value_len)
171 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
172 dbus_uint32_t i;
174 if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
175 key, DBUS_TYPE_ARRAY))
176 return FALSE;
178 if (!dbus_message_iter_open_container(&iter_dict_entry,
179 DBUS_TYPE_VARIANT,
180 DBUS_TYPE_ARRAY_AS_STRING
181 DBUS_TYPE_BYTE_AS_STRING,
182 &iter_dict_val))
183 return FALSE;
185 if (!dbus_message_iter_open_container(&iter_dict_val, DBUS_TYPE_ARRAY,
186 DBUS_TYPE_BYTE_AS_STRING,
187 &iter_array))
188 return FALSE;
190 for (i = 0; i < value_len; i++) {
191 if (!dbus_message_iter_append_basic(&iter_array,
192 DBUS_TYPE_BYTE,
193 &(value[i])))
194 return FALSE;
197 if (!dbus_message_iter_close_container(&iter_dict_val, &iter_array))
198 return FALSE;
200 if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
201 &iter_dict_val))
202 return FALSE;
204 return TRUE;
209 * Add a string entry to the dict.
211 * @param iter_dict A valid DBusMessageIter returned from
212 * wpa_dbus_dict_open_write()
213 * @param key The key of the dict item
214 * @param value The string value
215 * @return TRUE on success, FALSE on failure
218 dbus_bool_t wpa_dbus_dict_append_string(DBusMessageIter *iter_dict,
219 const char *key, const char *value)
221 if (!key || !value)
222 return FALSE;
223 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_STRING,
224 &value);
229 * Add a byte entry to the dict.
231 * @param iter_dict A valid DBusMessageIter returned from
232 * wpa_dbus_dict_open_write()
233 * @param key The key of the dict item
234 * @param value The byte value
235 * @return TRUE on success, FALSE on failure
238 dbus_bool_t wpa_dbus_dict_append_byte(DBusMessageIter *iter_dict,
239 const char *key, const char value)
241 if (!key)
242 return FALSE;
243 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_BYTE,
244 &value);
249 * Add a boolean entry to the dict.
251 * @param iter_dict A valid DBusMessageIter returned from
252 * wpa_dbus_dict_open_write()
253 * @param key The key of the dict item
254 * @param value The boolean value
255 * @return TRUE on success, FALSE on failure
258 dbus_bool_t wpa_dbus_dict_append_bool(DBusMessageIter *iter_dict,
259 const char *key, const dbus_bool_t value)
261 if (!key)
262 return FALSE;
263 return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
264 DBUS_TYPE_BOOLEAN, &value);
269 * Add a 16-bit signed integer entry to the dict.
271 * @param iter_dict A valid DBusMessageIter returned from
272 * wpa_dbus_dict_open_write()
273 * @param key The key of the dict item
274 * @param value The 16-bit signed integer value
275 * @return TRUE on success, FALSE on failure
278 dbus_bool_t wpa_dbus_dict_append_int16(DBusMessageIter *iter_dict,
279 const char *key,
280 const dbus_int16_t value)
282 if (!key)
283 return FALSE;
284 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT16,
285 &value);
290 * Add a 16-bit unsigned integer entry to the dict.
292 * @param iter_dict A valid DBusMessageIter returned from
293 * wpa_dbus_dict_open_write()
294 * @param key The key of the dict item
295 * @param value The 16-bit unsigned integer value
296 * @return TRUE on success, FALSE on failure
299 dbus_bool_t wpa_dbus_dict_append_uint16(DBusMessageIter *iter_dict,
300 const char *key,
301 const dbus_uint16_t value)
303 if (!key)
304 return FALSE;
305 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT16,
306 &value);
311 * Add a 32-bit signed integer to the dict.
313 * @param iter_dict A valid DBusMessageIter returned from
314 * wpa_dbus_dict_open_write()
315 * @param key The key of the dict item
316 * @param value The 32-bit signed integer value
317 * @return TRUE on success, FALSE on failure
320 dbus_bool_t wpa_dbus_dict_append_int32(DBusMessageIter *iter_dict,
321 const char *key,
322 const dbus_int32_t value)
324 if (!key)
325 return FALSE;
326 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT32,
327 &value);
332 * Add a 32-bit unsigned integer entry to the dict.
334 * @param iter_dict A valid DBusMessageIter returned from
335 * wpa_dbus_dict_open_write()
336 * @param key The key of the dict item
337 * @param value The 32-bit unsigned integer value
338 * @return TRUE on success, FALSE on failure
341 dbus_bool_t wpa_dbus_dict_append_uint32(DBusMessageIter *iter_dict,
342 const char *key,
343 const dbus_uint32_t value)
345 if (!key)
346 return FALSE;
347 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT32,
348 &value);
353 * Add a 64-bit integer entry to the dict.
355 * @param iter_dict A valid DBusMessageIter returned from
356 * wpa_dbus_dict_open_write()
357 * @param key The key of the dict item
358 * @param value The 64-bit integer value
359 * @return TRUE on success, FALSE on failure
362 dbus_bool_t wpa_dbus_dict_append_int64(DBusMessageIter *iter_dict,
363 const char *key,
364 const dbus_int64_t value)
366 if (!key)
367 return FALSE;
368 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT64,
369 &value);
374 * Add a 64-bit unsigned integer entry to the dict.
376 * @param iter_dict A valid DBusMessageIter returned from
377 * wpa_dbus_dict_open_write()
378 * @param key The key of the dict item
379 * @param value The 64-bit unsigned integer value
380 * @return TRUE on success, FALSE on failure
383 dbus_bool_t wpa_dbus_dict_append_uint64(DBusMessageIter *iter_dict,
384 const char *key,
385 const dbus_uint64_t value)
387 if (!key)
388 return FALSE;
389 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT64,
390 &value);
395 * Add a double-precision floating point entry to the dict.
397 * @param iter_dict A valid DBusMessageIter returned from
398 * wpa_dbus_dict_open_write()
399 * @param key The key of the dict item
400 * @param value The double-precision floating point value
401 * @return TRUE on success, FALSE on failure
404 dbus_bool_t wpa_dbus_dict_append_double(DBusMessageIter *iter_dict,
405 const char * key,
406 const double value)
408 if (!key)
409 return FALSE;
410 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_DOUBLE,
411 &value);
416 * Add a DBus object path entry to the dict.
418 * @param iter_dict A valid DBusMessageIter returned from
419 * wpa_dbus_dict_open_write()
420 * @param key The key of the dict item
421 * @param value The DBus object path value
422 * @return TRUE on success, FALSE on failure
425 dbus_bool_t wpa_dbus_dict_append_object_path(DBusMessageIter *iter_dict,
426 const char *key,
427 const char *value)
429 if (!key || !value)
430 return FALSE;
431 return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
432 DBUS_TYPE_OBJECT_PATH, &value);
437 * Add a byte array entry to the dict.
439 * @param iter_dict A valid DBusMessageIter returned from
440 * wpa_dbus_dict_open_write()
441 * @param key The key of the dict item
442 * @param value The byte array
443 * @param value_len The length of the byte array, in bytes
444 * @return TRUE on success, FALSE on failure
447 dbus_bool_t wpa_dbus_dict_append_byte_array(DBusMessageIter *iter_dict,
448 const char *key,
449 const char *value,
450 const dbus_uint32_t value_len)
452 if (!key)
453 return FALSE;
454 if (!value && (value_len != 0))
455 return FALSE;
456 return _wpa_dbus_add_dict_entry_byte_array(iter_dict, key, value,
457 value_len);
462 * Begin a string array entry in the dict
464 * @param iter_dict A valid DBusMessageIter returned from
465 * wpa_dbus_dict_open_write()
466 * @param key The key of the dict item
467 * @param iter_dict_entry A private DBusMessageIter provided by the caller to
468 * be passed to wpa_dbus_dict_end_string_array()
469 * @param iter_dict_val A private DBusMessageIter provided by the caller to
470 * be passed to wpa_dbus_dict_end_string_array()
471 * @param iter_array On return, the DBusMessageIter to be passed to
472 * wpa_dbus_dict_string_array_add_element()
473 * @return TRUE on success, FALSE on failure
476 dbus_bool_t wpa_dbus_dict_begin_string_array(DBusMessageIter *iter_dict,
477 const char *key,
478 DBusMessageIter *iter_dict_entry,
479 DBusMessageIter *iter_dict_val,
480 DBusMessageIter *iter_array)
482 if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array)
483 return FALSE;
485 if (!_wpa_dbus_add_dict_entry_start(iter_dict, iter_dict_entry,
486 key, DBUS_TYPE_ARRAY))
487 return FALSE;
489 if (!dbus_message_iter_open_container(iter_dict_entry,
490 DBUS_TYPE_VARIANT,
491 DBUS_TYPE_ARRAY_AS_STRING
492 DBUS_TYPE_STRING_AS_STRING,
493 iter_dict_val))
494 return FALSE;
496 if (!dbus_message_iter_open_container(iter_dict_val, DBUS_TYPE_ARRAY,
497 DBUS_TYPE_BYTE_AS_STRING,
498 iter_array))
499 return FALSE;
501 return TRUE;
506 * Add a single string element to a string array dict entry
508 * @param iter_array A valid DBusMessageIter returned from
509 * wpa_dbus_dict_begin_string_array()'s
510 * iter_array parameter
511 * @param elem The string element to be added to the dict entry's string array
512 * @return TRUE on success, FALSE on failure
515 dbus_bool_t wpa_dbus_dict_string_array_add_element(DBusMessageIter *iter_array,
516 const char *elem)
518 if (!iter_array || !elem)
519 return FALSE;
521 return dbus_message_iter_append_basic(iter_array, DBUS_TYPE_STRING,
522 &elem);
527 * End a string array dict entry
529 * @param iter_dict A valid DBusMessageIter returned from
530 * wpa_dbus_dict_open_write()
531 * @param iter_dict_entry A private DBusMessageIter returned from
532 * wpa_dbus_dict_end_string_array()
533 * @param iter_dict_val A private DBusMessageIter returned from
534 * wpa_dbus_dict_end_string_array()
535 * @param iter_array A DBusMessageIter returned from
536 * wpa_dbus_dict_end_string_array()
537 * @return TRUE on success, FALSE on failure
540 dbus_bool_t wpa_dbus_dict_end_string_array(DBusMessageIter *iter_dict,
541 DBusMessageIter *iter_dict_entry,
542 DBusMessageIter *iter_dict_val,
543 DBusMessageIter *iter_array)
545 if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array)
546 return FALSE;
548 if (!dbus_message_iter_close_container(iter_dict_val, iter_array))
549 return FALSE;
551 if (!_wpa_dbus_add_dict_entry_end(iter_dict, iter_dict_entry,
552 iter_dict_val))
553 return FALSE;
555 return TRUE;
560 * Convenience function to add an entire string array to the dict.
562 * @param iter_dict A valid DBusMessageIter returned from
563 * wpa_dbus_dict_open_write()
564 * @param key The key of the dict item
565 * @param items The array of strings
566 * @param num_items The number of strings in the array
567 * @return TRUE on success, FALSE on failure
570 dbus_bool_t wpa_dbus_dict_append_string_array(DBusMessageIter *iter_dict,
571 const char *key,
572 const char **items,
573 const dbus_uint32_t num_items)
575 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
576 dbus_uint32_t i;
578 if (!key)
579 return FALSE;
580 if (!items && (num_items != 0))
581 return FALSE;
583 if (!wpa_dbus_dict_begin_string_array(iter_dict, key,
584 &iter_dict_entry, &iter_dict_val,
585 &iter_array))
586 return FALSE;
588 for (i = 0; i < num_items; i++) {
589 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
590 items[i]))
591 return FALSE;
594 if (!wpa_dbus_dict_end_string_array(iter_dict, &iter_dict_entry,
595 &iter_dict_val, &iter_array))
596 return FALSE;
598 return TRUE;
602 /*****************************************************/
603 /* Stuff for reading dicts */
604 /*****************************************************/
607 * Start reading from a dbus dict.
609 * @param iter A valid DBusMessageIter pointing to the start of the dict
610 * @param iter_dict (out) A DBusMessageIter to be passed to
611 * wpa_dbus_dict_read_next_entry()
612 * @return TRUE on success, FALSE on failure
615 dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
616 DBusMessageIter *iter_dict)
618 if (!iter || !iter_dict)
619 return FALSE;
621 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY ||
622 dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY)
623 return FALSE;
625 dbus_message_iter_recurse(iter, iter_dict);
626 return TRUE;
630 #define BYTE_ARRAY_CHUNK_SIZE 34
631 #define BYTE_ARRAY_ITEM_SIZE (sizeof(char))
633 static dbus_bool_t _wpa_dbus_dict_entry_get_byte_array(
634 DBusMessageIter *iter, int array_type,
635 struct wpa_dbus_dict_entry *entry)
637 dbus_uint32_t count = 0;
638 dbus_bool_t success = FALSE;
639 char *buffer;
641 entry->bytearray_value = NULL;
642 entry->array_type = DBUS_TYPE_BYTE;
644 buffer = os_zalloc(BYTE_ARRAY_ITEM_SIZE * BYTE_ARRAY_CHUNK_SIZE);
645 if (!buffer) {
646 perror("_wpa_dbus_dict_entry_get_byte_array[dbus]: out of "
647 "memory");
648 goto done;
651 entry->bytearray_value = buffer;
652 entry->array_len = 0;
653 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_BYTE) {
654 char byte;
656 if ((count % BYTE_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
657 buffer = os_realloc(buffer, BYTE_ARRAY_ITEM_SIZE *
658 (count + BYTE_ARRAY_CHUNK_SIZE));
659 if (buffer == NULL) {
660 perror("_wpa_dbus_dict_entry_get_byte_array["
661 "dbus] out of memory trying to "
662 "retrieve the string array");
663 goto done;
666 entry->bytearray_value = buffer;
668 dbus_message_iter_get_basic(iter, &byte);
669 entry->bytearray_value[count] = byte;
670 entry->array_len = ++count;
671 dbus_message_iter_next(iter);
674 /* Zero-length arrays are valid. */
675 if (entry->array_len == 0) {
676 os_free(entry->bytearray_value);
677 entry->bytearray_value = NULL;
680 success = TRUE;
682 done:
683 return success;
687 #define STR_ARRAY_CHUNK_SIZE 8
688 #define STR_ARRAY_ITEM_SIZE (sizeof(char *))
690 static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
691 DBusMessageIter *iter, int array_type,
692 struct wpa_dbus_dict_entry *entry)
694 dbus_uint32_t count = 0;
695 dbus_bool_t success = FALSE;
696 char **buffer;
698 entry->strarray_value = NULL;
699 entry->array_type = DBUS_TYPE_STRING;
701 buffer = os_zalloc(STR_ARRAY_ITEM_SIZE * STR_ARRAY_CHUNK_SIZE);
702 if (buffer == NULL) {
703 perror("_wpa_dbus_dict_entry_get_string_array[dbus] out of "
704 "memory trying to retrieve a string array");
705 goto done;
708 entry->strarray_value = buffer;
709 entry->array_len = 0;
710 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
711 const char *value;
712 char *str;
714 if ((count % STR_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
715 buffer = os_realloc(buffer, STR_ARRAY_ITEM_SIZE *
716 (count + STR_ARRAY_CHUNK_SIZE));
717 if (buffer == NULL) {
718 perror("_wpa_dbus_dict_entry_get_string_array["
719 "dbus] out of memory trying to "
720 "retrieve the string array");
721 goto done;
724 entry->strarray_value = buffer;
726 dbus_message_iter_get_basic(iter, &value);
727 str = os_strdup(value);
728 if (str == NULL) {
729 perror("_wpa_dbus_dict_entry_get_string_array[dbus] "
730 "out of memory trying to duplicate the string "
731 "array");
732 goto done;
734 entry->strarray_value[count] = str;
735 entry->array_len = ++count;
736 dbus_message_iter_next(iter);
739 /* Zero-length arrays are valid. */
740 if (entry->array_len == 0) {
741 os_free(entry->strarray_value);
742 entry->strarray_value = NULL;
745 success = TRUE;
747 done:
748 return success;
752 static dbus_bool_t _wpa_dbus_dict_entry_get_array(
753 DBusMessageIter *iter_dict_val, struct wpa_dbus_dict_entry *entry)
755 int array_type = dbus_message_iter_get_element_type(iter_dict_val);
756 dbus_bool_t success = FALSE;
757 DBusMessageIter iter_array;
759 if (!entry)
760 return FALSE;
762 dbus_message_iter_recurse(iter_dict_val, &iter_array);
764 switch (array_type) {
765 case DBUS_TYPE_BYTE:
766 success = _wpa_dbus_dict_entry_get_byte_array(&iter_array,
767 array_type,
768 entry);
769 break;
770 case DBUS_TYPE_STRING:
771 success = _wpa_dbus_dict_entry_get_string_array(&iter_array,
772 array_type,
773 entry);
774 break;
775 default:
776 break;
779 return success;
783 static dbus_bool_t _wpa_dbus_dict_fill_value_from_variant(
784 struct wpa_dbus_dict_entry *entry, DBusMessageIter *iter_dict_val)
786 dbus_bool_t success = TRUE;
788 switch (entry->type) {
789 case DBUS_TYPE_STRING: {
790 const char *v;
791 dbus_message_iter_get_basic(iter_dict_val, &v);
792 entry->str_value = os_strdup(v);
793 break;
795 case DBUS_TYPE_BOOLEAN: {
796 dbus_bool_t v;
797 dbus_message_iter_get_basic(iter_dict_val, &v);
798 entry->bool_value = v;
799 break;
801 case DBUS_TYPE_BYTE: {
802 char v;
803 dbus_message_iter_get_basic(iter_dict_val, &v);
804 entry->byte_value = v;
805 break;
807 case DBUS_TYPE_INT16: {
808 dbus_int16_t v;
809 dbus_message_iter_get_basic(iter_dict_val, &v);
810 entry->int16_value = v;
811 break;
813 case DBUS_TYPE_UINT16: {
814 dbus_uint16_t v;
815 dbus_message_iter_get_basic(iter_dict_val, &v);
816 entry->uint16_value = v;
817 break;
819 case DBUS_TYPE_INT32: {
820 dbus_int32_t v;
821 dbus_message_iter_get_basic(iter_dict_val, &v);
822 entry->int32_value = v;
823 break;
825 case DBUS_TYPE_UINT32: {
826 dbus_uint32_t v;
827 dbus_message_iter_get_basic(iter_dict_val, &v);
828 entry->uint32_value = v;
829 break;
831 case DBUS_TYPE_INT64: {
832 dbus_int64_t v;
833 dbus_message_iter_get_basic(iter_dict_val, &v);
834 entry->int64_value = v;
835 break;
837 case DBUS_TYPE_UINT64: {
838 dbus_uint64_t v;
839 dbus_message_iter_get_basic(iter_dict_val, &v);
840 entry->uint64_value = v;
841 break;
843 case DBUS_TYPE_DOUBLE: {
844 double v;
845 dbus_message_iter_get_basic(iter_dict_val, &v);
846 entry->double_value = v;
847 break;
849 case DBUS_TYPE_OBJECT_PATH: {
850 char *v;
851 dbus_message_iter_get_basic(iter_dict_val, &v);
852 entry->str_value = os_strdup(v);
853 break;
855 case DBUS_TYPE_ARRAY: {
856 success = _wpa_dbus_dict_entry_get_array(iter_dict_val, entry);
857 break;
859 default:
860 success = FALSE;
861 break;
864 return success;
869 * Read the current key/value entry from the dict. Entries are dynamically
870 * allocated when needed and must be freed after use with the
871 * wpa_dbus_dict_entry_clear() function.
873 * The returned entry object will be filled with the type and value of the next
874 * entry in the dict, or the type will be DBUS_TYPE_INVALID if an error
875 * occurred.
877 * @param iter_dict A valid DBusMessageIter returned from
878 * wpa_dbus_dict_open_read()
879 * @param entry A valid dict entry object into which the dict key and value
880 * will be placed
881 * @return TRUE on success, FALSE on failure
884 dbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict,
885 struct wpa_dbus_dict_entry * entry)
887 DBusMessageIter iter_dict_entry, iter_dict_val;
888 int type;
889 const char *key;
891 if (!iter_dict || !entry)
892 goto error;
894 if (dbus_message_iter_get_arg_type(iter_dict) != DBUS_TYPE_DICT_ENTRY)
895 goto error;
897 dbus_message_iter_recurse(iter_dict, &iter_dict_entry);
898 dbus_message_iter_get_basic(&iter_dict_entry, &key);
899 entry->key = key;
901 if (!dbus_message_iter_next(&iter_dict_entry))
902 goto error;
903 type = dbus_message_iter_get_arg_type(&iter_dict_entry);
904 if (type != DBUS_TYPE_VARIANT)
905 goto error;
907 dbus_message_iter_recurse(&iter_dict_entry, &iter_dict_val);
908 entry->type = dbus_message_iter_get_arg_type(&iter_dict_val);
909 if (!_wpa_dbus_dict_fill_value_from_variant(entry, &iter_dict_val))
910 goto error;
912 dbus_message_iter_next(iter_dict);
913 return TRUE;
915 error:
916 if (entry) {
917 wpa_dbus_dict_entry_clear(entry);
918 entry->type = DBUS_TYPE_INVALID;
919 entry->array_type = DBUS_TYPE_INVALID;
922 return FALSE;
927 * Return whether or not there are additional dictionary entries.
929 * @param iter_dict A valid DBusMessageIter returned from
930 * wpa_dbus_dict_open_read()
931 * @return TRUE if more dict entries exists, FALSE if no more dict entries
932 * exist
934 dbus_bool_t wpa_dbus_dict_has_dict_entry(DBusMessageIter *iter_dict)
936 if (!iter_dict) {
937 perror("wpa_dbus_dict_has_dict_entry[dbus]: out of memory");
938 return FALSE;
940 return dbus_message_iter_get_arg_type(iter_dict) ==
941 DBUS_TYPE_DICT_ENTRY;
946 * Free any memory used by the entry object.
948 * @param entry The entry object
950 void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry)
952 unsigned int i;
954 if (!entry)
955 return;
956 switch (entry->type) {
957 case DBUS_TYPE_OBJECT_PATH:
958 case DBUS_TYPE_STRING:
959 os_free(entry->str_value);
960 break;
961 case DBUS_TYPE_ARRAY:
962 switch (entry->array_type) {
963 case DBUS_TYPE_BYTE:
964 os_free(entry->bytearray_value);
965 break;
966 case DBUS_TYPE_STRING:
967 for (i = 0; i < entry->array_len; i++)
968 os_free(entry->strarray_value[i]);
969 os_free(entry->strarray_value);
970 break;
972 break;
975 memset(entry, 0, sizeof(struct wpa_dbus_dict_entry));