/**
 * get_all_properties - Responds for GetAll properties calls on object
 * @message: Message with GetAll call
 * @interface: interface name which properties will be returned
 * @property_dsc: list of object's properties
 * Returns: Message with dict of variants as argument with properties values
 *
 * Iterates over all properties registered with object and execute getters
 * of those, which are readable and which interface matches interface
 * specified as argument. Returned message contains one dict argument
 * with properties names as keys and theirs values as values.
 */
static DBusMessage * get_all_properties(DBusMessage *message, char *interface,
					struct wpa_dbus_object_desc *obj_dsc)
{
	DBusMessage *reply;
	DBusMessageIter iter, dict_iter;
	DBusError error;

	reply = dbus_message_new_method_return(message);
	if (reply == NULL)
		return wpas_dbus_error_no_memory(message);

	dbus_message_iter_init_append(reply, &iter);
	if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
		dbus_message_unref(reply);
		return wpas_dbus_error_no_memory(message);
	}

	dbus_error_init(&error);
	if (!fill_dict_with_properties(&dict_iter, obj_dsc->properties,
				       interface, obj_dsc->user_data, &error)) {
		dbus_message_unref(reply);
		reply = wpas_dbus_reply_new_from_error(
			message, &error, DBUS_ERROR_INVALID_ARGS,
			"No readable properties in this interface");
		dbus_error_free(&error);
		return reply;
	}

	if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) {
		dbus_message_unref(reply);
		return wpas_dbus_error_no_memory(message);
	}

	return reply;
}
/**
 * get_all_properties - Responds for GetAll properties calls on object
 * @message: Message with GetAll call
 * @interface: interface name which properties will be returned
 * @property_dsc: list of object's properties
 * Returns: Message with dict of variants as argument with properties values
 *
 * Iterates over all properties registered with object and execute getters
 * of those, which are readable and which interface matches interface
 * specified as argument. Returned message contains one dict argument
 * with properties names as keys and theirs values as values.
 */
static DBusMessage * get_all_properties(DBusMessage *message, char *interface,
				        struct wpa_dbus_object_desc *obj_dsc)
{
	DBusMessage *reply;
	DBusMessageIter iter, dict_iter;
	DBusError error;

	reply = dbus_message_new_method_return(message);
	if (reply == NULL) {
		wpa_printf(MSG_ERROR, "%s: out of memory creating dbus reply",
			   __func__);
		return NULL;
	}

	dbus_message_iter_init_append(reply, &iter);
	if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
		wpa_printf(MSG_ERROR, "%s: out of memory creating reply",
			   __func__);
		dbus_message_unref(reply);
		reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
					       "out of memory");
		return reply;
	}

	dbus_error_init(&error);
	if (!fill_dict_with_properties(&dict_iter, obj_dsc->properties,
				       interface, obj_dsc->user_data, &error))
	{
		dbus_message_unref(reply);
		reply = wpas_dbus_reply_new_from_error(message, &error,
						       DBUS_ERROR_INVALID_ARGS,
						       "No readable properties"
						       " in this interface");
		dbus_error_free(&error);
		return reply;
	}

	if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) {
		dbus_message_unref(reply);
		return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
					      "out of memory");
	}

	return reply;
}
/**
 * wpa_dbus_get_object_properties - Put object's properties into dictionary
 * @iface: dbus priv struct
 * @path: path to DBus object which properties will be obtained
 * @interface: interface name which properties will be obtained
 * @iter: DBus message iter at which to append property dictionary.
 *
 * Iterates over all properties registered with object and execute getters
 * of those, which are readable and which interface matches interface
 * specified as argument. Obtained properties values are stored in
 * dict_iter dictionary.
 */
dbus_bool_t wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
					   const char *path,
					   const char *interface,
					   DBusMessageIter *iter)
{
	struct wpa_dbus_object_desc *obj_desc = NULL;
	DBusMessageIter dict_iter;
	DBusError error;

	dbus_connection_get_object_path_data(iface->con, path,
					     (void **) &obj_desc);
	if (!obj_desc) {
		wpa_printf(MSG_ERROR,
			   "dbus: %s: could not obtain object's private data: %s",
			   __func__, path);
		return FALSE;
	}

	if (!wpa_dbus_dict_open_write(iter, &dict_iter)) {
		wpa_printf(MSG_ERROR, "dbus: %s: failed to open message dict",
			   __func__);
		return FALSE;
	}

	dbus_error_init(&error);
	if (!fill_dict_with_properties(&dict_iter, obj_desc->properties,
				       interface, obj_desc->user_data,
				       &error)) {
		wpa_printf(MSG_ERROR,
			   "dbus: %s: failed to get object properties: (%s) %s",
			   __func__,
			   dbus_error_is_set(&error) ? error.name : "none",
			   dbus_error_is_set(&error) ? error.message : "none");
		dbus_error_free(&error);
		return FALSE;
	}

	return wpa_dbus_dict_close_write(iter, &dict_iter);
}