13ff40c12SJohn Marino /*
23ff40c12SJohn Marino  * WPA Supplicant / dbus-based control interface
33ff40c12SJohn Marino  * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
43ff40c12SJohn Marino  *
53ff40c12SJohn Marino  * This software may be distributed under the terms of the BSD license.
63ff40c12SJohn Marino  * See README for more details.
73ff40c12SJohn Marino  */
83ff40c12SJohn Marino 
93ff40c12SJohn Marino #include "includes.h"
103ff40c12SJohn Marino #include <dbus/dbus.h>
113ff40c12SJohn Marino 
123ff40c12SJohn Marino #include "common.h"
133ff40c12SJohn Marino #include "wpabuf.h"
143ff40c12SJohn Marino #include "dbus_dict_helpers.h"
153ff40c12SJohn Marino 
163ff40c12SJohn Marino 
173ff40c12SJohn Marino /**
183ff40c12SJohn Marino  * Start a dict in a dbus message.  Should be paired with a call to
193ff40c12SJohn Marino  * wpa_dbus_dict_close_write().
203ff40c12SJohn Marino  *
213ff40c12SJohn Marino  * @param iter A valid dbus message iterator
223ff40c12SJohn Marino  * @param iter_dict (out) A dict iterator to pass to further dict functions
233ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
243ff40c12SJohn Marino  *
253ff40c12SJohn Marino  */
wpa_dbus_dict_open_write(DBusMessageIter * iter,DBusMessageIter * iter_dict)263ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_open_write(DBusMessageIter *iter,
273ff40c12SJohn Marino 				     DBusMessageIter *iter_dict)
283ff40c12SJohn Marino {
293ff40c12SJohn Marino 	dbus_bool_t result;
303ff40c12SJohn Marino 
313ff40c12SJohn Marino 	if (!iter || !iter_dict)
323ff40c12SJohn Marino 		return FALSE;
333ff40c12SJohn Marino 
343ff40c12SJohn Marino 	result = dbus_message_iter_open_container(
353ff40c12SJohn Marino 		iter,
363ff40c12SJohn Marino 		DBUS_TYPE_ARRAY,
373ff40c12SJohn Marino 		DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
383ff40c12SJohn Marino 		DBUS_TYPE_STRING_AS_STRING
393ff40c12SJohn Marino 		DBUS_TYPE_VARIANT_AS_STRING
403ff40c12SJohn Marino 		DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
413ff40c12SJohn Marino 		iter_dict);
423ff40c12SJohn Marino 	return result;
433ff40c12SJohn Marino }
443ff40c12SJohn Marino 
453ff40c12SJohn Marino 
463ff40c12SJohn Marino /**
473ff40c12SJohn Marino  * End a dict element in a dbus message.  Should be paired with
483ff40c12SJohn Marino  * a call to wpa_dbus_dict_open_write().
493ff40c12SJohn Marino  *
503ff40c12SJohn Marino  * @param iter valid dbus message iterator, same as passed to
513ff40c12SJohn Marino  *    wpa_dbus_dict_open_write()
523ff40c12SJohn Marino  * @param iter_dict a dbus dict iterator returned from
533ff40c12SJohn Marino  *    wpa_dbus_dict_open_write()
543ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
553ff40c12SJohn Marino  *
563ff40c12SJohn Marino  */
wpa_dbus_dict_close_write(DBusMessageIter * iter,DBusMessageIter * iter_dict)573ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter,
583ff40c12SJohn Marino 				      DBusMessageIter *iter_dict)
593ff40c12SJohn Marino {
603ff40c12SJohn Marino 	if (!iter || !iter_dict)
613ff40c12SJohn Marino 		return FALSE;
623ff40c12SJohn Marino 
633ff40c12SJohn Marino 	return dbus_message_iter_close_container(iter, iter_dict);
643ff40c12SJohn Marino }
653ff40c12SJohn Marino 
663ff40c12SJohn Marino 
wpa_dbus_type_as_string(const int type)673ff40c12SJohn Marino const char * wpa_dbus_type_as_string(const int type)
683ff40c12SJohn Marino {
693ff40c12SJohn Marino 	switch (type) {
703ff40c12SJohn Marino 	case DBUS_TYPE_BYTE:
713ff40c12SJohn Marino 		return DBUS_TYPE_BYTE_AS_STRING;
723ff40c12SJohn Marino 	case DBUS_TYPE_BOOLEAN:
733ff40c12SJohn Marino 		return DBUS_TYPE_BOOLEAN_AS_STRING;
743ff40c12SJohn Marino 	case DBUS_TYPE_INT16:
753ff40c12SJohn Marino 		return DBUS_TYPE_INT16_AS_STRING;
763ff40c12SJohn Marino 	case DBUS_TYPE_UINT16:
773ff40c12SJohn Marino 		return DBUS_TYPE_UINT16_AS_STRING;
783ff40c12SJohn Marino 	case DBUS_TYPE_INT32:
793ff40c12SJohn Marino 		return DBUS_TYPE_INT32_AS_STRING;
803ff40c12SJohn Marino 	case DBUS_TYPE_UINT32:
813ff40c12SJohn Marino 		return DBUS_TYPE_UINT32_AS_STRING;
823ff40c12SJohn Marino 	case DBUS_TYPE_INT64:
833ff40c12SJohn Marino 		return DBUS_TYPE_INT64_AS_STRING;
843ff40c12SJohn Marino 	case DBUS_TYPE_UINT64:
853ff40c12SJohn Marino 		return DBUS_TYPE_UINT64_AS_STRING;
863ff40c12SJohn Marino 	case DBUS_TYPE_DOUBLE:
873ff40c12SJohn Marino 		return DBUS_TYPE_DOUBLE_AS_STRING;
883ff40c12SJohn Marino 	case DBUS_TYPE_STRING:
893ff40c12SJohn Marino 		return DBUS_TYPE_STRING_AS_STRING;
903ff40c12SJohn Marino 	case DBUS_TYPE_OBJECT_PATH:
913ff40c12SJohn Marino 		return DBUS_TYPE_OBJECT_PATH_AS_STRING;
923ff40c12SJohn Marino 	case DBUS_TYPE_ARRAY:
933ff40c12SJohn Marino 		return DBUS_TYPE_ARRAY_AS_STRING;
943ff40c12SJohn Marino 	default:
953ff40c12SJohn Marino 		return NULL;
963ff40c12SJohn Marino 	}
973ff40c12SJohn Marino }
983ff40c12SJohn Marino 
993ff40c12SJohn Marino 
_wpa_dbus_add_dict_entry_start(DBusMessageIter * iter_dict,DBusMessageIter * iter_dict_entry,const char * key,const int value_type)1003ff40c12SJohn Marino static dbus_bool_t _wpa_dbus_add_dict_entry_start(
1013ff40c12SJohn Marino 	DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
1023ff40c12SJohn Marino 	const char *key, const int value_type)
1033ff40c12SJohn Marino {
1043ff40c12SJohn Marino 	if (!dbus_message_iter_open_container(iter_dict,
1053ff40c12SJohn Marino 					      DBUS_TYPE_DICT_ENTRY, NULL,
1063ff40c12SJohn Marino 					      iter_dict_entry))
1073ff40c12SJohn Marino 		return FALSE;
1083ff40c12SJohn Marino 
109*a1157835SDaniel Fojt 	return dbus_message_iter_append_basic(iter_dict_entry, DBUS_TYPE_STRING,
110*a1157835SDaniel Fojt 					      &key);
1113ff40c12SJohn Marino }
1123ff40c12SJohn Marino 
1133ff40c12SJohn Marino 
_wpa_dbus_add_dict_entry_end(DBusMessageIter * iter_dict,DBusMessageIter * iter_dict_entry,DBusMessageIter * iter_dict_val)1143ff40c12SJohn Marino static dbus_bool_t _wpa_dbus_add_dict_entry_end(
1153ff40c12SJohn Marino 	DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
1163ff40c12SJohn Marino 	DBusMessageIter *iter_dict_val)
1173ff40c12SJohn Marino {
1183ff40c12SJohn Marino 	if (!dbus_message_iter_close_container(iter_dict_entry, iter_dict_val))
1193ff40c12SJohn Marino 		return FALSE;
1203ff40c12SJohn Marino 
121*a1157835SDaniel Fojt 	return dbus_message_iter_close_container(iter_dict, iter_dict_entry);
1223ff40c12SJohn Marino }
1233ff40c12SJohn Marino 
1243ff40c12SJohn Marino 
_wpa_dbus_add_dict_entry_basic(DBusMessageIter * iter_dict,const char * key,const int value_type,const void * value)1253ff40c12SJohn Marino static dbus_bool_t _wpa_dbus_add_dict_entry_basic(DBusMessageIter *iter_dict,
1263ff40c12SJohn Marino 						  const char *key,
1273ff40c12SJohn Marino 						  const int value_type,
1283ff40c12SJohn Marino 						  const void *value)
1293ff40c12SJohn Marino {
1303ff40c12SJohn Marino 	DBusMessageIter iter_dict_entry, iter_dict_val;
1313ff40c12SJohn Marino 	const char *type_as_string = NULL;
1323ff40c12SJohn Marino 
1333ff40c12SJohn Marino 	if (key == NULL)
1343ff40c12SJohn Marino 		return FALSE;
1353ff40c12SJohn Marino 
1363ff40c12SJohn Marino 	type_as_string = wpa_dbus_type_as_string(value_type);
1373ff40c12SJohn Marino 	if (!type_as_string)
1383ff40c12SJohn Marino 		return FALSE;
1393ff40c12SJohn Marino 
1403ff40c12SJohn Marino 	if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
141*a1157835SDaniel Fojt 					    key, value_type) ||
142*a1157835SDaniel Fojt 	    !dbus_message_iter_open_container(&iter_dict_entry,
1433ff40c12SJohn Marino 					      DBUS_TYPE_VARIANT,
144*a1157835SDaniel Fojt 					      type_as_string, &iter_dict_val) ||
145*a1157835SDaniel Fojt 	    !dbus_message_iter_append_basic(&iter_dict_val, value_type, value))
1463ff40c12SJohn Marino 		return FALSE;
1473ff40c12SJohn Marino 
148*a1157835SDaniel Fojt 	return _wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
149*a1157835SDaniel Fojt 					    &iter_dict_val);
1503ff40c12SJohn Marino }
1513ff40c12SJohn Marino 
1523ff40c12SJohn Marino 
_wpa_dbus_add_dict_entry_byte_array(DBusMessageIter * iter_dict,const char * key,const char * value,const dbus_uint32_t value_len)1533ff40c12SJohn Marino static dbus_bool_t _wpa_dbus_add_dict_entry_byte_array(
1543ff40c12SJohn Marino 	DBusMessageIter *iter_dict, const char *key,
1553ff40c12SJohn Marino 	const char *value, const dbus_uint32_t value_len)
1563ff40c12SJohn Marino {
1573ff40c12SJohn Marino 	DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
1583ff40c12SJohn Marino 	dbus_uint32_t i;
1593ff40c12SJohn Marino 
1603ff40c12SJohn Marino 	if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
161*a1157835SDaniel Fojt 					    key, DBUS_TYPE_ARRAY) ||
162*a1157835SDaniel Fojt 	    !dbus_message_iter_open_container(&iter_dict_entry,
1633ff40c12SJohn Marino 					      DBUS_TYPE_VARIANT,
1643ff40c12SJohn Marino 					      DBUS_TYPE_ARRAY_AS_STRING
1653ff40c12SJohn Marino 					      DBUS_TYPE_BYTE_AS_STRING,
166*a1157835SDaniel Fojt 					      &iter_dict_val) ||
167*a1157835SDaniel Fojt 	    !dbus_message_iter_open_container(&iter_dict_val, DBUS_TYPE_ARRAY,
1683ff40c12SJohn Marino 					      DBUS_TYPE_BYTE_AS_STRING,
1693ff40c12SJohn Marino 					      &iter_array))
1703ff40c12SJohn Marino 		return FALSE;
1713ff40c12SJohn Marino 
1723ff40c12SJohn Marino 	for (i = 0; i < value_len; i++) {
1733ff40c12SJohn Marino 		if (!dbus_message_iter_append_basic(&iter_array,
1743ff40c12SJohn Marino 						    DBUS_TYPE_BYTE,
1753ff40c12SJohn Marino 						    &(value[i])))
1763ff40c12SJohn Marino 			return FALSE;
1773ff40c12SJohn Marino 	}
1783ff40c12SJohn Marino 
1793ff40c12SJohn Marino 	if (!dbus_message_iter_close_container(&iter_dict_val, &iter_array))
1803ff40c12SJohn Marino 		return FALSE;
1813ff40c12SJohn Marino 
182*a1157835SDaniel Fojt 	return _wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
183*a1157835SDaniel Fojt 					    &iter_dict_val);
1843ff40c12SJohn Marino }
1853ff40c12SJohn Marino 
1863ff40c12SJohn Marino 
1873ff40c12SJohn Marino /**
1883ff40c12SJohn Marino  * Add a string entry to the dict.
1893ff40c12SJohn Marino  *
1903ff40c12SJohn Marino  * @param iter_dict A valid DBusMessageIter returned from
1913ff40c12SJohn Marino  *    wpa_dbus_dict_open_write()
1923ff40c12SJohn Marino  * @param key The key of the dict item
1933ff40c12SJohn Marino  * @param value The string value
1943ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
1953ff40c12SJohn Marino  *
1963ff40c12SJohn Marino  */
wpa_dbus_dict_append_string(DBusMessageIter * iter_dict,const char * key,const char * value)1973ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_append_string(DBusMessageIter *iter_dict,
1983ff40c12SJohn Marino 					const char *key, const char *value)
1993ff40c12SJohn Marino {
2003ff40c12SJohn Marino 	if (!value)
2013ff40c12SJohn Marino 		return FALSE;
2023ff40c12SJohn Marino 	return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_STRING,
2033ff40c12SJohn Marino 					      &value);
2043ff40c12SJohn Marino }
2053ff40c12SJohn Marino 
2063ff40c12SJohn Marino 
2073ff40c12SJohn Marino /**
2083ff40c12SJohn Marino  * Add a boolean entry to the dict.
2093ff40c12SJohn Marino  *
2103ff40c12SJohn Marino  * @param iter_dict A valid DBusMessageIter returned from
2113ff40c12SJohn Marino  *    wpa_dbus_dict_open_write()
2123ff40c12SJohn Marino  * @param key The key of the dict item
2133ff40c12SJohn Marino  * @param value The boolean value
2143ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
2153ff40c12SJohn Marino  *
2163ff40c12SJohn Marino  */
wpa_dbus_dict_append_bool(DBusMessageIter * iter_dict,const char * key,const dbus_bool_t value)2173ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_append_bool(DBusMessageIter *iter_dict,
2183ff40c12SJohn Marino 				      const char *key, const dbus_bool_t value)
2193ff40c12SJohn Marino {
2203ff40c12SJohn Marino 	return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
2213ff40c12SJohn Marino 					      DBUS_TYPE_BOOLEAN, &value);
2223ff40c12SJohn Marino }
2233ff40c12SJohn Marino 
2243ff40c12SJohn Marino 
2253ff40c12SJohn Marino /**
2263ff40c12SJohn Marino  * Add a 16-bit signed integer entry to the dict.
2273ff40c12SJohn Marino  *
2283ff40c12SJohn Marino  * @param iter_dict A valid DBusMessageIter returned from
2293ff40c12SJohn Marino  *    wpa_dbus_dict_open_write()
2303ff40c12SJohn Marino  * @param key The key of the dict item
2313ff40c12SJohn Marino  * @param value The 16-bit signed integer value
2323ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
2333ff40c12SJohn Marino  *
2343ff40c12SJohn Marino  */
wpa_dbus_dict_append_int16(DBusMessageIter * iter_dict,const char * key,const dbus_int16_t value)2353ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_append_int16(DBusMessageIter *iter_dict,
2363ff40c12SJohn Marino 				       const char *key,
2373ff40c12SJohn Marino 				       const dbus_int16_t value)
2383ff40c12SJohn Marino {
2393ff40c12SJohn Marino 	return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT16,
2403ff40c12SJohn Marino 					      &value);
2413ff40c12SJohn Marino }
2423ff40c12SJohn Marino 
2433ff40c12SJohn Marino 
2443ff40c12SJohn Marino /**
2453ff40c12SJohn Marino  * Add a 16-bit unsigned integer entry to the dict.
2463ff40c12SJohn Marino  *
2473ff40c12SJohn Marino  * @param iter_dict A valid DBusMessageIter returned from
2483ff40c12SJohn Marino  *    wpa_dbus_dict_open_write()
2493ff40c12SJohn Marino  * @param key The key of the dict item
2503ff40c12SJohn Marino  * @param value The 16-bit unsigned integer value
2513ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
2523ff40c12SJohn Marino  *
2533ff40c12SJohn Marino  */
wpa_dbus_dict_append_uint16(DBusMessageIter * iter_dict,const char * key,const dbus_uint16_t value)2543ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_append_uint16(DBusMessageIter *iter_dict,
2553ff40c12SJohn Marino 					const char *key,
2563ff40c12SJohn Marino 					const dbus_uint16_t value)
2573ff40c12SJohn Marino {
2583ff40c12SJohn Marino 	return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT16,
2593ff40c12SJohn Marino 					      &value);
2603ff40c12SJohn Marino }
2613ff40c12SJohn Marino 
2623ff40c12SJohn Marino 
2633ff40c12SJohn Marino /**
2643ff40c12SJohn Marino  * Add a 32-bit signed integer to the dict.
2653ff40c12SJohn Marino  *
2663ff40c12SJohn Marino  * @param iter_dict A valid DBusMessageIter returned from
2673ff40c12SJohn Marino  *    wpa_dbus_dict_open_write()
2683ff40c12SJohn Marino  * @param key The key of the dict item
2693ff40c12SJohn Marino  * @param value The 32-bit signed integer value
2703ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
2713ff40c12SJohn Marino  *
2723ff40c12SJohn Marino  */
wpa_dbus_dict_append_int32(DBusMessageIter * iter_dict,const char * key,const dbus_int32_t value)2733ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_append_int32(DBusMessageIter *iter_dict,
2743ff40c12SJohn Marino 				       const char *key,
2753ff40c12SJohn Marino 				       const dbus_int32_t value)
2763ff40c12SJohn Marino {
2773ff40c12SJohn Marino 	return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT32,
2783ff40c12SJohn Marino 					      &value);
2793ff40c12SJohn Marino }
2803ff40c12SJohn Marino 
2813ff40c12SJohn Marino 
2823ff40c12SJohn Marino /**
2833ff40c12SJohn Marino  * Add a 32-bit unsigned integer entry to the dict.
2843ff40c12SJohn Marino  *
2853ff40c12SJohn Marino  * @param iter_dict A valid DBusMessageIter returned from
2863ff40c12SJohn Marino  *    wpa_dbus_dict_open_write()
2873ff40c12SJohn Marino  * @param key The key of the dict item
2883ff40c12SJohn Marino  * @param value The 32-bit unsigned integer value
2893ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
2903ff40c12SJohn Marino  *
2913ff40c12SJohn Marino  */
wpa_dbus_dict_append_uint32(DBusMessageIter * iter_dict,const char * key,const dbus_uint32_t value)2923ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_append_uint32(DBusMessageIter *iter_dict,
2933ff40c12SJohn Marino 					const char *key,
2943ff40c12SJohn Marino 					const dbus_uint32_t value)
2953ff40c12SJohn Marino {
2963ff40c12SJohn Marino 	return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT32,
2973ff40c12SJohn Marino 					      &value);
2983ff40c12SJohn Marino }
2993ff40c12SJohn Marino 
3003ff40c12SJohn Marino 
3013ff40c12SJohn Marino /**
3023ff40c12SJohn Marino  * Add a DBus object path entry to the dict.
3033ff40c12SJohn Marino  *
3043ff40c12SJohn Marino  * @param iter_dict A valid DBusMessageIter returned from
3053ff40c12SJohn Marino  *    wpa_dbus_dict_open_write()
3063ff40c12SJohn Marino  * @param key The key of the dict item
3073ff40c12SJohn Marino  * @param value The DBus object path value
3083ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
3093ff40c12SJohn Marino  *
3103ff40c12SJohn Marino  */
wpa_dbus_dict_append_object_path(DBusMessageIter * iter_dict,const char * key,const char * value)3113ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_append_object_path(DBusMessageIter *iter_dict,
3123ff40c12SJohn Marino 					     const char *key,
3133ff40c12SJohn Marino 					     const char *value)
3143ff40c12SJohn Marino {
3153ff40c12SJohn Marino 	if (!value)
3163ff40c12SJohn Marino 		return FALSE;
3173ff40c12SJohn Marino 	return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
3183ff40c12SJohn Marino 					      DBUS_TYPE_OBJECT_PATH, &value);
3193ff40c12SJohn Marino }
3203ff40c12SJohn Marino 
3213ff40c12SJohn Marino 
3223ff40c12SJohn Marino /**
3233ff40c12SJohn Marino  * Add a byte array entry to the dict.
3243ff40c12SJohn Marino  *
3253ff40c12SJohn Marino  * @param iter_dict A valid DBusMessageIter returned from
3263ff40c12SJohn Marino  *    wpa_dbus_dict_open_write()
3273ff40c12SJohn Marino  * @param key The key of the dict item
3283ff40c12SJohn Marino  * @param value The byte array
3293ff40c12SJohn Marino  * @param value_len The length of the byte array, in bytes
3303ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
3313ff40c12SJohn Marino  *
3323ff40c12SJohn Marino  */
wpa_dbus_dict_append_byte_array(DBusMessageIter * iter_dict,const char * key,const char * value,const dbus_uint32_t value_len)3333ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_append_byte_array(DBusMessageIter *iter_dict,
3343ff40c12SJohn Marino 					    const char *key,
3353ff40c12SJohn Marino 					    const char *value,
3363ff40c12SJohn Marino 					    const dbus_uint32_t value_len)
3373ff40c12SJohn Marino {
338*a1157835SDaniel Fojt 	if (!key || (!value && value_len != 0))
3393ff40c12SJohn Marino 		return FALSE;
3403ff40c12SJohn Marino 	return _wpa_dbus_add_dict_entry_byte_array(iter_dict, key, value,
3413ff40c12SJohn Marino 						   value_len);
3423ff40c12SJohn Marino }
3433ff40c12SJohn Marino 
3443ff40c12SJohn Marino 
3453ff40c12SJohn Marino /**
3463ff40c12SJohn Marino  * Begin an array entry in the dict
3473ff40c12SJohn Marino  *
3483ff40c12SJohn Marino  * @param iter_dict A valid DBusMessageIter returned from
3493ff40c12SJohn Marino  *                  wpa_dbus_dict_open_write()
3503ff40c12SJohn Marino  * @param key The key of the dict item
3513ff40c12SJohn Marino  * @param type The type of the contained data
3523ff40c12SJohn Marino  * @param iter_dict_entry A private DBusMessageIter provided by the caller to
3533ff40c12SJohn Marino  *                        be passed to wpa_dbus_dict_end_string_array()
3543ff40c12SJohn Marino  * @param iter_dict_val A private DBusMessageIter provided by the caller to
3553ff40c12SJohn Marino  *                      be passed to wpa_dbus_dict_end_string_array()
3563ff40c12SJohn Marino  * @param iter_array On return, the DBusMessageIter to be passed to
3573ff40c12SJohn Marino  *                   wpa_dbus_dict_string_array_add_element()
3583ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
3593ff40c12SJohn Marino  *
3603ff40c12SJohn Marino  */
wpa_dbus_dict_begin_array(DBusMessageIter * iter_dict,const char * key,const char * type,DBusMessageIter * iter_dict_entry,DBusMessageIter * iter_dict_val,DBusMessageIter * iter_array)3613ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_begin_array(DBusMessageIter *iter_dict,
3623ff40c12SJohn Marino 				      const char *key, const char *type,
3633ff40c12SJohn Marino 				      DBusMessageIter *iter_dict_entry,
3643ff40c12SJohn Marino 				      DBusMessageIter *iter_dict_val,
3653ff40c12SJohn Marino 				      DBusMessageIter *iter_array)
3663ff40c12SJohn Marino {
3673ff40c12SJohn Marino 	char array_type[10];
3683ff40c12SJohn Marino 	int err;
3693ff40c12SJohn Marino 
3703ff40c12SJohn Marino 	err = os_snprintf(array_type, sizeof(array_type),
3713ff40c12SJohn Marino 			  DBUS_TYPE_ARRAY_AS_STRING "%s",
3723ff40c12SJohn Marino 			  type);
373*a1157835SDaniel Fojt 	if (os_snprintf_error(sizeof(array_type), err))
3743ff40c12SJohn Marino 		return FALSE;
3753ff40c12SJohn Marino 
376*a1157835SDaniel Fojt 	if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array ||
377*a1157835SDaniel Fojt 	    !_wpa_dbus_add_dict_entry_start(iter_dict, iter_dict_entry,
378*a1157835SDaniel Fojt 					    key, DBUS_TYPE_ARRAY) ||
379*a1157835SDaniel Fojt 	    !dbus_message_iter_open_container(iter_dict_entry,
3803ff40c12SJohn Marino 					      DBUS_TYPE_VARIANT,
3813ff40c12SJohn Marino 					      array_type,
3823ff40c12SJohn Marino 					      iter_dict_val))
3833ff40c12SJohn Marino 		return FALSE;
3843ff40c12SJohn Marino 
385*a1157835SDaniel Fojt 	return dbus_message_iter_open_container(iter_dict_val, DBUS_TYPE_ARRAY,
386*a1157835SDaniel Fojt 						type, iter_array);
3873ff40c12SJohn Marino }
3883ff40c12SJohn Marino 
3893ff40c12SJohn Marino 
wpa_dbus_dict_begin_string_array(DBusMessageIter * iter_dict,const char * key,DBusMessageIter * iter_dict_entry,DBusMessageIter * iter_dict_val,DBusMessageIter * iter_array)3903ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_begin_string_array(DBusMessageIter *iter_dict,
3913ff40c12SJohn Marino 					     const char *key,
3923ff40c12SJohn Marino 					     DBusMessageIter *iter_dict_entry,
3933ff40c12SJohn Marino 					     DBusMessageIter *iter_dict_val,
3943ff40c12SJohn Marino 					     DBusMessageIter *iter_array)
3953ff40c12SJohn Marino {
3963ff40c12SJohn Marino 	return wpa_dbus_dict_begin_array(
3973ff40c12SJohn Marino 		iter_dict, key,
3983ff40c12SJohn Marino 		DBUS_TYPE_STRING_AS_STRING,
3993ff40c12SJohn Marino 		iter_dict_entry, iter_dict_val, iter_array);
4003ff40c12SJohn Marino }
4013ff40c12SJohn Marino 
4023ff40c12SJohn Marino 
4033ff40c12SJohn Marino /**
4043ff40c12SJohn Marino  * Add a single string element to a string array dict entry
4053ff40c12SJohn Marino  *
4063ff40c12SJohn Marino  * @param iter_array A valid DBusMessageIter returned from
4073ff40c12SJohn Marino  *                   wpa_dbus_dict_begin_string_array()'s
4083ff40c12SJohn Marino  *                   iter_array parameter
4093ff40c12SJohn Marino  * @param elem The string element to be added to the dict entry's string array
4103ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
4113ff40c12SJohn Marino  *
4123ff40c12SJohn Marino  */
wpa_dbus_dict_string_array_add_element(DBusMessageIter * iter_array,const char * elem)4133ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_string_array_add_element(DBusMessageIter *iter_array,
4143ff40c12SJohn Marino 						   const char *elem)
4153ff40c12SJohn Marino {
4163ff40c12SJohn Marino 	if (!iter_array || !elem)
4173ff40c12SJohn Marino 		return FALSE;
4183ff40c12SJohn Marino 
4193ff40c12SJohn Marino 	return dbus_message_iter_append_basic(iter_array, DBUS_TYPE_STRING,
4203ff40c12SJohn Marino 					      &elem);
4213ff40c12SJohn Marino }
4223ff40c12SJohn Marino 
4233ff40c12SJohn Marino 
4243ff40c12SJohn Marino /**
4253ff40c12SJohn Marino  * Add a single byte array element to a string array dict entry
4263ff40c12SJohn Marino  *
4273ff40c12SJohn Marino  * @param iter_array A valid DBusMessageIter returned from
4283ff40c12SJohn Marino  *                   wpa_dbus_dict_begin_array()'s iter_array
4293ff40c12SJohn Marino  *                   parameter -- note that wpa_dbus_dict_begin_array()
4303ff40c12SJohn Marino  *                   must have been called with "ay" as the type
4313ff40c12SJohn Marino  * @param value The data to be added to the dict entry's array
4323ff40c12SJohn Marino  * @param value_len The length of the data
4333ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
4343ff40c12SJohn Marino  *
4353ff40c12SJohn Marino  */
wpa_dbus_dict_bin_array_add_element(DBusMessageIter * iter_array,const u8 * value,size_t value_len)4363ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_bin_array_add_element(DBusMessageIter *iter_array,
4373ff40c12SJohn Marino 						const u8 *value,
4383ff40c12SJohn Marino 						size_t value_len)
4393ff40c12SJohn Marino {
4403ff40c12SJohn Marino 	DBusMessageIter iter_bytes;
4413ff40c12SJohn Marino 	size_t i;
4423ff40c12SJohn Marino 
443*a1157835SDaniel Fojt 	if (!iter_array || !value ||
444*a1157835SDaniel Fojt 	    !dbus_message_iter_open_container(iter_array, DBUS_TYPE_ARRAY,
4453ff40c12SJohn Marino 					      DBUS_TYPE_BYTE_AS_STRING,
4463ff40c12SJohn Marino 					      &iter_bytes))
4473ff40c12SJohn Marino 		return FALSE;
4483ff40c12SJohn Marino 
4493ff40c12SJohn Marino 	for (i = 0; i < value_len; i++) {
4503ff40c12SJohn Marino 		if (!dbus_message_iter_append_basic(&iter_bytes,
4513ff40c12SJohn Marino 						    DBUS_TYPE_BYTE,
4523ff40c12SJohn Marino 						    &(value[i])))
4533ff40c12SJohn Marino 			return FALSE;
4543ff40c12SJohn Marino 	}
4553ff40c12SJohn Marino 
456*a1157835SDaniel Fojt 	return dbus_message_iter_close_container(iter_array, &iter_bytes);
4573ff40c12SJohn Marino }
4583ff40c12SJohn Marino 
4593ff40c12SJohn Marino 
4603ff40c12SJohn Marino /**
4613ff40c12SJohn Marino  * End an array dict entry
4623ff40c12SJohn Marino  *
4633ff40c12SJohn Marino  * @param iter_dict A valid DBusMessageIter returned from
4643ff40c12SJohn Marino  *                  wpa_dbus_dict_open_write()
4653ff40c12SJohn Marino  * @param iter_dict_entry A private DBusMessageIter returned from
4663ff40c12SJohn Marino  *                        wpa_dbus_dict_begin_string_array() or
4673ff40c12SJohn Marino  *			  wpa_dbus_dict_begin_array()
4683ff40c12SJohn Marino  * @param iter_dict_val A private DBusMessageIter returned from
4693ff40c12SJohn Marino  *                      wpa_dbus_dict_begin_string_array() or
4703ff40c12SJohn Marino  *			wpa_dbus_dict_begin_array()
4713ff40c12SJohn Marino  * @param iter_array A DBusMessageIter returned from
4723ff40c12SJohn Marino  *                   wpa_dbus_dict_begin_string_array() or
4733ff40c12SJohn Marino  *		     wpa_dbus_dict_begin_array()
4743ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
4753ff40c12SJohn Marino  *
4763ff40c12SJohn Marino  */
wpa_dbus_dict_end_array(DBusMessageIter * iter_dict,DBusMessageIter * iter_dict_entry,DBusMessageIter * iter_dict_val,DBusMessageIter * iter_array)4773ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_end_array(DBusMessageIter *iter_dict,
4783ff40c12SJohn Marino 				    DBusMessageIter *iter_dict_entry,
4793ff40c12SJohn Marino 				    DBusMessageIter *iter_dict_val,
4803ff40c12SJohn Marino 				    DBusMessageIter *iter_array)
4813ff40c12SJohn Marino {
482*a1157835SDaniel Fojt 	if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array ||
483*a1157835SDaniel Fojt 	    !dbus_message_iter_close_container(iter_dict_val, iter_array))
4843ff40c12SJohn Marino 		return FALSE;
4853ff40c12SJohn Marino 
486*a1157835SDaniel Fojt 	return _wpa_dbus_add_dict_entry_end(iter_dict, iter_dict_entry,
487*a1157835SDaniel Fojt 					    iter_dict_val);
4883ff40c12SJohn Marino }
4893ff40c12SJohn Marino 
4903ff40c12SJohn Marino 
4913ff40c12SJohn Marino /**
4923ff40c12SJohn Marino  * Convenience function to add an entire string array to the dict.
4933ff40c12SJohn Marino  *
4943ff40c12SJohn Marino  * @param iter_dict A valid DBusMessageIter returned from
4953ff40c12SJohn Marino  *                  wpa_dbus_dict_open_write()
4963ff40c12SJohn Marino  * @param key The key of the dict item
4973ff40c12SJohn Marino  * @param items The array of strings
4983ff40c12SJohn Marino  * @param num_items The number of strings in the array
4993ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
5003ff40c12SJohn Marino  *
5013ff40c12SJohn Marino  */
wpa_dbus_dict_append_string_array(DBusMessageIter * iter_dict,const char * key,const char ** items,const dbus_uint32_t num_items)5023ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_append_string_array(DBusMessageIter *iter_dict,
5033ff40c12SJohn Marino 					      const char *key,
5043ff40c12SJohn Marino 					      const char **items,
5053ff40c12SJohn Marino 					      const dbus_uint32_t num_items)
5063ff40c12SJohn Marino {
5073ff40c12SJohn Marino 	DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
5083ff40c12SJohn Marino 	dbus_uint32_t i;
5093ff40c12SJohn Marino 
510*a1157835SDaniel Fojt 	if (!key || (!items && num_items != 0) ||
511*a1157835SDaniel Fojt 	    !wpa_dbus_dict_begin_string_array(iter_dict, key,
5123ff40c12SJohn Marino 					      &iter_dict_entry, &iter_dict_val,
5133ff40c12SJohn Marino 					      &iter_array))
5143ff40c12SJohn Marino 		return FALSE;
5153ff40c12SJohn Marino 
5163ff40c12SJohn Marino 	for (i = 0; i < num_items; i++) {
5173ff40c12SJohn Marino 		if (!wpa_dbus_dict_string_array_add_element(&iter_array,
5183ff40c12SJohn Marino 							    items[i]))
5193ff40c12SJohn Marino 			return FALSE;
5203ff40c12SJohn Marino 	}
5213ff40c12SJohn Marino 
522*a1157835SDaniel Fojt 	return wpa_dbus_dict_end_string_array(iter_dict, &iter_dict_entry,
523*a1157835SDaniel Fojt 					      &iter_dict_val, &iter_array);
5243ff40c12SJohn Marino }
5253ff40c12SJohn Marino 
5263ff40c12SJohn Marino 
5273ff40c12SJohn Marino /**
5283ff40c12SJohn Marino  * Convenience function to add an wpabuf binary array to the dict.
5293ff40c12SJohn Marino  *
5303ff40c12SJohn Marino  * @param iter_dict A valid DBusMessageIter returned from
5313ff40c12SJohn Marino  *                  wpa_dbus_dict_open_write()
5323ff40c12SJohn Marino  * @param key The key of the dict item
5333ff40c12SJohn Marino  * @param items The array of wpabuf structures
5343ff40c12SJohn Marino  * @param num_items The number of strings in the array
5353ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
5363ff40c12SJohn Marino  *
5373ff40c12SJohn Marino  */
wpa_dbus_dict_append_wpabuf_array(DBusMessageIter * iter_dict,const char * key,const struct wpabuf ** items,const dbus_uint32_t num_items)5383ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_append_wpabuf_array(DBusMessageIter *iter_dict,
5393ff40c12SJohn Marino 					      const char *key,
5403ff40c12SJohn Marino 					      const struct wpabuf **items,
5413ff40c12SJohn Marino 					      const dbus_uint32_t num_items)
5423ff40c12SJohn Marino {
5433ff40c12SJohn Marino 	DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
5443ff40c12SJohn Marino 	dbus_uint32_t i;
5453ff40c12SJohn Marino 
546*a1157835SDaniel Fojt 	if (!key ||
547*a1157835SDaniel Fojt 	    (!items && num_items != 0) ||
548*a1157835SDaniel Fojt 	    !wpa_dbus_dict_begin_array(iter_dict, key,
5493ff40c12SJohn Marino 				       DBUS_TYPE_ARRAY_AS_STRING
5503ff40c12SJohn Marino 				       DBUS_TYPE_BYTE_AS_STRING,
5513ff40c12SJohn Marino 				       &iter_dict_entry, &iter_dict_val,
5523ff40c12SJohn Marino 				       &iter_array))
5533ff40c12SJohn Marino 		return FALSE;
5543ff40c12SJohn Marino 
5553ff40c12SJohn Marino 	for (i = 0; i < num_items; i++) {
5563ff40c12SJohn Marino 		if (!wpa_dbus_dict_bin_array_add_element(&iter_array,
5573ff40c12SJohn Marino 							 wpabuf_head(items[i]),
5583ff40c12SJohn Marino 							 wpabuf_len(items[i])))
5593ff40c12SJohn Marino 			return FALSE;
5603ff40c12SJohn Marino 	}
5613ff40c12SJohn Marino 
562*a1157835SDaniel Fojt 	return wpa_dbus_dict_end_array(iter_dict, &iter_dict_entry,
563*a1157835SDaniel Fojt 				       &iter_dict_val, &iter_array);
5643ff40c12SJohn Marino }
5653ff40c12SJohn Marino 
5663ff40c12SJohn Marino 
5673ff40c12SJohn Marino /*****************************************************/
5683ff40c12SJohn Marino /* Stuff for reading dicts                           */
5693ff40c12SJohn Marino /*****************************************************/
5703ff40c12SJohn Marino 
5713ff40c12SJohn Marino /**
5723ff40c12SJohn Marino  * Start reading from a dbus dict.
5733ff40c12SJohn Marino  *
5743ff40c12SJohn Marino  * @param iter A valid DBusMessageIter pointing to the start of the dict
5753ff40c12SJohn Marino  * @param iter_dict (out) A DBusMessageIter to be passed to
5763ff40c12SJohn Marino  *    wpa_dbus_dict_read_next_entry()
5773ff40c12SJohn Marino  * @error on failure a descriptive error
5783ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
5793ff40c12SJohn Marino  *
5803ff40c12SJohn Marino  */
wpa_dbus_dict_open_read(DBusMessageIter * iter,DBusMessageIter * iter_dict,DBusError * error)5813ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
5823ff40c12SJohn Marino 				    DBusMessageIter *iter_dict,
5833ff40c12SJohn Marino 				    DBusError *error)
5843ff40c12SJohn Marino {
585*a1157835SDaniel Fojt 	int type;
586*a1157835SDaniel Fojt 
587*a1157835SDaniel Fojt 	wpa_printf(MSG_MSGDUMP, "%s: start reading a dict entry", __func__);
5883ff40c12SJohn Marino 	if (!iter || !iter_dict) {
5893ff40c12SJohn Marino 		dbus_set_error_const(error, DBUS_ERROR_FAILED,
5903ff40c12SJohn Marino 				     "[internal] missing message iterators");
5913ff40c12SJohn Marino 		return FALSE;
5923ff40c12SJohn Marino 	}
5933ff40c12SJohn Marino 
594*a1157835SDaniel Fojt 	type = dbus_message_iter_get_arg_type(iter);
595*a1157835SDaniel Fojt 	if (type != DBUS_TYPE_ARRAY ||
5963ff40c12SJohn Marino 	    dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY) {
597*a1157835SDaniel Fojt 		wpa_printf(MSG_DEBUG,
598*a1157835SDaniel Fojt 			   "%s: unexpected message argument types (arg=%c element=%c)",
599*a1157835SDaniel Fojt 			   __func__, type,
600*a1157835SDaniel Fojt 			   type != DBUS_TYPE_ARRAY ? '?' :
601*a1157835SDaniel Fojt 			   dbus_message_iter_get_element_type(iter));
6023ff40c12SJohn Marino 		dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
6033ff40c12SJohn Marino 				     "unexpected message argument types");
6043ff40c12SJohn Marino 		return FALSE;
6053ff40c12SJohn Marino 	}
6063ff40c12SJohn Marino 
6073ff40c12SJohn Marino 	dbus_message_iter_recurse(iter, iter_dict);
6083ff40c12SJohn Marino 	return TRUE;
6093ff40c12SJohn Marino }
6103ff40c12SJohn Marino 
6113ff40c12SJohn Marino 
6123ff40c12SJohn Marino #define BYTE_ARRAY_CHUNK_SIZE 34
6133ff40c12SJohn Marino #define BYTE_ARRAY_ITEM_SIZE (sizeof(char))
6143ff40c12SJohn Marino 
_wpa_dbus_dict_entry_get_byte_array(DBusMessageIter * iter,struct wpa_dbus_dict_entry * entry)6153ff40c12SJohn Marino static dbus_bool_t _wpa_dbus_dict_entry_get_byte_array(
6163ff40c12SJohn Marino 	DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry)
6173ff40c12SJohn Marino {
6183ff40c12SJohn Marino 	dbus_uint32_t count = 0;
6193ff40c12SJohn Marino 	dbus_bool_t success = FALSE;
6203ff40c12SJohn Marino 	char *buffer, *nbuffer;
6213ff40c12SJohn Marino 
6223ff40c12SJohn Marino 	entry->bytearray_value = NULL;
6233ff40c12SJohn Marino 	entry->array_type = DBUS_TYPE_BYTE;
6243ff40c12SJohn Marino 
6253ff40c12SJohn Marino 	buffer = os_calloc(BYTE_ARRAY_CHUNK_SIZE, BYTE_ARRAY_ITEM_SIZE);
6263ff40c12SJohn Marino 	if (!buffer)
6273ff40c12SJohn Marino 		return FALSE;
6283ff40c12SJohn Marino 
6293ff40c12SJohn Marino 	entry->array_len = 0;
6303ff40c12SJohn Marino 	while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_BYTE) {
6313ff40c12SJohn Marino 		char byte;
6323ff40c12SJohn Marino 
6333ff40c12SJohn Marino 		if ((count % BYTE_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
6343ff40c12SJohn Marino 			nbuffer = os_realloc_array(
6353ff40c12SJohn Marino 				buffer, count + BYTE_ARRAY_CHUNK_SIZE,
6363ff40c12SJohn Marino 				BYTE_ARRAY_ITEM_SIZE);
6373ff40c12SJohn Marino 			if (nbuffer == NULL) {
6383ff40c12SJohn Marino 				os_free(buffer);
639*a1157835SDaniel Fojt 				wpa_printf(MSG_ERROR,
640*a1157835SDaniel Fojt 					   "dbus: %s out of memory trying to retrieve the string array",
641*a1157835SDaniel Fojt 					   __func__);
6423ff40c12SJohn Marino 				goto done;
6433ff40c12SJohn Marino 			}
6443ff40c12SJohn Marino 			buffer = nbuffer;
6453ff40c12SJohn Marino 		}
6463ff40c12SJohn Marino 
6473ff40c12SJohn Marino 		dbus_message_iter_get_basic(iter, &byte);
648*a1157835SDaniel Fojt 		buffer[count] = byte;
6493ff40c12SJohn Marino 		entry->array_len = ++count;
6503ff40c12SJohn Marino 		dbus_message_iter_next(iter);
6513ff40c12SJohn Marino 	}
652*a1157835SDaniel Fojt 	entry->bytearray_value = buffer;
653*a1157835SDaniel Fojt 	wpa_hexdump_key(MSG_MSGDUMP, "dbus: byte array contents",
654*a1157835SDaniel Fojt 			entry->bytearray_value, entry->array_len);
6553ff40c12SJohn Marino 
6563ff40c12SJohn Marino 	/* Zero-length arrays are valid. */
6573ff40c12SJohn Marino 	if (entry->array_len == 0) {
6583ff40c12SJohn Marino 		os_free(entry->bytearray_value);
6593ff40c12SJohn Marino 		entry->bytearray_value = NULL;
6603ff40c12SJohn Marino 	}
6613ff40c12SJohn Marino 
6623ff40c12SJohn Marino 	success = TRUE;
6633ff40c12SJohn Marino 
6643ff40c12SJohn Marino done:
6653ff40c12SJohn Marino 	return success;
6663ff40c12SJohn Marino }
6673ff40c12SJohn Marino 
6683ff40c12SJohn Marino 
6693ff40c12SJohn Marino #define STR_ARRAY_CHUNK_SIZE 8
6703ff40c12SJohn Marino #define STR_ARRAY_ITEM_SIZE (sizeof(char *))
6713ff40c12SJohn Marino 
_wpa_dbus_dict_entry_get_string_array(DBusMessageIter * iter,int array_type,struct wpa_dbus_dict_entry * entry)6723ff40c12SJohn Marino static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
6733ff40c12SJohn Marino 	DBusMessageIter *iter, int array_type,
6743ff40c12SJohn Marino 	struct wpa_dbus_dict_entry *entry)
6753ff40c12SJohn Marino {
6763ff40c12SJohn Marino 	dbus_uint32_t count = 0;
6773ff40c12SJohn Marino 	char **buffer, **nbuffer;
6783ff40c12SJohn Marino 
6793ff40c12SJohn Marino 	entry->strarray_value = NULL;
680*a1157835SDaniel Fojt 	entry->array_len = 0;
6813ff40c12SJohn Marino 	entry->array_type = DBUS_TYPE_STRING;
6823ff40c12SJohn Marino 
6833ff40c12SJohn Marino 	buffer = os_calloc(STR_ARRAY_CHUNK_SIZE, STR_ARRAY_ITEM_SIZE);
6843ff40c12SJohn Marino 	if (buffer == NULL)
6853ff40c12SJohn Marino 		return FALSE;
6863ff40c12SJohn Marino 
6873ff40c12SJohn Marino 	while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
6883ff40c12SJohn Marino 		const char *value;
6893ff40c12SJohn Marino 		char *str;
6903ff40c12SJohn Marino 
6913ff40c12SJohn Marino 		if ((count % STR_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
6923ff40c12SJohn Marino 			nbuffer = os_realloc_array(
6933ff40c12SJohn Marino 				buffer, count + STR_ARRAY_CHUNK_SIZE,
6943ff40c12SJohn Marino 				STR_ARRAY_ITEM_SIZE);
6953ff40c12SJohn Marino 			if (nbuffer == NULL) {
696*a1157835SDaniel Fojt 				wpa_printf(MSG_ERROR,
697*a1157835SDaniel Fojt 					   "dbus: %s out of memory trying to retrieve the string array",
698*a1157835SDaniel Fojt 					   __func__);
699*a1157835SDaniel Fojt 				goto fail;
7003ff40c12SJohn Marino 			}
7013ff40c12SJohn Marino 			buffer = nbuffer;
7023ff40c12SJohn Marino 		}
7033ff40c12SJohn Marino 
7043ff40c12SJohn Marino 		dbus_message_iter_get_basic(iter, &value);
705*a1157835SDaniel Fojt 		wpa_printf(MSG_MSGDUMP, "%s: string_array value: %s",
706*a1157835SDaniel Fojt 			   __func__, wpa_debug_show_keys ? value : "[omitted]");
7073ff40c12SJohn Marino 		str = os_strdup(value);
7083ff40c12SJohn Marino 		if (str == NULL) {
709*a1157835SDaniel Fojt 			wpa_printf(MSG_ERROR,
710*a1157835SDaniel Fojt 				   "dbus: %s out of memory trying to duplicate the string array",
711*a1157835SDaniel Fojt 				   __func__);
712*a1157835SDaniel Fojt 			goto fail;
7133ff40c12SJohn Marino 		}
714*a1157835SDaniel Fojt 		buffer[count++] = str;
7153ff40c12SJohn Marino 		dbus_message_iter_next(iter);
7163ff40c12SJohn Marino 	}
717*a1157835SDaniel Fojt 	entry->strarray_value = buffer;
718*a1157835SDaniel Fojt 	entry->array_len = count;
719*a1157835SDaniel Fojt 	wpa_printf(MSG_MSGDUMP, "%s: string_array length %u",
720*a1157835SDaniel Fojt 		   __func__, entry->array_len);
7213ff40c12SJohn Marino 
7223ff40c12SJohn Marino 	/* Zero-length arrays are valid. */
7233ff40c12SJohn Marino 	if (entry->array_len == 0) {
7243ff40c12SJohn Marino 		os_free(entry->strarray_value);
7253ff40c12SJohn Marino 		entry->strarray_value = NULL;
7263ff40c12SJohn Marino 	}
7273ff40c12SJohn Marino 
728*a1157835SDaniel Fojt 	return TRUE;
7293ff40c12SJohn Marino 
730*a1157835SDaniel Fojt fail:
731*a1157835SDaniel Fojt 	while (count > 0) {
732*a1157835SDaniel Fojt 		count--;
733*a1157835SDaniel Fojt 		os_free(buffer[count]);
734*a1157835SDaniel Fojt 	}
735*a1157835SDaniel Fojt 	os_free(buffer);
736*a1157835SDaniel Fojt 	return FALSE;
7373ff40c12SJohn Marino }
7383ff40c12SJohn Marino 
7393ff40c12SJohn Marino 
7403ff40c12SJohn Marino #define BIN_ARRAY_CHUNK_SIZE 10
7413ff40c12SJohn Marino #define BIN_ARRAY_ITEM_SIZE (sizeof(struct wpabuf *))
7423ff40c12SJohn Marino 
_wpa_dbus_dict_entry_get_binarray(DBusMessageIter * iter,struct wpa_dbus_dict_entry * entry)7433ff40c12SJohn Marino static dbus_bool_t _wpa_dbus_dict_entry_get_binarray(
7443ff40c12SJohn Marino 	DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry)
7453ff40c12SJohn Marino {
7463ff40c12SJohn Marino 	struct wpa_dbus_dict_entry tmpentry;
7473ff40c12SJohn Marino 	size_t buflen = 0;
748*a1157835SDaniel Fojt 	int i, type;
7493ff40c12SJohn Marino 
7503ff40c12SJohn Marino 	entry->array_type = WPAS_DBUS_TYPE_BINARRAY;
7513ff40c12SJohn Marino 	entry->array_len = 0;
7523ff40c12SJohn Marino 	entry->binarray_value = NULL;
7533ff40c12SJohn Marino 
754*a1157835SDaniel Fojt 	type = dbus_message_iter_get_arg_type(iter);
755*a1157835SDaniel Fojt 	wpa_printf(MSG_MSGDUMP, "%s: parsing binarray type %c", __func__, type);
756*a1157835SDaniel Fojt 	if (type == DBUS_TYPE_INVALID) {
757*a1157835SDaniel Fojt 		/* Likely an empty array of arrays */
758*a1157835SDaniel Fojt 		return TRUE;
759*a1157835SDaniel Fojt 	}
760*a1157835SDaniel Fojt 	if (type != DBUS_TYPE_ARRAY) {
761*a1157835SDaniel Fojt 		wpa_printf(MSG_DEBUG, "%s: not an array type: %c",
762*a1157835SDaniel Fojt 			   __func__, type);
763*a1157835SDaniel Fojt 		return FALSE;
764*a1157835SDaniel Fojt 	}
765*a1157835SDaniel Fojt 
766*a1157835SDaniel Fojt 	type = dbus_message_iter_get_element_type(iter);
767*a1157835SDaniel Fojt 	if (type != DBUS_TYPE_BYTE) {
768*a1157835SDaniel Fojt 		wpa_printf(MSG_DEBUG, "%s: unexpected element type %c",
769*a1157835SDaniel Fojt 			   __func__, type);
770*a1157835SDaniel Fojt 		return FALSE;
771*a1157835SDaniel Fojt 	}
772*a1157835SDaniel Fojt 
7733ff40c12SJohn Marino 	while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_ARRAY) {
7743ff40c12SJohn Marino 		DBusMessageIter iter_array;
7753ff40c12SJohn Marino 
7763ff40c12SJohn Marino 		if (entry->array_len == buflen) {
7773ff40c12SJohn Marino 			struct wpabuf **newbuf;
7783ff40c12SJohn Marino 
7793ff40c12SJohn Marino 			buflen += BIN_ARRAY_CHUNK_SIZE;
7803ff40c12SJohn Marino 
7813ff40c12SJohn Marino 			newbuf = os_realloc_array(entry->binarray_value,
7823ff40c12SJohn Marino 						  buflen, BIN_ARRAY_ITEM_SIZE);
7833ff40c12SJohn Marino 			if (!newbuf)
7843ff40c12SJohn Marino 				goto cleanup;
7853ff40c12SJohn Marino 			entry->binarray_value = newbuf;
7863ff40c12SJohn Marino 		}
7873ff40c12SJohn Marino 
7883ff40c12SJohn Marino 		dbus_message_iter_recurse(iter, &iter_array);
789*a1157835SDaniel Fojt 		os_memset(&tmpentry, 0, sizeof(tmpentry));
790*a1157835SDaniel Fojt 		tmpentry.type = DBUS_TYPE_ARRAY;
7913ff40c12SJohn Marino 		if (_wpa_dbus_dict_entry_get_byte_array(&iter_array, &tmpentry)
7923ff40c12SJohn Marino 		    == FALSE)
7933ff40c12SJohn Marino 			goto cleanup;
7943ff40c12SJohn Marino 
7953ff40c12SJohn Marino 		entry->binarray_value[entry->array_len] =
7963ff40c12SJohn Marino 			wpabuf_alloc_ext_data((u8 *) tmpentry.bytearray_value,
7973ff40c12SJohn Marino 					      tmpentry.array_len);
7983ff40c12SJohn Marino 		if (entry->binarray_value[entry->array_len] == NULL) {
7993ff40c12SJohn Marino 			wpa_dbus_dict_entry_clear(&tmpentry);
8003ff40c12SJohn Marino 			goto cleanup;
8013ff40c12SJohn Marino 		}
8023ff40c12SJohn Marino 		entry->array_len++;
8033ff40c12SJohn Marino 		dbus_message_iter_next(iter);
8043ff40c12SJohn Marino 	}
805*a1157835SDaniel Fojt 	wpa_printf(MSG_MSGDUMP, "%s: binarray length %u",
806*a1157835SDaniel Fojt 		   __func__, entry->array_len);
8073ff40c12SJohn Marino 
8083ff40c12SJohn Marino 	return TRUE;
8093ff40c12SJohn Marino 
8103ff40c12SJohn Marino  cleanup:
8113ff40c12SJohn Marino 	for (i = 0; i < (int) entry->array_len; i++)
8123ff40c12SJohn Marino 		wpabuf_free(entry->binarray_value[i]);
8133ff40c12SJohn Marino 	os_free(entry->binarray_value);
8143ff40c12SJohn Marino 	entry->array_len = 0;
8153ff40c12SJohn Marino 	entry->binarray_value = NULL;
8163ff40c12SJohn Marino 	return FALSE;
8173ff40c12SJohn Marino }
8183ff40c12SJohn Marino 
8193ff40c12SJohn Marino 
_wpa_dbus_dict_entry_get_array(DBusMessageIter * iter_dict_val,struct wpa_dbus_dict_entry * entry)8203ff40c12SJohn Marino static dbus_bool_t _wpa_dbus_dict_entry_get_array(
8213ff40c12SJohn Marino 	DBusMessageIter *iter_dict_val, struct wpa_dbus_dict_entry *entry)
8223ff40c12SJohn Marino {
8233ff40c12SJohn Marino 	int array_type = dbus_message_iter_get_element_type(iter_dict_val);
8243ff40c12SJohn Marino 	dbus_bool_t success = FALSE;
8253ff40c12SJohn Marino 	DBusMessageIter iter_array;
8263ff40c12SJohn Marino 
827*a1157835SDaniel Fojt 	wpa_printf(MSG_MSGDUMP, "%s: array_type %c", __func__, array_type);
8283ff40c12SJohn Marino 
8293ff40c12SJohn Marino 	dbus_message_iter_recurse(iter_dict_val, &iter_array);
8303ff40c12SJohn Marino 
8313ff40c12SJohn Marino 	switch (array_type) {
8323ff40c12SJohn Marino 	case DBUS_TYPE_BYTE:
8333ff40c12SJohn Marino 		success = _wpa_dbus_dict_entry_get_byte_array(&iter_array,
8343ff40c12SJohn Marino 							      entry);
8353ff40c12SJohn Marino 		break;
8363ff40c12SJohn Marino 	case DBUS_TYPE_STRING:
8373ff40c12SJohn Marino 		success = _wpa_dbus_dict_entry_get_string_array(&iter_array,
8383ff40c12SJohn Marino 								array_type,
8393ff40c12SJohn Marino 								entry);
8403ff40c12SJohn Marino 		break;
8413ff40c12SJohn Marino 	case DBUS_TYPE_ARRAY:
8423ff40c12SJohn Marino 		success = _wpa_dbus_dict_entry_get_binarray(&iter_array, entry);
843*a1157835SDaniel Fojt 		break;
8443ff40c12SJohn Marino 	default:
845*a1157835SDaniel Fojt 		wpa_printf(MSG_MSGDUMP, "%s: unsupported array type %c",
846*a1157835SDaniel Fojt 			   __func__, array_type);
8473ff40c12SJohn Marino 		break;
8483ff40c12SJohn Marino 	}
8493ff40c12SJohn Marino 
8503ff40c12SJohn Marino 	return success;
8513ff40c12SJohn Marino }
8523ff40c12SJohn Marino 
8533ff40c12SJohn Marino 
_wpa_dbus_dict_fill_value_from_variant(struct wpa_dbus_dict_entry * entry,DBusMessageIter * iter)8543ff40c12SJohn Marino static dbus_bool_t _wpa_dbus_dict_fill_value_from_variant(
8553ff40c12SJohn Marino 	struct wpa_dbus_dict_entry *entry, DBusMessageIter *iter)
8563ff40c12SJohn Marino {
8573ff40c12SJohn Marino 	const char *v;
8583ff40c12SJohn Marino 
8593ff40c12SJohn Marino 	switch (entry->type) {
8603ff40c12SJohn Marino 	case DBUS_TYPE_OBJECT_PATH:
861*a1157835SDaniel Fojt 		dbus_message_iter_get_basic(iter, &v);
862*a1157835SDaniel Fojt 		wpa_printf(MSG_MSGDUMP, "%s: object path value: %s",
863*a1157835SDaniel Fojt 			   __func__, v);
864*a1157835SDaniel Fojt 		entry->str_value = os_strdup(v);
865*a1157835SDaniel Fojt 		if (entry->str_value == NULL)
866*a1157835SDaniel Fojt 			return FALSE;
867*a1157835SDaniel Fojt 		break;
8683ff40c12SJohn Marino 	case DBUS_TYPE_STRING:
8693ff40c12SJohn Marino 		dbus_message_iter_get_basic(iter, &v);
870*a1157835SDaniel Fojt 		wpa_printf(MSG_MSGDUMP, "%s: string value: %s",
871*a1157835SDaniel Fojt 			   __func__, wpa_debug_show_keys ? v : "[omitted]");
8723ff40c12SJohn Marino 		entry->str_value = os_strdup(v);
8733ff40c12SJohn Marino 		if (entry->str_value == NULL)
8743ff40c12SJohn Marino 			return FALSE;
8753ff40c12SJohn Marino 		break;
8763ff40c12SJohn Marino 	case DBUS_TYPE_BOOLEAN:
8773ff40c12SJohn Marino 		dbus_message_iter_get_basic(iter, &entry->bool_value);
878*a1157835SDaniel Fojt 		wpa_printf(MSG_MSGDUMP, "%s: boolean value: %d",
879*a1157835SDaniel Fojt 			   __func__, entry->bool_value);
8803ff40c12SJohn Marino 		break;
8813ff40c12SJohn Marino 	case DBUS_TYPE_BYTE:
8823ff40c12SJohn Marino 		dbus_message_iter_get_basic(iter, &entry->byte_value);
883*a1157835SDaniel Fojt 		wpa_printf(MSG_MSGDUMP, "%s: byte value: %d",
884*a1157835SDaniel Fojt 			   __func__, entry->byte_value);
8853ff40c12SJohn Marino 		break;
8863ff40c12SJohn Marino 	case DBUS_TYPE_INT16:
8873ff40c12SJohn Marino 		dbus_message_iter_get_basic(iter, &entry->int16_value);
888*a1157835SDaniel Fojt 		wpa_printf(MSG_MSGDUMP, "%s: int16 value: %d",
889*a1157835SDaniel Fojt 			   __func__, entry->int16_value);
8903ff40c12SJohn Marino 		break;
8913ff40c12SJohn Marino 	case DBUS_TYPE_UINT16:
8923ff40c12SJohn Marino 		dbus_message_iter_get_basic(iter, &entry->uint16_value);
893*a1157835SDaniel Fojt 		wpa_printf(MSG_MSGDUMP, "%s: uint16 value: %d",
894*a1157835SDaniel Fojt 			   __func__, entry->uint16_value);
8953ff40c12SJohn Marino 		break;
8963ff40c12SJohn Marino 	case DBUS_TYPE_INT32:
8973ff40c12SJohn Marino 		dbus_message_iter_get_basic(iter, &entry->int32_value);
898*a1157835SDaniel Fojt 		wpa_printf(MSG_MSGDUMP, "%s: int32 value: %d",
899*a1157835SDaniel Fojt 			   __func__, entry->int32_value);
9003ff40c12SJohn Marino 		break;
9013ff40c12SJohn Marino 	case DBUS_TYPE_UINT32:
9023ff40c12SJohn Marino 		dbus_message_iter_get_basic(iter, &entry->uint32_value);
903*a1157835SDaniel Fojt 		wpa_printf(MSG_MSGDUMP, "%s: uint32 value: %d",
904*a1157835SDaniel Fojt 			   __func__, entry->uint32_value);
9053ff40c12SJohn Marino 		break;
9063ff40c12SJohn Marino 	case DBUS_TYPE_INT64:
9073ff40c12SJohn Marino 		dbus_message_iter_get_basic(iter, &entry->int64_value);
908*a1157835SDaniel Fojt 		wpa_printf(MSG_MSGDUMP, "%s: int64 value: %lld",
909*a1157835SDaniel Fojt 			   __func__, (long long int) entry->int64_value);
9103ff40c12SJohn Marino 		break;
9113ff40c12SJohn Marino 	case DBUS_TYPE_UINT64:
9123ff40c12SJohn Marino 		dbus_message_iter_get_basic(iter, &entry->uint64_value);
913*a1157835SDaniel Fojt 		wpa_printf(MSG_MSGDUMP, "%s: uint64 value: %llu",
914*a1157835SDaniel Fojt 			   __func__,
915*a1157835SDaniel Fojt 			   (unsigned long long int) entry->uint64_value);
9163ff40c12SJohn Marino 		break;
9173ff40c12SJohn Marino 	case DBUS_TYPE_DOUBLE:
9183ff40c12SJohn Marino 		dbus_message_iter_get_basic(iter, &entry->double_value);
919*a1157835SDaniel Fojt 		wpa_printf(MSG_MSGDUMP, "%s: double value: %f",
920*a1157835SDaniel Fojt 			   __func__, entry->double_value);
9213ff40c12SJohn Marino 		break;
9223ff40c12SJohn Marino 	case DBUS_TYPE_ARRAY:
9233ff40c12SJohn Marino 		return _wpa_dbus_dict_entry_get_array(iter, entry);
9243ff40c12SJohn Marino 	default:
925*a1157835SDaniel Fojt 		wpa_printf(MSG_MSGDUMP, "%s: unsupported type %c",
926*a1157835SDaniel Fojt 			   __func__, entry->type);
9273ff40c12SJohn Marino 		return FALSE;
9283ff40c12SJohn Marino 	}
9293ff40c12SJohn Marino 
9303ff40c12SJohn Marino 	return TRUE;
9313ff40c12SJohn Marino }
9323ff40c12SJohn Marino 
9333ff40c12SJohn Marino 
9343ff40c12SJohn Marino /**
9353ff40c12SJohn Marino  * Read the current key/value entry from the dict.  Entries are dynamically
9363ff40c12SJohn Marino  * allocated when needed and must be freed after use with the
9373ff40c12SJohn Marino  * wpa_dbus_dict_entry_clear() function.
9383ff40c12SJohn Marino  *
9393ff40c12SJohn Marino  * The returned entry object will be filled with the type and value of the next
9403ff40c12SJohn Marino  * entry in the dict, or the type will be DBUS_TYPE_INVALID if an error
9413ff40c12SJohn Marino  * occurred.
9423ff40c12SJohn Marino  *
9433ff40c12SJohn Marino  * @param iter_dict A valid DBusMessageIter returned from
9443ff40c12SJohn Marino  *    wpa_dbus_dict_open_read()
9453ff40c12SJohn Marino  * @param entry A valid dict entry object into which the dict key and value
9463ff40c12SJohn Marino  *    will be placed
9473ff40c12SJohn Marino  * @return TRUE on success, FALSE on failure
9483ff40c12SJohn Marino  *
9493ff40c12SJohn Marino  */
wpa_dbus_dict_get_entry(DBusMessageIter * iter_dict,struct wpa_dbus_dict_entry * entry)9503ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict,
9513ff40c12SJohn Marino 				    struct wpa_dbus_dict_entry * entry)
9523ff40c12SJohn Marino {
9533ff40c12SJohn Marino 	DBusMessageIter iter_dict_entry, iter_dict_val;
9543ff40c12SJohn Marino 	int type;
9553ff40c12SJohn Marino 	const char *key;
9563ff40c12SJohn Marino 
957*a1157835SDaniel Fojt 	if (!iter_dict || !entry ||
958*a1157835SDaniel Fojt 	    dbus_message_iter_get_arg_type(iter_dict) != DBUS_TYPE_DICT_ENTRY) {
959*a1157835SDaniel Fojt 		wpa_printf(MSG_DEBUG, "%s: not a dict entry", __func__);
9603ff40c12SJohn Marino 		goto error;
961*a1157835SDaniel Fojt 	}
9623ff40c12SJohn Marino 
9633ff40c12SJohn Marino 	dbus_message_iter_recurse(iter_dict, &iter_dict_entry);
9643ff40c12SJohn Marino 	dbus_message_iter_get_basic(&iter_dict_entry, &key);
965*a1157835SDaniel Fojt 	wpa_printf(MSG_MSGDUMP, "%s: dict entry key: %s", __func__, key);
9663ff40c12SJohn Marino 	entry->key = key;
9673ff40c12SJohn Marino 
968*a1157835SDaniel Fojt 	if (!dbus_message_iter_next(&iter_dict_entry)) {
969*a1157835SDaniel Fojt 		wpa_printf(MSG_DEBUG, "%s: no variant in dict entry", __func__);
9703ff40c12SJohn Marino 		goto error;
971*a1157835SDaniel Fojt 	}
9723ff40c12SJohn Marino 	type = dbus_message_iter_get_arg_type(&iter_dict_entry);
973*a1157835SDaniel Fojt 	if (type != DBUS_TYPE_VARIANT) {
974*a1157835SDaniel Fojt 		wpa_printf(MSG_DEBUG,
975*a1157835SDaniel Fojt 			   "%s: unexpected dict entry variant type: %c",
976*a1157835SDaniel Fojt 			   __func__, type);
9773ff40c12SJohn Marino 		goto error;
978*a1157835SDaniel Fojt 	}
9793ff40c12SJohn Marino 
9803ff40c12SJohn Marino 	dbus_message_iter_recurse(&iter_dict_entry, &iter_dict_val);
9813ff40c12SJohn Marino 	entry->type = dbus_message_iter_get_arg_type(&iter_dict_val);
982*a1157835SDaniel Fojt 	wpa_printf(MSG_MSGDUMP, "%s: dict entry variant content type: %c",
983*a1157835SDaniel Fojt 		   __func__, entry->type);
984*a1157835SDaniel Fojt 	entry->array_type = DBUS_TYPE_INVALID;
985*a1157835SDaniel Fojt 	if (!_wpa_dbus_dict_fill_value_from_variant(entry, &iter_dict_val)) {
986*a1157835SDaniel Fojt 		wpa_printf(MSG_DEBUG,
987*a1157835SDaniel Fojt 			   "%s: failed to fetch dict values from variant",
988*a1157835SDaniel Fojt 			   __func__);
9893ff40c12SJohn Marino 		goto error;
990*a1157835SDaniel Fojt 	}
9913ff40c12SJohn Marino 
9923ff40c12SJohn Marino 	dbus_message_iter_next(iter_dict);
9933ff40c12SJohn Marino 	return TRUE;
9943ff40c12SJohn Marino 
9953ff40c12SJohn Marino error:
9963ff40c12SJohn Marino 	if (entry) {
9973ff40c12SJohn Marino 		wpa_dbus_dict_entry_clear(entry);
9983ff40c12SJohn Marino 		entry->type = DBUS_TYPE_INVALID;
9993ff40c12SJohn Marino 		entry->array_type = DBUS_TYPE_INVALID;
10003ff40c12SJohn Marino 	}
10013ff40c12SJohn Marino 
10023ff40c12SJohn Marino 	return FALSE;
10033ff40c12SJohn Marino }
10043ff40c12SJohn Marino 
10053ff40c12SJohn Marino 
10063ff40c12SJohn Marino /**
10073ff40c12SJohn Marino  * Return whether or not there are additional dictionary entries.
10083ff40c12SJohn Marino  *
10093ff40c12SJohn Marino  * @param iter_dict A valid DBusMessageIter returned from
10103ff40c12SJohn Marino  *    wpa_dbus_dict_open_read()
10113ff40c12SJohn Marino  * @return TRUE if more dict entries exists, FALSE if no more dict entries
10123ff40c12SJohn Marino  * exist
10133ff40c12SJohn Marino  */
wpa_dbus_dict_has_dict_entry(DBusMessageIter * iter_dict)10143ff40c12SJohn Marino dbus_bool_t wpa_dbus_dict_has_dict_entry(DBusMessageIter *iter_dict)
10153ff40c12SJohn Marino {
10163ff40c12SJohn Marino 	if (!iter_dict)
10173ff40c12SJohn Marino 		return FALSE;
10183ff40c12SJohn Marino 	return dbus_message_iter_get_arg_type(iter_dict) ==
10193ff40c12SJohn Marino 		DBUS_TYPE_DICT_ENTRY;
10203ff40c12SJohn Marino }
10213ff40c12SJohn Marino 
10223ff40c12SJohn Marino 
10233ff40c12SJohn Marino /**
10243ff40c12SJohn Marino  * Free any memory used by the entry object.
10253ff40c12SJohn Marino  *
10263ff40c12SJohn Marino  * @param entry The entry object
10273ff40c12SJohn Marino  */
wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry * entry)10283ff40c12SJohn Marino void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry)
10293ff40c12SJohn Marino {
10303ff40c12SJohn Marino 	unsigned int i;
10313ff40c12SJohn Marino 
10323ff40c12SJohn Marino 	if (!entry)
10333ff40c12SJohn Marino 		return;
10343ff40c12SJohn Marino 	switch (entry->type) {
10353ff40c12SJohn Marino 	case DBUS_TYPE_OBJECT_PATH:
10363ff40c12SJohn Marino 	case DBUS_TYPE_STRING:
10373ff40c12SJohn Marino 		os_free(entry->str_value);
10383ff40c12SJohn Marino 		break;
10393ff40c12SJohn Marino 	case DBUS_TYPE_ARRAY:
10403ff40c12SJohn Marino 		switch (entry->array_type) {
10413ff40c12SJohn Marino 		case DBUS_TYPE_BYTE:
10423ff40c12SJohn Marino 			os_free(entry->bytearray_value);
10433ff40c12SJohn Marino 			break;
10443ff40c12SJohn Marino 		case DBUS_TYPE_STRING:
1045*a1157835SDaniel Fojt 			if (!entry->strarray_value)
1046*a1157835SDaniel Fojt 				break;
10473ff40c12SJohn Marino 			for (i = 0; i < entry->array_len; i++)
10483ff40c12SJohn Marino 				os_free(entry->strarray_value[i]);
10493ff40c12SJohn Marino 			os_free(entry->strarray_value);
10503ff40c12SJohn Marino 			break;
10513ff40c12SJohn Marino 		case WPAS_DBUS_TYPE_BINARRAY:
10523ff40c12SJohn Marino 			for (i = 0; i < entry->array_len; i++)
10533ff40c12SJohn Marino 				wpabuf_free(entry->binarray_value[i]);
10543ff40c12SJohn Marino 			os_free(entry->binarray_value);
10553ff40c12SJohn Marino 			break;
10563ff40c12SJohn Marino 		}
10573ff40c12SJohn Marino 		break;
10583ff40c12SJohn Marino 	}
10593ff40c12SJohn Marino 
10603ff40c12SJohn Marino 	os_memset(entry, 0, sizeof(struct wpa_dbus_dict_entry));
10613ff40c12SJohn Marino }
1062