#include "blacklist.h"
#include "bss.h"
#include "scan.h"
+#include "ap.h"
#include "p2p/p2p.h"
#include "p2p_supplicant.h"
#include "wps_supplicant.h"
static void wpa_supplicant_wps_event_fail(struct wpa_supplicant *wpa_s,
struct wps_event_fail *fail)
{
- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL "msg=%d", fail->msg);
+ wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL "msg=%d config_error=%d",
+ fail->msg, fail->config_error);
+ if (wpa_s->parent && wpa_s->parent != wpa_s)
+ wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
+ "msg=%d config_error=%d",
+ fail->msg, fail->config_error);
wpas_clear_wps(wpa_s);
wpas_notify_wps_event_fail(wpa_s, fail);
}
static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
- wpa_printf(MSG_INFO, WPS_EVENT_TIMEOUT "Requested operation timed "
- "out");
+ wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_TIMEOUT "Requested operation timed "
+ "out");
wpas_clear_wps(wpa_s);
}
}
+/* Cancel the wps pbc/pin requests */
+int wpas_wps_cancel(struct wpa_supplicant *wpa_s)
+{
+#ifdef CONFIG_AP
+ if (wpa_s->ap_iface) {
+ wpa_printf(MSG_DEBUG, "WPS: Cancelling in AP mode");
+ return wpa_supplicant_ap_wps_cancel(wpa_s);
+ }
+#endif /* CONFIG_AP */
+
+ if (wpa_s->wpa_state == WPA_SCANNING) {
+ wpa_printf(MSG_DEBUG, "WPS: Cancel operation - cancel scan");
+ wpa_supplicant_cancel_scan(wpa_s);
+ wpas_clear_wps(wpa_s);
+ } else if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
+ wpa_printf(MSG_DEBUG, "WPS: Cancel operation - "
+ "deauthenticate");
+ wpa_supplicant_deauthenticate(wpa_s,
+ WLAN_REASON_DEAUTH_LEAVING);
+ wpas_clear_wps(wpa_s);
+ }
+
+ return 0;
+}
+
+
#ifdef CONFIG_WPS_OOB
int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type,
char *path, char *method, char *name)
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) < 0)
+ wpabuf_head(wps->oob_conf.dev_password), 0,
+ DEV_PW_DEFAULT) < 0)
return -1;
return 0;
}
+static u16 wps_fix_config_methods(u16 config_methods)
+{
+#ifdef CONFIG_WPS2
+ if ((config_methods &
+ (WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY |
+ WPS_CONFIG_PHY_DISPLAY)) == WPS_CONFIG_DISPLAY) {
+ wpa_printf(MSG_INFO, "WPS: Converting display to "
+ "virtual_display for WPS 2.0 compliance");
+ config_methods |= WPS_CONFIG_VIRT_DISPLAY;
+ }
+ if ((config_methods &
+ (WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_VIRT_PUSHBUTTON |
+ WPS_CONFIG_PHY_PUSHBUTTON)) == WPS_CONFIG_PUSHBUTTON) {
+ wpa_printf(MSG_INFO, "WPS: Converting push_button to "
+ "virtual_push_button for WPS 2.0 compliance");
+ config_methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
+ }
+#endif /* CONFIG_WPS2 */
+
+ return config_methods;
+}
+
+
int wpas_wps_init(struct wpa_supplicant *wpa_s)
{
struct wps_context *wps;
os_free(wps);
return -1;
}
+ wps->config_methods = wps_fix_config_methods(wps->config_methods);
if (wpa_s->conf->device_type &&
wps_dev_type_str2bin(wpa_s->conf->device_type,
wps->dev.pri_dev_type) < 0) {
#ifdef CONFIG_WPS_STRICT
if (wps_ie) {
if (wps_validate_beacon_probe_resp(wps_ie, bss->beacon_ie_len >
- 0) < 0)
+ 0, bss->bssid) < 0)
ret = 0;
if (bss->beacon_ie_len) {
struct wpabuf *bcn_wps;
if (!eap_is_wps_pbc_enrollee(&ssid->eap))
return 0;
+ wpa_printf(MSG_DEBUG, "WPS: Check whether PBC session overlap is "
+ "present in scan results; selected BSSID " MACSTR,
+ MAC2STR(selected->bssid));
+
/* Make sure that only one AP is in active PBC mode */
wps_ie = wpa_bss_get_vendor_ie_multi(selected, WPS_IE_VENDOR_TYPE);
- if (wps_ie)
+ if (wps_ie) {
sel_uuid = wps_get_uuid_e(wps_ie);
- else
+ wpa_hexdump(MSG_DEBUG, "WPS: UUID of the selected BSS",
+ sel_uuid, UUID_LEN);
+ } else {
+ wpa_printf(MSG_DEBUG, "WPS: Selected BSS does not include "
+ "WPS IE?!");
sel_uuid = NULL;
+ }
dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
struct wpabuf *ie;
wpabuf_free(ie);
continue;
}
+ wpa_printf(MSG_DEBUG, "WPS: Another BSS in active PBC mode: "
+ MACSTR, MAC2STR(bss->bssid));
uuid = wps_get_uuid_e(ie);
+ wpa_hexdump(MSG_DEBUG, "WPS: UUID of the other BSS",
+ uuid, UUID_LEN);
if (sel_uuid == NULL || uuid == NULL ||
- os_memcmp(sel_uuid, uuid, 16) != 0) {
+ os_memcmp(sel_uuid, uuid, UUID_LEN) != 0) {
ret = 1; /* PBC overlap */
+ wpa_msg(wpa_s, MSG_INFO, "WPS: PBC overlap detected: "
+ MACSTR " and " MACSTR,
+ MAC2STR(selected->bssid),
+ MAC2STR(bss->bssid));
wpabuf_free(ie);
break;
}
wps->config_methods &= ~WPS_CONFIG_LABEL;
}
}
+ wps->config_methods = wps_fix_config_methods(wps->config_methods);
if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE) {
if (wpa_s->conf->device_type &&