#include "eap_peer/eap.h"
#include "wpa_supplicant_i.h"
#include "eloop.h"
+#include "wpa_ctrl.h"
#include "eap_common/eap_wsc_common.h"
#include "wps/wps.h"
#include "wps/wps_defs.h"
static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx);
+static void wpas_clear_wps(struct wpa_supplicant *wpa_s);
int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
struct wpa_supplicant *wpa_s = ctx;
struct wpa_ssid *ssid = wpa_s->current_ssid;
- wpa_msg(wpa_s, MSG_INFO, "WPS: New credential received");
+ wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_CRED_RECEIVED);
if (ssid && (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
wpa_printf(MSG_DEBUG, "WPS: Replace WPS network block based "
}
+static void wpa_supplicant_wps_event_m2d(struct wpa_supplicant *wpa_s,
+ struct wps_event_m2d *m2d)
+{
+ wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_M2D
+ "dev_password_id=%d config_error=%d",
+ m2d->dev_password_id, m2d->config_error);
+}
+
+
+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);
+ wpas_clear_wps(wpa_s);
+}
+
+
+static void wpa_supplicant_wps_event_success(struct wpa_supplicant *wpa_s)
+{
+ wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_SUCCESS);
+}
+
+
+static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
+ union wps_event_data *data)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+ switch (event) {
+ case WPS_EV_M2D:
+ wpa_supplicant_wps_event_m2d(wpa_s, &data->m2d);
+ break;
+ case WPS_EV_FAIL:
+ wpa_supplicant_wps_event_fail(wpa_s, &data->fail);
+ break;
+ case WPS_EV_SUCCESS:
+ wpa_supplicant_wps_event_success(wpa_s);
+ break;
+ }
+}
+
+
u8 wpas_wps_get_req_type(struct wpa_ssid *ssid)
{
if (eap_is_wps_pbc_enrollee(&ssid->eap) ||
/* Remove any existing WPS network from configuration */
ssid = wpa_s->conf->ssid;
while (ssid) {
- if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
+ if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
+ if (ssid == wpa_s->current_ssid)
+ wpa_s->current_ssid = NULL;
id = ssid->id;
- else
+ } else
id = -1;
ssid = ssid->next;
if (id >= 0)
struct wpa_scan_res *res;
os_memcpy(ssid->bssid, bssid, ETH_ALEN);
+ ssid->bssid_set = 1;
/* Try to get SSID from scan results */
if (wpa_s->scan_res == NULL &&
return -1;
wps->cred_cb = wpa_supplicant_wps_cred;
+ wps->event_cb = wpa_supplicant_wps_event;
wps->cb_ctx = wpa_s;
wps->dev.device_name = wpa_s->conf->device_name;
}
}
+ if (!ret && ssid->bssid_set &&
+ os_memcmp(ssid->bssid, bss->bssid, ETH_ALEN) == 0) {
+ /* allow wildcard SSID due to hardcoded BSSID match */
+ ret = 1;
+ }
+
wpabuf_free(wps_ie);
return ret;
}
/* TODO: verify that this is reasonable dual-band situation */
+
+ wpabuf_free(ie);
}
wpabuf_free(wps_ie);
return ret;
}
+
+
+void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s)
+{
+ size_t i;
+
+ if (wpa_s->disconnected || wpa_s->wpa_state >= WPA_ASSOCIATED)
+ return;
+
+ for (i = 0; i < wpa_s->scan_res->num; i++) {
+ struct wpa_scan_res *bss = wpa_s->scan_res->res[i];
+ struct wpabuf *ie;
+ ie = wpa_scan_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE);
+ if (!ie)
+ continue;
+ if (wps_is_selected_pbc_registrar(ie))
+ wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PBC);
+ else if (wps_is_selected_pin_registrar(ie))
+ wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE_PIN);
+ else
+ wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_AP_AVAILABLE);
+ wpabuf_free(ie);
+ break;
+ }
+}
+
+
+int wpas_wps_searching(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_ssid *ssid;
+
+ for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
+ if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && !ssid->disabled)
+ return 1;
+ }
+
+ return 0;
+}