/*
 * WPA Supplicant / dbus-based control interface
 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"
#include <dbus/dbus.h>

#include "common.h"
#include "wpabuf.h"
#include "dbus_dict_helpers.h"


/**
 * Start a dict in a dbus message.  Should be paired with a call to
 * wpa_dbus_dict_close_write().
 *
 * @param iter A valid dbus message iterator
 * @param iter_dict (out) A dict iterator to pass to further dict functions
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_open_write(DBusMessageIter *iter,
				     DBusMessageIter *iter_dict)
{
	dbus_bool_t result;

	if (!iter || !iter_dict)
		return FALSE;

	result = dbus_message_iter_open_container(
		iter,
		DBUS_TYPE_ARRAY,
		DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
		DBUS_TYPE_STRING_AS_STRING
		DBUS_TYPE_VARIANT_AS_STRING
		DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
		iter_dict);
	return result;
}


/**
 * End a dict element in a dbus message.  Should be paired with
 * a call to wpa_dbus_dict_open_write().
 *
 * @param iter valid dbus message iterator, same as passed to
 *    wpa_dbus_dict_open_write()
 * @param iter_dict a dbus dict iterator returned from
 *    wpa_dbus_dict_open_write()
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_close_write(DBusMessageIter *iter,
				      DBusMessageIter *iter_dict)
{
	if (!iter || !iter_dict)
		return FALSE;

	return dbus_message_iter_close_container(iter, iter_dict);
}


const char * wpa_dbus_type_as_string(const int type)
{
	switch(type) {
	case DBUS_TYPE_BYTE:
		return DBUS_TYPE_BYTE_AS_STRING;
	case DBUS_TYPE_BOOLEAN:
		return DBUS_TYPE_BOOLEAN_AS_STRING;
	case DBUS_TYPE_INT16:
		return DBUS_TYPE_INT16_AS_STRING;
	case DBUS_TYPE_UINT16:
		return DBUS_TYPE_UINT16_AS_STRING;
	case DBUS_TYPE_INT32:
		return DBUS_TYPE_INT32_AS_STRING;
	case DBUS_TYPE_UINT32:
		return DBUS_TYPE_UINT32_AS_STRING;
	case DBUS_TYPE_INT64:
		return DBUS_TYPE_INT64_AS_STRING;
	case DBUS_TYPE_UINT64:
		return DBUS_TYPE_UINT64_AS_STRING;
	case DBUS_TYPE_DOUBLE:
		return DBUS_TYPE_DOUBLE_AS_STRING;
	case DBUS_TYPE_STRING:
		return DBUS_TYPE_STRING_AS_STRING;
	case DBUS_TYPE_OBJECT_PATH:
		return DBUS_TYPE_OBJECT_PATH_AS_STRING;
	case DBUS_TYPE_ARRAY:
		return DBUS_TYPE_ARRAY_AS_STRING;
	default:
		return NULL;
	}
}


static dbus_bool_t _wpa_dbus_add_dict_entry_start(
	DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
	const char *key, const int value_type)
{
	if (!dbus_message_iter_open_container(iter_dict,
					      DBUS_TYPE_DICT_ENTRY, NULL,
					      iter_dict_entry))
		return FALSE;

	if (!dbus_message_iter_append_basic(iter_dict_entry, DBUS_TYPE_STRING,
					    &key))
		return FALSE;

	return TRUE;
}


static dbus_bool_t _wpa_dbus_add_dict_entry_end(
	DBusMessageIter *iter_dict, DBusMessageIter *iter_dict_entry,
	DBusMessageIter *iter_dict_val)
{
	if (!dbus_message_iter_close_container(iter_dict_entry, iter_dict_val))
		return FALSE;
	if (!dbus_message_iter_close_container(iter_dict, iter_dict_entry))
		return FALSE;

	return TRUE;
}


static dbus_bool_t _wpa_dbus_add_dict_entry_basic(DBusMessageIter *iter_dict,
						  const char *key,
						  const int value_type,
						  const void *value)
{
	DBusMessageIter iter_dict_entry, iter_dict_val;
	const char *type_as_string = NULL;

	if (key == NULL)
		return FALSE;

	type_as_string = wpa_dbus_type_as_string(value_type);
	if (!type_as_string)
		return FALSE;

	if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
					    key, value_type))
		return FALSE;

	if (!dbus_message_iter_open_container(&iter_dict_entry,
					      DBUS_TYPE_VARIANT,
					      type_as_string, &iter_dict_val))
		return FALSE;

	if (!dbus_message_iter_append_basic(&iter_dict_val, value_type, value))
		return FALSE;

	if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
					  &iter_dict_val))
		return FALSE;

	return TRUE;
}


static dbus_bool_t _wpa_dbus_add_dict_entry_byte_array(
	DBusMessageIter *iter_dict, const char *key,
	const char *value, const dbus_uint32_t value_len)
{
	DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
	dbus_uint32_t i;

	if (!_wpa_dbus_add_dict_entry_start(iter_dict, &iter_dict_entry,
					    key, DBUS_TYPE_ARRAY))
		return FALSE;

	if (!dbus_message_iter_open_container(&iter_dict_entry,
					      DBUS_TYPE_VARIANT,
					      DBUS_TYPE_ARRAY_AS_STRING
					      DBUS_TYPE_BYTE_AS_STRING,
					      &iter_dict_val))
		return FALSE;

	if (!dbus_message_iter_open_container(&iter_dict_val, DBUS_TYPE_ARRAY,
					      DBUS_TYPE_BYTE_AS_STRING,
					      &iter_array))
		return FALSE;

	for (i = 0; i < value_len; i++) {
		if (!dbus_message_iter_append_basic(&iter_array,
						    DBUS_TYPE_BYTE,
						    &(value[i])))
			return FALSE;
	}

	if (!dbus_message_iter_close_container(&iter_dict_val, &iter_array))
		return FALSE;

	if (!_wpa_dbus_add_dict_entry_end(iter_dict, &iter_dict_entry,
					  &iter_dict_val))
		return FALSE;

	return TRUE;
}


/**
 * Add a string entry to the dict.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *    wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param value The string value
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_append_string(DBusMessageIter *iter_dict,
					const char *key, const char *value)
{
	if (!value)
		return FALSE;
	return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_STRING,
					      &value);
}


/**
 * Add a byte entry to the dict.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *    wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param value The byte value
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_append_byte(DBusMessageIter *iter_dict,
				      const char *key, const char value)
{
	return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_BYTE,
					      &value);
}


/**
 * Add a boolean entry to the dict.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *    wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param value The boolean value
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_append_bool(DBusMessageIter *iter_dict,
				      const char *key, const dbus_bool_t value)
{
	return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
					      DBUS_TYPE_BOOLEAN, &value);
}


/**
 * Add a 16-bit signed integer entry to the dict.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *    wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param value The 16-bit signed integer value
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_append_int16(DBusMessageIter *iter_dict,
				       const char *key,
				       const dbus_int16_t value)
{
	return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT16,
					      &value);
}


/**
 * Add a 16-bit unsigned integer entry to the dict.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *    wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param value The 16-bit unsigned integer value
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_append_uint16(DBusMessageIter *iter_dict,
					const char *key,
					const dbus_uint16_t value)
{
	return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT16,
					      &value);
}


/**
 * Add a 32-bit signed integer to the dict.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *    wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param value The 32-bit signed integer value
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_append_int32(DBusMessageIter *iter_dict,
				       const char *key,
				       const dbus_int32_t value)
{
	return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT32,
					      &value);
}


/**
 * Add a 32-bit unsigned integer entry to the dict.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *    wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param value The 32-bit unsigned integer value
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_append_uint32(DBusMessageIter *iter_dict,
					const char *key,
					const dbus_uint32_t value)
{
	return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT32,
					      &value);
}


/**
 * Add a 64-bit integer entry to the dict.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *    wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param value The 64-bit integer value
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_append_int64(DBusMessageIter *iter_dict,
				       const char *key,
				       const dbus_int64_t value)
{
	return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_INT64,
					      &value);
}


/**
 * Add a 64-bit unsigned integer entry to the dict.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *    wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param value The 64-bit unsigned integer value
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_append_uint64(DBusMessageIter *iter_dict,
					const char *key,
					const dbus_uint64_t value)
{
	return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_UINT64,
					      &value);
}


/**
 * Add a double-precision floating point entry to the dict.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *    wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param value The double-precision floating point value
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_append_double(DBusMessageIter *iter_dict,
					const char *key, const double value)
{
	return _wpa_dbus_add_dict_entry_basic(iter_dict, key, DBUS_TYPE_DOUBLE,
					      &value);
}


/**
 * Add a DBus object path entry to the dict.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *    wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param value The DBus object path value
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_append_object_path(DBusMessageIter *iter_dict,
					     const char *key,
					     const char *value)
{
	if (!value)
		return FALSE;
	return _wpa_dbus_add_dict_entry_basic(iter_dict, key,
					      DBUS_TYPE_OBJECT_PATH, &value);
}


/**
 * Add a byte array entry to the dict.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *    wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param value The byte array
 * @param value_len The length of the byte array, in bytes
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_append_byte_array(DBusMessageIter *iter_dict,
					    const char *key,
					    const char *value,
					    const dbus_uint32_t value_len)
{
	if (!key)
		return FALSE;
	if (!value && (value_len != 0))
		return FALSE;
	return _wpa_dbus_add_dict_entry_byte_array(iter_dict, key, value,
						   value_len);
}


/**
 * Begin an array entry in the dict
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *                  wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param type The type of the contained data
 * @param iter_dict_entry A private DBusMessageIter provided by the caller to
 *                        be passed to wpa_dbus_dict_end_string_array()
 * @param iter_dict_val A private DBusMessageIter provided by the caller to
 *                      be passed to wpa_dbus_dict_end_string_array()
 * @param iter_array On return, the DBusMessageIter to be passed to
 *                   wpa_dbus_dict_string_array_add_element()
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t 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)
{
	char array_type[10];
	int err;

	err = os_snprintf(array_type, sizeof(array_type),
			  DBUS_TYPE_ARRAY_AS_STRING "%s",
			  type);
	if (err < 0 || err > (int) sizeof(array_type))
		return FALSE;

	if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array)
		return FALSE;

	if (!_wpa_dbus_add_dict_entry_start(iter_dict, iter_dict_entry,
					    key, DBUS_TYPE_ARRAY))
		return FALSE;

	if (!dbus_message_iter_open_container(iter_dict_entry,
					      DBUS_TYPE_VARIANT,
					      array_type,
					      iter_dict_val))
		return FALSE;

	if (!dbus_message_iter_open_container(iter_dict_val, DBUS_TYPE_ARRAY,
					      type, iter_array))
		return FALSE;

	return TRUE;
}


dbus_bool_t wpa_dbus_dict_begin_string_array(DBusMessageIter *iter_dict,
					     const char *key,
					     DBusMessageIter *iter_dict_entry,
					     DBusMessageIter *iter_dict_val,
					     DBusMessageIter *iter_array)
{
	return wpa_dbus_dict_begin_array(
		iter_dict, key,
		DBUS_TYPE_STRING_AS_STRING,
		iter_dict_entry, iter_dict_val, iter_array);
}


/**
 * Add a single string element to a string array dict entry
 *
 * @param iter_array A valid DBusMessageIter returned from
 *                   wpa_dbus_dict_begin_string_array()'s
 *                   iter_array parameter
 * @param elem The string element to be added to the dict entry's string array
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_string_array_add_element(DBusMessageIter *iter_array,
						   const char *elem)
{
	if (!iter_array || !elem)
		return FALSE;

	return dbus_message_iter_append_basic(iter_array, DBUS_TYPE_STRING,
					      &elem);
}


/**
 * Add a single byte array element to a string array dict entry
 *
 * @param iter_array A valid DBusMessageIter returned from
 *                   wpa_dbus_dict_begin_array()'s iter_array
 *                   parameter -- note that wpa_dbus_dict_begin_array()
 *                   must have been called with "ay" as the type
 * @param value The data to be added to the dict entry's array
 * @param value_len The length of the data
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_bin_array_add_element(DBusMessageIter *iter_array,
						const u8 *value,
						size_t value_len)
{
	DBusMessageIter iter_bytes;
	size_t i;

	if (!iter_array || !value)
		return FALSE;

	if (!dbus_message_iter_open_container(iter_array, DBUS_TYPE_ARRAY,
					      DBUS_TYPE_BYTE_AS_STRING,
					      &iter_bytes))
		return FALSE;

	for (i = 0; i < value_len; i++) {
		if (!dbus_message_iter_append_basic(&iter_bytes,
						    DBUS_TYPE_BYTE,
						    &(value[i])))
			return FALSE;
	}

	if (!dbus_message_iter_close_container(iter_array, &iter_bytes))
		return FALSE;

	return TRUE;
}


/**
 * End an array dict entry
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *                  wpa_dbus_dict_open_write()
 * @param iter_dict_entry A private DBusMessageIter returned from
 *                        wpa_dbus_dict_begin_string_array() or
 *			  wpa_dbus_dict_begin_array()
 * @param iter_dict_val A private DBusMessageIter returned from
 *                      wpa_dbus_dict_begin_string_array() or
 *			wpa_dbus_dict_begin_array()
 * @param iter_array A DBusMessageIter returned from
 *                   wpa_dbus_dict_begin_string_array() or
 *		     wpa_dbus_dict_begin_array()
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_end_array(DBusMessageIter *iter_dict,
				    DBusMessageIter *iter_dict_entry,
				    DBusMessageIter *iter_dict_val,
				    DBusMessageIter *iter_array)
{
	if (!iter_dict || !iter_dict_entry || !iter_dict_val || !iter_array)
		return FALSE;

	if (!dbus_message_iter_close_container(iter_dict_val, iter_array))
		return FALSE;

	if (!_wpa_dbus_add_dict_entry_end(iter_dict, iter_dict_entry,
					  iter_dict_val))
		return FALSE;

	return TRUE;
}


/**
 * Convenience function to add an entire string array to the dict.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *                  wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param items The array of strings
 * @param num_items The number of strings in the array
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_append_string_array(DBusMessageIter *iter_dict,
					      const char *key,
					      const char **items,
					      const dbus_uint32_t num_items)
{
	DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
	dbus_uint32_t i;

	if (!key)
		return FALSE;
	if (!items && (num_items != 0))
		return FALSE;

	if (!wpa_dbus_dict_begin_string_array(iter_dict, key,
					      &iter_dict_entry, &iter_dict_val,
					      &iter_array))
		return FALSE;

	for (i = 0; i < num_items; i++) {
		if (!wpa_dbus_dict_string_array_add_element(&iter_array,
							    items[i]))
			return FALSE;
	}

	if (!wpa_dbus_dict_end_string_array(iter_dict, &iter_dict_entry,
					    &iter_dict_val, &iter_array))
		return FALSE;

	return TRUE;
}


/**
 * Convenience function to add an wpabuf binary array to the dict.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *                  wpa_dbus_dict_open_write()
 * @param key The key of the dict item
 * @param items The array of wpabuf structures
 * @param num_items The number of strings in the array
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_append_wpabuf_array(DBusMessageIter *iter_dict,
					      const char *key,
					      const struct wpabuf **items,
					      const dbus_uint32_t num_items)
{
	DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
	dbus_uint32_t i;

	if (!key)
		return FALSE;
	if (!items && (num_items != 0))
		return FALSE;

	if (!wpa_dbus_dict_begin_array(iter_dict, key,
				       DBUS_TYPE_ARRAY_AS_STRING
				       DBUS_TYPE_BYTE_AS_STRING,
				       &iter_dict_entry, &iter_dict_val,
				       &iter_array))
		return FALSE;

	for (i = 0; i < num_items; i++) {
		if (!wpa_dbus_dict_bin_array_add_element(&iter_array,
							 wpabuf_head(items[i]),
							 wpabuf_len(items[i])))
			return FALSE;
	}

	if (!wpa_dbus_dict_end_array(iter_dict, &iter_dict_entry,
				     &iter_dict_val, &iter_array))
		return FALSE;

	return TRUE;
}


/*****************************************************/
/* Stuff for reading dicts                           */
/*****************************************************/

/**
 * Start reading from a dbus dict.
 *
 * @param iter A valid DBusMessageIter pointing to the start of the dict
 * @param iter_dict (out) A DBusMessageIter to be passed to
 *    wpa_dbus_dict_read_next_entry()
 * @error on failure a descriptive error
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
				    DBusMessageIter *iter_dict,
				    DBusError *error)
{
	if (!iter || !iter_dict) {
		dbus_set_error_const(error, DBUS_ERROR_FAILED,
		                     "[internal] missing message iterators");
		return FALSE;
	}

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY ||
	    dbus_message_iter_get_element_type(iter) != DBUS_TYPE_DICT_ENTRY) {
		dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
		                     "unexpected message argument types");
		return FALSE;
	}

	dbus_message_iter_recurse(iter, iter_dict);
	return TRUE;
}


#define BYTE_ARRAY_CHUNK_SIZE 34
#define BYTE_ARRAY_ITEM_SIZE (sizeof(char))

static dbus_bool_t _wpa_dbus_dict_entry_get_byte_array(
	DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry)
{
	dbus_uint32_t count = 0;
	dbus_bool_t success = FALSE;
	char *buffer, *nbuffer;

	entry->bytearray_value = NULL;
	entry->array_type = DBUS_TYPE_BYTE;

	buffer = os_calloc(BYTE_ARRAY_CHUNK_SIZE, BYTE_ARRAY_ITEM_SIZE);
	if (!buffer)
		return FALSE;

	entry->bytearray_value = buffer;
	entry->array_len = 0;
	while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_BYTE) {
		char byte;

		if ((count % BYTE_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
			nbuffer = os_realloc_array(
				buffer, count + BYTE_ARRAY_CHUNK_SIZE,
				BYTE_ARRAY_ITEM_SIZE);
			if (nbuffer == NULL) {
				os_free(buffer);
				wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_"
					   "entry_get_byte_array out of "
					   "memory trying to retrieve the "
					   "string array");
				goto done;
			}
			buffer = nbuffer;
		}
		entry->bytearray_value = buffer;

		dbus_message_iter_get_basic(iter, &byte);
		entry->bytearray_value[count] = byte;
		entry->array_len = ++count;
		dbus_message_iter_next(iter);
	}

	/* Zero-length arrays are valid. */
	if (entry->array_len == 0) {
		os_free(entry->bytearray_value);
		entry->bytearray_value = NULL;
	}

	success = TRUE;

done:
	return success;
}


#define STR_ARRAY_CHUNK_SIZE 8
#define STR_ARRAY_ITEM_SIZE (sizeof(char *))

static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
	DBusMessageIter *iter, int array_type,
	struct wpa_dbus_dict_entry *entry)
{
	dbus_uint32_t count = 0;
	dbus_bool_t success = FALSE;
	char **buffer, **nbuffer;

	entry->strarray_value = NULL;
	entry->array_type = DBUS_TYPE_STRING;

	buffer = os_calloc(STR_ARRAY_CHUNK_SIZE, STR_ARRAY_ITEM_SIZE);
	if (buffer == NULL)
		return FALSE;

	entry->strarray_value = buffer;
	entry->array_len = 0;
	while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
		const char *value;
		char *str;

		if ((count % STR_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
			nbuffer = os_realloc_array(
				buffer, count + STR_ARRAY_CHUNK_SIZE,
				STR_ARRAY_ITEM_SIZE);
			if (nbuffer == NULL) {
				os_free(buffer);
				wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_"
					   "entry_get_string_array out of "
					   "memory trying to retrieve the "
					   "string array");
				goto done;
			}
			buffer = nbuffer;
		}
		entry->strarray_value = buffer;

		dbus_message_iter_get_basic(iter, &value);
		str = os_strdup(value);
		if (str == NULL) {
			wpa_printf(MSG_ERROR, "dbus: _wpa_dbus_dict_entry_get_"
				   "string_array out of memory trying to "
				   "duplicate the string array");
			goto done;
		}
		entry->strarray_value[count] = str;
		entry->array_len = ++count;
		dbus_message_iter_next(iter);
	}

	/* Zero-length arrays are valid. */
	if (entry->array_len == 0) {
		os_free(entry->strarray_value);
		entry->strarray_value = NULL;
	}

	success = TRUE;

done:
	return success;
}


#define BIN_ARRAY_CHUNK_SIZE 10
#define BIN_ARRAY_ITEM_SIZE (sizeof(struct wpabuf *))

static dbus_bool_t _wpa_dbus_dict_entry_get_binarray(
	DBusMessageIter *iter, struct wpa_dbus_dict_entry *entry)
{
	struct wpa_dbus_dict_entry tmpentry;
	size_t buflen = 0;
	int i;

	if (dbus_message_iter_get_element_type(iter) != DBUS_TYPE_BYTE)
		return FALSE;

	entry->array_type = WPAS_DBUS_TYPE_BINARRAY;
	entry->array_len = 0;
	entry->binarray_value = NULL;

	while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_ARRAY) {
		DBusMessageIter iter_array;

		if (entry->array_len == buflen) {
			struct wpabuf **newbuf;

			buflen += BIN_ARRAY_CHUNK_SIZE;

			newbuf = os_realloc_array(entry->binarray_value,
						  buflen, BIN_ARRAY_ITEM_SIZE);
			if (!newbuf)
				goto cleanup;
			entry->binarray_value = newbuf;
		}

		dbus_message_iter_recurse(iter, &iter_array);
		if (_wpa_dbus_dict_entry_get_byte_array(&iter_array, &tmpentry)
					== FALSE)
			goto cleanup;

		entry->binarray_value[entry->array_len] =
			wpabuf_alloc_ext_data((u8 *) tmpentry.bytearray_value,
					      tmpentry.array_len);
		if (entry->binarray_value[entry->array_len] == NULL) {
			wpa_dbus_dict_entry_clear(&tmpentry);
			goto cleanup;
		}
		entry->array_len++;
		dbus_message_iter_next(iter);
	}

	return TRUE;

 cleanup:
	for (i = 0; i < (int) entry->array_len; i++)
		wpabuf_free(entry->binarray_value[i]);
	os_free(entry->binarray_value);
	entry->array_len = 0;
	entry->binarray_value = NULL;
	return FALSE;
}


static dbus_bool_t _wpa_dbus_dict_entry_get_array(
	DBusMessageIter *iter_dict_val, struct wpa_dbus_dict_entry *entry)
{
	int array_type = dbus_message_iter_get_element_type(iter_dict_val);
	dbus_bool_t success = FALSE;
	DBusMessageIter iter_array;

	if (!entry)
		return FALSE;

	dbus_message_iter_recurse(iter_dict_val, &iter_array);

 	switch (array_type) {
	case DBUS_TYPE_BYTE:
		success = _wpa_dbus_dict_entry_get_byte_array(&iter_array,
							      entry);
		break;
	case DBUS_TYPE_STRING:
		success = _wpa_dbus_dict_entry_get_string_array(&iter_array,
								array_type,
								entry);
		break;
	case DBUS_TYPE_ARRAY:
		success = _wpa_dbus_dict_entry_get_binarray(&iter_array, entry);
	default:
		break;
	}

	return success;
}


static dbus_bool_t _wpa_dbus_dict_fill_value_from_variant(
	struct wpa_dbus_dict_entry *entry, DBusMessageIter *iter)
{
	const char *v;

	switch (entry->type) {
	case DBUS_TYPE_OBJECT_PATH:
	case DBUS_TYPE_STRING:
		dbus_message_iter_get_basic(iter, &v);
		entry->str_value = os_strdup(v);
		if (entry->str_value == NULL)
			return FALSE;
		break;
	case DBUS_TYPE_BOOLEAN:
		dbus_message_iter_get_basic(iter, &entry->bool_value);
		break;
	case DBUS_TYPE_BYTE:
		dbus_message_iter_get_basic(iter, &entry->byte_value);
		break;
	case DBUS_TYPE_INT16:
		dbus_message_iter_get_basic(iter, &entry->int16_value);
		break;
	case DBUS_TYPE_UINT16:
		dbus_message_iter_get_basic(iter, &entry->uint16_value);
		break;
	case DBUS_TYPE_INT32:
		dbus_message_iter_get_basic(iter, &entry->int32_value);
		break;
	case DBUS_TYPE_UINT32:
		dbus_message_iter_get_basic(iter, &entry->uint32_value);
		break;
	case DBUS_TYPE_INT64:
		dbus_message_iter_get_basic(iter, &entry->int64_value);
		break;
	case DBUS_TYPE_UINT64:
		dbus_message_iter_get_basic(iter, &entry->uint64_value);
		break;
	case DBUS_TYPE_DOUBLE:
		dbus_message_iter_get_basic(iter, &entry->double_value);
		break;
	case DBUS_TYPE_ARRAY:
		return _wpa_dbus_dict_entry_get_array(iter, entry);
	default:
		return FALSE;
	}

	return TRUE;
}


/**
 * Read the current key/value entry from the dict.  Entries are dynamically
 * allocated when needed and must be freed after use with the
 * wpa_dbus_dict_entry_clear() function.
 *
 * The returned entry object will be filled with the type and value of the next
 * entry in the dict, or the type will be DBUS_TYPE_INVALID if an error
 * occurred.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *    wpa_dbus_dict_open_read()
 * @param entry A valid dict entry object into which the dict key and value
 *    will be placed
 * @return TRUE on success, FALSE on failure
 *
 */
dbus_bool_t wpa_dbus_dict_get_entry(DBusMessageIter *iter_dict,
				    struct wpa_dbus_dict_entry * entry)
{
	DBusMessageIter iter_dict_entry, iter_dict_val;
	int type;
	const char *key;

	if (!iter_dict || !entry)
		goto error;

	if (dbus_message_iter_get_arg_type(iter_dict) != DBUS_TYPE_DICT_ENTRY)
		goto error;

	dbus_message_iter_recurse(iter_dict, &iter_dict_entry);
	dbus_message_iter_get_basic(&iter_dict_entry, &key);
	entry->key = key;

	if (!dbus_message_iter_next(&iter_dict_entry))
		goto error;
	type = dbus_message_iter_get_arg_type(&iter_dict_entry);
	if (type != DBUS_TYPE_VARIANT)
		goto error;

	dbus_message_iter_recurse(&iter_dict_entry, &iter_dict_val);
	entry->type = dbus_message_iter_get_arg_type(&iter_dict_val);
	if (!_wpa_dbus_dict_fill_value_from_variant(entry, &iter_dict_val))
		goto error;

	dbus_message_iter_next(iter_dict);
	return TRUE;

error:
	if (entry) {
		wpa_dbus_dict_entry_clear(entry);
		entry->type = DBUS_TYPE_INVALID;
		entry->array_type = DBUS_TYPE_INVALID;
	}

	return FALSE;
}


/**
 * Return whether or not there are additional dictionary entries.
 *
 * @param iter_dict A valid DBusMessageIter returned from
 *    wpa_dbus_dict_open_read()
 * @return TRUE if more dict entries exists, FALSE if no more dict entries
 * exist
 */
dbus_bool_t wpa_dbus_dict_has_dict_entry(DBusMessageIter *iter_dict)
{
	if (!iter_dict)
		return FALSE;
	return dbus_message_iter_get_arg_type(iter_dict) ==
		DBUS_TYPE_DICT_ENTRY;
}


/**
 * Free any memory used by the entry object.
 *
 * @param entry The entry object
 */
void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry)
{
	unsigned int i;

	if (!entry)
		return;
	switch (entry->type) {
	case DBUS_TYPE_OBJECT_PATH:
	case DBUS_TYPE_STRING:
		os_free(entry->str_value);
		break;
	case DBUS_TYPE_ARRAY:
		switch (entry->array_type) {
		case DBUS_TYPE_BYTE:
			os_free(entry->bytearray_value);
			break;
		case DBUS_TYPE_STRING:
			for (i = 0; i < entry->array_len; i++)
				os_free(entry->strarray_value[i]);
			os_free(entry->strarray_value);
			break;
		case WPAS_DBUS_TYPE_BINARRAY:
			for (i = 0; i < entry->array_len; i++)
				wpabuf_free(entry->binarray_value[i]);
			os_free(entry->binarray_value);
			break;
		}
		break;
	}

	os_memset(entry, 0, sizeof(struct wpa_dbus_dict_entry));
}
