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 43216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic void p2ps_add_new_group_info(struct p2p_data *p2p, struct wpabuf *buf) 44216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 45216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt int found; 46216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 intended_addr[ETH_ALEN]; 479d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt u8 ssid[SSID_MAX_LEN]; 48216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t ssid_len; 49216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt int group_iface; 50216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 51216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!p2p->cfg->get_go_info) 52216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return; 53216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 54216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt found = p2p->cfg->get_go_info( 55216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->cb_ctx, intended_addr, ssid, 56216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt &ssid_len, &group_iface); 57216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (found) { 58216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, 59216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt ssid, ssid_len); 60216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_intended_addr(buf, intended_addr); 61216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else { 62216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!p2p->ssid_set) { 63216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_build_ssid(p2p, p2p->ssid, &p2p->ssid_len); 64216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->ssid_set = 1; 65216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 66216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 67216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Add pre-composed P2P Group ID */ 68216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_group_id(buf, p2p->cfg->dev_addr, 69216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->ssid, p2p->ssid_len); 70216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 71216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (group_iface) 72216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_intended_addr( 73216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt buf, p2p->intended_addr); 74216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else 75216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_intended_addr( 76216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt buf, p2p->cfg->dev_addr); 77216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 78216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 79216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 80216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 81216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev, 82216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct wpabuf *buf, u16 config_methods) 83216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 84216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2ps_provision *prov = p2p->p2ps_prov; 85216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 feat_cap_mask[] = { 1, 0 }; 86216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt int shared_group = 0; 879d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt u8 ssid[SSID_MAX_LEN]; 88216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t ssid_len; 89216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 90216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 91216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* If we might be explicite group owner, add GO details */ 92216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (prov->conncap & (P2PS_SETUP_GROUP_OWNER | 93216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2PS_SETUP_NEW)) 94216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2ps_add_new_group_info(p2p, buf); 95216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 96216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (prov->status >= 0) 97216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_status(buf, (u8) prov->status); 98216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else 99216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt prov->method = config_methods; 100216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 101216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->cfg->get_persistent_group) { 102216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt shared_group = p2p->cfg->get_persistent_group( 103216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->cb_ctx, dev->info.p2p_device_addr, NULL, 0, 104216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt go_dev_addr, ssid, &ssid_len); 105216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 106216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 107216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Add Operating Channel if conncap includes GO */ 108216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (shared_group || 109216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (prov->conncap & (P2PS_SETUP_GROUP_OWNER | 110216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2PS_SETUP_NEW))) { 111216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 tmp; 112216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 113216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_go_select_channel(p2p, dev, &tmp); 114216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 115216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->op_reg_class && p2p->op_channel) 116216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_operating_channel(buf, p2p->cfg->country, 117216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->op_reg_class, 118216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->op_channel); 119216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else 120216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_operating_channel(buf, p2p->cfg->country, 121216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->op_reg_class, 122216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->op_channel); 123216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 124216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 125216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->cfg->channels); 126216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 127216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (prov->info[0]) 128216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_session_info(buf, prov->info); 129216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 130216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_connection_capability(buf, prov->conncap); 131216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 132216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_advertisement_id(buf, prov->adv_id, prov->adv_mac); 133216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 134216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (shared_group || prov->conncap == P2PS_SETUP_NEW || 135216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt prov->conncap == 136216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW) || 137216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt prov->conncap == 138216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT)) { 139216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Add Config Timeout */ 140216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_config_timeout(buf, p2p->go_timeout, 141216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->client_timeout); 142216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 143216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 144216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_listen_channel(buf, p2p->cfg->country, p2p->cfg->reg_class, 145216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->channel); 146216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 147216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_session_id(buf, prov->session_id, prov->session_mac); 148216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 149216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_feature_capability(buf, sizeof(feat_cap_mask), 150216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt feat_cap_mask); 151216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 152216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (shared_group) 153216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_persistent_group_info(buf, go_dev_addr, 154216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt ssid, ssid_len); 155216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 156216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 157216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p, 159216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2p_device *dev, 160216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt int join) 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *len; 16461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 165216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 dialog_token = dev->dialog_token; 166216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u16 config_methods = dev->req_config_methods; 167216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2p_device *go = join ? dev : NULL; 168216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 group_capab; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 17161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_prov_disc_req) 17261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(p2p->wfd_ie_prov_disc_req); 17361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 17461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1752e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]) 1762e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]); 1772e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 178216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->p2ps_prov) 179216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt extra += os_strlen(p2p->p2ps_prov->info) + 1 + 180216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt sizeof(struct p2ps_provision); 181216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 18261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf = wpabuf_alloc(1000 + extra); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token); 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = p2p_buf_add_ie_hdr(buf); 189216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 190216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_capab = 0; 191216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->p2ps_prov) { 192216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP; 193216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_PERSISTENT_RECONN; 194216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->cross_connect) 195216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; 196216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->cfg->p2p_intra_bss) 197216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST; 198216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 19904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab & 200216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 201216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_capab); 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 203216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->p2ps_prov) { 204216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2ps_add_pd_req_attrs(p2p, dev, buf, config_methods); 205216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (go) { 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_group_id(buf, go->info.p2p_device_addr, 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt go->oper_ssid, go->oper_ssid_len); 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_update_ie_hdr(buf, len); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPS IE with Config Methods attribute */ 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_wps_ie_config_methods(buf, config_methods); 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 21561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->wfd_ie_prov_disc_req) 21661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(buf, p2p->wfd_ie_prov_disc_req); 21761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 21861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2192e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]) 2202e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]); 2212e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p, 227216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2p_device *dev, 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 dialog_token, 229216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt enum p2p_status_code status, 23061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u16 config_methods, 231216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u32 adv_id, 23261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *group_id, 233216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t group_id_len, 234216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt const u8 *persist_ssid, 235216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t persist_ssid_len) 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 23861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t extra = 0; 239216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt int persist = 0; 24061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 24161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 24261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *wfd_ie = p2p->wfd_ie_prov_disc_resp; 24361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wfd_ie && group_id) { 24461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t i; 24561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < p2p->num_groups; i++) { 24661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct p2p_group *g = p2p->groups[i]; 24761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *ie; 24861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!p2p_group_is_group_id_match(g, group_id, 24961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt group_id_len)) 25061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt continue; 25161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ie = p2p_group_get_wfd_ie(g); 25261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ie) { 25361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wfd_ie = ie; 25461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 25561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 25661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 25761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 25861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wfd_ie) 25961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra = wpabuf_len(wfd_ie); 26061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2622e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]) 2632e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]); 2642e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 265216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt buf = wpabuf_alloc(1000 + extra); 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_RESP, dialog_token); 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 271216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Add P2P IE for P2PS */ 272216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->p2ps_prov && p2p->p2ps_prov->adv_id == adv_id) { 273216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 feat_cap_mask[] = { 1, 0 }; 274216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 *len = p2p_buf_add_ie_hdr(buf); 275216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2ps_provision *prov = p2p->p2ps_prov; 276216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 group_capab; 277216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 278216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!status && prov->status != -1) 279216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt status = prov->status; 280216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 281216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_status(buf, status); 282216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_capab = P2P_GROUP_CAPAB_PERSISTENT_GROUP | 283216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_GROUP_CAPAB_PERSISTENT_RECONN; 284216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->cross_connect) 285216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; 286216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->cfg->p2p_intra_bss) 287216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST; 288216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_capability(buf, p2p->dev_capab & 289216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 290216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_capab); 291216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_device_info(buf, p2p, NULL); 292216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 293216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (persist_ssid && p2p->cfg->get_persistent_group && 294216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (status == P2P_SC_SUCCESS || 295216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt status == P2P_SC_SUCCESS_DEFERRED)) { 2969d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt u8 ssid[SSID_MAX_LEN]; 297216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t ssid_len; 298216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 go_dev_addr[ETH_ALEN]; 299216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 300216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt persist = p2p->cfg->get_persistent_group( 301216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->cb_ctx, 302216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->info.p2p_device_addr, 303216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt persist_ssid, persist_ssid_len, go_dev_addr, 304216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt ssid, &ssid_len); 305216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (persist) 306216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_persistent_group_info( 307216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt buf, go_dev_addr, ssid, ssid_len); 308216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 309216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 310216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!persist && (prov->conncap & P2PS_SETUP_GROUP_OWNER)) 311216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2ps_add_new_group_info(p2p, buf); 312216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 313216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Add Operating Channel if conncap indicates GO */ 314216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (persist || (prov->conncap & P2PS_SETUP_GROUP_OWNER)) { 315216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 tmp; 316216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 317216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (dev) 318216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_go_select_channel(p2p, dev, &tmp); 319216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 320216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->op_reg_class && p2p->op_channel) 321216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_operating_channel( 322216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt buf, p2p->cfg->country, 323216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->op_reg_class, 324216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->op_channel); 325216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else 326216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_operating_channel( 327216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt buf, p2p->cfg->country, 328216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->op_reg_class, 329216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->op_channel); 330216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 331216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 332216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_channel_list(buf, p2p->cfg->country, 333216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt &p2p->cfg->channels); 334216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 335216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!persist && (status == P2P_SC_SUCCESS || 336216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt status == P2P_SC_SUCCESS_DEFERRED)) 337216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_connection_capability(buf, prov->conncap); 338216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 339216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_advertisement_id(buf, adv_id, prov->adv_mac); 340216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 341216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_config_timeout(buf, p2p->go_timeout, 342216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->client_timeout); 343216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 344216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_session_id(buf, prov->session_id, 345216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt prov->session_mac); 346216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 347216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_feature_capability(buf, sizeof(feat_cap_mask), 348216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt feat_cap_mask); 349216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_update_ie_hdr(buf, len); 350216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (status != P2P_SC_SUCCESS || adv_id) { 351216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 *len = p2p_buf_add_ie_hdr(buf); 352216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 353216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_status(buf, status); 354216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 355216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->p2ps_prov) 356216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_add_advertisement_id(buf, adv_id, 357216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov->adv_mac); 358216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 359216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_buf_update_ie_hdr(buf, len); 360216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 361216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPS IE with Config Methods attribute */ 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_build_wps_ie_config_methods(buf, config_methods); 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 36661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wfd_ie) 36761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_put_buf(buf, wfd_ie); 36861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 36961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 3702e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]) 3712e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]); 3722e67f06149ff649fb6f8782bad041d3d9124685eDmitry Shmidt 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 377216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidtstatic int p2ps_setup_p2ps_prov(struct p2p_data *p2p, u32 adv_id, 378216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u32 session_id, u16 method, 379216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt const u8 *session_mac, const u8 *adv_mac) 380216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt{ 381216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2ps_provision *tmp; 382216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 383216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!p2p->p2ps_prov) { 384216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov = os_zalloc(sizeof(struct p2ps_provision) + 1); 385216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!p2p->p2ps_prov) 386216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 387216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else { 388216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memset(p2p->p2ps_prov, 0, sizeof(struct p2ps_provision) + 1); 389216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 390216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 391216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp = p2p->p2ps_prov; 392216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp->adv_id = adv_id; 393216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp->session_id = session_id; 394216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp->method = method; 395216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(tmp->session_mac, session_mac, ETH_ALEN); 396216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(tmp->adv_mac, adv_mac, ETH_ALEN); 397216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp->info[0] = '\0'; 398216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 399216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return 0; 400216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt} 401216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 402216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, int rx_freq) 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 409216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt enum p2p_status_code reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS; 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 411216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u32 adv_id = 0; 412216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2ps_advertisement *p2ps_adv = NULL; 413216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 conncap = P2PS_SETUP_NEW; 414216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 auto_accept = 0; 415216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u32 session_id = 0; 416216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 session_mac[ETH_ALEN]; 417216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 adv_mac[ETH_ALEN]; 418216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 group_mac[ETH_ALEN]; 419216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt int passwd_id = DEV_PW_DEFAULT; 420216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u16 config_methods; 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg)) 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 425b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received Provision Discovery Request from " MACSTR 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with config methods 0x%x (freq=%d)", 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), msg.wps_config_methods, rx_freq); 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, sa); 4301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 431b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request from unknown peer " 432b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR, MAC2STR(sa)); 433a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 434f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (p2p_add_device(p2p, sa, rx_freq, NULL, 0, data + 1, len - 1, 435a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 0)) { 436b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request add device failed " 437b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR, MAC2STR(sa)); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 43961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (msg.wfd_subelems) { 44061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(dev->info.wfd_subelems); 44161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(msg.wps_config_methods & 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD | 446216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_P2PS))) { 447b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unsupported Config Methods in Provision Discovery Request"); 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 451216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Legacy (non-P2PS) - Unknown groups allowed for P2PS */ 452216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!msg.adv_id && msg.group_id) { 45304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t i; 45404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < p2p->num_groups; i++) { 45504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p_group_is_group_id_match(p2p->groups[i], 45604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt msg.group_id, 45704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt msg.group_id_len)) 45804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 45904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 46004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (i == p2p->num_groups) { 461b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "PD request for unknown P2P Group ID - reject"); 46204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt goto out; 46304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 46404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 46504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 466216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (dev) { 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY | 468216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_DEV_PD_PEER_KEYPAD | 469216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_DEV_PD_PEER_P2PS); 470216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 471216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Remove stale persistent groups */ 472216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->cfg->remove_stale_groups) { 473216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->remove_stale_groups( 474216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->cb_ctx, dev->info.p2p_device_addr, 475216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_dev, 476216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid, msg.persistent_ssid_len); 477216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 478216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.wps_config_methods & WPS_CONFIG_DISPLAY) { 480b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " requested us to show a PIN on display", MAC2STR(sa)); 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_KEYPAD; 484216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt passwd_id = DEV_PW_USER_SPECIFIED; 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) { 486b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " requested us to write its PIN using keypad", 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa)); 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev) 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_DISPLAY; 491216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt passwd_id = DEV_PW_REGISTRAR_SPECIFIED; 492216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (msg.wps_config_methods & WPS_CONFIG_P2PS) { 493216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR " requesting P2PS PIN", 494216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(sa)); 495216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (dev) 496216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_P2PS; 497216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt passwd_id = DEV_PW_P2PS_DEFAULT; 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 500216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject = P2P_SC_SUCCESS; 501216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 502216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memset(session_mac, 0, ETH_ALEN); 503216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memset(adv_mac, 0, ETH_ALEN); 504216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memset(group_mac, 0, ETH_ALEN); 505216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 506216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (msg.adv_id && msg.session_id && msg.session_mac && msg.adv_mac && 507216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (msg.status || msg.conn_cap)) { 508216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 remote_conncap; 509216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 510216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (msg.intended_addr) 511216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(group_mac, msg.intended_addr, ETH_ALEN); 512216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 513216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(session_mac, msg.session_mac, ETH_ALEN); 514216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN); 515216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 516216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt session_id = WPA_GET_LE32(msg.session_id); 517216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_id = WPA_GET_LE32(msg.adv_id); 518216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 519216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!msg.status) 520216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2ps_adv = p2p_service_p2ps_id(p2p, adv_id); 521216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 522216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "adv_id: %x - p2ps_adv - %p", adv_id, p2ps_adv); 523216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 524216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (msg.conn_cap) 525216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = *msg.conn_cap; 526216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt remote_conncap = conncap; 527216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 528216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2ps_adv) { 529216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt auto_accept = p2ps_adv->auto_accept; 530216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = p2p->cfg->p2ps_group_capability( 531216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->cb_ctx, conncap, auto_accept); 532216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 533216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "Conncap: local:%d remote:%d result:%d", 534216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt auto_accept, remote_conncap, conncap); 535216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 536216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2ps_adv->config_methods && 537216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt !(msg.wps_config_methods & 538216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2ps_adv->config_methods)) { 539216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, 540216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "Unsupported config methods in Provision Discovery Request (own=0x%x peer=0x%x)", 541216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2ps_adv->config_methods, 542216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.wps_config_methods); 543216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS; 544216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (!p2ps_adv->state) { 545216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "P2PS state unavailable"); 546216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE; 547216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (!conncap) { 548216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "Conncap resolution failed"); 549216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS; 550216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 551216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 552216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) { 553216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "Keypad - always defer"); 554216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt auto_accept = 0; 555216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 556216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 557216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (auto_accept || reject != P2P_SC_SUCCESS) { 558216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2ps_provision *tmp; 559216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 560216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (reject == P2P_SC_SUCCESS && !conncap) { 561216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject = 562216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_SC_FAIL_INCOMPATIBLE_PARAMS; 563216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 564216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 565216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2ps_setup_p2ps_prov( 566216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p, adv_id, session_id, 567216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.wps_config_methods, 568216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt session_mac, adv_mac) < 0) { 569216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE; 570216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt goto out; 571216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 572216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 573216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp = p2p->p2ps_prov; 574216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (conncap) { 575216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp->conncap = conncap; 576216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp->status = P2P_SC_SUCCESS; 577216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else { 578216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp->conncap = auto_accept; 579216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp->status = P2P_SC_FAIL_INCOMPATIBLE_PARAMS; 580216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 581216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 582216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (reject != P2P_SC_SUCCESS) 583216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt goto out; 584216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 585216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (!msg.status) { 586216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS; 587216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt goto out; 588216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 589216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 590216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!msg.status && !auto_accept && 591216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (!p2p->p2ps_prov || p2p->p2ps_prov->adv_id != adv_id)) { 592216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2ps_provision *tmp; 593216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 594216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!conncap) { 595216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS; 596216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt goto out; 597216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 598216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 599216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2ps_setup_p2ps_prov(p2p, adv_id, session_id, 600216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.wps_config_methods, 601216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt session_mac, adv_mac) < 0) { 602216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE; 603216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt goto out; 604216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 605216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp = p2p->p2ps_prov; 606216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE; 607216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt tmp->status = reject; 608216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 609216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 610216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (msg.status) { 611216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (*msg.status && 612216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *msg.status != P2P_SC_SUCCESS_DEFERRED) { 613216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject = *msg.status; 614216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (*msg.status == P2P_SC_SUCCESS_DEFERRED && 615216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov) { 616216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u16 method = p2p->p2ps_prov->method; 617216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 618216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = p2p->cfg->p2ps_group_capability( 619216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->cb_ctx, remote_conncap, 620216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov->conncap); 621216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 622216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, 623216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "Conncap: local:%d remote:%d result:%d", 624216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov->conncap, 625216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt remote_conncap, conncap); 626216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 627216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* 628216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * Ensure that if we asked for PIN originally, 629216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * our method is consistent with original 630216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * request. 631216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt */ 632216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (method & WPS_CONFIG_DISPLAY) 633216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt method = WPS_CONFIG_KEYPAD; 634216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else if (method & WPS_CONFIG_KEYPAD) 635216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt method = WPS_CONFIG_DISPLAY; 636216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 637216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Reject this "Deferred Accept* if incompatible 638216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt * conncap or method */ 639216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!conncap || 640216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt !(msg.wps_config_methods & method)) 641216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject = 642216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_SC_FAIL_INCOMPATIBLE_PARAMS; 643216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else 644216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject = P2P_SC_SUCCESS; 645216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 646216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov->status = reject; 647216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov->conncap = conncap; 648216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 649216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 650216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout: 653216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (reject == P2P_SC_SUCCESS || 654216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) 655216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt config_methods = msg.wps_config_methods; 656216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else 657216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt config_methods = 0; 658216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt resp = p2p_build_prov_disc_resp(p2p, dev, msg.dialog_token, reject, 659216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt config_methods, adv_id, 660216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.group_id, msg.group_id_len, 661216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid, 662216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid_len); 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) { 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 667b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Sending Provision Discovery Response"); 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rx_freq > 0) 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freq = rx_freq; 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6714b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt freq = p2p_channel_to_freq(p2p->cfg->reg_class, 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->channel); 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq < 0) { 674b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Unknown regulatory class/channel"); 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 679216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->pending_action_state = P2P_PENDING_PD_RESPONSE; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_addr, 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { 683b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to send Action frame"); 6844582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt } else 6854582d2a5dd8180c52eb95b1100fb183b9a289708Dmitry Shmidt p2p->send_action_in_progress = 1; 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 689216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!p2p->cfg->p2ps_prov_complete) { 690216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Don't emit anything */ 691216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (msg.status && *msg.status != P2P_SC_SUCCESS && 692216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *msg.status != P2P_SC_SUCCESS_DEFERRED) { 693216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt reject = *msg.status; 694216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject, 695216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt sa, adv_mac, session_mac, 696216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt NULL, adv_id, session_id, 697216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 0, 0, msg.persistent_ssid, 698216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid_len, 699216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 0, 0, NULL); 700216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED && 701216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov) { 702216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov->status = reject; 703216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov->conncap = conncap; 704216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 705216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (reject != P2P_SC_SUCCESS) 706216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject, 707216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt sa, adv_mac, session_mac, 708216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt NULL, adv_id, 709216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt session_id, conncap, 0, 710216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid, 711216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid_len, 0, 712216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 0, NULL); 713216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else 714216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, 715216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *msg.status, 716216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt sa, adv_mac, session_mac, 717216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_mac, adv_id, 718216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt session_id, conncap, 719216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt passwd_id, 720216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid, 721216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid_len, 0, 722216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 0, NULL); 723216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (msg.status && p2p->p2ps_prov) { 724216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov->status = P2P_SC_SUCCESS; 725216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg.status, sa, 726216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_mac, session_mac, group_mac, 727216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_id, session_id, conncap, 728216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt passwd_id, 729216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid, 730216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid_len, 731216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 0, 0, NULL); 732216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (msg.status) { 733216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (auto_accept && reject == P2P_SC_SUCCESS) { 734216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS, 735216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt sa, adv_mac, session_mac, 736216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_mac, adv_id, session_id, 737216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap, passwd_id, 738216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid, 739216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid_len, 740216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 0, 0, NULL); 741216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE && 742216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (!msg.session_info || !msg.session_info_len)) { 743216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov->method = msg.wps_config_methods; 744216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 745216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS, 746216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt sa, adv_mac, session_mac, 747216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_mac, adv_id, session_id, 748216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap, passwd_id, 749216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid, 750216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid_len, 751216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 0, 1, NULL); 752216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) { 753216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t buf_len = msg.session_info_len; 754216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt char *buf = os_malloc(2 * buf_len + 1); 755216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 756216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (buf) { 757216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov->method = msg.wps_config_methods; 758216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 759216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt utf8_escape((char *) msg.session_info, buf_len, 760216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt buf, 2 * buf_len + 1); 761216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 762216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->p2ps_prov_complete( 763216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->cb_ctx, P2P_SC_SUCCESS, sa, 764216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_mac, session_mac, group_mac, adv_id, 765216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt session_id, conncap, passwd_id, 766216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid, msg.persistent_ssid_len, 767216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 0, 1, buf); 768216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 769216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_free(buf); 770216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 771216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 772216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 773216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (reject == P2P_SC_SUCCESS && p2p->cfg->prov_disc_req) { 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *dev_addr = sa; 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev_addr = msg.p2p_device_addr; 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->prov_disc_req(p2p->cfg->cb_ctx, sa, 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.wps_config_methods, 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev_addr, msg.pri_dev_type, 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.device_name, msg.config_methods, 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.capability ? msg.capability[0] : 0, 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.capability ? msg.capability[1] : 7831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 0, 7841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt msg.group_id, msg.group_id_len); 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len) 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 795444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt u16 report_config_methods = 0, req_config_methods; 796216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 status = P2P_SC_SUCCESS; 79704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int success = 0; 798216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u32 adv_id = 0; 799216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 conncap = P2PS_SETUP_NEW; 800216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 adv_mac[ETH_ALEN]; 801216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 group_mac[ETH_ALEN]; 802216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt int passwd_id = DEV_PW_DEFAULT; 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse(data, len, &msg)) 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 807216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Parse the P2PS members present */ 808216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (msg.status) 809216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt status = *msg.status; 810216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 811216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (msg.intended_addr) 812216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(group_mac, msg.intended_addr, ETH_ALEN); 813216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else 814216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memset(group_mac, 0, ETH_ALEN); 815216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 816216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (msg.adv_mac) 817216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN); 818216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else 819216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memset(adv_mac, 0, ETH_ALEN); 820216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 821216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (msg.adv_id) 822216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_id = WPA_GET_LE32(msg.adv_id); 823216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 824216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (msg.conn_cap) { 825216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = *msg.conn_cap; 826216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 827216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Switch bits to local relative */ 828216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt switch (conncap) { 829216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2PS_SETUP_GROUP_OWNER: 830216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = P2PS_SETUP_CLIENT; 831216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 832216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2PS_SETUP_CLIENT: 833216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap = P2PS_SETUP_GROUP_OWNER; 834216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 835216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 836216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 837216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 838b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Received Provision Discovery Response from " MACSTR 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " with config methods 0x%x", 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa), msg.wps_config_methods); 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, sa); 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || !dev->req_config_methods) { 844b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore Provision Discovery Response from " MACSTR 845b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " with no pending request", MAC2STR(sa)); 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->dialog_token != msg.dialog_token) { 851b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Ignore Provision Discovery Response with unexpected Dialog Token %u (expected %u)", 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.dialog_token, dev->dialog_token); 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 85791c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt if (p2p->pending_action_state == P2P_PENDING_PD) { 85891c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN); 85991c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt p2p->pending_action_state = P2P_NO_PENDING_ACTION; 86091c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt } 86191c40cdce17424d9a4718876becf0b7811cf68f2Dmitry Shmidt 86275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 863444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt * Use a local copy of the requested config methods since 864444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt * p2p_reset_pending_pd() can clear this in the peer entry. 865444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt */ 866444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt req_config_methods = dev->req_config_methods; 867444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 868444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt /* 86975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * If the response is from the peer to whom a user initiated request 87075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * was sent earlier, we reset that state info here. 87175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 87275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->user_initiated_pd && 87375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_memcmp(p2p->pending_pd_devaddr, sa, ETH_ALEN) == 0) 87475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p_reset_pending_pd(p2p); 87575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 876444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (msg.wps_config_methods != req_config_methods) { 877b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer rejected our Provision Discovery Request (received config_methods 0x%x expected 0x%x", 878444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt msg.wps_config_methods, req_config_methods); 87975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (p2p->cfg->prov_disc_fail) 88075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa, 881216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_PROV_DISC_REJECTED, 882216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_id, adv_mac, NULL); 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 884a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2ps_prov_free(p2p); 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 888444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt report_config_methods = req_config_methods; 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY | 890216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_DEV_PD_PEER_KEYPAD | 891216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_DEV_PD_PEER_P2PS); 892444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (req_config_methods & WPS_CONFIG_DISPLAY) { 893b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " accepted to show a PIN on display", MAC2STR(sa)); 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_DISPLAY; 896216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt passwd_id = DEV_PW_REGISTRAR_SPECIFIED; 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) { 898b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " accepted to write our PIN using keypad", 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sa)); 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_KEYPAD; 902216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt passwd_id = DEV_PW_USER_SPECIFIED; 903216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (msg.wps_config_methods & WPS_CONFIG_P2PS) { 904216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "Peer " MACSTR " accepted P2PS PIN", 905216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(sa)); 906216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->flags |= P2P_DEV_PD_PEER_P2PS; 907216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt passwd_id = DEV_PW_P2PS_DEFAULT; 908216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 909216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 910216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if ((msg.conn_cap || msg.persistent_dev) && 911216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.adv_id && 912216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt (status == P2P_SC_SUCCESS || status == P2P_SC_SUCCESS_DEFERRED) && 913216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov) { 914216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->cfg->p2ps_prov_complete) { 915216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->p2ps_prov_complete( 916216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->cb_ctx, status, sa, adv_mac, 917216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov->session_mac, 918216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_mac, adv_id, p2p->p2ps_prov->session_id, 919216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt conncap, passwd_id, msg.persistent_ssid, 920216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg.persistent_ssid_len, 1, 0, NULL); 921216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 922a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2ps_prov_free(p2p); 923216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 924216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 925216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (status != P2P_SC_SUCCESS && 926216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE && 927216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt status != P2P_SC_SUCCESS_DEFERRED && p2p->p2ps_prov) { 928216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->cfg->p2ps_prov_complete) 929216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->p2ps_prov_complete( 930216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->cb_ctx, status, sa, adv_mac, 931216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov->session_mac, 932216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt group_mac, adv_id, p2p->p2ps_prov->session_id, 933216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 0, 0, NULL, 0, 1, 0, NULL); 934a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2ps_prov_free(p2p); 935216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 936216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 937216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) { 938216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->cfg->remove_stale_groups) { 939216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->remove_stale_groups(p2p->cfg->cb_ctx, 940216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->info.p2p_device_addr, 941216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt NULL, NULL, 0); 942216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 943216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 944216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (msg.session_info && msg.session_info_len) { 945216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt size_t info_len = msg.session_info_len; 946216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt char *deferred_sess_resp = os_malloc(2 * info_len + 1); 947216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 948216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!deferred_sess_resp) { 949216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_parse_free(&msg); 950a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2ps_prov_free(p2p); 951216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt goto out; 952216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 953216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt utf8_escape((char *) msg.session_info, info_len, 954216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt deferred_sess_resp, 2 * info_len + 1); 955216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 956216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->cfg->prov_disc_fail) 957216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->prov_disc_fail( 958216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->cb_ctx, sa, 959216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_PROV_DISC_INFO_UNAVAILABLE, 960216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_id, adv_mac, 961216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt deferred_sess_resp); 962216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_free(deferred_sess_resp); 963216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else 964216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->cfg->prov_disc_fail) 965216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->prov_disc_fail( 966216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->cb_ctx, sa, 967216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_PROV_DISC_INFO_UNAVAILABLE, 968216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt adv_id, adv_mac, NULL); 969216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else if (msg.wps_config_methods != dev->req_config_methods || 970216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt status != P2P_SC_SUCCESS) { 971216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, "Peer rejected our Provision Discovery Request"); 972216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->cfg->prov_disc_fail) 973216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa, 974216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt P2P_PROV_DISC_REJECTED, 0, 975216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt NULL, NULL); 976216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_parse_free(&msg); 977a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2ps_prov_free(p2p); 978216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt goto out; 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Store the provisioning info */ 9821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = msg.wps_config_methods; 9831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(&msg); 98504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt success = 1; 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtout: 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods = 0; 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 99004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) { 991b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Start GO Neg after the PD-before-GO-Neg workaround with " 992b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR, MAC2STR(dev->info.p2p_device_addr)); 99304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG; 99404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_connect_send(p2p, dev); 99504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 99604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 99704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (success && p2p->cfg->prov_disc_resp) 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa, 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt report_config_methods); 100037d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 100137d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt if (p2p->state == P2P_PD_DURING_FIND) { 100237d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt p2p_clear_timeout(p2p); 100337d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt p2p_continue_find(p2p); 100437d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt } 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev, 10091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int join, int force_freq) 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freq; 1013497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt 10141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (force_freq > 0) 10151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt freq = force_freq; 10161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 10171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt freq = dev->listen_freq > 0 ? dev->listen_freq : 10181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->oper_freq; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (freq <= 0) { 1020b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "No Listen/Operating frequency known for the peer " 1021b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR " to send Provision Discovery Request", 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(dev->info.dev_capab & 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { 1029b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Cannot use PD with P2P Device " MACSTR 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " that is in a group and is not discoverable", 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dev->info.p2p_device_addr)); 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: use device discoverability request through GO */ 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1037216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->p2ps_prov) { 1038216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED) { 1039216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->p2ps_prov->method == WPS_CONFIG_DISPLAY) 1040216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->req_config_methods = WPS_CONFIG_KEYPAD; 1041216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else if (p2p->p2ps_prov->method == WPS_CONFIG_KEYPAD) 1042216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->req_config_methods = WPS_CONFIG_DISPLAY; 1043216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else 1044216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->req_config_methods = WPS_CONFIG_P2PS; 1045216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else { 1046216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Order of preference, based on peer's capabilities */ 1047216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2p->p2ps_prov->method) 1048216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->req_config_methods = 1049216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov->method; 1050216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else if (dev->info.config_methods & WPS_CONFIG_P2PS) 1051216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->req_config_methods = WPS_CONFIG_P2PS; 1052216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else if (dev->info.config_methods & WPS_CONFIG_DISPLAY) 1053216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->req_config_methods = WPS_CONFIG_DISPLAY; 1054216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt else 1055216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->req_config_methods = WPS_CONFIG_KEYPAD; 1056216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1057216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p_dbg(p2p, 1058216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "Building PD Request based on P2PS config method 0x%x status %d --> req_config_methods 0x%x", 1059216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov->method, p2p->p2ps_prov->status, 1060216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt dev->req_config_methods); 1061216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1062216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1063216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt req = p2p_build_prov_disc_req(p2p, dev, join); 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 106704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (p2p->state != P2P_IDLE) 106804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p2p_stop_listen_for_freq(p2p, freq); 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->pending_action_state = P2P_PENDING_PD; 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr, 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p->cfg->dev_addr, dev->info.p2p_device_addr, 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(req), wpabuf_len(req), 200) < 0) { 1073b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Failed to send Action frame"); 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 107875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN); 107975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(req); 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_prov_disc_req(struct p2p_data *p2p, const u8 *peer_addr, 1086216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt struct p2ps_provision *p2ps_prov, 1087d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u16 config_methods, int join, int force_freq, 1088d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int user_initiated_pd) 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_device *dev; 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device(p2p, peer_addr); 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL) 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev = p2p_get_device_interface(p2p, peer_addr); 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 1096b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request destination " MACSTR 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " not yet known", MAC2STR(peer_addr)); 1098216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_free(p2ps_prov); 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1102b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Provision Discovery Request with " MACSTR 1103b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt " (config methods 0x%x)", 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), config_methods); 1105216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (config_methods == 0 && !p2ps_prov) { 1106216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_free(p2ps_prov); 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1108216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 1109216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 1110216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (p2ps_prov && p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED && 1111216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov) { 1112216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt /* Use cached method from deferred provisioning */ 1113216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2ps_prov->method = p2p->p2ps_prov->method; 1114216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Reset provisioning info */ 11171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->wps_prov_info = 0; 1118a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2ps_prov_free(p2p); 1119216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt p2p->p2ps_prov = p2ps_prov; 11201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->req_config_methods = config_methods; 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (join) 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags |= P2P_DEV_PD_FOR_JOIN; 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dev->flags &= ~P2P_DEV_PD_FOR_JOIN; 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1127c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH && 1128c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt p2p->state != P2P_LISTEN_ONLY) { 1129b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt p2p_dbg(p2p, "Busy with other operations; postpone Provision Discovery Request with " 1130b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt MACSTR " (config methods 0x%x)", 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(peer_addr), config_methods); 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1135d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt p2p->user_initiated_pd = user_initiated_pd; 1136051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt p2p->pd_force_freq = force_freq; 113775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 113861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (p2p->user_initiated_pd) 113975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES; 114075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 1141a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt /* 1142a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Assign dialog token here to use the same value in each retry within 1143a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * the same PD exchange. 1144a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 1145a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->dialog_token++; 1146a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (dev->dialog_token == 0) 1147a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt dev->dialog_token = 1; 1148a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 11491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return p2p_send_prov_disc_req(p2p, dev, join, force_freq); 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 115175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 115275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 115375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenvoid p2p_reset_pending_pd(struct p2p_data *p2p) 115475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen{ 11551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct p2p_device *dev; 11561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 11581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_memcmp(p2p->pending_pd_devaddr, 11591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->info.p2p_device_addr, ETH_ALEN)) 11601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 11611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!dev->req_config_methods) 11621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 11631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (dev->flags & P2P_DEV_PD_FOR_JOIN) 11641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 11651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Reset the config methods of the device */ 11661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dev->req_config_methods = 0; 11671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 116975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->user_initiated_pd = 0; 117075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN); 117175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen p2p->pd_retries = 0; 1172051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt p2p->pd_force_freq = 0; 117375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen} 1174a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt 1175a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt 1176a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidtvoid p2ps_prov_free(struct p2p_data *p2p) 1177a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt{ 1178a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt os_free(p2p->p2ps_prov); 1179a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt p2p->p2ps_prov = NULL; 1180a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt} 1181