#include "blacklist.h"
#include "bss.h"
#include "scan.h"
+#include "p2p_supplicant.h"
#include "wps_supplicant.h"
ssid->eap.phase1 = NULL;
os_free(ssid->eap.eap_methods);
ssid->eap.eap_methods = NULL;
+ if (!ssid->p2p_group)
+ ssid->temporary = 0;
} else {
wpa_printf(MSG_DEBUG, "WPS: Create a new network based on the "
"received credential");
wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_SUCCESS);
wpa_s->wps_success = 1;
wpas_notify_wps_event_success(wpa_s);
+#ifdef CONFIG_P2P
+ wpas_p2p_wps_success(wpa_s, wpa_s->bssid, 0);
+#endif /* CONFIG_P2P */
}
return NULL;
wpas_notify_network_added(wpa_s, ssid);
wpa_config_set_network_defaults(ssid);
+ ssid->temporary = 1;
if (wpa_config_set(ssid, "key_mgmt", "WPS", 0) < 0 ||
wpa_config_set(ssid, "eap", "WSC", 0) < 0 ||
wpa_config_set(ssid, "identity", registrar ?
}
if (bssid) {
+#ifndef CONFIG_P2P
struct wpa_bss *bss;
int count = 0;
+#endif /* CONFIG_P2P */
os_memcpy(ssid->bssid, bssid, ETH_ALEN);
ssid->bssid_set = 1;
+ /*
+ * Note: With P2P, the SSID may change at the time the WPS
+ * provisioning is started, so better not filter the AP based
+ * on the current SSID in the scan results.
+ */
+#ifndef CONFIG_P2P
dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
if (os_memcmp(bssid, bss->bssid, ETH_ALEN) != 0)
continue;
ssid->ssid = NULL;
ssid->ssid_len = 0;
}
+#endif /* CONFIG_P2P */
}
return ssid;
}
-int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid)
+int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
+ int p2p_group)
{
struct wpa_ssid *ssid;
wpas_clear_wps(wpa_s);
ssid = wpas_wps_add_network(wpa_s, 0, bssid);
if (ssid == NULL)
return -1;
+ ssid->temporary = 1;
+ ssid->p2p_group = p2p_group;
wpa_config_set(ssid, "phase1", "\"pbc=1\"", 0);
+ if (wpa_s->wps_fragment_size)
+ ssid->eap.fragment_size = wpa_s->wps_fragment_size;
eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
wpa_s, NULL);
wpas_wps_reassoc(wpa_s, ssid);
int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const char *pin)
+ const char *pin, int p2p_group, u16 dev_pw_id)
{
struct wpa_ssid *ssid;
char val[128];
ssid = wpas_wps_add_network(wpa_s, 0, bssid);
if (ssid == NULL)
return -1;
+ ssid->temporary = 1;
+ ssid->p2p_group = p2p_group;
if (pin)
- os_snprintf(val, sizeof(val), "\"pin=%s\"", pin);
+ os_snprintf(val, sizeof(val), "\"pin=%s dev_pw_id=%u\"",
+ pin, dev_pw_id);
else {
rpin = wps_generate_pin();
- os_snprintf(val, sizeof(val), "\"pin=%08d\"", rpin);
+ os_snprintf(val, sizeof(val), "\"pin=%08d dev_pw_id=%u\"",
+ rpin, dev_pw_id);
}
wpa_config_set(ssid, "phase1", val, 0);
+ if (wpa_s->wps_fragment_size)
+ ssid->eap.fragment_size = wpa_s->wps_fragment_size;
eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
wpa_s, NULL);
wpas_wps_reassoc(wpa_s, ssid);
if ((wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E ||
wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_R) &&
wpas_wps_start_pin(wpa_s, NULL,
- wpabuf_head(wps->oob_conf.dev_password)) < 0)
+ wpabuf_head(wps->oob_conf.dev_password), 0) < 0)
return -1;
return 0;
ssid = wpas_wps_add_network(wpa_s, 1, bssid);
if (ssid == NULL)
return -1;
+ ssid->temporary = 1;
pos = val;
end = pos + sizeof(val);
res = os_snprintf(pos, end - pos, "\"pin=%s", pin);
if (res < 0 || res >= end - pos)
return -1;
wpa_config_set(ssid, "phase1", val, 0);
+ if (wpa_s->wps_fragment_size)
+ ssid->eap.fragment_size = wpa_s->wps_fragment_size;
eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
wpa_s, NULL);
wpas_wps_reassoc(wpa_s, ssid);
if (wpa_s->wps_er == NULL)
return;
+ wpa_printf(MSG_DEBUG, "WPS ER: SetSelectedRegistrar - sel_reg=%d "
+ "dev_password_id=%u sel_reg_config_methods=0x%x",
+ sel_reg, dev_passwd_id, sel_reg_config_methods);
wps_er_set_sel_reg(wpa_s->wps_er, sel_reg, dev_passwd_id,
sel_reg_config_methods);
#endif /* CONFIG_WPS_ER */
ret = 1;
}
+#ifdef CONFIG_WPS_STRICT
+ if (wps_ie) {
+ if (wps_validate_beacon_probe_resp(wps_ie, bss->beacon_ie_len >
+ 0) < 0)
+ ret = 0;
+ if (bss->beacon_ie_len) {
+ struct wpabuf *bcn_wps;
+ bcn_wps = wpa_scan_get_vendor_ie_multi_beacon(
+ bss, WPS_IE_VENDOR_TYPE);
+ if (bcn_wps == NULL) {
+ wpa_printf(MSG_DEBUG, "WPS: Mandatory WPS IE "
+ "missing from AP Beacon");
+ ret = 0;
+ } else {
+ if (wps_validate_beacon(wps_ie) < 0)
+ ret = 0;
+ wpabuf_free(bcn_wps);
+ }
+ }
+ }
+#endif /* CONFIG_WPS_STRICT */
+
wpabuf_free(wps_ie);
return ret;
return 0;
}
+
+
+void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
+{
+ struct wps_context *wps = wpa_s->wps;
+
+ if (wps == NULL)
+ return;
+
+ if (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS) {
+ wps->config_methods = wps_config_methods_str2bin(
+ wpa_s->conf->config_methods);
+ if ((wps->config_methods &
+ (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) ==
+ (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) {
+ wpa_printf(MSG_ERROR, "WPS: Both Label and Display "
+ "config methods are not allowed at the "
+ "same time");
+ wps->config_methods &= ~WPS_CONFIG_LABEL;
+ }
+ }
+
+ if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE) {
+ if (wpa_s->conf->device_type &&
+ wps_dev_type_str2bin(wpa_s->conf->device_type,
+ wps->dev.pri_dev_type) < 0)
+ wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
+ }
+
+ if (wpa_s->conf->changed_parameters & CFG_CHANGED_OS_VERSION)
+ wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
+
+ if (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID) {
+ if (is_nil_uuid(wpa_s->conf->uuid)) {
+ uuid_gen_mac_addr(wpa_s->own_addr, wps->uuid);
+ wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC "
+ "address", wps->uuid, WPS_UUID_LEN);
+ } else
+ os_memcpy(wps->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
+ }
+}