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
12 * See README and COPYING for more details.
16 #include <dbus/dbus.h>
20 #include "dbus_dict_helpers.h"
24 * Start a dict in a dbus message. Should be paired with a call to
25 * wpa_dbus_dict_close_write().
27 * @param iter A valid dbus message iterator
28 * @param iter_dict (out) A dict iterator to pass to further dict functions
29 * @return TRUE on success, FALSE on failure
32 dbus_bool_t wpa_dbus_dict_open_write(DBusMessageIter *iter,
33 DBusMessageIter *iter_dict)
37 if (!iter || !iter_dict)
40 result = dbus_message_iter_open_container(
43 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
44 DBUS_TYPE_STRING_AS_STRING
45 DBUS_TYPE_VARIANT_AS_STRING
46 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
53 * End a dict element in a dbus message. Should be paired with
54 * a call to wpa_dbus_dict_open_write().
56 * @param iter valid dbus message iterator, same as passed to
57 * wpa_dbus_dict_open_write()
58 * @param iter_dict a dbus dict iterator returned from
59 * wpa_dbus_dict_open_write()
60 * @return TRUE on success, FALSE on failure
63 dbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter,
64 DBusMessageIter *iter_dict)
66 if (!iter || !iter_dict)
69 return dbus_message_iter_close_container(iter, iter_dict);
73 const char * wpa_dbus_type_as_string(const int type)
77 return DBUS_TYPE_BYTE_AS_STRING;
78 case DBUS_TYPE_BOOLEAN:
79 return DBUS_TYPE_BOOLEAN_AS_STRING;
81 return DBUS_TYPE_INT16_AS_STRING;
82 case DBUS_TYPE_UINT16:
83 return DBUS_TYPE_UINT16_AS_STRING;
85 return DBUS_TYPE_INT32_AS_STRING;
86 case DBUS_TYPE_UINT32:
87 return DBUS_TYPE_UINT32_AS_STRING;
89 return DBUS_TYPE_INT64_AS_STRING;
90 case DBUS_TYPE_UINT64:
91 return DBUS_TYPE_UINT64_AS_STRING;
92 case DBUS_TYPE_DOUBLE:
93 return DBUS_TYPE_DOUBLE_AS_STRING;
94 case DBUS_TYPE_STRING:
95 return DBUS_TYPE_STRING_AS_STRING;
96 case DBUS_TYPE_OBJECT_PATH:
97 return DBUS_TYPE_OBJECT_PATH_AS_STRING;
99 return DBUS_TYPE_ARRAY_AS_STRING;
106 static dbus_bool_t _wpa_dbus_add_dict_entry_start(
107 DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
108 const char *key, const int value_type)
110 if (!dbus_message_iter_open_container(iter_dict,
111 DBUS_TYPE_DICT_ENTRY, NULL,
115 if (!dbus_message_iter_append_basic(iter_dict_entry, DBUS_TYPE_STRING,
123 static dbus_bool_t _wpa_dbus_add_dict_entry_end(
124 DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
125 DBusMessageIter *iter_dict_val)
127 if (!dbus_message_iter_close_container(iter_dict_entry, iter_dict_val))
129 if (!dbus_message_iter_close_container(iter_dict, iter_dict_entry))
136 static dbus_bool_t _wpa_dbus_add_dict_entry_basic(DBusMessageIter *iter_dict,
138 const int value_type,
141 DBusMessageIter iter_dict_entry, iter_dict_val;
142 const char *type_as_string = NULL;
147 type_as_string = wpa_dbus_type_as_string(value_type);
151 if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
155 if (!dbus_message_iter_open_container(&iter_dict_entry,
157 type_as_string, &iter_dict_val))
160 if (!dbus_message_iter_append_basic(&iter_dict_val, value_type, value))
163 if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
171 static dbus_bool_t _wpa_dbus_add_dict_entry_byte_array(
172 DBusMessageIter *iter_dict, const char *key,
173 const char *value, const dbus_uint32_t value_len)
175 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
178 if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
179 key, DBUS_TYPE_ARRAY))
182 if (!dbus_message_iter_open_container(&iter_dict_entry,
184 DBUS_TYPE_ARRAY_AS_STRING
185 DBUS_TYPE_BYTE_AS_STRING,
189 if (!dbus_message_iter_open_container(&iter_dict_val, DBUS_TYPE_ARRAY,
190 DBUS_TYPE_BYTE_AS_STRING,
194 for (i = 0; i < value_len; i++) {
195 if (!dbus_message_iter_append_basic(&iter_array,
201 if (!dbus_message_iter_close_container(&iter_dict_val, &iter_array))
204 if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
213 * Add a string entry to the dict.
215 * @param iter_dict A valid DBusMessageIter returned from
216 * wpa_dbus_dict_open_write()
217 * @param key The key of the dict item
218 * @param value The string value
219 * @return TRUE on success, FALSE on failure
222 dbus_bool_t wpa_dbus_dict_append_string(DBusMessageIter *iter_dict,
223 const char *key, const char *value)
227 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_STRING,
233 * Add a byte entry to the dict.
235 * @param iter_dict A valid DBusMessageIter returned from
236 * wpa_dbus_dict_open_write()
237 * @param key The key of the dict item
238 * @param value The byte value
239 * @return TRUE on success, FALSE on failure
242 dbus_bool_t wpa_dbus_dict_append_byte(DBusMessageIter *iter_dict,
243 const char *key, const char value)
245 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_BYTE,
251 * Add a boolean entry to the dict.
253 * @param iter_dict A valid DBusMessageIter returned from
254 * wpa_dbus_dict_open_write()
255 * @param key The key of the dict item
256 * @param value The boolean value
257 * @return TRUE on success, FALSE on failure
260 dbus_bool_t wpa_dbus_dict_append_bool(DBusMessageIter *iter_dict,
261 const char *key, const dbus_bool_t value)
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,
280 const dbus_int16_t value)
282 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT16,
288 * Add a 16-bit unsigned integer entry to the dict.
290 * @param iter_dict A valid DBusMessageIter returned from
291 * wpa_dbus_dict_open_write()
292 * @param key The key of the dict item
293 * @param value The 16-bit unsigned integer value
294 * @return TRUE on success, FALSE on failure
297 dbus_bool_t wpa_dbus_dict_append_uint16(DBusMessageIter *iter_dict,
299 const dbus_uint16_t value)
301 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT16,
307 * Add a 32-bit signed integer to the dict.
309 * @param iter_dict A valid DBusMessageIter returned from
310 * wpa_dbus_dict_open_write()
311 * @param key The key of the dict item
312 * @param value The 32-bit signed integer value
313 * @return TRUE on success, FALSE on failure
316 dbus_bool_t wpa_dbus_dict_append_int32(DBusMessageIter *iter_dict,
318 const dbus_int32_t value)
320 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT32,
326 * Add a 32-bit unsigned integer entry to the dict.
328 * @param iter_dict A valid DBusMessageIter returned from
329 * wpa_dbus_dict_open_write()
330 * @param key The key of the dict item
331 * @param value The 32-bit unsigned integer value
332 * @return TRUE on success, FALSE on failure
335 dbus_bool_t wpa_dbus_dict_append_uint32(DBusMessageIter *iter_dict,
337 const dbus_uint32_t value)
339 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT32,
345 * Add a 64-bit integer entry to the dict.
347 * @param iter_dict A valid DBusMessageIter returned from
348 * wpa_dbus_dict_open_write()
349 * @param key The key of the dict item
350 * @param value The 64-bit integer value
351 * @return TRUE on success, FALSE on failure
354 dbus_bool_t wpa_dbus_dict_append_int64(DBusMessageIter *iter_dict,
356 const dbus_int64_t value)
358 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT64,
364 * Add a 64-bit unsigned integer entry to the dict.
366 * @param iter_dict A valid DBusMessageIter returned from
367 * wpa_dbus_dict_open_write()
368 * @param key The key of the dict item
369 * @param value The 64-bit unsigned integer value
370 * @return TRUE on success, FALSE on failure
373 dbus_bool_t wpa_dbus_dict_append_uint64(DBusMessageIter *iter_dict,
375 const dbus_uint64_t value)
377 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT64,
383 * Add a double-precision floating point entry to the dict.
385 * @param iter_dict A valid DBusMessageIter returned from
386 * wpa_dbus_dict_open_write()
387 * @param key The key of the dict item
388 * @param value The double-precision floating point value
389 * @return TRUE on success, FALSE on failure
392 dbus_bool_t wpa_dbus_dict_append_double(DBusMessageIter *iter_dict,
393 const char *key, const double value)
395 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_DOUBLE,
401 * Add a DBus object path entry to the dict.
403 * @param iter_dict A valid DBusMessageIter returned from
404 * wpa_dbus_dict_open_write()
405 * @param key The key of the dict item
406 * @param value The DBus object path value
407 * @return TRUE on success, FALSE on failure
410 dbus_bool_t wpa_dbus_dict_append_object_path(DBusMessageIter *iter_dict,
416 return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
417 DBUS_TYPE_OBJECT_PATH, &value);
422 * Add a byte array entry to the dict.
424 * @param iter_dict A valid DBusMessageIter returned from
425 * wpa_dbus_dict_open_write()
426 * @param key The key of the dict item
427 * @param value The byte array
428 * @param value_len The length of the byte array, in bytes
429 * @return TRUE on success, FALSE on failure
432 dbus_bool_t wpa_dbus_dict_append_byte_array(DBusMessageIter *iter_dict,
435 const dbus_uint32_t value_len)
439 if (!value && (value_len != 0))
441 return _wpa_dbus_add_dict_entry_byte_array(iter_dict, key, value,
447 * Begin an array entry in the dict
449 * @param iter_dict A valid DBusMessageIter returned from
450 * wpa_dbus_dict_open_write()
451 * @param key The key of the dict item
452 * @param type The type of the contained data
453 * @param iter_dict_entry A private DBusMessageIter provided by the caller to
454 * be passed to wpa_dbus_dict_end_string_array()
455 * @param iter_dict_val A private DBusMessageIter provided by the caller to
456 * be passed to wpa_dbus_dict_end_string_array()
457 * @param iter_array On return, the DBusMessageIter to be passed to
458 * wpa_dbus_dict_string_array_add_element()
459 * @return TRUE on success, FALSE on failure
462 dbus_bool_t wpa_dbus_dict_begin_array(DBusMessageIter *iter_dict,
463 const char *key, const char *type,
464 DBusMessageIter *iter_dict_entry,
465 DBusMessageIter *iter_dict_val,
466 DBusMessageIter *iter_array)
471 err = os_snprintf(array_type, sizeof(array_type),
472 DBUS_TYPE_ARRAY_AS_STRING "%s",
474 if (err < 0 || err > (int) sizeof(array_type))
477 if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array)
480 if (!_wpa_dbus_add_dict_entry_start(iter_dict, iter_dict_entry,
481 key, DBUS_TYPE_ARRAY))
484 if (!dbus_message_iter_open_container(iter_dict_entry,
490 if (!dbus_message_iter_open_container(iter_dict_val, DBUS_TYPE_ARRAY,
498 dbus_bool_t wpa_dbus_dict_begin_string_array(DBusMessageIter *iter_dict,
500 DBusMessageIter *iter_dict_entry,
501 DBusMessageIter *iter_dict_val,
502 DBusMessageIter *iter_array)
504 return wpa_dbus_dict_begin_array(
506 DBUS_TYPE_STRING_AS_STRING,
507 iter_dict_entry, iter_dict_val, iter_array);
512 * Add a single string element to a string array dict entry
514 * @param iter_array A valid DBusMessageIter returned from
515 * wpa_dbus_dict_begin_string_array()'s
516 * iter_array parameter
517 * @param elem The string element to be added to the dict entry's string array
518 * @return TRUE on success, FALSE on failure
521 dbus_bool_t wpa_dbus_dict_string_array_add_element(DBusMessageIter *iter_array,
524 if (!iter_array || !elem)
527 return dbus_message_iter_append_basic(iter_array, DBUS_TYPE_STRING,
533 * Add a single byte array element to a string array dict entry
535 * @param iter_array A valid DBusMessageIter returned from
536 * wpa_dbus_dict_begin_array()'s iter_array
537 * parameter -- note that wpa_dbus_dict_begin_array()
538 * must have been called with "ay" as the type
539 * @param value The data to be added to the dict entry's array
540 * @param value_len The length of the data
541 * @return TRUE on success, FALSE on failure
544 dbus_bool_t wpa_dbus_dict_bin_array_add_element(DBusMessageIter *iter_array,
548 DBusMessageIter iter_bytes;
551 if (!iter_array || !value)
554 if (!dbus_message_iter_open_container(iter_array, DBUS_TYPE_ARRAY,
555 DBUS_TYPE_BYTE_AS_STRING,
559 for (i = 0; i < value_len; i++) {
560 if (!dbus_message_iter_append_basic(&iter_bytes,
566 if (!dbus_message_iter_close_container(iter_array, &iter_bytes))
574 * End an array dict entry
576 * @param iter_dict A valid DBusMessageIter returned from
577 * wpa_dbus_dict_open_write()
578 * @param iter_dict_entry A private DBusMessageIter returned from
579 * wpa_dbus_dict_begin_string_array() or
580 * wpa_dbus_dict_begin_array()
581 * @param iter_dict_val A private DBusMessageIter returned from
582 * wpa_dbus_dict_begin_string_array() or
583 * wpa_dbus_dict_begin_array()
584 * @param iter_array A DBusMessageIter returned from
585 * wpa_dbus_dict_begin_string_array() or
586 * wpa_dbus_dict_begin_array()
587 * @return TRUE on success, FALSE on failure
590 dbus_bool_t wpa_dbus_dict_end_array(DBusMessageIter *iter_dict,
591 DBusMessageIter *iter_dict_entry,
592 DBusMessageIter *iter_dict_val,
593 DBusMessageIter *iter_array)
595 if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array)
598 if (!dbus_message_iter_close_container(iter_dict_val, iter_array))
601 if (!_wpa_dbus_add_dict_entry_end(iter_dict, iter_dict_entry,
610 * Convenience function to add an entire string array to the dict.
612 * @param iter_dict A valid DBusMessageIter returned from
613 * wpa_dbus_dict_open_write()
614 * @param key The key of the dict item
615 * @param items The array of strings
616 * @param num_items The number of strings in the array
617 * @return TRUE on success, FALSE on failure
620 dbus_bool_t wpa_dbus_dict_append_string_array(DBusMessageIter *iter_dict,
623 const dbus_uint32_t num_items)
625 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
630 if (!items && (num_items != 0))
633 if (!wpa_dbus_dict_begin_string_array(iter_dict, key,
634 &iter_dict_entry, &iter_dict_val,
638 for (i = 0; i < num_items; i++) {
639 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
644 if (!wpa_dbus_dict_end_string_array(iter_dict, &iter_dict_entry,
645 &iter_dict_val, &iter_array))
653 * Convenience function to add an wpabuf binary array to the dict.
655 * @param iter_dict A valid DBusMessageIter returned from
656 * wpa_dbus_dict_open_write()
657 * @param key The key of the dict item
658 * @param items The array of wpabuf structures
659 * @param num_items The number of strings in the array
660 * @return TRUE on success, FALSE on failure
663 dbus_bool_t wpa_dbus_dict_append_wpabuf_array(DBusMessageIter *iter_dict,
665 const struct wpabuf **items,
666 const dbus_uint32_t num_items)
668 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
673 if (!items && (num_items != 0))
676 if (!wpa_dbus_dict_begin_array(iter_dict, key,
677 DBUS_TYPE_ARRAY_AS_STRING
678 DBUS_TYPE_BYTE_AS_STRING,
679 &iter_dict_entry, &iter_dict_val,
683 for (i = 0; i < num_items; i++) {
684 if (!wpa_dbus_dict_bin_array_add_element(&iter_array,
685 wpabuf_head(items[i]),
686 wpabuf_len(items[i])))
690 if (!wpa_dbus_dict_end_array(iter_dict, &iter_dict_entry,
691 &iter_dict_val, &iter_array))
698 /*****************************************************/
699 /* Stuff for reading dicts */
700 /*****************************************************/
703 * Start reading from a dbus dict.
705 * @param iter A valid DBusMessageIter pointing to the start of the dict
706 * @param iter_dict (out) A DBusMessageIter to be passed to
707 * wpa_dbus_dict_read_next_entry()
708 * @return TRUE on success, FALSE on failure
711 dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
712 DBusMessageIter *iter_dict)
714 if (!iter || !iter_dict)
717 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY ||
718 dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY)
721 dbus_message_iter_recurse(iter, iter_dict);
726 #define BYTE_ARRAY_CHUNK_SIZE 34
727 #define BYTE_ARRAY_ITEM_SIZE (sizeof(char))
729 static dbus_bool_t _wpa_dbus_dict_entry_get_byte_array(
730 DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry)
732 dbus_uint32_t count = 0;
733 dbus_bool_t success = FALSE;
734 char *buffer, *nbuffer;;
736 entry->bytearray_value = NULL;
737 entry->array_type = DBUS_TYPE_BYTE;
739 buffer = os_zalloc(BYTE_ARRAY_ITEM_SIZE * BYTE_ARRAY_CHUNK_SIZE);
743 entry->bytearray_value = buffer;
744 entry->array_len = 0;
745 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_BYTE) {
748 if ((count % BYTE_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
749 nbuffer = os_realloc(buffer, BYTE_ARRAY_ITEM_SIZE *
750 (count + BYTE_ARRAY_CHUNK_SIZE));
751 if (nbuffer == NULL) {
753 wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_"
754 "entry_get_byte_array out of "
755 "memory trying to retrieve the "
761 entry->bytearray_value = buffer;
763 dbus_message_iter_get_basic(iter, &byte);
764 entry->bytearray_value[count] = byte;
765 entry->array_len = ++count;
766 dbus_message_iter_next(iter);
769 /* Zero-length arrays are valid. */
770 if (entry->array_len == 0) {
771 os_free(entry->bytearray_value);
772 entry->bytearray_value = NULL;
782 #define STR_ARRAY_CHUNK_SIZE 8
783 #define STR_ARRAY_ITEM_SIZE (sizeof(char *))
785 static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
786 DBusMessageIter *iter, int array_type,
787 struct wpa_dbus_dict_entry *entry)
789 dbus_uint32_t count = 0;
790 dbus_bool_t success = FALSE;
791 char **buffer, **nbuffer;
793 entry->strarray_value = NULL;
794 entry->array_type = DBUS_TYPE_STRING;
796 buffer = os_zalloc(STR_ARRAY_ITEM_SIZE * STR_ARRAY_CHUNK_SIZE);
800 entry->strarray_value = buffer;
801 entry->array_len = 0;
802 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
806 if ((count % STR_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
807 nbuffer = os_realloc(buffer, STR_ARRAY_ITEM_SIZE *
808 (count + STR_ARRAY_CHUNK_SIZE));
809 if (nbuffer == NULL) {
811 wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_"
812 "entry_get_string_array out of "
813 "memory trying to retrieve the "
819 entry->strarray_value = buffer;
821 dbus_message_iter_get_basic(iter, &value);
822 str = os_strdup(value);
824 wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_entry_get_"
825 "string_array out of memory trying to "
826 "duplicate the string array");
829 entry->strarray_value[count] = str;
830 entry->array_len = ++count;
831 dbus_message_iter_next(iter);
834 /* Zero-length arrays are valid. */
835 if (entry->array_len == 0) {
836 os_free(entry->strarray_value);
837 entry->strarray_value = NULL;
847 #define BIN_ARRAY_CHUNK_SIZE 10
848 #define BIN_ARRAY_ITEM_SIZE (sizeof(struct wpabuf *))
850 static dbus_bool_t _wpa_dbus_dict_entry_get_binarray(
851 DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry)
853 struct wpa_dbus_dict_entry tmpentry;
857 if (dbus_message_iter_get_element_type(iter) != DBUS_TYPE_BYTE)
860 entry->array_type = WPAS_DBUS_TYPE_BINARRAY;
861 entry->array_len = 0;
862 entry->binarray_value = NULL;
864 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_ARRAY) {
865 DBusMessageIter iter_array;
867 if (entry->array_len == buflen) {
868 struct wpabuf **newbuf;
870 buflen += BIN_ARRAY_CHUNK_SIZE;
872 newbuf = os_realloc(entry->binarray_value,
873 buflen * BIN_ARRAY_ITEM_SIZE);
876 entry->binarray_value = newbuf;
879 dbus_message_iter_recurse(iter, &iter_array);
880 if (_wpa_dbus_dict_entry_get_byte_array(&iter_array, &tmpentry)
884 entry->binarray_value[entry->array_len] =
885 wpabuf_alloc_ext_data((u8 *) tmpentry.bytearray_value,
887 if (entry->binarray_value[entry->array_len] == NULL) {
888 wpa_dbus_dict_entry_clear(&tmpentry);
892 dbus_message_iter_next(iter);
898 for (i = 0; i < (int) entry->array_len; i++)
899 wpabuf_free(entry->binarray_value[i]);
900 os_free(entry->binarray_value);
901 entry->array_len = 0;
902 entry->binarray_value = NULL;
907 static dbus_bool_t _wpa_dbus_dict_entry_get_array(
908 DBusMessageIter *iter_dict_val, struct wpa_dbus_dict_entry *entry)
910 int array_type = dbus_message_iter_get_element_type(iter_dict_val);
911 dbus_bool_t success = FALSE;
912 DBusMessageIter iter_array;
917 dbus_message_iter_recurse(iter_dict_val, &iter_array);
919 switch (array_type) {
921 success = _wpa_dbus_dict_entry_get_byte_array(&iter_array,
924 case DBUS_TYPE_STRING:
925 success = _wpa_dbus_dict_entry_get_string_array(&iter_array,
929 case DBUS_TYPE_ARRAY:
930 success = _wpa_dbus_dict_entry_get_binarray(&iter_array, entry);
939 static dbus_bool_t _wpa_dbus_dict_fill_value_from_variant(
940 struct wpa_dbus_dict_entry *entry, DBusMessageIter *iter)
944 switch (entry->type) {
945 case DBUS_TYPE_OBJECT_PATH:
946 case DBUS_TYPE_STRING:
947 dbus_message_iter_get_basic(iter, &v);
948 entry->str_value = os_strdup(v);
949 if (entry->str_value == NULL)
952 case DBUS_TYPE_BOOLEAN:
953 dbus_message_iter_get_basic(iter, &entry->bool_value);
956 dbus_message_iter_get_basic(iter, &entry->byte_value);
958 case DBUS_TYPE_INT16:
959 dbus_message_iter_get_basic(iter, &entry->int16_value);
961 case DBUS_TYPE_UINT16:
962 dbus_message_iter_get_basic(iter, &entry->uint16_value);
964 case DBUS_TYPE_INT32:
965 dbus_message_iter_get_basic(iter, &entry->int32_value);
967 case DBUS_TYPE_UINT32:
968 dbus_message_iter_get_basic(iter, &entry->uint32_value);
970 case DBUS_TYPE_INT64:
971 dbus_message_iter_get_basic(iter, &entry->int64_value);
973 case DBUS_TYPE_UINT64:
974 dbus_message_iter_get_basic(iter, &entry->uint64_value);
976 case DBUS_TYPE_DOUBLE:
977 dbus_message_iter_get_basic(iter, &entry->double_value);
979 case DBUS_TYPE_ARRAY:
980 return _wpa_dbus_dict_entry_get_array(iter, entry);
990 * Read the current key/value entry from the dict. Entries are dynamically
991 * allocated when needed and must be freed after use with the
992 * wpa_dbus_dict_entry_clear() function.
994 * The returned entry object will be filled with the type and value of the next
995 * entry in the dict, or the type will be DBUS_TYPE_INVALID if an error
998 * @param iter_dict A valid DBusMessageIter returned from
999 * wpa_dbus_dict_open_read()
1000 * @param entry A valid dict entry object into which the dict key and value
1002 * @return TRUE on success, FALSE on failure
1005 dbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict,
1006 struct wpa_dbus_dict_entry * entry)
1008 DBusMessageIter iter_dict_entry, iter_dict_val;
1012 if (!iter_dict || !entry)
1015 if (dbus_message_iter_get_arg_type(iter_dict) != DBUS_TYPE_DICT_ENTRY)
1018 dbus_message_iter_recurse(iter_dict, &iter_dict_entry);
1019 dbus_message_iter_get_basic(&iter_dict_entry, &key);
1022 if (!dbus_message_iter_next(&iter_dict_entry))
1024 type = dbus_message_iter_get_arg_type(&iter_dict_entry);
1025 if (type != DBUS_TYPE_VARIANT)
1028 dbus_message_iter_recurse(&iter_dict_entry, &iter_dict_val);
1029 entry->type = dbus_message_iter_get_arg_type(&iter_dict_val);
1030 if (!_wpa_dbus_dict_fill_value_from_variant(entry, &iter_dict_val))
1033 dbus_message_iter_next(iter_dict);
1038 wpa_dbus_dict_entry_clear(entry);
1039 entry->type = DBUS_TYPE_INVALID;
1040 entry->array_type = DBUS_TYPE_INVALID;
1048 * Return whether or not there are additional dictionary entries.
1050 * @param iter_dict A valid DBusMessageIter returned from
1051 * wpa_dbus_dict_open_read()
1052 * @return TRUE if more dict entries exists, FALSE if no more dict entries
1055 dbus_bool_t wpa_dbus_dict_has_dict_entry(DBusMessageIter *iter_dict)
1059 return dbus_message_iter_get_arg_type(iter_dict) ==
1060 DBUS_TYPE_DICT_ENTRY;
1065 * Free any memory used by the entry object.
1067 * @param entry The entry object
1069 void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry)
1075 switch (entry->type) {
1076 case DBUS_TYPE_OBJECT_PATH:
1077 case DBUS_TYPE_STRING:
1078 os_free(entry->str_value);
1080 case DBUS_TYPE_ARRAY:
1081 switch (entry->array_type) {
1082 case DBUS_TYPE_BYTE:
1083 os_free(entry->bytearray_value);
1085 case DBUS_TYPE_STRING:
1086 for (i = 0; i < entry->array_len; i++)
1087 os_free(entry->strarray_value[i]);
1088 os_free(entry->strarray_value);
1092 case WPAS_DBUS_TYPE_BINARRAY:
1093 for (i = 0; i < entry->array_len; i++)
1094 wpabuf_free(entry->binarray_value[i]);
1095 os_free(entry->binarray_value);
1099 memset(entry, 0, sizeof(struct wpa_dbus_dict_entry));