2 * WPA Supplicant / dbus-based control interface
3 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
10 #include <dbus/dbus.h>
14 #include "dbus_dict_helpers.h"
18 * Start a dict in a dbus message. Should be paired with a call to
19 * wpa_dbus_dict_close_write().
21 * @param iter A valid dbus message iterator
22 * @param iter_dict (out) A dict iterator to pass to further dict functions
23 * @return TRUE on success, FALSE on failure
26 dbus_bool_t wpa_dbus_dict_open_write(DBusMessageIter *iter,
27 DBusMessageIter *iter_dict)
31 if (!iter || !iter_dict)
34 result = dbus_message_iter_open_container(
37 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
38 DBUS_TYPE_STRING_AS_STRING
39 DBUS_TYPE_VARIANT_AS_STRING
40 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
47 * End a dict element in a dbus message. Should be paired with
48 * a call to wpa_dbus_dict_open_write().
50 * @param iter valid dbus message iterator, same as passed to
51 * wpa_dbus_dict_open_write()
52 * @param iter_dict a dbus dict iterator returned from
53 * wpa_dbus_dict_open_write()
54 * @return TRUE on success, FALSE on failure
57 dbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter,
58 DBusMessageIter *iter_dict)
60 if (!iter || !iter_dict)
63 return dbus_message_iter_close_container(iter, iter_dict);
67 const char * wpa_dbus_type_as_string(const int type)
71 return DBUS_TYPE_BYTE_AS_STRING;
72 case DBUS_TYPE_BOOLEAN:
73 return DBUS_TYPE_BOOLEAN_AS_STRING;
75 return DBUS_TYPE_INT16_AS_STRING;
76 case DBUS_TYPE_UINT16:
77 return DBUS_TYPE_UINT16_AS_STRING;
79 return DBUS_TYPE_INT32_AS_STRING;
80 case DBUS_TYPE_UINT32:
81 return DBUS_TYPE_UINT32_AS_STRING;
83 return DBUS_TYPE_INT64_AS_STRING;
84 case DBUS_TYPE_UINT64:
85 return DBUS_TYPE_UINT64_AS_STRING;
86 case DBUS_TYPE_DOUBLE:
87 return DBUS_TYPE_DOUBLE_AS_STRING;
88 case DBUS_TYPE_STRING:
89 return DBUS_TYPE_STRING_AS_STRING;
90 case DBUS_TYPE_OBJECT_PATH:
91 return DBUS_TYPE_OBJECT_PATH_AS_STRING;
93 return DBUS_TYPE_ARRAY_AS_STRING;
100 static dbus_bool_t _wpa_dbus_add_dict_entry_start(
101 DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
102 const char *key, const int value_type)
104 if (!dbus_message_iter_open_container(iter_dict,
105 DBUS_TYPE_DICT_ENTRY, NULL,
109 return dbus_message_iter_append_basic(iter_dict_entry, DBUS_TYPE_STRING,
114 static dbus_bool_t _wpa_dbus_add_dict_entry_end(
115 DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
116 DBusMessageIter *iter_dict_val)
118 if (!dbus_message_iter_close_container(iter_dict_entry, iter_dict_val))
121 return dbus_message_iter_close_container(iter_dict, iter_dict_entry);
125 static dbus_bool_t _wpa_dbus_add_dict_entry_basic(DBusMessageIter *iter_dict,
127 const int value_type,
130 DBusMessageIter iter_dict_entry, iter_dict_val;
131 const char *type_as_string = NULL;
136 type_as_string = wpa_dbus_type_as_string(value_type);
140 if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
142 !dbus_message_iter_open_container(&iter_dict_entry,
144 type_as_string, &iter_dict_val) ||
145 !dbus_message_iter_append_basic(&iter_dict_val, value_type, value))
148 return _wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
153 static dbus_bool_t _wpa_dbus_add_dict_entry_byte_array(
154 DBusMessageIter *iter_dict, const char *key,
155 const char *value, const dbus_uint32_t value_len)
157 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
160 if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
161 key, DBUS_TYPE_ARRAY) ||
162 !dbus_message_iter_open_container(&iter_dict_entry,
164 DBUS_TYPE_ARRAY_AS_STRING
165 DBUS_TYPE_BYTE_AS_STRING,
167 !dbus_message_iter_open_container(&iter_dict_val, DBUS_TYPE_ARRAY,
168 DBUS_TYPE_BYTE_AS_STRING,
172 for (i = 0; i < value_len; i++) {
173 if (!dbus_message_iter_append_basic(&iter_array,
179 if (!dbus_message_iter_close_container(&iter_dict_val, &iter_array))
182 return _wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
188 * Add a string entry to the dict.
190 * @param iter_dict A valid DBusMessageIter returned from
191 * wpa_dbus_dict_open_write()
192 * @param key The key of the dict item
193 * @param value The string value
194 * @return TRUE on success, FALSE on failure
197 dbus_bool_t wpa_dbus_dict_append_string(DBusMessageIter *iter_dict,
198 const char *key, const char *value)
202 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_STRING,
208 * Add a boolean entry to the dict.
210 * @param iter_dict A valid DBusMessageIter returned from
211 * wpa_dbus_dict_open_write()
212 * @param key The key of the dict item
213 * @param value The boolean value
214 * @return TRUE on success, FALSE on failure
217 dbus_bool_t wpa_dbus_dict_append_bool(DBusMessageIter *iter_dict,
218 const char *key, const dbus_bool_t value)
220 return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
221 DBUS_TYPE_BOOLEAN, &value);
226 * Add a 16-bit signed integer entry to the dict.
228 * @param iter_dict A valid DBusMessageIter returned from
229 * wpa_dbus_dict_open_write()
230 * @param key The key of the dict item
231 * @param value The 16-bit signed integer value
232 * @return TRUE on success, FALSE on failure
235 dbus_bool_t wpa_dbus_dict_append_int16(DBusMessageIter *iter_dict,
237 const dbus_int16_t value)
239 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT16,
245 * Add a 16-bit unsigned integer entry to the dict.
247 * @param iter_dict A valid DBusMessageIter returned from
248 * wpa_dbus_dict_open_write()
249 * @param key The key of the dict item
250 * @param value The 16-bit unsigned integer value
251 * @return TRUE on success, FALSE on failure
254 dbus_bool_t wpa_dbus_dict_append_uint16(DBusMessageIter *iter_dict,
256 const dbus_uint16_t value)
258 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT16,
264 * Add a 32-bit signed integer to the dict.
266 * @param iter_dict A valid DBusMessageIter returned from
267 * wpa_dbus_dict_open_write()
268 * @param key The key of the dict item
269 * @param value The 32-bit signed integer value
270 * @return TRUE on success, FALSE on failure
273 dbus_bool_t wpa_dbus_dict_append_int32(DBusMessageIter *iter_dict,
275 const dbus_int32_t value)
277 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT32,
283 * Add a 32-bit unsigned integer entry to the dict.
285 * @param iter_dict A valid DBusMessageIter returned from
286 * wpa_dbus_dict_open_write()
287 * @param key The key of the dict item
288 * @param value The 32-bit unsigned integer value
289 * @return TRUE on success, FALSE on failure
292 dbus_bool_t wpa_dbus_dict_append_uint32(DBusMessageIter *iter_dict,
294 const dbus_uint32_t value)
296 return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT32,
302 * Add a DBus object path entry to the dict.
304 * @param iter_dict A valid DBusMessageIter returned from
305 * wpa_dbus_dict_open_write()
306 * @param key The key of the dict item
307 * @param value The DBus object path value
308 * @return TRUE on success, FALSE on failure
311 dbus_bool_t wpa_dbus_dict_append_object_path(DBusMessageIter *iter_dict,
317 return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
318 DBUS_TYPE_OBJECT_PATH, &value);
323 * Add a byte array entry to the dict.
325 * @param iter_dict A valid DBusMessageIter returned from
326 * wpa_dbus_dict_open_write()
327 * @param key The key of the dict item
328 * @param value The byte array
329 * @param value_len The length of the byte array, in bytes
330 * @return TRUE on success, FALSE on failure
333 dbus_bool_t wpa_dbus_dict_append_byte_array(DBusMessageIter *iter_dict,
336 const dbus_uint32_t value_len)
338 if (!key || (!value && value_len != 0))
340 return _wpa_dbus_add_dict_entry_byte_array(iter_dict, key, value,
346 * Begin an array entry in the dict
348 * @param iter_dict A valid DBusMessageIter returned from
349 * wpa_dbus_dict_open_write()
350 * @param key The key of the dict item
351 * @param type The type of the contained data
352 * @param iter_dict_entry A private DBusMessageIter provided by the caller to
353 * be passed to wpa_dbus_dict_end_string_array()
354 * @param iter_dict_val A private DBusMessageIter provided by the caller to
355 * be passed to wpa_dbus_dict_end_string_array()
356 * @param iter_array On return, the DBusMessageIter to be passed to
357 * wpa_dbus_dict_string_array_add_element()
358 * @return TRUE on success, FALSE on failure
361 dbus_bool_t wpa_dbus_dict_begin_array(DBusMessageIter *iter_dict,
362 const char *key, const char *type,
363 DBusMessageIter *iter_dict_entry,
364 DBusMessageIter *iter_dict_val,
365 DBusMessageIter *iter_array)
370 err = os_snprintf(array_type, sizeof(array_type),
371 DBUS_TYPE_ARRAY_AS_STRING "%s",
373 if (os_snprintf_error(sizeof(array_type), err))
376 if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array ||
377 !_wpa_dbus_add_dict_entry_start(iter_dict, iter_dict_entry,
378 key, DBUS_TYPE_ARRAY) ||
379 !dbus_message_iter_open_container(iter_dict_entry,
385 return dbus_message_iter_open_container(iter_dict_val, DBUS_TYPE_ARRAY,
390 dbus_bool_t wpa_dbus_dict_begin_string_array(DBusMessageIter *iter_dict,
392 DBusMessageIter *iter_dict_entry,
393 DBusMessageIter *iter_dict_val,
394 DBusMessageIter *iter_array)
396 return wpa_dbus_dict_begin_array(
398 DBUS_TYPE_STRING_AS_STRING,
399 iter_dict_entry, iter_dict_val, iter_array);
404 * Add a single string element to a string array dict entry
406 * @param iter_array A valid DBusMessageIter returned from
407 * wpa_dbus_dict_begin_string_array()'s
408 * iter_array parameter
409 * @param elem The string element to be added to the dict entry's string array
410 * @return TRUE on success, FALSE on failure
413 dbus_bool_t wpa_dbus_dict_string_array_add_element(DBusMessageIter *iter_array,
416 if (!iter_array || !elem)
419 return dbus_message_iter_append_basic(iter_array, DBUS_TYPE_STRING,
425 * Add a single byte array element to a string array dict entry
427 * @param iter_array A valid DBusMessageIter returned from
428 * wpa_dbus_dict_begin_array()'s iter_array
429 * parameter -- note that wpa_dbus_dict_begin_array()
430 * must have been called with "ay" as the type
431 * @param value The data to be added to the dict entry's array
432 * @param value_len The length of the data
433 * @return TRUE on success, FALSE on failure
436 dbus_bool_t wpa_dbus_dict_bin_array_add_element(DBusMessageIter *iter_array,
440 DBusMessageIter iter_bytes;
443 if (!iter_array || !value ||
444 !dbus_message_iter_open_container(iter_array, DBUS_TYPE_ARRAY,
445 DBUS_TYPE_BYTE_AS_STRING,
449 for (i = 0; i < value_len; i++) {
450 if (!dbus_message_iter_append_basic(&iter_bytes,
456 return dbus_message_iter_close_container(iter_array, &iter_bytes);
461 * End an array dict entry
463 * @param iter_dict A valid DBusMessageIter returned from
464 * wpa_dbus_dict_open_write()
465 * @param iter_dict_entry A private DBusMessageIter returned from
466 * wpa_dbus_dict_begin_string_array() or
467 * wpa_dbus_dict_begin_array()
468 * @param iter_dict_val A private DBusMessageIter returned from
469 * wpa_dbus_dict_begin_string_array() or
470 * wpa_dbus_dict_begin_array()
471 * @param iter_array A DBusMessageIter returned from
472 * wpa_dbus_dict_begin_string_array() or
473 * wpa_dbus_dict_begin_array()
474 * @return TRUE on success, FALSE on failure
477 dbus_bool_t wpa_dbus_dict_end_array(DBusMessageIter *iter_dict,
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 !dbus_message_iter_close_container(iter_dict_val, iter_array))
486 return _wpa_dbus_add_dict_entry_end(iter_dict, iter_dict_entry,
492 * Convenience function to add an entire string array to the dict.
494 * @param iter_dict A valid DBusMessageIter returned from
495 * wpa_dbus_dict_open_write()
496 * @param key The key of the dict item
497 * @param items The array of strings
498 * @param num_items The number of strings in the array
499 * @return TRUE on success, FALSE on failure
502 dbus_bool_t wpa_dbus_dict_append_string_array(DBusMessageIter *iter_dict,
505 const dbus_uint32_t num_items)
507 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
510 if (!key || (!items && num_items != 0) ||
511 !wpa_dbus_dict_begin_string_array(iter_dict, key,
512 &iter_dict_entry, &iter_dict_val,
516 for (i = 0; i < num_items; i++) {
517 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
522 return wpa_dbus_dict_end_string_array(iter_dict, &iter_dict_entry,
523 &iter_dict_val, &iter_array);
528 * Convenience function to add an wpabuf binary array to the dict.
530 * @param iter_dict A valid DBusMessageIter returned from
531 * wpa_dbus_dict_open_write()
532 * @param key The key of the dict item
533 * @param items The array of wpabuf structures
534 * @param num_items The number of strings in the array
535 * @return TRUE on success, FALSE on failure
538 dbus_bool_t wpa_dbus_dict_append_wpabuf_array(DBusMessageIter *iter_dict,
540 const struct wpabuf **items,
541 const dbus_uint32_t num_items)
543 DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
547 (!items && num_items != 0) ||
548 !wpa_dbus_dict_begin_array(iter_dict, key,
549 DBUS_TYPE_ARRAY_AS_STRING
550 DBUS_TYPE_BYTE_AS_STRING,
551 &iter_dict_entry, &iter_dict_val,
555 for (i = 0; i < num_items; i++) {
556 if (!wpa_dbus_dict_bin_array_add_element(&iter_array,
557 wpabuf_head(items[i]),
558 wpabuf_len(items[i])))
562 return wpa_dbus_dict_end_array(iter_dict, &iter_dict_entry,
563 &iter_dict_val, &iter_array);
567 /*****************************************************/
568 /* Stuff for reading dicts */
569 /*****************************************************/
572 * Start reading from a dbus dict.
574 * @param iter A valid DBusMessageIter pointing to the start of the dict
575 * @param iter_dict (out) A DBusMessageIter to be passed to
576 * wpa_dbus_dict_read_next_entry()
577 * @error on failure a descriptive error
578 * @return TRUE on success, FALSE on failure
581 dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
582 DBusMessageIter *iter_dict,
587 wpa_printf(MSG_MSGDUMP, "%s: start reading a dict entry", __func__);
588 if (!iter || !iter_dict) {
589 dbus_set_error_const(error, DBUS_ERROR_FAILED,
590 "[internal] missing message iterators");
594 type = dbus_message_iter_get_arg_type(iter);
595 if (type != DBUS_TYPE_ARRAY ||
596 dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY) {
597 wpa_printf(MSG_DEBUG,
598 "%s: unexpected message argument types (arg=%c element=%c)",
600 type != DBUS_TYPE_ARRAY ? '?' :
601 dbus_message_iter_get_element_type(iter));
602 dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
603 "unexpected message argument types");
607 dbus_message_iter_recurse(iter, iter_dict);
612 #define BYTE_ARRAY_CHUNK_SIZE 34
613 #define BYTE_ARRAY_ITEM_SIZE (sizeof(char))
615 static dbus_bool_t _wpa_dbus_dict_entry_get_byte_array(
616 DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry)
618 dbus_uint32_t count = 0;
619 dbus_bool_t success = FALSE;
620 char *buffer, *nbuffer;
622 entry->bytearray_value = NULL;
623 entry->array_type = DBUS_TYPE_BYTE;
625 buffer = os_calloc(BYTE_ARRAY_CHUNK_SIZE, BYTE_ARRAY_ITEM_SIZE);
629 entry->array_len = 0;
630 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_BYTE) {
633 if ((count % BYTE_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
634 nbuffer = os_realloc_array(
635 buffer, count + BYTE_ARRAY_CHUNK_SIZE,
636 BYTE_ARRAY_ITEM_SIZE);
637 if (nbuffer == NULL) {
639 wpa_printf(MSG_ERROR,
640 "dbus: %s out of memory trying to retrieve the string array",
647 dbus_message_iter_get_basic(iter, &byte);
648 buffer[count] = byte;
649 entry->array_len = ++count;
650 dbus_message_iter_next(iter);
652 entry->bytearray_value = buffer;
653 wpa_hexdump_key(MSG_MSGDUMP, "dbus: byte array contents",
654 entry->bytearray_value, entry->array_len);
656 /* Zero-length arrays are valid. */
657 if (entry->array_len == 0) {
658 os_free(entry->bytearray_value);
659 entry->bytearray_value = NULL;
669 #define STR_ARRAY_CHUNK_SIZE 8
670 #define STR_ARRAY_ITEM_SIZE (sizeof(char *))
672 static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
673 DBusMessageIter *iter, int array_type,
674 struct wpa_dbus_dict_entry *entry)
676 dbus_uint32_t count = 0;
677 char **buffer, **nbuffer;
679 entry->strarray_value = NULL;
680 entry->array_len = 0;
681 entry->array_type = DBUS_TYPE_STRING;
683 buffer = os_calloc(STR_ARRAY_CHUNK_SIZE, STR_ARRAY_ITEM_SIZE);
687 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
691 if ((count % STR_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
692 nbuffer = os_realloc_array(
693 buffer, count + STR_ARRAY_CHUNK_SIZE,
694 STR_ARRAY_ITEM_SIZE);
695 if (nbuffer == NULL) {
696 wpa_printf(MSG_ERROR,
697 "dbus: %s out of memory trying to retrieve the string array",
704 dbus_message_iter_get_basic(iter, &value);
705 wpa_printf(MSG_MSGDUMP, "%s: string_array value: %s",
706 __func__, wpa_debug_show_keys ? value : "[omitted]");
707 str = os_strdup(value);
709 wpa_printf(MSG_ERROR,
710 "dbus: %s out of memory trying to duplicate the string array",
714 buffer[count++] = str;
715 dbus_message_iter_next(iter);
717 entry->strarray_value = buffer;
718 entry->array_len = count;
719 wpa_printf(MSG_MSGDUMP, "%s: string_array length %u",
720 __func__, entry->array_len);
722 /* Zero-length arrays are valid. */
723 if (entry->array_len == 0) {
724 os_free(entry->strarray_value);
725 entry->strarray_value = NULL;
733 os_free(buffer[count]);
740 #define BIN_ARRAY_CHUNK_SIZE 10
741 #define BIN_ARRAY_ITEM_SIZE (sizeof(struct wpabuf *))
743 static dbus_bool_t _wpa_dbus_dict_entry_get_binarray(
744 DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry)
746 struct wpa_dbus_dict_entry tmpentry;
750 entry->array_type = WPAS_DBUS_TYPE_BINARRAY;
751 entry->array_len = 0;
752 entry->binarray_value = NULL;
754 type = dbus_message_iter_get_arg_type(iter);
755 wpa_printf(MSG_MSGDUMP, "%s: parsing binarray type %c", __func__, type);
756 if (type == DBUS_TYPE_INVALID) {
757 /* Likely an empty array of arrays */
760 if (type != DBUS_TYPE_ARRAY) {
761 wpa_printf(MSG_DEBUG, "%s: not an array type: %c",
766 type = dbus_message_iter_get_element_type(iter);
767 if (type != DBUS_TYPE_BYTE) {
768 wpa_printf(MSG_DEBUG, "%s: unexpected element type %c",
773 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_ARRAY) {
774 DBusMessageIter iter_array;
776 if (entry->array_len == buflen) {
777 struct wpabuf **newbuf;
779 buflen += BIN_ARRAY_CHUNK_SIZE;
781 newbuf = os_realloc_array(entry->binarray_value,
782 buflen, BIN_ARRAY_ITEM_SIZE);
785 entry->binarray_value = newbuf;
788 dbus_message_iter_recurse(iter, &iter_array);
789 os_memset(&tmpentry, 0, sizeof(tmpentry));
790 tmpentry.type = DBUS_TYPE_ARRAY;
791 if (_wpa_dbus_dict_entry_get_byte_array(&iter_array, &tmpentry)
795 entry->binarray_value[entry->array_len] =
796 wpabuf_alloc_ext_data((u8 *) tmpentry.bytearray_value,
798 if (entry->binarray_value[entry->array_len] == NULL) {
799 wpa_dbus_dict_entry_clear(&tmpentry);
803 dbus_message_iter_next(iter);
805 wpa_printf(MSG_MSGDUMP, "%s: binarray length %u",
806 __func__, entry->array_len);
811 for (i = 0; i < (int) entry->array_len; i++)
812 wpabuf_free(entry->binarray_value[i]);
813 os_free(entry->binarray_value);
814 entry->array_len = 0;
815 entry->binarray_value = NULL;
820 static dbus_bool_t _wpa_dbus_dict_entry_get_array(
821 DBusMessageIter *iter_dict_val, struct wpa_dbus_dict_entry *entry)
823 int array_type = dbus_message_iter_get_element_type(iter_dict_val);
824 dbus_bool_t success = FALSE;
825 DBusMessageIter iter_array;
827 wpa_printf(MSG_MSGDUMP, "%s: array_type %c", __func__, array_type);
829 dbus_message_iter_recurse(iter_dict_val, &iter_array);
831 switch (array_type) {
833 success = _wpa_dbus_dict_entry_get_byte_array(&iter_array,
836 case DBUS_TYPE_STRING:
837 success = _wpa_dbus_dict_entry_get_string_array(&iter_array,
841 case DBUS_TYPE_ARRAY:
842 success = _wpa_dbus_dict_entry_get_binarray(&iter_array, entry);
845 wpa_printf(MSG_MSGDUMP, "%s: unsupported array type %c",
846 __func__, array_type);
854 static dbus_bool_t _wpa_dbus_dict_fill_value_from_variant(
855 struct wpa_dbus_dict_entry *entry, DBusMessageIter *iter)
859 switch (entry->type) {
860 case DBUS_TYPE_OBJECT_PATH:
861 dbus_message_iter_get_basic(iter, &v);
862 wpa_printf(MSG_MSGDUMP, "%s: object path value: %s",
864 entry->str_value = os_strdup(v);
865 if (entry->str_value == NULL)
868 case DBUS_TYPE_STRING:
869 dbus_message_iter_get_basic(iter, &v);
870 wpa_printf(MSG_MSGDUMP, "%s: string value: %s",
871 __func__, wpa_debug_show_keys ? v : "[omitted]");
872 entry->str_value = os_strdup(v);
873 if (entry->str_value == NULL)
876 case DBUS_TYPE_BOOLEAN:
877 dbus_message_iter_get_basic(iter, &entry->bool_value);
878 wpa_printf(MSG_MSGDUMP, "%s: boolean value: %d",
879 __func__, entry->bool_value);
882 dbus_message_iter_get_basic(iter, &entry->byte_value);
883 wpa_printf(MSG_MSGDUMP, "%s: byte value: %d",
884 __func__, entry->byte_value);
886 case DBUS_TYPE_INT16:
887 dbus_message_iter_get_basic(iter, &entry->int16_value);
888 wpa_printf(MSG_MSGDUMP, "%s: int16 value: %d",
889 __func__, entry->int16_value);
891 case DBUS_TYPE_UINT16:
892 dbus_message_iter_get_basic(iter, &entry->uint16_value);
893 wpa_printf(MSG_MSGDUMP, "%s: uint16 value: %d",
894 __func__, entry->uint16_value);
896 case DBUS_TYPE_INT32:
897 dbus_message_iter_get_basic(iter, &entry->int32_value);
898 wpa_printf(MSG_MSGDUMP, "%s: int32 value: %d",
899 __func__, entry->int32_value);
901 case DBUS_TYPE_UINT32:
902 dbus_message_iter_get_basic(iter, &entry->uint32_value);
903 wpa_printf(MSG_MSGDUMP, "%s: uint32 value: %d",
904 __func__, entry->uint32_value);
906 case DBUS_TYPE_INT64:
907 dbus_message_iter_get_basic(iter, &entry->int64_value);
908 wpa_printf(MSG_MSGDUMP, "%s: int64 value: %lld",
909 __func__, (long long int) entry->int64_value);
911 case DBUS_TYPE_UINT64:
912 dbus_message_iter_get_basic(iter, &entry->uint64_value);
913 wpa_printf(MSG_MSGDUMP, "%s: uint64 value: %llu",
915 (unsigned long long int) entry->uint64_value);
917 case DBUS_TYPE_DOUBLE:
918 dbus_message_iter_get_basic(iter, &entry->double_value);
919 wpa_printf(MSG_MSGDUMP, "%s: double value: %f",
920 __func__, entry->double_value);
922 case DBUS_TYPE_ARRAY:
923 return _wpa_dbus_dict_entry_get_array(iter, entry);
925 wpa_printf(MSG_MSGDUMP, "%s: unsupported type %c",
926 __func__, entry->type);
935 * Read the current key/value entry from the dict. Entries are dynamically
936 * allocated when needed and must be freed after use with the
937 * wpa_dbus_dict_entry_clear() function.
939 * The returned entry object will be filled with the type and value of the next
940 * entry in the dict, or the type will be DBUS_TYPE_INVALID if an error
943 * @param iter_dict A valid DBusMessageIter returned from
944 * wpa_dbus_dict_open_read()
945 * @param entry A valid dict entry object into which the dict key and value
947 * @return TRUE on success, FALSE on failure
950 dbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict,
951 struct wpa_dbus_dict_entry * entry)
953 DBusMessageIter iter_dict_entry, iter_dict_val;
957 if (!iter_dict || !entry ||
958 dbus_message_iter_get_arg_type(iter_dict) != DBUS_TYPE_DICT_ENTRY) {
959 wpa_printf(MSG_DEBUG, "%s: not a dict entry", __func__);
963 dbus_message_iter_recurse(iter_dict, &iter_dict_entry);
964 dbus_message_iter_get_basic(&iter_dict_entry, &key);
965 wpa_printf(MSG_MSGDUMP, "%s: dict entry key: %s", __func__, key);
968 if (!dbus_message_iter_next(&iter_dict_entry)) {
969 wpa_printf(MSG_DEBUG, "%s: no variant in dict entry", __func__);
972 type = dbus_message_iter_get_arg_type(&iter_dict_entry);
973 if (type != DBUS_TYPE_VARIANT) {
974 wpa_printf(MSG_DEBUG,
975 "%s: unexpected dict entry variant type: %c",
980 dbus_message_iter_recurse(&iter_dict_entry, &iter_dict_val);
981 entry->type = dbus_message_iter_get_arg_type(&iter_dict_val);
982 wpa_printf(MSG_MSGDUMP, "%s: dict entry variant content type: %c",
983 __func__, entry->type);
984 entry->array_type = DBUS_TYPE_INVALID;
985 if (!_wpa_dbus_dict_fill_value_from_variant(entry, &iter_dict_val)) {
986 wpa_printf(MSG_DEBUG,
987 "%s: failed to fetch dict values from variant",
992 dbus_message_iter_next(iter_dict);
997 wpa_dbus_dict_entry_clear(entry);
998 entry->type = DBUS_TYPE_INVALID;
999 entry->array_type = DBUS_TYPE_INVALID;
1007 * Return whether or not there are additional dictionary entries.
1009 * @param iter_dict A valid DBusMessageIter returned from
1010 * wpa_dbus_dict_open_read()
1011 * @return TRUE if more dict entries exists, FALSE if no more dict entries
1014 dbus_bool_t wpa_dbus_dict_has_dict_entry(DBusMessageIter *iter_dict)
1018 return dbus_message_iter_get_arg_type(iter_dict) ==
1019 DBUS_TYPE_DICT_ENTRY;
1024 * Free any memory used by the entry object.
1026 * @param entry The entry object
1028 void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry)
1034 switch (entry->type) {
1035 case DBUS_TYPE_OBJECT_PATH:
1036 case DBUS_TYPE_STRING:
1037 os_free(entry->str_value);
1039 case DBUS_TYPE_ARRAY:
1040 switch (entry->array_type) {
1041 case DBUS_TYPE_BYTE:
1042 os_free(entry->bytearray_value);
1044 case DBUS_TYPE_STRING:
1045 if (!entry->strarray_value)
1047 for (i = 0; i < entry->array_len; i++)
1048 os_free(entry->strarray_value[i]);
1049 os_free(entry->strarray_value);
1051 case WPAS_DBUS_TYPE_BINARRAY:
1052 for (i = 0; i < entry->array_len; i++)
1053 wpabuf_free(entry->binarray_value[i]);
1054 os_free(entry->binarray_value);
1060 os_memset(entry, 0, sizeof(struct wpa_dbus_dict_entry));