p2p_pd.c revision 04949598a23f501be6eec21697465fd46a28840a
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Wi-Fi Direct - P2P provision discovery
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009-2010, Atheros Communications
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_defs.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_i.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/*
1975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * Number of retries to attempt for provision discovery requests during IDLE
2075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * state in case the peer is not listening.
2175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */
2275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen#define MAX_PROV_DISC_REQ_RETRIES 10
2375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
2475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_build_wps_ie_config_methods(struct wpabuf *buf,
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    u16 config_methods)
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *len;
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = wpabuf_put(buf, 1);
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_put_be32(buf, WPS_DEV_OUI_WFA);
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Config Methods */
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_put_be16(buf, ATTR_CONFIG_METHODS);
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_put_be16(buf, 2);
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_put_be16(buf, config_methods);
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_update_ie_hdr(buf, len);
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p,
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       u8 dialog_token,
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       u16 config_methods,
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       struct p2p_device *go)
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *buf;
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *len;
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	buf = wpabuf_alloc(1000);
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (buf == NULL)
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token);
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	len = p2p_buf_add_ie_hdr(buf);
5704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	p2p_buf_add_capability(buf, p2p->dev_capab &
5804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			       ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0);
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_device_info(buf, p2p, NULL);
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (go) {
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_buf_add_group_id(buf, go->info.p2p_device_addr,
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     go->oper_ssid, go->oper_ssid_len);
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_update_ie_hdr(buf, len);
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* WPS IE with Config Methods attribute */
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_build_wps_ie_config_methods(buf, config_methods);
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return buf;
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p,
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						u8 dialog_token,
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						u16 config_methods)
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *buf;
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	buf = wpabuf_alloc(100);
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (buf == NULL)
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_RESP, dialog_token);
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* WPS IE with Config Methods attribute */
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_build_wps_ie_config_methods(buf, config_methods);
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return buf;
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			       const u8 *data, size_t len, int rx_freq)
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_message msg;
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_device *dev;
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int freq;
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int reject = 1;
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *resp;
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p_parse(data, len, &msg))
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"P2P: Received Provision Discovery Request from " MACSTR
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		" with config methods 0x%x (freq=%d)",
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		MAC2STR(sa), msg.wps_config_methods, rx_freq);
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dev = p2p_get_device(p2p, sa);
1101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"P2P: Provision Discovery Request from "
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"unknown peer " MACSTR, MAC2STR(sa));
11404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (p2p_add_device(p2p, sa, rx_freq, 0, data + 1, len - 1, 0))
11504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		{
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			        "P2P: Provision Discovery Request add device "
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"failed " MACSTR, MAC2STR(sa));
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(msg.wps_config_methods &
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	      (WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD |
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	       WPS_CONFIG_PUSHBUTTON))) {
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unsupported "
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"Config Methods in Provision Discovery Request");
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (msg.group_id) {
13104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		size_t i;
13204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		for (i = 0; i < p2p->num_groups; i++) {
13304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			if (p2p_group_is_group_id_match(p2p->groups[i],
13404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt							msg.group_id,
13504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt							msg.group_id_len))
13604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				break;
13704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
13804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (i == p2p->num_groups) {
13904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: PD "
14004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				"request for unknown P2P Group ID - reject");
14104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			goto out;
14204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
14304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
14404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev)
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				P2P_DEV_PD_PEER_KEYPAD);
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (msg.wps_config_methods & WPS_CONFIG_DISPLAY) {
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			" requested us to show a PIN on display", MAC2STR(sa));
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (dev)
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			" requested us to write its PIN using keypad",
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MAC2STR(sa));
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (dev)
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reject = 0;
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout:
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	resp = p2p_build_prov_disc_resp(p2p, msg.dialog_token,
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					reject ? 0 : msg.wps_config_methods);
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (resp == NULL) {
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_parse_free(&msg);
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"P2P: Sending Provision Discovery Response");
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (rx_freq > 0)
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		freq = rx_freq;
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		freq = p2p_channel_to_freq(p2p->cfg->country,
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   p2p->cfg->reg_class,
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   p2p->cfg->channel);
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freq < 0) {
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"P2P: Unknown regulatory class/channel");
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(resp);
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_parse_free(&msg);
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p->pending_action_state = P2P_NO_PENDING_ACTION;
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    p2p->cfg->dev_addr,
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"P2P: Failed to send Action frame");
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(resp);
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!reject && p2p->cfg->prov_disc_req) {
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const u8 *dev_addr = sa;
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (msg.p2p_device_addr)
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			dev_addr = msg.p2p_device_addr;
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->cfg->prov_disc_req(p2p->cfg->cb_ctx, sa,
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					msg.wps_config_methods,
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					dev_addr, msg.pri_dev_type,
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					msg.device_name, msg.config_methods,
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					msg.capability ? msg.capability[0] : 0,
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					msg.capability ? msg.capability[1] :
2051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					0,
2061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					msg.group_id, msg.group_id_len);
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_parse_free(&msg);
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				const u8 *data, size_t len)
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_message msg;
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_device *dev;
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 report_config_methods = 0;
21804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int success = 0;
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p_parse(data, len, &msg))
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		"P2P: Received Provision Discovery Response from " MACSTR
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		" with config methods 0x%x",
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		MAC2STR(sa), msg.wps_config_methods);
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dev = p2p_get_device(p2p, sa);
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev == NULL || !dev->req_config_methods) {
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			"P2P: Ignore Provision Discovery Response from "
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MACSTR " with no pending request", MAC2STR(sa));
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_parse_free(&msg);
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (p2p->pending_action_state == P2P_PENDING_PD) {
23875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
23975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		p2p->pending_action_state = P2P_NO_PENDING_ACTION;
24075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	}
24175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev->dialog_token != msg.dialog_token) {
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
2441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			"P2P: Ignore Provision Discovery Response with "
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"unexpected Dialog Token %u (expected %u)",
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			msg.dialog_token, dev->dialog_token);
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_parse_free(&msg);
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
25175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/*
25275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * If the response is from the peer to whom a user initiated request
25375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * was sent earlier, we reset that state info here.
25475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 */
25575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (p2p->user_initiated_pd &&
25675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	    os_memcmp(p2p->pending_pd_devaddr, sa, ETH_ALEN) == 0)
25775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		p2p_reset_pending_pd(p2p);
25875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (msg.wps_config_methods != dev->req_config_methods) {
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer rejected "
2611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			"our Provision Discovery Request");
26275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (p2p->cfg->prov_disc_fail)
26375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
26475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen						 P2P_PROV_DISC_REJECTED);
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p_parse_free(&msg);
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	report_config_methods = dev->req_config_methods;
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			P2P_DEV_PD_PEER_KEYPAD);
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev->req_config_methods & WPS_CONFIG_DISPLAY) {
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			" accepted to show a PIN on display", MAC2STR(sa));
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			" accepted to write our PIN using keypad",
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MAC2STR(sa));
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/* Store the provisioning info */
2841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dev->wps_prov_info = msg.wps_config_methods;
2851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p_parse_free(&msg);
28704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	success = 1;
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout:
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dev->req_config_methods = 0;
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
29204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) {
29304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
29404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			"P2P: Start GO Neg after the PD-before-GO-Neg "
29504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			"workaround with " MACSTR,
29604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			MAC2STR(dev->info.p2p_device_addr));
29704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
29804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		p2p_connect_send(p2p, dev);
29904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
30004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
30104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (success && p2p->cfg->prov_disc_resp)
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa,
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 report_config_methods);
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
3081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   int join, int force_freq)
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf *req;
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int freq;
312497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt
3131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (force_freq > 0)
3141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		freq = force_freq;
3151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	else
3161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		freq = dev->listen_freq > 0 ? dev->listen_freq :
3171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			dev->oper_freq;
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freq <= 0) {
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"P2P: No Listen/Operating frequency known for the "
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"peer " MACSTR " to send Provision Discovery Request",
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MAC2STR(dev->info.p2p_device_addr));
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(dev->info.dev_capab &
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		      P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"P2P: Cannot use PD with P2P Device " MACSTR
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				" that is in a group and is not discoverable",
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				MAC2STR(dev->info.p2p_device_addr));
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* TODO: use device discoverability request through GO */
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dev->dialog_token++;
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev->dialog_token == 0)
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->dialog_token = 1;
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	req = p2p_build_prov_disc_req(p2p, dev->dialog_token,
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      dev->req_config_methods,
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      join ? dev : NULL);
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (req == NULL)
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (p2p->state != P2P_IDLE)
34804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		p2p_stop_listen_for_freq(p2p, freq);
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	p2p->pending_action_state = P2P_PENDING_PD;
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    p2p->cfg->dev_addr, dev->info.p2p_device_addr,
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    wpabuf_head(req), wpabuf_len(req), 200) < 0) {
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"P2P: Failed to send Action frame");
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(req);
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN);
36075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(req);
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_prov_disc_req(struct p2p_data *p2p, const u8 *peer_addr,
3671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		      u16 config_methods, int join, int force_freq)
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct p2p_device *dev;
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dev = p2p_get_device(p2p, peer_addr);
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev == NULL)
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev = p2p_get_device_interface(p2p, peer_addr);
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Provision "
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"Discovery Request destination " MACSTR
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			" not yet known", MAC2STR(peer_addr));
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Provision Discovery "
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"Request with " MACSTR " (config methods 0x%x)",
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		MAC2STR(peer_addr), config_methods);
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (config_methods == 0)
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/* Reset provisioning info */
3881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dev->wps_prov_info = 0;
3891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dev->req_config_methods = config_methods;
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (join)
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->flags |= P2P_DEV_PD_FOR_JOIN;
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		dev->flags &= ~P2P_DEV_PD_FOR_JOIN;
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
396c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH &&
397c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	    p2p->state != P2P_LISTEN_ONLY) {
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Busy with other "
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"operations; postpone Provision Discovery Request "
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"with " MACSTR " (config methods 0x%x)",
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MAC2STR(peer_addr), config_methods);
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/*
40675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * We use the join param as a cue to differentiate between user
40775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 * initiated PD request and one issued during finds (internal).
40875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	 */
40975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	p2p->user_initiated_pd = !join;
41075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
41175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	/* Also set some retries to attempt in case of IDLE state */
41275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (p2p->user_initiated_pd && p2p->state == P2P_IDLE)
41375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES;
41475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
4151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return p2p_send_prov_disc_req(p2p, dev, join, force_freq);
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
41775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
41875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen
41975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenvoid p2p_reset_pending_pd(struct p2p_data *p2p)
42075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{
4211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct p2p_device *dev;
4221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
4241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (os_memcmp(p2p->pending_pd_devaddr,
4251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			      dev->info.p2p_device_addr, ETH_ALEN))
4261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			continue;
4271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!dev->req_config_methods)
4281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			continue;
4291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (dev->flags & P2P_DEV_PD_FOR_JOIN)
4301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			continue;
4311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		/* Reset the config methods of the device */
4321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		dev->req_config_methods = 0;
4331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
4341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
43575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	p2p->user_initiated_pd = 0;
43675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
43775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	p2p->pd_retries = 0;
43875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen}
439