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/* 1961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Number of retries to attempt for provision discovery requests 2061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * 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; 4961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 5261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_prov_disc_req) 5361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_prov_disc_req); 5461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 5561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 5661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf = wpabuf_alloc(1000 + extra); 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(buf); 6304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab & 6404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go) { 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_group_id(buf, go->info.p2p_device_addr, 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go->oper_ssid, go->oper_ssid_len); 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(buf, len); 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPS IE with Config Methods attribute */ 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_wps_ie_config_methods(buf, config_methods); 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 7661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_prov_disc_req) 7761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(buf, p2p->wfd_ie_prov_disc_req); 7861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 7961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p, 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 dialog_token, 8661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u16 config_methods, 8761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *group_id, 8861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t group_id_len) 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 9161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 9261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 9361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 9461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *wfd_ie = p2p->wfd_ie_prov_disc_resp; 9561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wfd_ie && group_id) { 9661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t i; 9761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < p2p->num_groups; i++) { 9861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct p2p_group *g = p2p->groups[i]; 9961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *ie; 10061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!p2p_group_is_group_id_match(g, group_id, 10161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt group_id_len)) 10261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 10361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ie = p2p_group_get_wfd_ie(g); 10461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ie) { 10561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wfd_ie = ie; 10661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 10761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 10861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 10961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 11061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wfd_ie) 11161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(wfd_ie); 11261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf = wpabuf_alloc(100 + extra); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_RESP, dialog_token); 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPS IE with Config Methods attribute */ 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_wps_ie_config_methods(buf, config_methods); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 12461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wfd_ie) 12561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(buf, wfd_ie); 12661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 12761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int rx_freq) 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reject = 1; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg)) 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Received Provision Discovery Request from " MACSTR 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with config methods 0x%x (freq=%d)", 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), msg.wps_config_methods, rx_freq); 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, sa); 1501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Provision Discovery Request from " 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unknown peer " MACSTR, MAC2STR(sa)); 15404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_add_device(p2p, sa, rx_freq, 0, data + 1, len - 1, 0)) 15504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt { 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Provision Discovery Request add device " 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed " MACSTR, MAC2STR(sa)); 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (msg.wfd_subelems) { 16161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 16261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(msg.wps_config_methods & 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD | 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_CONFIG_PUSHBUTTON))) { 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unsupported " 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Config Methods in Provision Discovery Request"); 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (msg.group_id) { 17404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t i; 17504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < p2p->num_groups; i++) { 17604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_group_is_group_id_match(p2p->groups[i], 17704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt msg.group_id, 17804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt msg.group_id_len)) 17904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 18004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 18104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (i == p2p->num_groups) { 18204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: PD " 18304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "request for unknown P2P Group ID - reject"); 18404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt goto out; 18504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 18604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 18704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY | 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_PD_PEER_KEYPAD); 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.wps_config_methods & WPS_CONFIG_DISPLAY) { 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " requested us to show a PIN on display", MAC2STR(sa)); 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_KEYPAD; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) { 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " requested us to write its PIN using keypad", 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa)); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_DISPLAY; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reject = 0; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout: 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = p2p_build_prov_disc_resp(p2p, msg.dialog_token, 20861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt reject ? 0 : msg.wps_config_methods, 20961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt msg.group_id, msg.group_id_len); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) { 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Sending Provision Discovery Response"); 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rx_freq > 0) 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = rx_freq; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->country, 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->reg_class, 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unknown regulatory class/channel"); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_addr, 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to send Action frame"); 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!reject && p2p->cfg->prov_disc_req) { 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *dev_addr = sa; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev_addr = msg.p2p_device_addr; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->prov_disc_req(p2p->cfg->cb_ctx, sa, 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.wps_config_methods, 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev_addr, msg.pri_dev_type, 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.device_name, msg.config_methods, 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.capability ? msg.capability[0] : 0, 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.capability ? msg.capability[1] : 2491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 0, 2501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt msg.group_id, msg.group_id_len); 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len) 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 report_config_methods = 0; 26204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int success = 0; 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg)) 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "P2P: Received Provision Discovery Response from " MACSTR 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with config methods 0x%x", 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), msg.wps_config_methods); 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, sa); 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || !dev->req_config_methods) { 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "P2P: Ignore Provision Discovery Response from " 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " with no pending request", MAC2STR(sa)); 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->dialog_token != msg.dialog_token) { 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "P2P: Ignore Provision Discovery Response with " 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unexpected Dialog Token %u (expected %u)", 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.dialog_token, dev->dialog_token); 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29091c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt if (p2p->pending_action_state == P2P_PENDING_PD) { 29191c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN); 29291c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 29391c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt } 29491c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt 29575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 29675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * If the response is from the peer to whom a user initiated request 29775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * was sent earlier, we reset that state info here. 29875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 29975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->user_initiated_pd && 30075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_memcmp(p2p->pending_pd_devaddr, sa, ETH_ALEN) == 0) 30175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_reset_pending_pd(p2p); 30275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.wps_config_methods != dev->req_config_methods) { 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer rejected " 3051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "our Provision Discovery Request"); 30675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->cfg->prov_disc_fail) 30775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa, 30875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen P2P_PROV_DISC_REJECTED); 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt report_config_methods = dev->req_config_methods; 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY | 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_PD_PEER_KEYPAD); 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->req_config_methods & WPS_CONFIG_DISPLAY) { 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " accepted to show a PIN on display", MAC2STR(sa)); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_DISPLAY; 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) { 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " accepted to write our PIN using keypad", 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa)); 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_KEYPAD; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Store the provisioning info */ 3281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = msg.wps_config_methods; 3291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 33104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt success = 1; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout: 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods = 0; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 33604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) { 33704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 33804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "P2P: Start GO Neg after the PD-before-GO-Neg " 33904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "workaround with " MACSTR, 34004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 34104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG; 34204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_connect_send(p2p, dev); 34304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 34404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 34504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (success && p2p->cfg->prov_disc_resp) 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa, 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt report_config_methods); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev, 3521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int join, int force_freq) 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 356497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt 3571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (force_freq > 0) 3581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt freq = force_freq; 3591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 3601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt freq = dev->listen_freq > 0 ? dev->listen_freq : 3611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->oper_freq; 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq <= 0) { 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No Listen/Operating frequency known for the " 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "peer " MACSTR " to send Provision Discovery Request", 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(dev->info.dev_capab & 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Cannot use PD with P2P Device " MACSTR 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " that is in a group and is not discoverable", 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: use device discoverability request through GO */ 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->dialog_token++; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->dialog_token == 0) 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->dialog_token = 1; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = p2p_build_prov_disc_req(p2p, dev->dialog_token, 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods, 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt join ? dev : NULL); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->state != P2P_IDLE) 39204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_listen_for_freq(p2p, freq); 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_PENDING_PD; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr, 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_addr, dev->info.p2p_device_addr, 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(req), wpabuf_len(req), 200) < 0) { 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to send Action frame"); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 40375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN); 40475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_prov_disc_req(struct p2p_data *p2p, const u8 *peer_addr, 4111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u16 config_methods, int join, int force_freq) 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device_interface(p2p, peer_addr); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Provision " 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Discovery Request destination " MACSTR 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " not yet known", MAC2STR(peer_addr)); 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Provision Discovery " 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request with " MACSTR " (config methods 0x%x)", 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), config_methods); 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config_methods == 0) 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Reset provisioning info */ 4321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = 0; 4331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods = config_methods; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (join) 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_FOR_JOIN; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PD_FOR_JOIN; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 440c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH && 441c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->state != P2P_LISTEN_ONLY) { 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Busy with other " 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "operations; postpone Provision Discovery Request " 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "with " MACSTR " (config methods 0x%x)", 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), config_methods); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 45075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * We use the join param as a cue to differentiate between user 45175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * initiated PD request and one issued during finds (internal). 45275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 45375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->user_initiated_pd = !join; 45475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 45561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->user_initiated_pd) 45675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES; 45775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 4581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p_send_prov_disc_req(p2p, dev, join, force_freq); 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 46075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 46175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 46275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenvoid p2p_reset_pending_pd(struct p2p_data *p2p) 46375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 4641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev; 4651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 4671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(p2p->pending_pd_devaddr, 4681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->info.p2p_device_addr, ETH_ALEN)) 4691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 4701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!dev->req_config_methods) 4711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 4721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev->flags & P2P_DEV_PD_FOR_JOIN) 4731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 4741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Reset the config methods of the device */ 4751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->req_config_methods = 0; 4761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 47875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->user_initiated_pd = 0; 47975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN); 48075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries = 0; 48175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 482