175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/*
275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * WPA Supplicant / dbus-based control interface (P2P)
304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Copyright (c) 2011-2012, Intel Corporation
475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *
504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * This software may be distributed under the terms of the BSD license.
604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * See README for more details.
775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */
875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "includes.h"
1075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
1175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "utils/includes.h"
1275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "common.h"
1375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "../config.h"
1475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "../wpa_supplicant_i.h"
1575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "../wps_supplicant.h"
1675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "../notify.h"
1775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "dbus_new_helpers.h"
1875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "dbus_new.h"
1975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "dbus_new_handlers.h"
2075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "dbus_new_handlers_p2p.h"
2175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "dbus_dict_helpers.h"
2275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "p2p/p2p.h"
2375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "common/ieee802_11_defs.h"
2475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "ap/hostapd.h"
2575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "ap/ap_config.h"
2675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "ap/wps_hostapd.h"
2775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
2875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#include "../p2p_supplicant.h"
2975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
3075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/**
3175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Parses out the mac address from the peer object path.
3275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @peer_path - object path of the form
3375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *	/fi/w1/wpa_supplicant1/Interfaces/n/Peers/00112233445566 (no colons)
3475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @addr - out param must be of ETH_ALEN size
3575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Returns 0 if valid (including MAC), -1 otherwise
3675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */
3775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic int parse_peer_object_path(char *peer_path, u8 addr[ETH_ALEN])
3875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
3975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *p;
4075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
4175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!peer_path)
4275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return -1;
4304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	p = os_strrchr(peer_path, '/');
4475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!p)
4575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return -1;
4675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	p++;
4775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return hwaddr_compact_aton(p, addr);
4875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
4975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
5075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
5175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/**
5275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * wpas_dbus_error_persistent_group_unknown - Return a new PersistentGroupUnknown
5375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * error message
5475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @message: Pointer to incoming dbus message this error refers to
5575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Returns: a dbus error message
5675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *
5775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Convenience function to create and return an invalid persistent group error.
5875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */
5975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic DBusMessage * wpas_dbus_error_persistent_group_unknown(
6075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *message)
6175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
6275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return dbus_message_new_error(message, WPAS_DBUS_ERROR_NETWORK_UNKNOWN,
6375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				      "There is no such persistent group in "
6475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				      "this P2P device.");
6575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
6675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
6775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					 struct wpa_supplicant *wpa_s)
7075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
7175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_dbus_dict_entry entry;
7275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *reply = NULL;
7375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter;
7475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter_dict;
7575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	unsigned int timeout = 0;
7675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	enum p2p_discovery_type type = P2P_FIND_ONLY_SOCIAL;
7775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int num_req_dev_types = 0;
7875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	unsigned int i;
7975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	u8 *req_dev_types = NULL;
8075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
8175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	entry.key = NULL;
8375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
8575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto error;
8675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
8775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
8875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
8975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
9075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
9175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!os_strcmp(entry.key, "Timeout") &&
9275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    (entry.type == DBUS_TYPE_INT32)) {
9375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			timeout = entry.uint32_value;
9475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else if (os_strcmp(entry.key, "RequestedDeviceTypes") == 0) {
9575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if ((entry.type != DBUS_TYPE_ARRAY) ||
9675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    (entry.array_type != WPAS_DBUS_TYPE_BINARRAY))
9775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto error_clear;
9875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			os_free(req_dev_types);
10075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			req_dev_types =
10175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				os_malloc(WPS_DEV_TYPE_LEN * entry.array_len);
10275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if (!req_dev_types)
10375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto error_clear;
10475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
10575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			for (i = 0; i < entry.array_len; i++) {
10675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				if (wpabuf_len(entry.binarray_value[i]) !=
10775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen							WPS_DEV_TYPE_LEN)
10875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					goto error_clear;
10975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				os_memcpy(req_dev_types + i * WPS_DEV_TYPE_LEN,
11075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					  wpabuf_head(entry.binarray_value[i]),
11175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					  WPS_DEV_TYPE_LEN);
11275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			}
11375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			num_req_dev_types = entry.array_len;
1141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "DiscoveryType") &&
1151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   (entry.type == DBUS_TYPE_STRING)) {
1161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (!os_strcmp(entry.str_value, "start_with_full"))
1171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				type = P2P_FIND_START_WITH_FULL;
1181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			else if (!os_strcmp(entry.str_value, "social"))
1191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				type = P2P_FIND_ONLY_SOCIAL;
1201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			else if (!os_strcmp(entry.str_value, "progressive"))
1211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				type = P2P_FIND_PROGRESSIVE;
1221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			else
1231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				goto error_clear;
12475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else
12575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error_clear;
12675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_dbus_dict_entry_clear(&entry);
12775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
12875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
129c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types, req_dev_types,
13061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		      NULL, 0);
1311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_free(req_dev_types);
13275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return reply;
13375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
13475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror_clear:
13575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_dbus_dict_entry_clear(&entry);
13675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror:
1371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_free(req_dev_types);
13875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	reply = wpas_dbus_error_invalid_args(message, entry.key);
13975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return reply;
14075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
14175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
1421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_stop_find(DBusMessage *message,
1441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					      struct wpa_supplicant *wpa_s)
14575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
14675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpas_p2p_stop_find(wpa_s);
14775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return NULL;
14875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
14975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
1501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_rejectpeer(DBusMessage *message,
1521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					       struct wpa_supplicant *wpa_s)
15375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
15475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter;
15575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *peer_object_path = NULL;
15675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	u8 peer_addr[ETH_ALEN];
15775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
15875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
15975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_get_basic(&iter, &peer_object_path);
16075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
16175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (parse_peer_object_path(peer_object_path, peer_addr) < 0)
16275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return wpas_dbus_error_invalid_args(message, NULL);
16375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
16475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpas_p2p_reject(wpa_s, peer_addr) < 0)
16575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return wpas_dbus_error_unknown_error(message,
16675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				"Failed to call wpas_p2p_reject method.");
16775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
16875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return NULL;
16975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
17075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
1711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_listen(DBusMessage *message,
1731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					   struct wpa_supplicant *wpa_s)
17475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
17575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_int32_t timeout = 0;
17675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
17775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_INT32, &timeout,
17875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				   DBUS_TYPE_INVALID))
17975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
18075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					      NULL);
18175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
18275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpas_p2p_listen(wpa_s, (unsigned int)timeout))
18375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
18475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					      NULL);
18575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
18675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return NULL;
18775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
18875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
1891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_extendedlisten(
1911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	DBusMessage *message, struct wpa_supplicant *wpa_s)
19275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
19375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	unsigned int period = 0, interval = 0;
19475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_dbus_dict_entry entry;
19575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter;
19675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter_dict;
19775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
19875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
1991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	entry.key = NULL;
20075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
2011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
20275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto error;
20375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
20475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
20575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
20675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
20775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
2081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!os_strcmp(entry.key, "period") &&
20975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    (entry.type == DBUS_TYPE_INT32))
21075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			period = entry.uint32_value;
2111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		else if (!os_strcmp(entry.key, "interval") &&
21275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 (entry.type == DBUS_TYPE_INT32))
21375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			interval = entry.uint32_value;
21475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		else
21575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error_clear;
21675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_dbus_dict_entry_clear(&entry);
21775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
21875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
21975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpas_p2p_ext_listen(wpa_s, period, interval))
2201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return wpas_dbus_error_unknown_error(
2211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			message, "failed to initiate a p2p_ext_listen.");
22275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
22375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return NULL;
22475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
22575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror_clear:
22675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_dbus_dict_entry_clear(&entry);
22775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror:
22875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return wpas_dbus_error_invalid_args(message, entry.key);
22975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
23075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
2311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_presence_request(
2331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	DBusMessage *message, struct wpa_supplicant *wpa_s)
23475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
23575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	unsigned int dur1 = 0, int1 = 0, dur2 = 0, int2 = 0;
23675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_dbus_dict_entry entry;
23775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter;
23875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter_dict;
23975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
24075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
2411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	entry.key = NULL;
24275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
2431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
24475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto error;
24575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
24675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
24775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
24875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
24975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
2501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!os_strcmp(entry.key, "duration1") &&
25175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    (entry.type == DBUS_TYPE_INT32))
25275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			dur1 = entry.uint32_value;
2531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		else if (!os_strcmp(entry.key, "interval1") &&
25475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 entry.type == DBUS_TYPE_INT32)
25575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			int1 = entry.uint32_value;
2561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		else if (!os_strcmp(entry.key, "duration2") &&
25775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 entry.type == DBUS_TYPE_INT32)
25875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			dur2 = entry.uint32_value;
2591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		else if (!os_strcmp(entry.key, "interval2") &&
26075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 entry.type == DBUS_TYPE_INT32)
26175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			int2 = entry.uint32_value;
26275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		else
26375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error_clear;
26475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
26575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_dbus_dict_entry_clear(&entry);
26675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
26775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpas_p2p_presence_req(wpa_s, dur1, int1, dur2, int2) < 0)
26875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return wpas_dbus_error_unknown_error(message,
26975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				"Failed to invoke presence request.");
27075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
27175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return NULL;
27275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
27375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror_clear:
27475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_dbus_dict_entry_clear(&entry);
27575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror:
27675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return wpas_dbus_error_invalid_args(message, entry.key);
27775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
27875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
2791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
2811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					      struct wpa_supplicant *wpa_s)
28275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
28375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter_dict;
28475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *reply = NULL;
28575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter;
28675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_dbus_dict_entry entry;
28775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *pg_object_path = NULL;
28875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int persistent_group = 0;
28975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int freq = 0;
29075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *iface = NULL;
29175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *net_id_str = NULL;
29275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	unsigned int group_id = 0;
29375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_ssid *ssid;
29475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
29575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
29675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
2971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
29875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto inv_args;
29975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
30075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
30175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
30275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto inv_args;
30375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
3041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!os_strcmp(entry.key, "persistent") &&
30575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    (entry.type == DBUS_TYPE_BOOLEAN)) {
30675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			persistent_group = (entry.bool_value == TRUE) ? 1 : 0;
3071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "frequency") &&
30875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_INT32)) {
30975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			freq = entry.int32_value;
31075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if (freq <= 0)
31175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto inv_args_clear;
3121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "persistent_group_object") &&
31375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   entry.type == DBUS_TYPE_OBJECT_PATH)
31475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			pg_object_path = os_strdup(entry.str_value);
31575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		else
31675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto inv_args_clear;
31775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
31875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_dbus_dict_entry_clear(&entry);
31975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
32075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
32175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (pg_object_path != NULL) {
32275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		/*
32375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * A persistent group Object Path is defined meaning we want
32475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * to re-invoke a persistent group.
32575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 */
32675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
32775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		iface = wpas_dbus_new_decompose_object_path(pg_object_path, 1,
32875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen							    &net_id_str, NULL);
32975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (iface == NULL ||
33075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
33175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			reply =
33275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    wpas_dbus_error_invalid_args(message,
33375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen							 pg_object_path);
33475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto out;
33575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
33675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
33775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		group_id = strtoul(net_id_str, NULL, 10);
33875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (errno == EINVAL) {
33975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			reply = wpas_dbus_error_invalid_args(
34075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen						message, pg_object_path);
34175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto out;
34275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
34375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
3441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		/* Get the SSID structure from the persistent group id */
34575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		ssid = wpa_config_get_network(wpa_s->conf, group_id);
34675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (ssid == NULL || ssid->disabled != 2)
34775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto inv_args;
34875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
34961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0)) {
3501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			reply = wpas_dbus_error_unknown_error(
3511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				message,
3521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				"Failed to reinvoke a persistent group");
35375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto out;
35475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
35561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, 0))
35675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto inv_args;
35775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
35875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenout:
35975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_free(pg_object_path);
36075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_free(net_id_str);
36175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_free(iface);
36275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return reply;
36375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malineninv_args_clear:
36475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_dbus_dict_entry_clear(&entry);
36575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malineninv_args:
36675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	reply = wpas_dbus_error_invalid_args(message, NULL);
36775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	goto out;
36875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
36975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
3701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_disconnect(DBusMessage *message,
3721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					       struct wpa_supplicant *wpa_s)
37375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
37475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpas_p2p_disconnect(wpa_s))
37575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return wpas_dbus_error_unknown_error(message,
37675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen						"failed to disconnect");
37775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
37875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return NULL;
37975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
38075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
3811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic dbus_bool_t wpa_dbus_p2p_check_enabled(struct wpa_supplicant *wpa_s,
3831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					      DBusMessage *message,
3841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					      DBusMessage **out_reply,
3851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					      DBusError *error)
38675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
3871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/* Return an error message or an error if P2P isn't available */
3881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
3891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (out_reply) {
3901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			*out_reply = dbus_message_new_error(
3911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				message, DBUS_ERROR_FAILED,
3921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				"P2P is not available for this interface");
3931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
3941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		dbus_set_error_const(error, DBUS_ERROR_FAILED,
3951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				     "P2P is not available for this "
3961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				     "interface");
3971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return FALSE;
3981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
3991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return TRUE;
4001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
4011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_flush(DBusMessage *message,
4041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					  struct wpa_supplicant *wpa_s)
4051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
4061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	DBusMessage *reply = NULL;
4071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
4091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return reply;
4101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
41175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
41275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_s->force_long_sd = 0;
41375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	p2p_flush(wpa_s->global->p2p);
41475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
41575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return NULL;
41675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
41775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
4181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message,
4201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					    struct wpa_supplicant *wpa_s)
42175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
42275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter_dict;
42375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *reply = NULL;
42475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter;
42575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_dbus_dict_entry entry;
42675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *peer_object_path = NULL;
42775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int persistent_group = 0;
42875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int join = 0;
42975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int authorize_only = 0;
43075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int go_intent = -1;
43175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int freq = 0;
43275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	u8 addr[ETH_ALEN];
43375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *pin = NULL;
43475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	enum p2p_wps_method wps_method = WPS_NOT_READY;
43575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int new_pin;
43675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *err_msg = NULL;
43775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *iface = NULL;
43875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
4391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
4401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return reply;
4411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
44275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
44375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
4441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
44575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto inv_args;
44675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
44775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
44875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
44975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto inv_args;
45075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
4511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!os_strcmp(entry.key, "peer") &&
45275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    (entry.type == DBUS_TYPE_OBJECT_PATH)) {
45375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			peer_object_path = os_strdup(entry.str_value);
4541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "persistent") &&
45575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_BOOLEAN)) {
45675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			persistent_group = (entry.bool_value == TRUE) ? 1 : 0;
4571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "join") &&
45875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_BOOLEAN)) {
45975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			join = (entry.bool_value == TRUE) ? 1 : 0;
4601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "authorize_only") &&
46175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_BOOLEAN)) {
46275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			authorize_only = (entry.bool_value == TRUE) ? 1 : 0;
4631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "frequency") &&
46475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_INT32)) {
46575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			freq = entry.int32_value;
46675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if (freq <= 0)
46775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto inv_args_clear;
4681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "go_intent") &&
46975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_INT32)) {
47075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			go_intent = entry.int32_value;
47175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if ((go_intent < 0) || (go_intent > 15))
47275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto inv_args_clear;
4731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "wps_method") &&
47475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_STRING)) {
4751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (!os_strcmp(entry.str_value, "pbc"))
47675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				wps_method = WPS_PBC;
4771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			else if (!os_strcmp(entry.str_value, "pin"))
47875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				wps_method = WPS_PIN_DISPLAY;
4791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			else if (!os_strcmp(entry.str_value, "display"))
48075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				wps_method = WPS_PIN_DISPLAY;
4811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			else if (!os_strcmp(entry.str_value, "keypad"))
48275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				wps_method = WPS_PIN_KEYPAD;
48375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			else
48475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto inv_args_clear;
4851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "pin") &&
48675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_STRING)) {
48775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			pin = os_strdup(entry.str_value);
48875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else
48975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto inv_args_clear;
49075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
49175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_dbus_dict_entry_clear(&entry);
49275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
49375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
49475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!peer_object_path || (wps_method == WPS_NOT_READY) ||
49575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    (parse_peer_object_path(peer_object_path, addr) < 0) ||
4961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    !p2p_peer_known(wpa_s->global->p2p, addr))
49775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto inv_args;
49875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
49975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/*
50075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * Validate the wps_method specified and the pin value.
50175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 */
5021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if ((!pin || !pin[0]) && (wps_method == WPS_PIN_KEYPAD))
50375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto inv_args;
50475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
50575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
50604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   persistent_group, 0, join, authorize_only,
50761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				   go_intent, freq, -1, 0, 0);
50875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
50975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (new_pin >= 0) {
5101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		char npin[9];
5111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		char *generated_pin;
5121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		os_snprintf(npin, sizeof(npin), "%08d", new_pin);
5131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		generated_pin = npin;
51475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		reply = dbus_message_new_method_return(message);
5151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		dbus_message_append_args(reply, DBUS_TYPE_STRING,
5161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					 &generated_pin, DBUS_TYPE_INVALID);
51775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	} else {
51875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		switch (new_pin) {
51975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		case -2:
5201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			err_msg = "connect failed due to channel "
5211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				"unavailability.";
52275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			iface = WPAS_DBUS_ERROR_CONNECT_CHANNEL_UNAVAILABLE;
52375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			break;
52475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
52575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		case -3:
5261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			err_msg = "connect failed due to unsupported channel.";
52775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			iface = WPAS_DBUS_ERROR_CONNECT_CHANNEL_UNSUPPORTED;
52875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			break;
52975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
53075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		default:
5311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			err_msg = "connect failed due to unspecified error.";
53275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			iface = WPAS_DBUS_ERROR_CONNECT_UNSPECIFIED_ERROR;
53375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			break;
53475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
5351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
53675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		/*
5371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 * TODO:
53875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * Do we need specialized errors corresponding to above
53975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * error conditions as against just returning a different
54075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * error message?
54175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 */
54275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		reply = dbus_message_new_error(message, iface, err_msg);
54375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
54475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
54575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenout:
54675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_free(peer_object_path);
54775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_free(pin);
54875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return reply;
54975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malineninv_args_clear:
55075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_dbus_dict_entry_clear(&entry);
55175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malineninv_args:
55275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	reply = wpas_dbus_error_invalid_args(message, NULL);
55375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	goto out;
55475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
55575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
5561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
5571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
5581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					   struct wpa_supplicant *wpa_s)
55975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
56075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter_dict;
56175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *reply = NULL;
56275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter;
56375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_dbus_dict_entry entry;
56475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *peer_object_path = NULL;
56575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *pg_object_path = NULL;
56675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *iface = NULL;
56775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *net_id_str = NULL;
56875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	u8 peer_addr[ETH_ALEN];
56975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	unsigned int group_id = 0;
57075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int persistent = 0;
57175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_ssid *ssid;
57275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
5731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_p2p_check_enabled(wpa_s, message, &reply, NULL))
5741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return reply;
5751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
57675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
57775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
5781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
57975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err;
58075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
58175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
58275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
58375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto err;
58475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
5851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!os_strcmp(entry.key, "peer") &&
58675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    (entry.type == DBUS_TYPE_OBJECT_PATH)) {
58775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			peer_object_path = os_strdup(entry.str_value);
58875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_dbus_dict_entry_clear(&entry);
5891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "persistent_group_object") &&
59075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_OBJECT_PATH)) {
59175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			pg_object_path = os_strdup(entry.str_value);
59275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			persistent = 1;
59375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_dbus_dict_entry_clear(&entry);
59475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else {
59575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_dbus_dict_entry_clear(&entry);
59675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto err;
59775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
59875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
59975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
60075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!peer_object_path ||
60175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    (parse_peer_object_path(peer_object_path, peer_addr) < 0) ||
6021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    !p2p_peer_known(wpa_s->global->p2p, peer_addr)) {
60375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err;
60475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
60575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
60675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (persistent) {
60775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		/*
60875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * A group ID is defined meaning we want to re-invoke a
6091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		 * persistent group
61075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 */
61175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
61275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		iface = wpas_dbus_new_decompose_object_path(pg_object_path, 1,
61375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen							    &net_id_str, NULL);
61475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (iface == NULL ||
61575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
6161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			reply = wpas_dbus_error_invalid_args(message,
6171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							     pg_object_path);
61875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto out;
61975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
62075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
62175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		group_id = strtoul(net_id_str, NULL, 10);
62275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (errno == EINVAL) {
62375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			reply = wpas_dbus_error_invalid_args(
6241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				message, pg_object_path);
62575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto out;
62675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
62775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
6281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		/* Get the SSID structure from the persistent group id */
62975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		ssid = wpa_config_get_network(wpa_s->conf, group_id);
63075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (ssid == NULL || ssid->disabled != 2)
63175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto err;
63275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
63331be0a4b946ecab910c0a9af3837dbccea5d204bJouni Malinen		if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0) < 0) {
63475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			reply = wpas_dbus_error_unknown_error(
6351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				message,
6361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				"Failed to reinvoke a persistent group");
63775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto out;
63875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
63975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	} else {
64075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		/*
64175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 * No group ID means propose to a peer to join my active group
64275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		 */
64375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (wpas_p2p_invite_group(wpa_s, wpa_s->ifname,
6441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					  peer_addr, NULL)) {
64575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			reply = wpas_dbus_error_unknown_error(
6461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				message, "Failed to join to an active group");
64775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto out;
64875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
64975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
65075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
65175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenout:
65275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_free(pg_object_path);
65375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_free(peer_object_path);
65475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return reply;
65575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
65675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerr:
65775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	reply = wpas_dbus_error_invalid_args(message, NULL);
65875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	goto out;
65975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
66075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
6611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
6621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_prov_disc_req(DBusMessage *message,
6631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						  struct wpa_supplicant *wpa_s)
66475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
66575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter;
66675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *peer_object_path = NULL;
66775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *config_method = NULL;
66875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	u8 peer_addr[ETH_ALEN];
66975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
67075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
67175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_get_basic(&iter, &peer_object_path);
67275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
67375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (parse_peer_object_path(peer_object_path, peer_addr) < 0)
67475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return wpas_dbus_error_invalid_args(message, NULL);
67575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
67675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_next(&iter);
67775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_get_basic(&iter, &config_method);
67875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
67975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/*
68075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * Validation checks on config_method are being duplicated here
68175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * to be able to return invalid args reply since the error code
68275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * from p2p module are not granular enough (yet).
68375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 */
68475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (os_strcmp(config_method, "display") &&
68575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    os_strcmp(config_method, "keypad") &&
68675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    os_strcmp(config_method, "pbc") &&
68775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    os_strcmp(config_method, "pushbutton"))
68875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return wpas_dbus_error_invalid_args(message, NULL);
68975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
69004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpas_p2p_prov_disc(wpa_s, peer_addr, config_method,
69104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			       WPAS_P2P_PD_FOR_GO_NEG) < 0)
69275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return wpas_dbus_error_unknown_error(message,
69375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				"Failed to send provision discovery request");
69475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
69575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return NULL;
69675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
69775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
6981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
69975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/*
70075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * P2P Device property accessor methods.
70175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */
70275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
70304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_device_config(DBusMessageIter *iter,
70404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       DBusError *error,
70504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       void *user_data)
70675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
7071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
7081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	DBusMessageIter variant_iter, dict_iter;
709c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	DBusMessageIter iter_secdev_dict_entry, iter_secdev_dict_val,
710c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		iter_secdev_dict_array;
71175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	const char *dev_name;
71275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int num_vendor_extensions = 0;
71375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int i;
71475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	const struct wpabuf *vendor_ext[P2P_MAX_WPS_VENDOR_EXT];
71575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
7161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error))
7171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return FALSE;
71875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
7191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
72075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					      "a{sv}", &variant_iter) ||
72175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    !wpa_dbus_dict_open_write(&variant_iter, &dict_iter))
72275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
72375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
72475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* DeviceName */
72575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dev_name = wpa_s->conf->device_name;
72675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (dev_name &&
72775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    !wpa_dbus_dict_append_string(&dict_iter, "DeviceName", dev_name))
72875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
72975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
73075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Primary device type */
73175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!wpa_dbus_dict_append_byte_array(&dict_iter, "PrimaryDeviceType",
73275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    				     (char *)wpa_s->conf->device_type,
73375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    				     WPS_DEV_TYPE_LEN))
73475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
73575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
73675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Secondary device types */
737c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	if (wpa_s->conf->num_sec_device_types) {
738c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		if (!wpa_dbus_dict_begin_array(&dict_iter,
739c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt					       "SecondaryDeviceTypes",
740c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt					       DBUS_TYPE_ARRAY_AS_STRING
741c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt					       DBUS_TYPE_BYTE_AS_STRING,
742c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt					       &iter_secdev_dict_entry,
743c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt					       &iter_secdev_dict_val,
744c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt					       &iter_secdev_dict_array))
745c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt			goto err_no_mem;
746c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
747c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		for (i = 0; i < wpa_s->conf->num_sec_device_types; i++)
748c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt			wpa_dbus_dict_bin_array_add_element(
749c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt				&iter_secdev_dict_array,
750c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt				wpa_s->conf->sec_device_type[i],
751c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt				WPS_DEV_TYPE_LEN);
752c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
753c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		if (!wpa_dbus_dict_end_array(&dict_iter,
754c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt					     &iter_secdev_dict_entry,
755c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt					     &iter_secdev_dict_val,
756c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt					     &iter_secdev_dict_array))
757c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt			goto err_no_mem;
75875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
75975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
76075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Vendor Extensions */
76175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
76275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (wpa_s->conf->wps_vendor_ext[i] == NULL)
76375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			continue;
76475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		vendor_ext[num_vendor_extensions++] =
76575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->wps_vendor_ext[i];
76675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
76775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
76875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (num_vendor_extensions &&
76975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    !wpa_dbus_dict_append_wpabuf_array(&dict_iter,
77075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					       "VendorExtension",
77175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					       vendor_ext,
77275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					       num_vendor_extensions))
77375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
77475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
77575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* GO Intent */
77675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!wpa_dbus_dict_append_uint32(&dict_iter, "GOIntent",
77775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					 wpa_s->conf->p2p_go_intent))
77875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
77975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
7801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/* Persistent Reconnect */
78104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpa_dbus_dict_append_bool(&dict_iter, "PersistentReconnect",
78275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				       wpa_s->conf->persistent_reconnect))
78375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
78475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
78575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Listen Reg Class */
78675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!wpa_dbus_dict_append_uint32(&dict_iter, "ListenRegClass",
78775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					 wpa_s->conf->p2p_listen_reg_class))
78875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
78975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
79075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Listen Channel */
79175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!wpa_dbus_dict_append_uint32(&dict_iter, "ListenChannel",
79275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					 wpa_s->conf->p2p_listen_channel))
79375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
79475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
79575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Oper Reg Class */
79675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!wpa_dbus_dict_append_uint32(&dict_iter, "OperRegClass",
79775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					 wpa_s->conf->p2p_oper_reg_class))
79875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
79975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
80075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Oper Channel */
80175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!wpa_dbus_dict_append_uint32(&dict_iter, "OperChannel",
80275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					 wpa_s->conf->p2p_oper_channel))
80375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
80475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
80575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* SSID Postfix */
80675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpa_s->conf->p2p_ssid_postfix &&
80775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    !wpa_dbus_dict_append_string(&dict_iter, "SsidPostfix",
80875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					 wpa_s->conf->p2p_ssid_postfix))
80975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
81075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
81175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Intra Bss */
81275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!wpa_dbus_dict_append_bool(&dict_iter, "IntraBss",
81375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				       wpa_s->conf->p2p_intra_bss))
81475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
81575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
81675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Group Idle */
81775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!wpa_dbus_dict_append_uint32(&dict_iter, "GroupIdle",
81875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					 wpa_s->conf->p2p_group_idle))
81975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
82075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
82175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Dissasociation low ack */
82275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!wpa_dbus_dict_append_uint32(&dict_iter, "disassoc_low_ack",
82375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					 wpa_s->conf->disassoc_low_ack))
82475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
82575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
82675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
8271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    !dbus_message_iter_close_container(iter, &variant_iter))
82875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err_no_mem;
82975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
8301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return TRUE;
8311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
83275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerr_no_mem:
8331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
8341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return FALSE;
83575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
83675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
8371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
83804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtdbus_bool_t wpas_dbus_setter_p2p_device_config(DBusMessageIter *iter,
83904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       DBusError *error,
84004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       void *user_data)
84175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
8421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
8431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	DBusMessageIter variant_iter, iter_dict;
84475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_dbus_dict_entry entry = {.type = DBUS_TYPE_STRING };
84575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	unsigned int i;
84675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
8471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error))
8481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return FALSE;
84975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
8501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dbus_message_iter_recurse(iter, &variant_iter);
8511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error))
8521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return FALSE;
85375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
85475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
8551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
8561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
8571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					     "invalid message format");
8581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return FALSE;
8591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
86075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
86175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (os_strcmp(entry.key, "DeviceName") == 0) {
86275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			char *devname;
86375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
86475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if (entry.type != DBUS_TYPE_STRING)
8651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				goto error;
86675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
86775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			devname = os_strdup(entry.str_value);
86875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if (devname == NULL)
86975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto err_no_mem_clear;
87075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
87175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			os_free(wpa_s->conf->device_name);
87275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->device_name = devname;
87375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
87475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->changed_parameters |=
8751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				CFG_CHANGED_DEVICE_NAME;
87675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else if (os_strcmp(entry.key, "PrimaryDeviceType") == 0) {
87775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if (entry.type != DBUS_TYPE_ARRAY ||
87875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    entry.array_type != DBUS_TYPE_BYTE ||
87975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    entry.array_len != WPS_DEV_TYPE_LEN)
8801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				goto error;
88175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
88275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			os_memcpy(wpa_s->conf->device_type,
88375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				  entry.bytearray_value,
88475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				  WPS_DEV_TYPE_LEN);
88575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->changed_parameters |=
88675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				CFG_CHANGED_DEVICE_TYPE;
88775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else if (os_strcmp(entry.key, "SecondaryDeviceTypes") == 0) {
88875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if (entry.type != DBUS_TYPE_ARRAY ||
88975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    entry.array_type != WPAS_DBUS_TYPE_BINARRAY ||
89075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    entry.array_len > MAX_SEC_DEVICE_TYPES)
89175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto error;
89275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
89375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			for (i = 0; i < entry.array_len; i++)
8941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				if (wpabuf_len(entry.binarray_value[i]) !=
8951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				    WPS_DEV_TYPE_LEN)
89675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					goto err_no_mem_clear;
89775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			for (i = 0; i < entry.array_len; i++)
89875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				os_memcpy(wpa_s->conf->sec_device_type[i],
89975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					  wpabuf_head(entry.binarray_value[i]),
90075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					  WPS_DEV_TYPE_LEN);
90175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->num_sec_device_types = entry.array_len;
90275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->changed_parameters |=
90375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					CFG_CHANGED_SEC_DEVICE_TYPE;
90475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else if (os_strcmp(entry.key, "VendorExtension") == 0) {
90575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if ((entry.type != DBUS_TYPE_ARRAY) ||
90675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    (entry.array_type != WPAS_DBUS_TYPE_BINARRAY) ||
90775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    (entry.array_len > P2P_MAX_WPS_VENDOR_EXT))
9081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				goto error;
90975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
91075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->changed_parameters |=
9111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				CFG_CHANGED_VENDOR_EXTENSION;
91275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
91375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
91475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				wpabuf_free(wpa_s->conf->wps_vendor_ext[i]);
91575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				if (i < entry.array_len) {
91675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					wpa_s->conf->wps_vendor_ext[i] =
91775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen						entry.binarray_value[i];
91875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					entry.binarray_value[i] = NULL;
91975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				} else
92075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					wpa_s->conf->wps_vendor_ext[i] = NULL;
92175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			}
92275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else if ((os_strcmp(entry.key, "GOIntent") == 0) &&
92375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_UINT32) &&
92475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.uint32_value <= 15))
92575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->p2p_go_intent = entry.uint32_value;
92604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		else if ((os_strcmp(entry.key, "PersistentReconnect") == 0) &&
92775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 (entry.type == DBUS_TYPE_BOOLEAN))
92875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->persistent_reconnect = entry.bool_value;
92975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		else if ((os_strcmp(entry.key, "ListenRegClass") == 0) &&
93075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 (entry.type == DBUS_TYPE_UINT32)) {
93175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->p2p_listen_reg_class = entry.uint32_value;
93275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->changed_parameters |=
93375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				CFG_CHANGED_P2P_LISTEN_CHANNEL;
93475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else if ((os_strcmp(entry.key, "ListenChannel") == 0) &&
93575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_UINT32)) {
93675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->p2p_listen_channel = entry.uint32_value;
93775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->changed_parameters |=
93875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				CFG_CHANGED_P2P_LISTEN_CHANNEL;
93975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else if ((os_strcmp(entry.key, "OperRegClass") == 0) &&
94075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_UINT32)) {
94175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->p2p_oper_reg_class = entry.uint32_value;
94275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->changed_parameters |=
94375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				CFG_CHANGED_P2P_OPER_CHANNEL;
94475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else if ((os_strcmp(entry.key, "OperChannel") == 0) &&
94575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_UINT32)) {
94675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->p2p_oper_channel = entry.uint32_value;
94775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->changed_parameters |=
94875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				CFG_CHANGED_P2P_OPER_CHANNEL;
94975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else if (os_strcmp(entry.key, "SsidPostfix") == 0) {
95075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			char *postfix;
95175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
95275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if (entry.type != DBUS_TYPE_STRING)
9531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				goto error;
95475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
95575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			postfix = os_strdup(entry.str_value);
95675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if (!postfix)
95775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto err_no_mem_clear;
95875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
95975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			os_free(wpa_s->conf->p2p_ssid_postfix);
96075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->p2p_ssid_postfix = postfix;
96175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
96275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->changed_parameters |=
96375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					CFG_CHANGED_P2P_SSID_POSTFIX;
96475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else if ((os_strcmp(entry.key, "IntraBss") == 0) &&
96575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_BOOLEAN)) {
96675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->p2p_intra_bss = entry.bool_value;
96775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->changed_parameters |=
9681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				CFG_CHANGED_P2P_INTRA_BSS;
96975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else if ((os_strcmp(entry.key, "GroupIdle") == 0) &&
97075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   (entry.type == DBUS_TYPE_UINT32))
97175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->p2p_group_idle = entry.uint32_value;
97275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		else if (os_strcmp(entry.key, "disassoc_low_ack") == 0 &&
97375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 entry.type == DBUS_TYPE_UINT32)
97475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_s->conf->disassoc_low_ack = entry.uint32_value;
97575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		else
9761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto error;
97775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
97875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_dbus_dict_entry_clear(&entry);
97975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
98075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
98175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpa_s->conf->changed_parameters) {
98275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		/* Some changed parameters requires to update config*/
98375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_supplicant_update_config(wpa_s);
98475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
98575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
9861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return TRUE;
98775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
98875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen error:
9891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
9901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			     "invalid message format");
99175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_dbus_dict_entry_clear(&entry);
9921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return FALSE;
99375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
99475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen err_no_mem_clear:
9951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
99675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_dbus_dict_entry_clear(&entry);
9971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return FALSE;
99875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
99975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
10001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
10011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_peers(DBusMessageIter *iter, DBusError *error,
10021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				       void *user_data)
100375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
10041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
100575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct p2p_data *p2p = wpa_s->global->p2p;
100675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int next = 0, i = 0;
100775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int num = 0, out_of_mem = 0;
100875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	const u8 *addr;
100975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	const struct p2p_peer_info *peer_info = NULL;
10101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dbus_bool_t success = FALSE;
101175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
101275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct dl_list peer_objpath_list;
101375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct peer_objpath_node {
101475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		struct dl_list list;
101575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		char path[WPAS_DBUS_OBJECT_PATH_MAX];
101675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	} *node, *tmp;
101775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
101875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char **peer_obj_paths = NULL;
101975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
10201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_p2p_check_enabled(wpa_s, NULL, NULL, error))
10211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return FALSE;
10221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
102375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dl_list_init(&peer_objpath_list);
102475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
102575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Get the first peer info */
102675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	peer_info = p2p_get_peer_found(p2p, NULL, next);
102775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
102875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Get next and accumulate them */
102975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	next = 1;
103075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	while (peer_info != NULL) {
103175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		node = os_zalloc(sizeof(struct peer_objpath_node));
103275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!node) {
103375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			out_of_mem = 1;
103475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
103575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
103675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
103775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		addr = peer_info->p2p_device_addr;
103875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		os_snprintf(node->path, WPAS_DBUS_OBJECT_PATH_MAX,
103975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART
104075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    "/" COMPACT_MACSTR,
104175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    wpa_s->dbus_new_path, MAC2STR(addr));
104275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		dl_list_add_tail(&peer_objpath_list, &node->list);
104375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		num++;
104475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
104575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		peer_info = p2p_get_peer_found(p2p, addr, next);
104675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
104775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
104875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/*
104975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * Now construct the peer object paths in a form suitable for
105075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * array_property_getter helper below.
105175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 */
105261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	peer_obj_paths = os_calloc(num, sizeof(char *));
105375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
105475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!peer_obj_paths) {
105575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		out_of_mem = 1;
105675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto error;
105775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
105875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
105975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dl_list_for_each_safe(node, tmp, &peer_objpath_list,
106075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			      struct peer_objpath_node, list)
106175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		peer_obj_paths[i++] = node->path;
106275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
10631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	success = wpas_dbus_simple_array_property_getter(iter,
10641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							 DBUS_TYPE_OBJECT_PATH,
10651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							 peer_obj_paths, num,
10661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							 error);
106775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
106875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror:
106975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (peer_obj_paths)
107075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		os_free(peer_obj_paths);
107175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
107275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dl_list_for_each_safe(node, tmp, &peer_objpath_list,
107375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			      struct peer_objpath_node, list) {
107475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		dl_list_del(&node->list);
107575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		os_free(node);
107675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
107775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (out_of_mem)
10781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
107975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
10801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return success;
108175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
108275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
10831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
108475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenenum wpas_p2p_role {
108575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	WPAS_P2P_ROLE_DEVICE,
108675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	WPAS_P2P_ROLE_GO,
108775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	WPAS_P2P_ROLE_CLIENT,
108875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen};
108975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
109075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic enum wpas_p2p_role wpas_get_p2p_role(struct wpa_supplicant *wpa_s)
109175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
109275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_ssid *ssid = wpa_s->current_ssid;
109375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
109475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!ssid)
109575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return WPAS_P2P_ROLE_DEVICE;
109675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpa_s->wpa_state != WPA_COMPLETED)
109775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return WPAS_P2P_ROLE_DEVICE;
109875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
109975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	switch (ssid->mode) {
110075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	case WPAS_MODE_P2P_GO:
110175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	case WPAS_MODE_P2P_GROUP_FORMATION:
110275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return WPAS_P2P_ROLE_GO;
110375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	case WPAS_MODE_INFRA:
110475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (ssid->p2p_group)
110575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			return WPAS_P2P_ROLE_CLIENT;
110675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return WPAS_P2P_ROLE_DEVICE;
110775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	default:
110875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return WPAS_P2P_ROLE_DEVICE;
110975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
111075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
111175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
11121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
11131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_role(DBusMessageIter *iter, DBusError *error,
11141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				      void *user_data)
111575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
11161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
111775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *str;
111875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
111975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	switch (wpas_get_p2p_role(wpa_s)) {
112075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	case WPAS_P2P_ROLE_GO:
112175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		str = "GO";
112275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		break;
112375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	case WPAS_P2P_ROLE_CLIENT:
112475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		str = "client";
112575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		break;
112675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	default:
112775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		str = "device";
112875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
112975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
11301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &str,
11311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						error);
113275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
113375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
11341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
11351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_group(DBusMessageIter *iter, DBusError *error,
11361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				       void *user_data)
113775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
11381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
113904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	char path_buf[WPAS_DBUS_OBJECT_PATH_MAX];
114004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	char *dbus_groupobj_path = path_buf;
11411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
114275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpa_s->dbus_groupobj_path == NULL)
114304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_snprintf(dbus_groupobj_path, WPAS_DBUS_OBJECT_PATH_MAX,
114404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    "/");
114504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else
114604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_snprintf(dbus_groupobj_path, WPAS_DBUS_OBJECT_PATH_MAX,
114704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    "%s", wpa_s->dbus_groupobj_path);
114875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
11491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
115004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						&dbus_groupobj_path, error);
115175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
115275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
11531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
11541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_peergo(DBusMessageIter *iter,
11551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					DBusError *error, void *user_data)
115675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
11571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
115875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char go_peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
115975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
116075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpas_get_p2p_role(wpa_s) != WPAS_P2P_ROLE_CLIENT)
116104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
116204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else
116304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
116404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
116504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    COMPACT_MACSTR,
116604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    wpa_s->dbus_new_path, MAC2STR(wpa_s->go_dev_addr));
116775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
116875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	path = go_peer_obj_path;
11691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
11701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						&path, error);
117175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
117275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
11731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
117475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/*
117575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Peer object properties accessor methods
117675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */
117775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
1178c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_peer_device_name(DBusMessageIter *iter,
1179c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt						  DBusError *error,
1180c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt						  void *user_data)
118175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
11821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct peer_handler_args *peer_args = user_data;
1183c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	const struct p2p_peer_info *info;
1184c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	char *tmp;
11851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
11861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_p2p_check_enabled(peer_args->wpa_s, NULL, NULL, error))
11871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return FALSE;
118875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
118975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* get the peer info */
119075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
119175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				  peer_args->p2p_device_addr, 0);
11921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (info == NULL) {
1193c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error(error, DBUS_ERROR_FAILED,
1194c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			       "failed to find peer");
11951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return FALSE;
11961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
119775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
1198c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	tmp = os_strdup(info->device_name);
1199c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!tmp) {
1200c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
1201c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
1202c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
120375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
1204c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &tmp,
1205c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					      error)) {
1206c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
1207c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		os_free(tmp);
1208c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
1209c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
1210c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1211c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	os_free(tmp);
1212c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return TRUE;
1213c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
1214c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1215c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1216c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_peer_primary_device_type(
1217c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	DBusMessageIter *iter, DBusError *error, void *user_data)
1218c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
1219c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct peer_handler_args *peer_args = user_data;
1220c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	const struct p2p_peer_info *info;
1221c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1222c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
1223c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				  peer_args->p2p_device_addr, 0);
1224c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (info == NULL) {
1225c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error(error, DBUS_ERROR_FAILED,
1226c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			       "failed to find peer");
1227c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
1228c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
1229c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1230c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
1231c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt						    (char *)
1232c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt						    info->pri_dev_type,
1233c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt						    WPS_DEV_TYPE_LEN, error)) {
1234c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
1235c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
1236c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
1237c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1238c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return TRUE;
1239c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
1240c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1241c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1242c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_peer_config_method(DBusMessageIter *iter,
1243c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt                                                    DBusError *error,
1244c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt                                                    void *user_data)
1245c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
1246c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct peer_handler_args *peer_args = user_data;
1247c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	const struct p2p_peer_info *info;
1248c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1249c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
1250c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				  peer_args->p2p_device_addr, 0);
1251c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (info == NULL) {
1252c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error(error, DBUS_ERROR_FAILED,
1253c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			       "failed to find peer");
1254c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
1255c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
1256c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1257c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
1258c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					      &info->config_methods, error)) {
1259c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
1260c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
1261c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
1262c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1263c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return TRUE;
1264c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
1265c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1266c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1267c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_peer_level(DBusMessageIter *iter,
1268c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt                                            DBusError *error,
1269c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt                                            void *user_data)
1270c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
1271c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct peer_handler_args *peer_args = user_data;
1272c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	const struct p2p_peer_info *info;
1273c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1274c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
1275c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				  peer_args->p2p_device_addr, 0);
1276c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (info == NULL) {
1277c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error(error, DBUS_ERROR_FAILED,
1278c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			       "failed to find peer");
1279c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
1280c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
1281c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1282c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
1283c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					      &info->level, error)) {
1284c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
1285c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
1286c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
1287c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1288c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return TRUE;
1289c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
1290c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1291c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1292c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_peer_device_capability(DBusMessageIter *iter,
1293c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt                                                        DBusError *error,
1294c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt                                                        void *user_data)
1295c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
1296c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct peer_handler_args *peer_args = user_data;
1297c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	const struct p2p_peer_info *info;
1298c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1299c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
1300c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				  peer_args->p2p_device_addr, 0);
1301c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (info == NULL) {
1302c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error(error, DBUS_ERROR_FAILED,
1303c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			       "failed to find peer");
1304c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
1305c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
1306c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1307c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BYTE,
1308c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					      &info->dev_capab, error)) {
1309c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
1310c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
1311c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
1312c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1313c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return TRUE;
1314c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
1315c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1316c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1317c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_peer_group_capability(DBusMessageIter *iter,
1318c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt						       DBusError *error,
1319c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt						       void *user_data)
1320c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
1321c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct peer_handler_args *peer_args = user_data;
1322c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	const struct p2p_peer_info *info;
1323c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1324c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
1325c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				  peer_args->p2p_device_addr, 0);
1326c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (info == NULL) {
1327c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error(error, DBUS_ERROR_FAILED,
1328c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			       "failed to find peer");
1329c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
1330c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
1331c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1332c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BYTE,
1333c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					      &info->group_capab, error)) {
1334c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
1335c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
1336c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
1337c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1338c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return TRUE;
1339c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
1340c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1341c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1342c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_peer_secondary_device_types(
1343c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	DBusMessageIter *iter, DBusError *error, void *user_data)
1344c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
1345c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct peer_handler_args *peer_args = user_data;
1346c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	const struct p2p_peer_info *info;
134704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	DBusMessageIter variant_iter, array_iter;
1348c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1349c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
1350c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				  peer_args->p2p_device_addr, 0);
1351c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (info == NULL) {
1352c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error(error, DBUS_ERROR_FAILED,
1353c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			       "failed to find peer");
1354c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
1355c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
135675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
135704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
135804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      DBUS_TYPE_ARRAY_AS_STRING
135904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      DBUS_TYPE_ARRAY_AS_STRING
136004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      DBUS_TYPE_BYTE_AS_STRING,
136104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      &variant_iter)) {
136204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		dbus_set_error(error, DBUS_ERROR_FAILED,
136304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		               "%s: failed to construct message 1", __func__);
136404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return FALSE;
136504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
136604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
136704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
136804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      DBUS_TYPE_ARRAY_AS_STRING
136904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      DBUS_TYPE_BYTE_AS_STRING,
137004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      &array_iter)) {
137104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		dbus_set_error(error, DBUS_ERROR_FAILED,
137204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		               "%s: failed to construct message 2", __func__);
137304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return FALSE;
137404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
137504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
137675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (info->wps_sec_dev_type_list_len) {
13771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		const u8 *sec_dev_type_list = info->wps_sec_dev_type_list;
137804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		int num_sec_device_types =
137904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			info->wps_sec_dev_type_list_len / WPS_DEV_TYPE_LEN;
138004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		int i;
138104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		DBusMessageIter inner_array_iter;
138204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
138304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		for (i = 0; i < num_sec_device_types; i++) {
138404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (!dbus_message_iter_open_container(
138504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				    &array_iter, DBUS_TYPE_ARRAY,
138604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				    DBUS_TYPE_BYTE_AS_STRING,
138704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				    &inner_array_iter)) {
138804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				dbus_set_error(error, DBUS_ERROR_FAILED,
138904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       "%s: failed to construct "
139004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       "message 3 (%d)",
139104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       __func__, i);
139204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return FALSE;
139304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			}
139475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
139504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (!dbus_message_iter_append_fixed_array(
139604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				    &inner_array_iter, DBUS_TYPE_BYTE,
139704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				    &sec_dev_type_list, WPS_DEV_TYPE_LEN)) {
139804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				dbus_set_error(error, DBUS_ERROR_FAILED,
139904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       "%s: failed to construct "
140004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       "message 4 (%d)",
140104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       __func__, i);
140204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return FALSE;
140304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			}
140404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
140504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (!dbus_message_iter_close_container(
140604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				    &array_iter, &inner_array_iter)) {
140704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				dbus_set_error(error, DBUS_ERROR_FAILED,
140804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       "%s: failed to construct "
140904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       "message 5 (%d)",
141004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       __func__, i);
141104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				return FALSE;
141204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			}
141304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
141404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			sec_dev_type_list += WPS_DEV_TYPE_LEN;
141504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
1416c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
1417c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
141804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
141904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		dbus_set_error(error, DBUS_ERROR_FAILED,
142004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		               "%s: failed to construct message 6", __func__);
142104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return FALSE;
142204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
1423c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
142404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!dbus_message_iter_close_container(iter, &variant_iter)) {
142504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		dbus_set_error(error, DBUS_ERROR_FAILED,
142604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		               "%s: failed to construct message 7", __func__);
142704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return FALSE;
142804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
1429c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
143004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return TRUE;
1431c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
1432c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1433c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1434c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_peer_vendor_extension(DBusMessageIter *iter,
1435c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt						       DBusError *error,
1436c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt						       void *user_data)
1437c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
143804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpabuf *vendor_extension[P2P_MAX_WPS_VENDOR_EXT];
1439c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	int i, num;
1440c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct peer_handler_args *peer_args = user_data;
1441c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	const struct p2p_peer_info *info;
1442c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1443c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
1444c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				  peer_args->p2p_device_addr, 0);
1445c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (info == NULL) {
1446c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		dbus_set_error(error, DBUS_ERROR_FAILED,
1447c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			       "failed to find peer");
1448c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
144975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
145075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
14511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/* Add WPS vendor extensions attribute */
14521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	for (i = 0, num = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) {
14531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (info->wps_vendor_ext[i] == NULL)
14541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			continue;
14551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		vendor_extension[num] = info->wps_vendor_ext[i];
14561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		num++;
145775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
145875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
145904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpas_dbus_simple_array_array_property_getter(iter, DBUS_TYPE_BYTE,
146004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt							  vendor_extension,
146104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt							  num, error))
1462c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return FALSE;
146375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
14641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return TRUE;
146575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
146675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
14671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
14681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_peer_ies(DBusMessageIter *iter,
14691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					  DBusError *error, void *user_data)
147075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
147104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	dbus_bool_t success;
14721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/* struct peer_handler_args *peer_args = user_data; */
14731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
147404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	success = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
147504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt							 NULL, 0, error);
147604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return success;
147775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
147875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
147975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
148075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/**
14811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * wpas_dbus_getter_persistent_groups - Get array of persistent group objects
14821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @iter: Pointer to incoming dbus message iter
14831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @error: Location to store error on failure
14841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @user_data: Function specific data
14851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Returns: TRUE on success, FALSE on failure
148675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *
14871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Getter for "PersistentGroups" property.
148875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */
14891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtdbus_bool_t wpas_dbus_getter_persistent_groups(DBusMessageIter *iter,
14901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					       DBusError *error,
14911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					       void *user_data)
149275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
14931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
149475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_ssid *ssid;
149575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char **paths;
149675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	unsigned int i = 0, num = 0;
14971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dbus_bool_t success = FALSE;
149875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
149975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpa_s->conf == NULL) {
150075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_printf(MSG_ERROR, "dbus: %s: "
150175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   "An error occurred getting persistent groups list",
150275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   __func__);
15031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		dbus_set_error_const(error, DBUS_ERROR_FAILED, "an error "
15041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				     "occurred getting persistent groups list");
15051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return FALSE;
150675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
150775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
150875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
150975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (network_is_persistent_group(ssid))
151075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			num++;
151175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
151261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	paths = os_calloc(num, sizeof(char *));
151375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!paths) {
15141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
15151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return FALSE;
151675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
151775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
151875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Loop through configured networks and append object path of each */
151975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
152075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!network_is_persistent_group(ssid))
152175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			continue;
152275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
152375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (paths[i] == NULL) {
15241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY,
15251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					     "no memory");
152675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto out;
152775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
152875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		/* Construct the object path for this network. */
152975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		os_snprintf(paths[i++], WPAS_DBUS_OBJECT_PATH_MAX,
153075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%d",
153175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    wpa_s->dbus_new_path, ssid->id);
153275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
153375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
15341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	success = wpas_dbus_simple_array_property_getter(iter,
15351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							 DBUS_TYPE_OBJECT_PATH,
15361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							 paths, num, error);
153775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
153875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenout:
153975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	while (i)
154075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		os_free(paths[--i]);
154175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_free(paths);
15421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return success;
154375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
154475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
154575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
154675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/**
154775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * wpas_dbus_getter_persistent_group_properties - Get options for a persistent
154875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *	group
15491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @iter: Pointer to incoming dbus message iter
15501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @error: Location to store error on failure
15511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @user_data: Function specific data
15521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Returns: TRUE on success, FALSE on failure
155375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *
155475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Getter for "Properties" property of a persistent group.
155575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */
15561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtdbus_bool_t wpas_dbus_getter_persistent_group_properties(DBusMessageIter *iter,
15571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							 DBusError *error,
15581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							 void *user_data)
155975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
15601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct network_handler_args *net = user_data;
15611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
15621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/* Leveraging the fact that persistent group object is still
156375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * represented in same manner as network within.
156475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 */
15651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return wpas_dbus_getter_network_properties(iter, error, net);
156675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
156775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
156875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
156975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/**
157075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * wpas_dbus_setter_persistent_group_properties - Get options for a persistent
157175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *	group
15721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @iter: Pointer to incoming dbus message iter
15731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @error: Location to store error on failure
15741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @user_data: Function specific data
15751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Returns: TRUE on success, FALSE on failure
157675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *
157775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Setter for "Properties" property of a persistent group.
157875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */
15791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtdbus_bool_t wpas_dbus_setter_persistent_group_properties(DBusMessageIter *iter,
15801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							 DBusError *error,
15811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							 void *user_data)
158275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
15831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct network_handler_args *net = user_data;
158475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_ssid *ssid = net->ssid;
15851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	DBusMessageIter	variant_iter;
158675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
158775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/*
158875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * Leveraging the fact that persistent group object is still
158975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * represented in same manner as network within.
159075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 */
15911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dbus_message_iter_recurse(iter, &variant_iter);
15921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return set_network_properties(net->wpa_s, ssid, &variant_iter, error);
159375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
159475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
159575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
159675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/**
159775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * wpas_dbus_new_iface_add_persistent_group - Add a new configured
159875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *	persistent_group
159975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @message: Pointer to incoming dbus message
160075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @wpa_s: wpa_supplicant structure for a network interface
160175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Returns: A dbus message containing the object path of the new
160275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * persistent group
160375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *
160475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Handler function for "AddPersistentGroup" method call of a P2P Device
160575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * interface.
160675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */
160775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni MalinenDBusMessage * wpas_dbus_handler_add_persistent_group(
160875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *message, struct wpa_supplicant *wpa_s)
160975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
161075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *reply = NULL;
161175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter	iter;
161275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_ssid *ssid = NULL;
161375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
16141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	DBusError error;
161575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
161675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
161775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
161875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	ssid = wpa_config_add_network(wpa_s->conf);
161975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (ssid == NULL) {
162075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_printf(MSG_ERROR, "dbus: %s: "
162175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   "Cannot add new persistent group", __func__);
162275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		reply = wpas_dbus_error_unknown_error(
162375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			message,
162475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			"wpa_supplicant could not add "
162575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			"a persistent group on this interface.");
162675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err;
162775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
162875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
162975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Mark the ssid as being a persistent group before the notification */
163075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	ssid->disabled = 2;
163175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	ssid->p2p_persistent_group = 1;
163275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpas_notify_persistent_group_added(wpa_s, ssid);
163375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
163475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_config_set_network_defaults(ssid);
163575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
16361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dbus_error_init(&error);
16371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!set_network_properties(wpa_s, ssid, &iter, &error)) {
163875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_printf(MSG_DEBUG, "dbus: %s: "
163975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   "Control interface could not set persistent group "
164075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   "properties", __func__);
16411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		reply = wpas_dbus_reply_new_from_error(message, &error,
16421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						       DBUS_ERROR_INVALID_ARGS,
16431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						       "Failed to set network "
16441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						       "properties");
16451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		dbus_error_free(&error);
164675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err;
164775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
164875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
164975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Construct the object path for this network. */
165075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
165175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%d",
165275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    wpa_s->dbus_new_path, ssid->id);
165375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
165475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	reply = dbus_message_new_method_return(message);
165575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (reply == NULL) {
165675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
165775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					       NULL);
165875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err;
165975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
166075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path,
166175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				      DBUS_TYPE_INVALID)) {
166275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		dbus_message_unref(reply);
166375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY,
166475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					       NULL);
166575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto err;
166675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
166775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
166875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return reply;
166975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
167075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerr:
167175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (ssid) {
167275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpas_notify_persistent_group_removed(wpa_s, ssid);
167375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_config_remove_network(wpa_s->conf, ssid->id);
167475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
167575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return reply;
167675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
167775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
167875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
167975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/**
168075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * wpas_dbus_handler_remove_persistent_group - Remove a configured persistent
168175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *	group
168275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @message: Pointer to incoming dbus message
168375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @wpa_s: wpa_supplicant structure for a network interface
168475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Returns: NULL on success or dbus error on failure
168575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *
168675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Handler function for "RemovePersistentGroup" method call of a P2P Device
168775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * interface.
168875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */
168975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni MalinenDBusMessage * wpas_dbus_handler_remove_persistent_group(
169075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *message, struct wpa_supplicant *wpa_s)
169175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
169275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *reply = NULL;
169375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	const char *op;
169475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *iface = NULL, *persistent_group_id = NULL;
169575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int id;
169675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_ssid *ssid;
169775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
169875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op,
169975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			      DBUS_TYPE_INVALID);
170075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
170175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/*
170275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * Extract the network ID and ensure the network is actually a child of
170375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * this interface.
170475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 */
170575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	iface = wpas_dbus_new_decompose_object_path(op, 1,
170675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen						    &persistent_group_id,
170775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen						    NULL);
170875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (iface == NULL || os_strcmp(iface, wpa_s->dbus_new_path) != 0) {
170975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		reply = wpas_dbus_error_invalid_args(message, op);
171075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto out;
171175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
171275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
171375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	id = strtoul(persistent_group_id, NULL, 10);
171475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (errno == EINVAL) {
171575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		reply = wpas_dbus_error_invalid_args(message, op);
171675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto out;
171775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
171875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
171975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	ssid = wpa_config_get_network(wpa_s->conf, id);
172075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (ssid == NULL) {
172175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		reply = wpas_dbus_error_persistent_group_unknown(message);
172275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto out;
172375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
172475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
172575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpas_notify_persistent_group_removed(wpa_s, ssid);
172675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
172775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
172875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_printf(MSG_ERROR, "dbus: %s: "
172975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   "error occurred when removing persistent group %d",
173075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   __func__, id);
173175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		reply = wpas_dbus_error_unknown_error(
173275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			message,
173375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			"error removing the specified persistent group on "
173475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			"this interface.");
173575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto out;
173675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
173775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
173875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenout:
173975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_free(iface);
174075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_free(persistent_group_id);
174175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return reply;
174275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
174375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
174475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
174575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic void remove_persistent_group(struct wpa_supplicant *wpa_s,
174675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				    struct wpa_ssid *ssid)
174775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
174875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpas_notify_persistent_group_removed(wpa_s, ssid);
174975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
175075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpa_config_remove_network(wpa_s->conf, ssid->id) < 0) {
175175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_printf(MSG_ERROR, "dbus: %s: "
175275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   "error occurred when removing persistent group %d",
175375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   __func__, ssid->id);
175475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		return;
175575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
175675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
175775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
175875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
175975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/**
176075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * wpas_dbus_handler_remove_all_persistent_groups - Remove all configured
176175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * persistent groups
176275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @message: Pointer to incoming dbus message
176375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * @wpa_s: wpa_supplicant structure for a network interface
176475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Returns: NULL on success or dbus error on failure
176575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen *
176675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Handler function for "RemoveAllPersistentGroups" method call of a
176775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * P2P Device interface.
176875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */
176975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni MalinenDBusMessage * wpas_dbus_handler_remove_all_persistent_groups(
177075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *message, struct wpa_supplicant *wpa_s)
177175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
177275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_ssid *ssid, *next;
177375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_config *config;
177475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
177575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	config = wpa_s->conf;
177675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	ssid = config->ssid;
177775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	while (ssid) {
177875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		next = ssid->next;
177975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (network_is_persistent_group(ssid))
178075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			remove_persistent_group(wpa_s, ssid);
178175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		ssid = next;
178275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
178375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return NULL;
178475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
178575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
178675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
178775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/*
178875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Group object properties accessor methods
178975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */
179075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
17911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_group_members(DBusMessageIter *iter,
17921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					       DBusError *error,
17931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					       void *user_data)
179475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
17951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
179675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_ssid *ssid;
179775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	unsigned int num_members;
179875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char **paths;
179975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	unsigned int i;
180075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	void *next = NULL;
180175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	const u8 *addr;
18021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dbus_bool_t success = FALSE;
180375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
180404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/* Verify correct role for this property */
180504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpas_get_p2p_role(wpa_s) != WPAS_P2P_ROLE_GO) {
180604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return wpas_dbus_simple_array_property_getter(
180704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			iter, DBUS_TYPE_OBJECT_PATH, NULL, 0, error);
180804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
180975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
181075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	ssid = wpa_s->conf->ssid;
181175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* At present WPAS P2P_GO mode only applicable for p2p_go */
181275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (ssid->mode != WPAS_MODE_P2P_GO &&
181375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    ssid->mode != WPAS_MODE_AP &&
181475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION)
18151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return FALSE;
181675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
181775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	num_members = p2p_get_group_num_members(wpa_s->p2p_group);
181875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
181961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	paths = os_calloc(num_members, sizeof(char *));
182075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!paths)
182175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto out_of_memory;
182275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
182375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	i = 0;
182475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	while ((addr = p2p_iterate_group_members(wpa_s->p2p_group, &next))) {
182575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		paths[i] = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
182675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!paths[i])
182775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto out_of_memory;
182875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		os_snprintf(paths[i], WPAS_DBUS_OBJECT_PATH_MAX,
182975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    "%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART
183075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    "/" COMPACT_MACSTR,
183175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    wpa_s->dbus_groupobj_path, MAC2STR(addr));
183275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		i++;
183375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
183475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
18351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	success = wpas_dbus_simple_array_property_getter(iter,
18361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							 DBUS_TYPE_OBJECT_PATH,
18371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							 paths, num_members,
18381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt							 error);
183975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
184075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	for (i = 0; i < num_members; i++)
184175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		os_free(paths[i]);
184275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_free(paths);
18431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return success;
18441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
184575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenout_of_memory:
18461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
18471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (paths) {
18481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		for (i = 0; i < num_members; i++)
18491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			os_free(paths[i]);
18501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		os_free(paths);
18511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
18521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return FALSE;
185375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
185475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
185575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
185604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_group_ssid(DBusMessageIter *iter,
185704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					    DBusError *error, void *user_data)
185804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
185904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
186004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->current_ssid == NULL)
186104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return FALSE;
186204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return wpas_dbus_simple_array_property_getter(
186304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		iter, DBUS_TYPE_BYTE, wpa_s->current_ssid->ssid,
186404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->current_ssid->ssid_len, error);
186504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
186604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
186704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
186804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_group_bssid(DBusMessageIter *iter,
186904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					     DBusError *error,
187004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					     void *user_data)
187175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
18721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
1873c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	u8 role = wpas_get_p2p_role(wpa_s);
187404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u8 *p_bssid;
187575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
187604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (role == WPAS_P2P_ROLE_CLIENT) {
187704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_s->current_ssid == NULL)
187804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return FALSE;
187904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		p_bssid = wpa_s->current_ssid->bssid;
188004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else {
188104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_s->ap_iface == NULL)
188204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return FALSE;
188304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		p_bssid = wpa_s->ap_iface->bss[0]->own_addr;
188404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
1885c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
188604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
188704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						      p_bssid, ETH_ALEN,
188804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						      error);
188904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
189004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
189104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
189204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_group_frequency(DBusMessageIter *iter,
189304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						 DBusError *error,
189404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						 void *user_data)
189504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
189604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
189704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u16 op_freq;
189804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u8 role = wpas_get_p2p_role(wpa_s);
189904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
190004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (role == WPAS_P2P_ROLE_CLIENT) {
190104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_s->go_params == NULL)
1902c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			return FALSE;
190304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		op_freq = wpa_s->go_params->freq;
190404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else {
190504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_s->ap_iface == NULL)
1906c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			return FALSE;
190704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		op_freq = wpa_s->ap_iface->freq;
190875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
190975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
191004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
191104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						&op_freq, error);
191204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
191304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
191404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
191504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_group_passphrase(DBusMessageIter *iter,
191604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						  DBusError *error,
191704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						  void *user_data)
191804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
191904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
192004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u8 role = wpas_get_p2p_role(wpa_s);
192104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	char *p_pass = NULL;
192275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
192304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/* Verify correct role for this property */
1924c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (role == WPAS_P2P_ROLE_GO) {
192504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_s->current_ssid == NULL)
192604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return FALSE;
192704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		p_pass = wpa_s->current_ssid->passphrase;
192804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else
192904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		p_pass = "";
193004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
193104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
193204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						&p_pass, error);
193304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
193404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
193504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
193604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
193704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_group_psk(DBusMessageIter *iter,
193804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   DBusError *error, void *user_data)
193904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
194004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
194104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u8 role = wpas_get_p2p_role(wpa_s);
194204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u8 *p_psk = NULL;
194304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u8 psk_len = 0;
194404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
194504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/* Verify correct role for this property */
194604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (role == WPAS_P2P_ROLE_CLIENT) {
194704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_s->current_ssid == NULL)
194804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return FALSE;
194904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		p_psk = wpa_s->current_ssid->psk;
195004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		psk_len = 32;
195104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
195204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
195304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
195404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						      &p_psk, psk_len, error);
195504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
195604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
195704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
195804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtdbus_bool_t wpas_dbus_getter_p2p_group_vendor_ext(DBusMessageIter *iter,
195904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						  DBusError *error,
196004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						  void *user_data)
196104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
196204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
196304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct hostapd_data *hapd;
196404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
196504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int num_vendor_ext = 0;
196604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int i;
196704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
196804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/* Verify correct role for this property */
196904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpas_get_p2p_role(wpa_s) == WPAS_P2P_ROLE_GO) {
197004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpa_s->ap_iface == NULL)
197104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return FALSE;
197204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		hapd = wpa_s->ap_iface->bss[0];
197304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
1974c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		/* Parse WPS Vendor Extensions sent in Beacon/Probe Response */
197504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
1976c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			if (hapd->conf->wps_vendor_ext[i] == NULL)
197704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				vendor_ext[i] = NULL;
197804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			else {
197904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				vendor_ext[num_vendor_ext++] =
198004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					hapd->conf->wps_vendor_ext[i];
198104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			}
1982c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		}
198375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
198475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
198504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	/* Return vendor extensions or no data */
198604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return wpas_dbus_simple_array_array_property_getter(iter,
198704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt							    DBUS_TYPE_BYTE,
198804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt							    vendor_ext,
198904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt							    num_vendor_ext,
199004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						 error);
199175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
199275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
19931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
199404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtdbus_bool_t wpas_dbus_setter_p2p_group_vendor_ext(DBusMessageIter *iter,
19951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						  DBusError *error,
19961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						  void *user_data)
199775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
19981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_supplicant *wpa_s = user_data;
19991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	DBusMessageIter variant_iter, iter_dict;
20001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
200175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	unsigned int i;
2002c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct hostapd_data *hapd = NULL;
200375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
2004c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (wpas_get_p2p_role(wpa_s) == WPAS_P2P_ROLE_GO &&
2005c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	    wpa_s->ap_iface != NULL)
2006c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		hapd = wpa_s->ap_iface->bss[0];
2007c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	else
20081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return FALSE;
200975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
20101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dbus_message_iter_recurse(iter, &variant_iter);
20111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error))
20121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return FALSE;
201375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
201475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
201575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
20161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
20171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					     "invalid message format");
20181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return FALSE;
201975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
202075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
202175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (os_strcmp(entry.key, "WPSVendorExtensions") == 0) {
202275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if (entry.type != DBUS_TYPE_ARRAY ||
202375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    entry.array_type != WPAS_DBUS_TYPE_BINARRAY ||
202475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    entry.array_len > MAX_WPS_VENDOR_EXTENSIONS)
202575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto error;
202675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
202775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
202875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				if (i < entry.array_len) {
202975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					hapd->conf->wps_vendor_ext[i] =
203075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen						entry.binarray_value[i];
203175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					entry.binarray_value[i] = NULL;
203275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				} else
203375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					hapd->conf->wps_vendor_ext[i] = NULL;
203475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			}
203575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
203675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			hostapd_update_wps(hapd);
203775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else
203875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
203975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
204075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_dbus_dict_entry_clear(&entry);
204175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
204275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
20431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return TRUE;
204475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
204575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror:
204675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_dbus_dict_entry_clear(&entry);
20471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS,
20481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			     "invalid message format");
20491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return FALSE;
205075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
205175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
20521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
20531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_add_service(DBusMessage *message,
20541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						struct wpa_supplicant *wpa_s)
205575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
205675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter_dict;
205775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *reply = NULL;
205875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter;
205975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_dbus_dict_entry entry;
206075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int upnp = 0;
206175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int bonjour = 0;
206275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *service = NULL;
206375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpabuf *query = NULL;
206475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpabuf *resp = NULL;
206575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	u8 version = 0;
206675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
206775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
206875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
20691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
207075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto error;
207175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
207204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
207375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
207475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
207575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
20761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!os_strcmp(entry.key, "service_type") &&
207775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    (entry.type == DBUS_TYPE_STRING)) {
20781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (!os_strcmp(entry.str_value, "upnp"))
207975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				upnp = 1;
20801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			else if (!os_strcmp(entry.str_value, "bonjour"))
208175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				bonjour = 1;
208275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			else
208375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto error_clear;
208404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (!os_strcmp(entry.key, "version") &&
208504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		           entry.type == DBUS_TYPE_INT32) {
208604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			version = entry.uint32_value;
208704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (!os_strcmp(entry.key, "service") &&
208804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			     (entry.type == DBUS_TYPE_STRING)) {
208904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			service = os_strdup(entry.str_value);
209004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (!os_strcmp(entry.key, "query")) {
209104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if ((entry.type != DBUS_TYPE_ARRAY) ||
209204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    (entry.array_type != DBUS_TYPE_BYTE))
209304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				goto error_clear;
209404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			query = wpabuf_alloc_copy(
209504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				entry.bytearray_value,
209604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				entry.array_len);
209704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		} else if (!os_strcmp(entry.key, "response")) {
209804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if ((entry.type != DBUS_TYPE_ARRAY) ||
209904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    (entry.array_type != DBUS_TYPE_BYTE))
210004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				goto error_clear;
210104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			resp = wpabuf_alloc_copy(entry.bytearray_value,
210204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						 entry.array_len);
210375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
210404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_dbus_dict_entry_clear(&entry);
210575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
210675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
210775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (upnp == 1) {
210875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (version <= 0 || service == NULL)
210975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
211075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
211175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (wpas_p2p_service_add_upnp(wpa_s, version, service) != 0)
211275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
211375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
211475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		os_free(service);
211504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		service = NULL;
211675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	} else if (bonjour == 1) {
211775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (query == NULL || resp == NULL)
211875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
211975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
212004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (wpas_p2p_service_add_bonjour(wpa_s, query, resp) < 0)
212175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
212204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		query = NULL;
212304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		resp = NULL;
212475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	} else
212575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto error;
212675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
212775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return reply;
212875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror_clear:
212975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_dbus_dict_entry_clear(&entry);
213075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror:
213104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_free(service);
213204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpabuf_free(query);
213304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpabuf_free(resp);
213475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return wpas_dbus_error_invalid_args(message, NULL);
213575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
213675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
21371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_delete_service(
21391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	DBusMessage *message, struct wpa_supplicant *wpa_s)
214075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
214175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter_dict;
214275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *reply = NULL;
214375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter;
214475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_dbus_dict_entry entry;
214575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int upnp = 0;
214675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int bonjour = 0;
214775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int ret = 0;
214875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *service = NULL;
214975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpabuf *query = NULL;
215075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	u8 version = 0;
215175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
215275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
215375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
21541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
215575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto error;
215675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
215775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
215875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
215975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
216075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
21611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!os_strcmp(entry.key, "service_type") &&
216275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    (entry.type == DBUS_TYPE_STRING)) {
21631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (!os_strcmp(entry.str_value, "upnp"))
216475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				upnp = 1;
21651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			else if (!os_strcmp(entry.str_value, "bonjour"))
216675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				bonjour = 1;
216775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			else
216875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto error_clear;
216975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_dbus_dict_entry_clear(&entry);
217075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
217175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
217275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (upnp == 1) {
217375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
217475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
217575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto error;
21761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (!os_strcmp(entry.key, "version") &&
217775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    entry.type == DBUS_TYPE_INT32)
217875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				version = entry.uint32_value;
21791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			else if (!os_strcmp(entry.key, "service") &&
218075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				 entry.type == DBUS_TYPE_STRING)
218175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				service = os_strdup(entry.str_value);
218275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			else
218375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto error_clear;
218475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
218575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_dbus_dict_entry_clear(&entry);
218675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
218775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
218875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (version <= 0 || service == NULL)
218975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
219075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
219175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		ret = wpas_p2p_service_del_upnp(wpa_s, version, service);
219275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		os_free(service);
219375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (ret != 0)
219475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
219575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	} else if (bonjour == 1) {
219675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
219775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
219875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto error;
219975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
22001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (!os_strcmp(entry.key, "query")) {
220175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				if ((entry.type != DBUS_TYPE_ARRAY) ||
220275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				    (entry.array_type != DBUS_TYPE_BYTE))
220375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					goto error_clear;
22041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				query = wpabuf_alloc_copy(
22051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					entry.bytearray_value,
22061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					entry.array_len);
220775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			} else
220875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto error_clear;
220975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
221075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_dbus_dict_entry_clear(&entry);
221175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
221275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
221375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (query == NULL)
221475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
221575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
221675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		ret = wpas_p2p_service_del_bonjour(wpa_s, query);
221775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (ret != 0)
221875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
221975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpabuf_free(query);
222075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	} else
222175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto error;
222275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
222375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return reply;
222475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror_clear:
222575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_dbus_dict_entry_clear(&entry);
222675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror:
222775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return wpas_dbus_error_invalid_args(message, NULL);
222875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
222975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
22301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
22311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_flush_service(DBusMessage *message,
22321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						  struct wpa_supplicant *wpa_s)
223375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
223475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpas_p2p_service_flush(wpa_s);
223575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return NULL;
223675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
223775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
22381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
22391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_service_sd_req(
22401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	DBusMessage *message, struct wpa_supplicant *wpa_s)
224175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
224275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter_dict;
224375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *reply = NULL;
224475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter;
224575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_dbus_dict_entry entry;
224675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int upnp = 0;
224775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *service = NULL;
224875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *peer_object_path = NULL;
224975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpabuf *tlv = NULL;
225075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	u8 version = 0;
225175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	u64 ref = 0;
225204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	u8 addr_buf[ETH_ALEN], *addr;
225375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
225475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
225575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
22561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
225775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto error;
225875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
225975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
226075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
226175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
22621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!os_strcmp(entry.key, "peer_object") &&
226375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    entry.type == DBUS_TYPE_OBJECT_PATH) {
226475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			peer_object_path = os_strdup(entry.str_value);
22651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "service_type") &&
226675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   entry.type == DBUS_TYPE_STRING) {
22671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (!os_strcmp(entry.str_value, "upnp"))
226875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				upnp = 1;
226975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			else
227075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto error_clear;
22711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "version") &&
227275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   entry.type == DBUS_TYPE_INT32) {
227375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			version = entry.uint32_value;
22741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "service") &&
227575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   entry.type == DBUS_TYPE_STRING) {
227675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			service = os_strdup(entry.str_value);
22771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "tlv")) {
227875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if (entry.type != DBUS_TYPE_ARRAY ||
227975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    entry.array_type != DBUS_TYPE_BYTE)
228075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto error_clear;
228175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			tlv = wpabuf_alloc_copy(entry.bytearray_value,
228275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen						entry.array_len);
228375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else
228475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error_clear;
228575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
228675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_dbus_dict_entry_clear(&entry);
228775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
228875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
228904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!peer_object_path) {
229004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		addr = NULL;
229104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	} else {
229204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (parse_peer_object_path(peer_object_path, addr_buf) < 0 ||
229304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		    !p2p_peer_known(wpa_s->global->p2p, addr_buf))
229404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			goto error;
229504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
229604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		addr = addr_buf;
229704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
229875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
229975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (upnp == 1) {
230075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (version <= 0 || service == NULL)
230175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
230275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
23031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ref = wpas_p2p_sd_request_upnp(wpa_s, addr, version, service);
230475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	} else {
230575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (tlv == NULL)
230675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
23071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ref = wpas_p2p_sd_request(wpa_s, addr, tlv);
230875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpabuf_free(tlv);
230975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
231075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
231175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (ref != 0) {
231275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		reply = dbus_message_new_method_return(message);
231375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		dbus_message_append_args(reply, DBUS_TYPE_UINT64,
231475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen					 &ref, DBUS_TYPE_INVALID);
231575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	} else {
23161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		reply = wpas_dbus_error_unknown_error(
23171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			message, "Unable to send SD request");
231875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
231975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenout:
232075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_free(service);
232175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_free(peer_object_path);
232275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return reply;
232375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror_clear:
232475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_dbus_dict_entry_clear(&entry);
232575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror:
232675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (tlv)
232775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpabuf_free(tlv);
232875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	reply = wpas_dbus_error_invalid_args(message, NULL);
232975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	goto out;
233075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
233175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
23321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
23331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_service_sd_res(
233475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *message, struct wpa_supplicant *wpa_s)
233575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
233675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter_dict;
233775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessage *reply = NULL;
233875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter;
233975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpa_dbus_dict_entry entry;
234075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	char *peer_object_path = NULL;
234175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	struct wpabuf *tlv = NULL;
234275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int freq = 0;
234375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int dlg_tok = 0;
234475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	u8 addr[ETH_ALEN];
234575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
234675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
234775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
23481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
234975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto error;
235075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
235175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
235275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
235375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error;
235475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
23551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!os_strcmp(entry.key, "peer_object") &&
235675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    entry.type == DBUS_TYPE_OBJECT_PATH) {
235775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			peer_object_path = os_strdup(entry.str_value);
23581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "frequency") &&
235975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   entry.type == DBUS_TYPE_INT32) {
236075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			freq = entry.uint32_value;
23611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "dialog_token") &&
236275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			   entry.type == DBUS_TYPE_UINT32) {
236375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			dlg_tok = entry.uint32_value;
23641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		} else if (!os_strcmp(entry.key, "tlvs")) {
236575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			if (entry.type != DBUS_TYPE_ARRAY ||
236675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			    entry.array_type != DBUS_TYPE_BYTE)
236775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				goto error_clear;
236875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			tlv = wpabuf_alloc_copy(entry.bytearray_value,
236975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen						entry.array_len);
237075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		} else
237175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			goto error_clear;
237275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
237375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpa_dbus_dict_entry_clear(&entry);
237475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
237575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (!peer_object_path ||
237675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    (parse_peer_object_path(peer_object_path, addr) < 0) ||
23771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    !p2p_peer_known(wpa_s->global->p2p, addr))
237875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto error;
237975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
238075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (tlv == NULL)
238175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto error;
238275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
238375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpas_p2p_sd_response(wpa_s, freq, addr, (u8) dlg_tok, tlv);
238475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpabuf_free(tlv);
238575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenout:
238675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_free(peer_object_path);
238775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return reply;
238875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror_clear:
238975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_dbus_dict_entry_clear(&entry);
239075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror:
239175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	reply = wpas_dbus_error_invalid_args(message, NULL);
239275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	goto out;
239375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
239475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
23951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
23961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_service_sd_cancel_req(
23971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	DBusMessage *message, struct wpa_supplicant *wpa_s)
239875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
239975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter;
240075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	u64 req = 0;
240175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
240275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
240375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_get_basic(&iter, &req);
240475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
240575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (req == 0)
240675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto error;
240775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
24081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (!wpas_p2p_sd_cancel_request(wpa_s, req))
240975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		goto error;
241075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
241175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return NULL;
241275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenerror:
241375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return wpas_dbus_error_invalid_args(message, NULL);
241475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
241575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
24161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
24171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_service_update(
24181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	DBusMessage *message, struct wpa_supplicant *wpa_s)
241975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
242075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpas_p2p_sd_service_update(wpa_s);
242175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return NULL;
242275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
242375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
24241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
24251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry ShmidtDBusMessage * wpas_dbus_handler_p2p_serv_disc_external(
24261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	DBusMessage *message, struct wpa_supplicant *wpa_s)
242775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
242875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	DBusMessageIter iter;
242975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	int ext = 0;
243075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
243175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_init(message, &iter);
243275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	dbus_message_iter_get_basic(&iter, &ext);
243375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
243475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_s->p2p_sd_over_ctrl_iface = ext;
243575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
243675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	return NULL;
243775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
243875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
2439