p2p_pd.c revision 444d567b27731d8572ef37697dd12fd1c37c2f24
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Wi-Fi Direct - P2P provision discovery 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2009-2010, Atheros Communications 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This software may be distributed under the terms of the BSD license. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See README for more details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "includes.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "common.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "common/ieee802_11_defs.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "wps/wps_defs.h" 148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "p2p_i.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "p2p.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Number of retries to attempt for provision discovery requests 2023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * in case the peer is not listening. 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define MAX_PROV_DISC_REQ_RETRIES 120 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void p2p_build_wps_ie_config_methods(struct wpabuf *buf, 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) u16 config_methods) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u8 *len; 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) len = wpabuf_put(buf, 1); 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) wpabuf_put_be32(buf, WPS_DEV_OUI_WFA); 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Config Methods */ 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) wpabuf_put_be16(buf, ATTR_CONFIG_METHODS); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpabuf_put_be16(buf, 2); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpabuf_put_be16(buf, config_methods); 378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p_buf_update_ie_hdr(buf, len); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u8 dialog_token, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u16 config_methods, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct p2p_device *go) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct wpabuf *buf; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u8 *len; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t extra = 0; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef CONFIG_WIFI_DISPLAY 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p2p->wfd_ie_prov_disc_req) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra = wpabuf_len(p2p->wfd_ie_prov_disc_req); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* CONFIG_WIFI_DISPLAY */ 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf = wpabuf_alloc(1000 + extra); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buf == NULL) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) len = p2p_buf_add_ie_hdr(buf); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p2p_buf_add_capability(buf, p2p->dev_capab & 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p2p_buf_add_device_info(buf, p2p, NULL); 668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (go) { 678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) p2p_buf_add_group_id(buf, go->info.p2p_device_addr, 688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) go->oper_ssid, go->oper_ssid_len); 698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p2p_buf_update_ie_hdr(buf, len); 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* WPS IE with Config Methods attribute */ 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p2p_build_wps_ie_config_methods(buf, config_methods); 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef CONFIG_WIFI_DISPLAY 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p2p->wfd_ie_prov_disc_req) 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) wpabuf_put_buf(buf, p2p->wfd_ie_prov_disc_req); 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif /* CONFIG_WIFI_DISPLAY */ 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return buf; 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p, 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) u8 dialog_token, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u16 config_methods, 87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const u8 *group_id, 88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size_t group_id_len) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct wpabuf *buf; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t extra = 0; 92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#ifdef CONFIG_WIFI_DISPLAY 94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch struct wpabuf *wfd_ie = p2p->wfd_ie_prov_disc_resp; 95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (wfd_ie && group_id) { 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size_t i; 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (i = 0; i < p2p->num_groups; i++) { 98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch struct p2p_group *g = p2p->groups[i]; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct wpabuf *ie; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!p2p_group_is_group_id_match(g, group_id, 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) group_id_len)) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ie = p2p_group_get_wfd_ie(g); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ie) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wfd_ie = ie; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (wfd_ie) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extra = wpabuf_len(wfd_ie); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* CONFIG_WIFI_DISPLAY */ 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buf = wpabuf_alloc(100 + extra); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buf == NULL) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_RESP, dialog_token); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* WPS IE with Config Methods attribute */ 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p2p_build_wps_ie_config_methods(buf, config_methods); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef CONFIG_WIFI_DISPLAY 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (wfd_ie) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpabuf_put_buf(buf, wfd_ie); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* CONFIG_WIFI_DISPLAY */ 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return buf; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const u8 *data, size_t len, int rx_freq) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct p2p_message msg; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct p2p_device *dev; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int freq; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int reject = 1; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct wpabuf *resp; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (p2p_parse(data, len, &msg)) 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "P2P: Received Provision Discovery Request from " MACSTR 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " with config methods 0x%x (freq=%d)", 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAC2STR(sa), msg.wps_config_methods, rx_freq); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dev = p2p_get_device(p2p, sa); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "P2P: Provision Discovery Request from " 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "unknown peer " MACSTR, MAC2STR(sa)); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (p2p_add_device(p2p, sa, rx_freq, NULL, 0, data + 1, len - 1, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0)) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "P2P: Provision Discovery Request add device " 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "failed " MACSTR, MAC2STR(sa)); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 161a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } else if (msg.wfd_subelems) { 162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) wpabuf_free(dev->info.wfd_subelems); 163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems); 164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(msg.wps_config_methods & 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD | 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WPS_CONFIG_PUSHBUTTON))) { 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unsupported " 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "Config Methods in Provision Discovery Request"); 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) goto out; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (msg.group_id) { 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t i; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < p2p->num_groups; i++) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p2p_group_is_group_id_match(p2p->groups[i], 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) msg.group_id, 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) msg.group_id_len)) 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (i == p2p->num_groups) { 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: PD " 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "request for unknown P2P Group ID - reject"); 1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) goto out; 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (dev) 1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY | 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) P2P_DEV_PD_PEER_KEYPAD); 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (msg.wps_config_methods & WPS_CONFIG_DISPLAY) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " requested us to show a PIN on display", MAC2STR(sa)); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dev) 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dev->flags |= P2P_DEV_PD_PEER_KEYPAD; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) { 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) " requested us to write its PIN using keypad", 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAC2STR(sa)); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dev) 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dev->flags |= P2P_DEV_PD_PEER_DISPLAY; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reject = 0; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)out: 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resp = p2p_build_prov_disc_resp(p2p, msg.dialog_token, 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reject ? 0 : msg.wps_config_methods, 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg.group_id, msg.group_id_len); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (resp == NULL) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p_parse_free(&msg); 2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 2148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "P2P: Sending Provision Discovery Response"); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rx_freq > 0) 2188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) freq = rx_freq; 2198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) else 2208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) freq = p2p_channel_to_freq(p2p->cfg->country, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p->cfg->reg_class, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p->cfg->channel); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (freq < 0) { 2248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "P2P: Unknown regulatory class/channel"); 2268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) wpabuf_free(resp); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p_parse_free(&msg); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) p2p->pending_action_state = P2P_NO_PENDING_ACTION; 2318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, 2328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) p2p->cfg->dev_addr, 2338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { 2348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "P2P: Failed to send Action frame"); 2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpabuf_free(resp); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!reject && p2p->cfg->prov_disc_req) { 2418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const u8 *dev_addr = sa; 2428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (msg.p2p_device_addr) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dev_addr = msg.p2p_device_addr; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p->cfg->prov_disc_req(p2p->cfg->cb_ctx, sa, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg.wps_config_methods, 2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) dev_addr, msg.pri_dev_type, 2478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) msg.device_name, msg.config_methods, 2488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) msg.capability ? msg.capability[0] : 0, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg.capability ? msg.capability[1] : 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg.group_id, msg.group_id_len); 2528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 2538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) p2p_parse_free(&msg); 2548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, 2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const u8 *data, size_t len) 2598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles){ 2608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) struct p2p_message msg; 2618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) struct p2p_device *dev; 2628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) u16 report_config_methods = 0, req_config_methods; 2638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int success = 0; 2648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p2p_parse(data, len, &msg)) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "P2P: Received Provision Discovery Response from " MACSTR 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " with config methods 0x%x", 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAC2STR(sa), msg.wps_config_methods); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dev = p2p_get_device(p2p, sa); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dev == NULL || !dev->req_config_methods) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "P2P: Ignore Provision Discovery Response from " 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MACSTR " with no pending request", MAC2STR(sa)); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p_parse_free(&msg); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (dev->dialog_token != msg.dialog_token) { 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "P2P: Ignore Provision Discovery Response with " 28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "unexpected Dialog Token %u (expected %u)", 28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) msg.dialog_token, dev->dialog_token); 28758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) p2p_parse_free(&msg); 28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (p2p->pending_action_state == P2P_PENDING_PD) { 2920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN); 2930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch p2p->pending_action_state = P2P_NO_PENDING_ACTION; 2940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /* 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use a local copy of the requested config methods since 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * p2p_reset_pending_pd() can clear this in the peer entry. 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) req_config_methods = dev->req_config_methods; 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /* 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * If the response is from the peer to whom a user initiated request 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * was sent earlier, we reset that state info here. 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p2p->user_initiated_pd && 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) os_memcmp(p2p->pending_pd_devaddr, sa, ETH_ALEN) == 0) 3088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) p2p_reset_pending_pd(p2p); 3098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (msg.wps_config_methods != req_config_methods) { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer rejected " 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "our Provision Discovery Request (received " 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "config_methods 0x%x expected 0x%x", 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg.wps_config_methods, req_config_methods); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p2p->cfg->prov_disc_fail) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa, 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) P2P_PROV_DISC_REJECTED); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p_parse_free(&msg); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto out; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report_config_methods = req_config_methods; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY | 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) P2P_DEV_PD_PEER_KEYPAD); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (req_config_methods & WPS_CONFIG_DISPLAY) { 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " accepted to show a PIN on display", MAC2STR(sa)); 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dev->flags |= P2P_DEV_PD_PEER_DISPLAY; 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) { 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " MACSTR 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " accepted to write our PIN using keypad", 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MAC2STR(sa)); 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dev->flags |= P2P_DEV_PD_PEER_KEYPAD; 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Store the provisioning info */ 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dev->wps_prov_info = msg.wps_config_methods; 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p_parse_free(&msg); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = 1; 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)out: 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dev->req_config_methods = 0; 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p2p->cfg->send_action_done(p2p->cfg->cb_ctx); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "P2P: Start GO Neg after the PD-before-GO-Neg " 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "workaround with " MACSTR, 3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MAC2STR(dev->info.p2p_device_addr)); 350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p_connect_send(p2p, dev); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 353ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (success && p2p->cfg->prov_disc_resp) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa, 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) report_config_methods); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p2p->state == P2P_PD_DURING_FIND) { 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p2p_clear_timeout(p2p); 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p2p_continue_find(p2p); 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev, 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int join, int force_freq) 367{ 368 struct wpabuf *req; 369 int freq; 370 371 if (force_freq > 0) 372 freq = force_freq; 373 else 374 freq = dev->listen_freq > 0 ? dev->listen_freq : 375 dev->oper_freq; 376 if (freq <= 0) { 377 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 378 "P2P: No Listen/Operating frequency known for the " 379 "peer " MACSTR " to send Provision Discovery Request", 380 MAC2STR(dev->info.p2p_device_addr)); 381 return -1; 382 } 383 384 if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { 385 if (!(dev->info.dev_capab & 386 P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { 387 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 388 "P2P: Cannot use PD with P2P Device " MACSTR 389 " that is in a group and is not discoverable", 390 MAC2STR(dev->info.p2p_device_addr)); 391 return -1; 392 } 393 /* TODO: use device discoverability request through GO */ 394 } 395 396 req = p2p_build_prov_disc_req(p2p, dev->dialog_token, 397 dev->req_config_methods, 398 join ? dev : NULL); 399 if (req == NULL) 400 return -1; 401 402 if (p2p->state != P2P_IDLE) 403 p2p_stop_listen_for_freq(p2p, freq); 404 p2p->pending_action_state = P2P_PENDING_PD; 405 if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr, 406 p2p->cfg->dev_addr, dev->info.p2p_device_addr, 407 wpabuf_head(req), wpabuf_len(req), 200) < 0) { 408 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, 409 "P2P: Failed to send Action frame"); 410 wpabuf_free(req); 411 return -1; 412 } 413 414 os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN); 415 416 wpabuf_free(req); 417 return 0; 418} 419 420 421int p2p_prov_disc_req(struct p2p_data *p2p, const u8 *peer_addr, 422 u16 config_methods, int join, int force_freq, 423 int user_initiated_pd) 424{ 425 struct p2p_device *dev; 426 427 dev = p2p_get_device(p2p, peer_addr); 428 if (dev == NULL) 429 dev = p2p_get_device_interface(p2p, peer_addr); 430 if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 431 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Provision " 432 "Discovery Request destination " MACSTR 433 " not yet known", MAC2STR(peer_addr)); 434 return -1; 435 } 436 437 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Provision Discovery " 438 "Request with " MACSTR " (config methods 0x%x)", 439 MAC2STR(peer_addr), config_methods); 440 if (config_methods == 0) 441 return -1; 442 443 /* Reset provisioning info */ 444 dev->wps_prov_info = 0; 445 446 dev->req_config_methods = config_methods; 447 if (join) 448 dev->flags |= P2P_DEV_PD_FOR_JOIN; 449 else 450 dev->flags &= ~P2P_DEV_PD_FOR_JOIN; 451 452 if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH && 453 p2p->state != P2P_LISTEN_ONLY) { 454 wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Busy with other " 455 "operations; postpone Provision Discovery Request " 456 "with " MACSTR " (config methods 0x%x)", 457 MAC2STR(peer_addr), config_methods); 458 return 0; 459 } 460 461 p2p->user_initiated_pd = user_initiated_pd; 462 463 if (p2p->user_initiated_pd) 464 p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES; 465 466 /* 467 * Assign dialog token here to use the same value in each retry within 468 * the same PD exchange. 469 */ 470 dev->dialog_token++; 471 if (dev->dialog_token == 0) 472 dev->dialog_token = 1; 473 474 return p2p_send_prov_disc_req(p2p, dev, join, force_freq); 475} 476 477 478void p2p_reset_pending_pd(struct p2p_data *p2p) 479{ 480 struct p2p_device *dev; 481 482 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { 483 if (os_memcmp(p2p->pending_pd_devaddr, 484 dev->info.p2p_device_addr, ETH_ALEN)) 485 continue; 486 if (!dev->req_config_methods) 487 continue; 488 if (dev->flags & P2P_DEV_PD_FOR_JOIN) 489 continue; 490 /* Reset the config methods of the device */ 491 dev->req_config_methods = 0; 492 } 493 494 p2p->user_initiated_pd = 0; 495 os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN); 496 p2p->pd_retries = 0; 497} 498