p2p_pd.c revision c5ec7f57ead87efa365800228aa0b09a12d9e6c4
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); 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab, 0); 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (go) { 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_group_id(buf, go->info.p2p_device_addr, 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go->oper_ssid, go->oper_ssid_len); 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(buf, len); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPS IE with Config Methods attribute */ 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_wps_ie_config_methods(buf, config_methods); 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p, 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 dialog_token, 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 config_methods) 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(100); 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_RESP, dialog_token); 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPS IE with Config Methods attribute */ 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_wps_ie_config_methods(buf, config_methods); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int rx_freq) 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reject = 1; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg)) 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Received Provision Discovery Request from " MACSTR 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with config methods 0x%x (freq=%d)", 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), msg.wps_config_methods, rx_freq); 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, sa); 1091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Provision Discovery Request from " 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unknown peer " MACSTR, MAC2STR(sa)); 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_add_device(p2p, sa, rx_freq, 0, data + 1, len - 1)) { 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Provision Discovery Request add device " 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed " MACSTR, MAC2STR(sa)); 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(msg.wps_config_methods & 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD | 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_CONFIG_PUSHBUTTON))) { 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unsupported " 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Config Methods in Provision Discovery Request"); 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY | 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_PD_PEER_KEYPAD); 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.wps_config_methods & WPS_CONFIG_DISPLAY) { 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " requested us to show a PIN on display", MAC2STR(sa)); 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_KEYPAD; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) { 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " requested us to write its PIN using keypad", 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa)); 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_DISPLAY; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reject = 0; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout: 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = p2p_build_prov_disc_resp(p2p, msg.dialog_token, 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reject ? 0 : msg.wps_config_methods); 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) { 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Sending Provision Discovery Response"); 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rx_freq > 0) 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = rx_freq; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->country, 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->reg_class, 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Unknown regulatory class/channel"); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_addr, 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to send Action frame"); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!reject && p2p->cfg->prov_disc_req) { 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *dev_addr = sa; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev_addr = msg.p2p_device_addr; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->prov_disc_req(p2p->cfg->cb_ctx, sa, 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.wps_config_methods, 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev_addr, msg.pri_dev_type, 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.device_name, msg.config_methods, 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.capability ? msg.capability[0] : 0, 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.capability ? msg.capability[1] : 1881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 0, 1891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt msg.group_id, msg.group_id_len); 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len) 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 report_config_methods = 0; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg)) 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "P2P: Received Provision Discovery Response from " MACSTR 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with config methods 0x%x", 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), msg.wps_config_methods); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, sa); 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || !dev->req_config_methods) { 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "P2P: Ignore Provision Discovery Response from " 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " with no pending request", MAC2STR(sa)); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->pending_action_state == P2P_PENDING_PD) { 22075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN); 22175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pending_action_state = P2P_NO_PENDING_ACTION; 22275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 22375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->dialog_token != msg.dialog_token) { 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "P2P: Ignore Provision Discovery Response with " 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unexpected Dialog Token %u (expected %u)", 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.dialog_token, dev->dialog_token); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 23475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * If the response is from the peer to whom a user initiated request 23575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * was sent earlier, we reset that state info here. 23675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 23775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->user_initiated_pd && 23875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_memcmp(p2p->pending_pd_devaddr, sa, ETH_ALEN) == 0) 23975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_reset_pending_pd(p2p); 24075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.wps_config_methods != dev->req_config_methods) { 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer rejected " 2431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "our Provision Discovery Request"); 24475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->cfg->prov_disc_fail) 24575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa, 24675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen P2P_PROV_DISC_REJECTED); 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt report_config_methods = dev->req_config_methods; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY | 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_PD_PEER_KEYPAD); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->req_config_methods & WPS_CONFIG_DISPLAY) { 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " accepted to show a PIN on display", MAC2STR(sa)); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_DISPLAY; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) { 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " accepted to write our PIN using keypad", 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa)); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_KEYPAD; 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Store the provisioning info */ 2661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = msg.wps_config_methods; 2671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout: 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods = 0; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p->cfg->prov_disc_resp) 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa, 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt report_config_methods); 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev, 2801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int join, int force_freq) 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 284497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt 2851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (force_freq > 0) 2861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt freq = force_freq; 2871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 2881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt freq = dev->listen_freq > 0 ? dev->listen_freq : 2891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->oper_freq; 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq <= 0) { 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: No Listen/Operating frequency known for the " 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "peer " MACSTR " to send Provision Discovery Request", 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(dev->info.dev_capab & 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Cannot use PD with P2P Device " MACSTR 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " that is in a group and is not discoverable", 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: use device discoverability request through GO */ 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->dialog_token++; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->dialog_token == 0) 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->dialog_token = 1; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = p2p_build_prov_disc_req(p2p, dev->dialog_token, 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods, 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt join ? dev : NULL); 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_PENDING_PD; 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr, 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_addr, dev->info.p2p_device_addr, 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(req), wpabuf_len(req), 200) < 0) { 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "P2P: Failed to send Action frame"); 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN); 33075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_prov_disc_req(struct p2p_data *p2p, const u8 *peer_addr, 3371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u16 config_methods, int join, int force_freq) 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device_interface(p2p, peer_addr); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Provision " 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Discovery Request destination " MACSTR 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " not yet known", MAC2STR(peer_addr)); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Provision Discovery " 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request with " MACSTR " (config methods 0x%x)", 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), config_methods); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config_methods == 0) 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Reset provisioning info */ 3581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = 0; 3591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods = config_methods; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (join) 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_FOR_JOIN; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PD_FOR_JOIN; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 366c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH && 367c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->state != P2P_LISTEN_ONLY) { 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Busy with other " 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "operations; postpone Provision Discovery Request " 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "with " MACSTR " (config methods 0x%x)", 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), config_methods); 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 37675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * We use the join param as a cue to differentiate between user 37775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * initiated PD request and one issued during finds (internal). 37875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 37975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->user_initiated_pd = !join; 38075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 38175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* Also set some retries to attempt in case of IDLE state */ 38275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->user_initiated_pd && p2p->state == P2P_IDLE) 38375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES; 38475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 3851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p_send_prov_disc_req(p2p, dev, join, force_freq); 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 38775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 38875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 38975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenvoid p2p_reset_pending_pd(struct p2p_data *p2p) 39075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 3911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev; 3921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 3941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(p2p->pending_pd_devaddr, 3951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->info.p2p_device_addr, ETH_ALEN)) 3961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 3971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!dev->req_config_methods) 3981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 3991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev->flags & P2P_DEV_PD_FOR_JOIN) 4001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 4011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Reset the config methods of the device */ 4021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->req_config_methods = 0; 4031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 40575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->user_initiated_pd = 0; 40675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN); 40775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries = 0; 40875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 409