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" 132e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt#include "common/wpa_ctrl.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_defs.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_i.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen/* 2061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Number of retries to attempt for provision discovery requests 2161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * in case the peer is not listening. 2275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 23d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#define MAX_PROV_DISC_REQ_RETRIES 120 2475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 2575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void p2p_build_wps_ie_config_methods(struct wpabuf *buf, 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 config_methods) 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = wpabuf_put(buf, 1); 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be32(buf, WPS_DEV_OUI_WFA); 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Config Methods */ 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be16(buf, ATTR_CONFIG_METHODS); 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be16(buf, 2); 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be16(buf, config_methods); 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(buf, len); 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p, 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 dialog_token, 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 config_methods, 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *go) 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 5061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 5361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_prov_disc_req) 5461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_prov_disc_req); 5561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 5661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 572e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]) 582e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]); 592e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 6061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf = wpabuf_alloc(1000 + extra); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(buf); 6704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab & 6804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go) { 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_group_id(buf, go->info.p2p_device_addr, 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go->oper_ssid, go->oper_ssid_len); 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(buf, len); 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPS IE with Config Methods attribute */ 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_wps_ie_config_methods(buf, config_methods); 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 8061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_prov_disc_req) 8161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(buf, p2p->wfd_ie_prov_disc_req); 8261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 8361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 842e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]) 852e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]); 862e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p, 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 dialog_token, 9361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u16 config_methods, 9461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *group_id, 9561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t group_id_len) 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 9861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 9961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 10061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 10161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *wfd_ie = p2p->wfd_ie_prov_disc_resp; 10261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wfd_ie && group_id) { 10361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t i; 10461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < p2p->num_groups; i++) { 10561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct p2p_group *g = p2p->groups[i]; 10661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *ie; 10761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!p2p_group_is_group_id_match(g, group_id, 10861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt group_id_len)) 10961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 11061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ie = p2p_group_get_wfd_ie(g); 11161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ie) { 11261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wfd_ie = ie; 11361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 11461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 11561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 11661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 11761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wfd_ie) 11861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(wfd_ie); 11961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1212e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]) 1222e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]); 1232e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 12461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf = wpabuf_alloc(100 + extra); 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_RESP, dialog_token); 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPS IE with Config Methods attribute */ 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_wps_ie_config_methods(buf, config_methods); 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 13461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wfd_ie) 13561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(buf, wfd_ie); 13661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 13761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1382e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]) 1392e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]); 1402e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int rx_freq) 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reject = 1; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg)) 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 157b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received Provision Discovery Request from " MACSTR 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with config methods 0x%x (freq=%d)", 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), msg.wps_config_methods, rx_freq); 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, sa); 1621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 163b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request from unknown peer " 164b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR, MAC2STR(sa)); 165a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 166f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (p2p_add_device(p2p, sa, rx_freq, NULL, 0, data + 1, len - 1, 167a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 0)) { 168b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request add device failed " 169b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR, MAC2STR(sa)); 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (msg.wfd_subelems) { 17261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 17361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(msg.wps_config_methods & 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD | 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_CONFIG_PUSHBUTTON))) { 179b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unsupported Config Methods in Provision Discovery Request"); 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (msg.group_id) { 18404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t i; 18504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < p2p->num_groups; i++) { 18604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_group_is_group_id_match(p2p->groups[i], 18704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt msg.group_id, 18804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt msg.group_id_len)) 18904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 19004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 19104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (i == p2p->num_groups) { 192b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "PD request for unknown P2P Group ID - reject"); 19304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt goto out; 19404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 19504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 19604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY | 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_PD_PEER_KEYPAD); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.wps_config_methods & WPS_CONFIG_DISPLAY) { 201b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " requested us to show a PIN on display", MAC2STR(sa)); 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_KEYPAD; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) { 206b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " requested us to write its PIN using keypad", 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa)); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_DISPLAY; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reject = 0; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout: 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = p2p_build_prov_disc_resp(p2p, msg.dialog_token, 21761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt reject ? 0 : msg.wps_config_methods, 21861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt msg.group_id, msg.group_id_len); 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) { 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 223b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Sending Provision Discovery Response"); 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rx_freq > 0) 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = rx_freq; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2274b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->reg_class, 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 230b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown regulatory class/channel"); 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_addr, 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { 239b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to send Action frame"); 2404582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt } else 2414582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt p2p->send_action_in_progress = 1; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!reject && p2p->cfg->prov_disc_req) { 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *dev_addr = sa; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev_addr = msg.p2p_device_addr; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->prov_disc_req(p2p->cfg->cb_ctx, sa, 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.wps_config_methods, 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev_addr, msg.pri_dev_type, 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.device_name, msg.config_methods, 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.capability ? msg.capability[0] : 0, 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.capability ? msg.capability[1] : 2551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 0, 2561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt msg.group_id, msg.group_id_len); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len) 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 267444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt u16 report_config_methods = 0, req_config_methods; 26804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int success = 0; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg)) 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 273b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received Provision Discovery Response from " MACSTR 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with config methods 0x%x", 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), msg.wps_config_methods); 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, sa); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || !dev->req_config_methods) { 279b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore Provision Discovery Response from " MACSTR 280b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " with no pending request", MAC2STR(sa)); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->dialog_token != msg.dialog_token) { 286b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore Provision Discovery Response with unexpected Dialog Token %u (expected %u)", 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.dialog_token, dev->dialog_token); 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29291c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt if (p2p->pending_action_state == P2P_PENDING_PD) { 29391c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN); 29491c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 29591c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt } 29691c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt 29775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 298444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt * Use a local copy of the requested config methods since 299444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt * p2p_reset_pending_pd() can clear this in the peer entry. 300444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt */ 301444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt req_config_methods = dev->req_config_methods; 302444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 303444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt /* 30475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * If the response is from the peer to whom a user initiated request 30575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * was sent earlier, we reset that state info here. 30675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 30775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->user_initiated_pd && 30875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_memcmp(p2p->pending_pd_devaddr, sa, ETH_ALEN) == 0) 30975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_reset_pending_pd(p2p); 31075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 311444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (msg.wps_config_methods != req_config_methods) { 312b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer rejected our Provision Discovery Request (received config_methods 0x%x expected 0x%x", 313444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt msg.wps_config_methods, req_config_methods); 31475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->cfg->prov_disc_fail) 31575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa, 31675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen P2P_PROV_DISC_REJECTED); 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 321444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt report_config_methods = req_config_methods; 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY | 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_PD_PEER_KEYPAD); 324444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (req_config_methods & WPS_CONFIG_DISPLAY) { 325b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " accepted to show a PIN on display", MAC2STR(sa)); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_DISPLAY; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) { 329b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " accepted to write our PIN using keypad", 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa)); 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_KEYPAD; 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Store the provisioning info */ 3361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = msg.wps_config_methods; 3371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 33904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt success = 1; 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout: 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods = 0; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 34404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) { 345b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Start GO Neg after the PD-before-GO-Neg workaround with " 346b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR, MAC2STR(dev->info.p2p_device_addr)); 34704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG; 34804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_connect_send(p2p, dev); 34904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 35004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 35104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (success && p2p->cfg->prov_disc_resp) 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa, 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt report_config_methods); 35437d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 35537d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt if (p2p->state == P2P_PD_DURING_FIND) { 35637d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt p2p_clear_timeout(p2p); 35737d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt p2p_continue_find(p2p); 35837d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt } 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev, 3631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int join, int force_freq) 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 367497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt 3681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (force_freq > 0) 3691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt freq = force_freq; 3701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 3711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt freq = dev->listen_freq > 0 ? dev->listen_freq : 3721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->oper_freq; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq <= 0) { 374b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No Listen/Operating frequency known for the peer " 375b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR " to send Provision Discovery Request", 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(dev->info.dev_capab & 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { 383b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot use PD with P2P Device " MACSTR 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " that is in a group and is not discoverable", 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: use device discoverability request through GO */ 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = p2p_build_prov_disc_req(p2p, dev->dialog_token, 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods, 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt join ? dev : NULL); 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->state != P2P_IDLE) 39804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_listen_for_freq(p2p, freq); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_PENDING_PD; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr, 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_addr, dev->info.p2p_device_addr, 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(req), wpabuf_len(req), 200) < 0) { 403b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to send Action frame"); 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN); 40975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_prov_disc_req(struct p2p_data *p2p, const u8 *peer_addr, 416d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u16 config_methods, int join, int force_freq, 417d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int user_initiated_pd) 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device_interface(p2p, peer_addr); 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 425b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request destination " MACSTR 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " not yet known", MAC2STR(peer_addr)); 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 430b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request with " MACSTR 431b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " (config methods 0x%x)", 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), config_methods); 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config_methods == 0) 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Reset provisioning info */ 4371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = 0; 4381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods = config_methods; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (join) 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_FOR_JOIN; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PD_FOR_JOIN; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 445c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH && 446c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->state != P2P_LISTEN_ONLY) { 447b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Busy with other operations; postpone Provision Discovery Request with " 448b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR " (config methods 0x%x)", 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), config_methods); 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 453d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->user_initiated_pd = user_initiated_pd; 454051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt p2p->pd_force_freq = force_freq; 45575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 45661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->user_initiated_pd) 45775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES; 45875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 459a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* 460a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Assign dialog token here to use the same value in each retry within 461a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * the same PD exchange. 462a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 463a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->dialog_token++; 464a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (dev->dialog_token == 0) 465a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->dialog_token = 1; 466a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 4671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p_send_prov_disc_req(p2p, dev, join, force_freq); 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 46975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 47075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 47175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenvoid p2p_reset_pending_pd(struct p2p_data *p2p) 47275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 4731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev; 4741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(p2p->pending_pd_devaddr, 4771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->info.p2p_device_addr, ETH_ALEN)) 4781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 4791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!dev->req_config_methods) 4801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 4811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev->flags & P2P_DEV_PD_FOR_JOIN) 4821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 4831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Reset the config methods of the device */ 4841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->req_config_methods = 0; 4851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 48775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->user_initiated_pd = 0; 48875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN); 48975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries = 0; 490051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt p2p->pd_force_freq = 0; 49175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 492