Accumulative patch from commit 1075b2957169d8f9d6dddd7679339c751dc9515b
1075b29 P2P: Report group formation failure on error to start GO mode
b62b29e Do not block on ctrl_iface monitor events
eb7ddbf WPS: Stop SSDP service before freeing the pending entries
98cbc0a Remove forgotten Xcode defines
0b9d3b2 Interworking: Relax 3GPP info PLMN matching for MNC
c7a67a7 WPS: Disconnect when removing existing WPS network block
fe65847 EAP-EKE: Add server implementation
7e7610d EAP-EKE: Add peer implementation
489202d EAP-SAKE: Use configured server identity
a607b42 EAP-PSK: Use configured server identity
15b042b EAP-MSCHAPv2: Use configured server identity
162865b EAP-IKEv2 server: Use configured server identity
8f89d82 EAP-GPSK server: Use configured server identity
67fe933 Add server identity configuration for EAP server
06aeff5 dbus: Register the AutoScan method call at the right place
78f79fe P2P: Do not add ctrl interface for P2P_DEVICE (p2p-dev-*)
1c42b42 P2P: Fix TDLS and l2_packet init without P2P Device interface
9e6a321 Fix non-P2P build after the P2P_DEVICE changes
d53d259 Fix build with older OpenSSL versions
54d4ba4 nl80211: Silence a compiler warning with older gcc versions
2e5ba4b P2P: Derive group interface name bit more sensibly
c68f620 P2P: Create P2P Device interface if supported
851b0c5 nl80211: Do not indicate P2P_DEVICE support by default
bb4028f P2P: Ignore p2p_no_group_iface when driver advertizes P2P_DEVICE support
7940c79 nl80211: Use wdev id when cancelling wait for frame using P2P_DEVICE
f608081 nl80211: Verify P2P GO/client address with all interface addresses
5fbcb45 nl80211: Fix determining phy name for P2P Device
27ce1d6 nl80211: Fix nl80211_get_wiphy_index() for P2P Device
080585c Add support for OCSP stapling to validate server certificate
72950ed P2P: Remove a call to wpas_p2p_deinit_global()
ab7a1ad nl80211: Fix P2P group interface creating using P2P Device
fa93de4 nl80211: Use wdev_id in nl80211_create_iface_once()
fdc554b nl80211: Use wdev id to obtain P2P Device scan results
597b94f nl80211: Add .get_mac_addr() callback for P2P Device
8e12685 nl80211: Rework setting interface mode
91724d6 nl80211: Introduce i802_set_iface_flags()
eb4582f nl80211: Remove P2P Device interface upon .deinit()
f632e48 nl80211: Fix P2P Device interface initialization
e472e1b nl80211: Handle creation of P2P Device interface
01517c8 nl80211: Allow Android P2P functionality
6bae92e nl80211: Add support for P2P Device in add interface
d6dcfcd nl80211: Add a handler to create_interface
d3aaef8 nl80211: Hold wdev identification for P2P Device
7aad838 nl80211: Identify if nl80211 is capable of P2P Device abstraction
6a71413 nl80211: Rename is_p2p_interface
8393e1a nl80211: Print interface name on set_key()
80ebfd9 VLAN: Avoid access to non-existing interfaces
4345fe9 bridge: Track inter-BSS usage
459eee9 bridge: Use safe default bridge interface
2aaeedf bridge: Give bridge name in per-bss configuration
8a901d7 D-Bus: Emit signal when a station is authorized or deauthorized
9578329 Add AVG_RSSI report in signal_poll
2cc8d8f Add bandwidth and center freq info to signal_poll
1e0e943 Remove 802.11b rates only in case of P2P group operation
2090a0b nl80211: Add prints for kernel events
8743676 TDLS: Validate ext_supp_rates in copy_supp_rates
85b4eac P2P: Do not reply to 802.11b-only Probe Request frames as GO
ec7b97a Interworking: Add support for using eap_proxy offload
4331263 Fix session timeout after ANQP dummy STA entry with SME-in-driver
56cb4e1 wpadebug: Add option to ignore SSL errors
aa20e1a Remove CONFIG_NO_WPA2 build parameter
5d5c4ee Remove compiler warnings with CONFIG_NO_SCAN_PROCESSING
9aaa695 Remove compiler warnings if TDLS is enabled without WPA2
84ae1d4 Fix WNM build without WPA2
c33d5eb Fix build without WPA2 or EAP
1aef400 IBSS RSN: Implement disconnect() callback using sta_deauth()
Change-Id: I4593be5b1478f6532da917423b1d2afa95fb8020
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index a0c97f0..8515b5a 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -236,7 +236,7 @@
NEED_MD5=y
NEED_RC4=y
else
-L_CFLAGS += -DCONFIG_NO_WPA -DCONFIG_NO_WPA2
+L_CFLAGS += -DCONFIG_NO_WPA
endif
ifdef CONFIG_IBSS_RSN
@@ -286,10 +286,6 @@
NEED_GAS=y
endif
-ifdef CONFIG_NO_WPA2
-L_CFLAGS += -DCONFIG_NO_WPA2
-endif
-
include $(LOCAL_PATH)/src/drivers/drivers.mk
ifdef CONFIG_AP
@@ -601,6 +597,22 @@
NEED_SHA256=y
endif
+ifdef CONFIG_EAP_EKE
+# EAP-EKE
+ifeq ($(CONFIG_EAP_EKE), dyn)
+L_CFLAGS += -DEAP_EKE_DYNAMIC
+EAPDYN += src/eap_peer/eap_eke.so
+else
+L_CFLAGS += -DEAP_EKE
+OBJS += src/eap_peer/eap_eke.c src/eap_common/eap_eke_common.c
+OBJS_h += src/eap_server/eap_server_eke.c
+endif
+CONFIG_IEEE8021X_EAPOL=y
+NEED_DH_GROUPS=y
+NEED_DH_GROUPS_ALL=y
+NEED_SHA256=y
+endif
+
ifdef CONFIG_WPS
ifdef CONFIG_WPS2
L_CFLAGS += -DCONFIG_WPS2
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 0634219..5698619 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -215,7 +215,7 @@
NEED_MD5=y
NEED_RC4=y
else
-CFLAGS += -DCONFIG_NO_WPA -DCONFIG_NO_WPA2
+CFLAGS += -DCONFIG_NO_WPA
endif
ifdef CONFIG_IBSS_RSN
@@ -265,10 +265,6 @@
NEED_GAS=y
endif
-ifdef CONFIG_NO_WPA2
-CFLAGS += -DCONFIG_NO_WPA2
-endif
-
include ../src/drivers/drivers.mak
ifdef CONFIG_AP
OBJS_d += $(DRV_BOTH_OBJS)
@@ -579,6 +575,22 @@
NEED_SHA256=y
endif
+ifdef CONFIG_EAP_EKE
+# EAP-EKE
+ifeq ($(CONFIG_EAP_EKE), dyn)
+CFLAGS += -DEAP_EKE_DYNAMIC
+EAPDYN += ../src/eap_peer/eap_eke.so
+else
+CFLAGS += -DEAP_EKE
+OBJS += ../src/eap_peer/eap_eke.o ../src/eap_common/eap_eke_common.o
+OBJS_h += ../src/eap_server/eap_server_eke.o
+endif
+CONFIG_IEEE8021X_EAPOL=y
+NEED_DH_GROUPS=y
+NEED_DH_GROUPS_ALL=y
+NEED_SHA256=y
+endif
+
ifdef CONFIG_WPS
ifdef CONFIG_WPS2
CFLAGS += -DCONFIG_WPS2
@@ -1581,6 +1593,10 @@
$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
-Deap_peer_ikev2_register=eap_peer_method_dynamic_init
+eap_eke.so: ../src/eap_peer/eap_eke.c ../src/eap_common/eap_eke_common.c
+ $(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
+ -Deap_peer_eke_register=eap_peer_method_dynamic_init
+
%.so: %.c
$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $< \
-D$(*F:eap_%=eap_peer_%)_register=eap_peer_method_dynamic_init
diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
index 331940c..8b3d6b4 100644
--- a/wpa_supplicant/android.config
+++ b/wpa_supplicant/android.config
@@ -262,11 +262,6 @@
# 35-50 kB in code size.
#CONFIG_NO_WPA=y
-# Remove WPA2 support. This allows WPA to be used, but removes WPA2 code to
-# save about 1 kB in code size when building only WPA-Personal (no EAP support)
-# or 6 kB if building for WPA-Enterprise.
-#CONFIG_NO_WPA2=y
-
# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
# This option can be used to reduce code size by removing support for
# converting ASCII passphrases into PSK. If this functionality is removed, the
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index d9e1f82..c48a286 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -124,7 +124,9 @@
#endif /* CONFIG_IEEE80211N */
#ifdef CONFIG_P2P
- if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
+ if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G &&
+ (ssid->mode == WPAS_MODE_P2P_GO ||
+ ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)) {
/* Remove 802.11b rates from supported and basic rate sets */
int *list = os_malloc(4 * sizeof(int));
if (list) {
@@ -492,6 +494,11 @@
if (wpa_drv_associate(wpa_s, ¶ms) < 0) {
wpa_msg(wpa_s, MSG_INFO, "Failed to start AP functionality");
+#ifdef CONFIG_P2P
+ if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION &&
+ wpa_s->global->p2p_group_formation == wpa_s)
+ wpas_p2p_group_formation_failed(wpa_s->parent);
+#endif /* CONFIG_P2P */
return -1;
}
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 7a860b6..a35be51 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -1522,6 +1522,7 @@
{ INT(eap_workaround) },
{ STRe(pac_file) },
{ INTe(fragment_size) },
+ { INTe(ocsp) },
#endif /* IEEE8021X_EAPOL */
{ INT_RANGE(mode, 0, 4) },
{ INT_RANGE(proactive_key_caching, 0, 1) },
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index a354a11..a24abaf 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -5018,23 +5018,76 @@
#endif /* CONFIG_WNM */
+/* Get string representation of channel width */
+static const char * channel_width_name(enum chan_width width)
+{
+ switch (width) {
+ case CHAN_WIDTH_20_NOHT:
+ return "20 MHz (no HT)";
+ case CHAN_WIDTH_20:
+ return "20 MHz";
+ case CHAN_WIDTH_40:
+ return "40 MHz";
+ case CHAN_WIDTH_80:
+ return "80 MHz";
+ case CHAN_WIDTH_80P80:
+ return "80+80 MHz";
+ case CHAN_WIDTH_160:
+ return "160 MHz";
+ default:
+ return "unknown";
+ }
+}
+
+
static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf,
size_t buflen)
{
struct wpa_signal_info si;
int ret;
+ char *pos, *end;
ret = wpa_drv_signal_poll(wpa_s, &si);
if (ret)
return -1;
- ret = os_snprintf(buf, buflen, "RSSI=%d\nLINKSPEED=%d\n"
+ pos = buf;
+ end = buf + buflen;
+
+ ret = os_snprintf(pos, end - pos, "RSSI=%d\nLINKSPEED=%d\n"
"NOISE=%d\nFREQUENCY=%u\n",
si.current_signal, si.current_txrate / 1000,
si.current_noise, si.frequency);
- if (ret < 0 || (unsigned int) ret > buflen)
+ if (ret < 0 || ret > end - pos)
return -1;
- return ret;
+ pos += ret;
+
+ if (si.chanwidth != CHAN_WIDTH_UNKNOWN) {
+ ret = os_snprintf(pos, end - pos, "WIDTH=%s\n",
+ channel_width_name(si.chanwidth));
+ if (ret < 0 || ret > end - pos)
+ return -1;
+ pos += ret;
+ }
+
+ if (si.center_frq1 > 0 && si.center_frq2 > 0) {
+ ret = os_snprintf(pos, end - pos,
+ "CENTER_FRQ1=%d\nCENTER_FRQ2=%d\n",
+ si.center_frq1, si.center_frq2);
+ if (ret < 0 || ret > end - pos)
+ return -1;
+ pos += ret;
+ }
+
+ if (si.avg_signal) {
+ ret = os_snprintf(pos, end - pos,
+ "AVG_RSSI=%d\n", si.avg_signal);
+ if (ret < 0 || ret >= end - pos)
+ return -1;
+ pos += ret;
+ }
+
+ return pos - buf;
}
diff --git a/wpa_supplicant/ctrl_iface_unix.c b/wpa_supplicant/ctrl_iface_unix.c
index 1b4b9b0..fc0d649 100644
--- a/wpa_supplicant/ctrl_iface_unix.c
+++ b/wpa_supplicant/ctrl_iface_unix.c
@@ -602,7 +602,7 @@
offsetof(struct sockaddr_un, sun_path));
msg.msg_name = (void *) &dst->addr;
msg.msg_namelen = dst->addrlen;
- if (sendmsg(sock, &msg, 0) < 0) {
+ if (sendmsg(sock, &msg, MSG_DONTWAIT) < 0) {
int _errno = errno;
wpa_printf(MSG_INFO, "CTRL_IFACE monitor[%d]: "
"%d - %s",
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index e9bd51f..ddd2c82 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -869,6 +869,76 @@
}
+/**
+ * wpas_dbus_signal_sta - Send a station related event signal
+ * @wpa_s: %wpa_supplicant network interface data
+ * @sta: station mac address
+ * @sig_name: signal name - StaAuthorized or StaDeauthorized
+ *
+ * Notify listeners about event related with station
+ */
+static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
+ const u8 *sta, const char *sig_name)
+{
+ struct wpas_dbus_priv *iface;
+ DBusMessage *msg;
+ char sta_mac[WPAS_DBUS_OBJECT_PATH_MAX];
+ char *dev_mac;
+
+ os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(sta));
+ dev_mac = sta_mac;
+
+ iface = wpa_s->global->dbus;
+
+ /* Do nothing if the control interface is not turned on */
+ if (iface == NULL)
+ return;
+
+ msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+ WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
+ if (msg == NULL)
+ return;
+
+ if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_mac,
+ DBUS_TYPE_INVALID))
+ dbus_connection_send(iface->con, msg, NULL);
+ else
+ wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
+ dbus_message_unref(msg);
+
+ wpa_printf(MSG_DEBUG, "dbus: Station MAC address '%s' '%s'",
+ sta_mac, sig_name);
+}
+
+
+/**
+ * wpas_dbus_signal_sta_authorized - Send a STA authorized signal
+ * @wpa_s: %wpa_supplicant network interface data
+ * @sta: station mac address
+ *
+ * Notify listeners a new station has been authorized
+ */
+void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
+ const u8 *sta)
+{
+ wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
+}
+
+
+/**
+ * wpas_dbus_signal_sta_deauthorized - Send a STA deauthorized signal
+ * @wpa_s: %wpa_supplicant network interface data
+ * @sta: station mac address
+ *
+ * Notify listeners a station has been deauthorized
+ */
+void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
+ const u8 *sta)
+{
+ wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
+}
+
+
#ifdef CONFIG_P2P
/**
@@ -1920,15 +1990,6 @@
END_ARGS
}
},
-#ifdef CONFIG_AUTOSCAN
- { "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
- (WPADBusMethodHandler) &wpas_dbus_handler_autoscan,
- {
- { "arg", "s", ARG_IN },
- END_ARGS
- }
- },
-#endif /* CONFIG_AUTOSCAN */
{ NULL, NULL, NULL, { END_ARGS } }
};
@@ -2666,6 +2727,15 @@
END_ARGS
}
},
+#ifdef CONFIG_AUTOSCAN
+ { "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler) &wpas_dbus_handler_autoscan,
+ {
+ { "arg", "s", ARG_IN },
+ END_ARGS
+ }
+ },
+#endif /* CONFIG_AUTOSCAN */
{ NULL, NULL, NULL, { END_ARGS } }
};
@@ -3017,6 +3087,18 @@
END_ARGS
}
},
+ { "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ {
+ { "name", "s", ARG_OUT },
+ END_ARGS
+ }
+ },
+ { "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ {
+ { "name", "s", ARG_OUT },
+ END_ARGS
+ }
+ },
{ NULL, NULL, { END_ARGS } }
};
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index 363a7e5..61c480a 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -222,6 +222,10 @@
const u8 *ie, size_t ie_len, u32 ssi_signal);
void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
const char *status, const char *parameter);
+void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
+ const u8 *sta);
+void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
+ const u8 *sta);
#else /* CONFIG_CTRL_IFACE_DBUS_NEW */
@@ -493,6 +497,18 @@
{
}
+static inline
+void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
+ const u8 *sta)
+{
+}
+
+static inline
+void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
+ const u8 *sta)
+{
+}
+
#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
#endif /* CTRL_IFACE_DBUS_H_NEW */
diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig
index 5663a5f..aa6005f 100644
--- a/wpa_supplicant/defconfig
+++ b/wpa_supplicant/defconfig
@@ -210,6 +210,9 @@
# EAP-IKEv2
#CONFIG_EAP_IKEV2=y
+# EAP-EKE
+#CONFIG_EAP_EKE=y
+
# PKCS#12 (PFX) support (used to read private key and certificate file from
# a file that usually has extension .p12 or .pfx)
CONFIG_PKCS12=y
@@ -261,11 +264,6 @@
# 35-50 kB in code size.
#CONFIG_NO_WPA=y
-# Remove WPA2 support. This allows WPA to be used, but removes WPA2 code to
-# save about 1 kB in code size when building only WPA-Personal (no EAP support)
-# or 6 kB if building for WPA-Enterprise.
-#CONFIG_NO_WPA2=y
-
# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
# This option can be used to reduce code size by removing support for
# converting ASCII passphrases into PSK. If this functionality is removed, the
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 6bab19c..9922e07 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -129,6 +129,16 @@
return -1;
}
+static inline int wpa_drv_sta_deauth(struct wpa_supplicant *wpa_s,
+ const u8 *addr, int reason_code)
+{
+ if (wpa_s->driver->sta_deauth) {
+ return wpa_s->driver->sta_deauth(wpa_s->drv_priv, NULL, addr,
+ reason_code);
+ }
+ return -1;
+}
+
static inline int wpa_drv_deauthenticate(struct wpa_supplicant *wpa_s,
const u8 *addr, int reason_code)
{
diff --git a/wpa_supplicant/eap_register.c b/wpa_supplicant/eap_register.c
index d1eb4ff..6cd2fc5 100644
--- a/wpa_supplicant/eap_register.c
+++ b/wpa_supplicant/eap_register.c
@@ -135,6 +135,11 @@
ret = eap_peer_pwd_register();
#endif /* EAP_PWD */
+#ifdef EAP_EKE
+ if (ret == 0)
+ ret = eap_peer_eke_register();
+#endif /* EAP_EKE */
+
#ifdef EAP_SERVER_IDENTITY
if (ret == 0)
ret = eap_server_identity_register();
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 60e71b6..d39216f 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -44,8 +44,10 @@
#include "interworking.h"
+#ifndef CONFIG_NO_SCAN_PROCESSING
static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
int new_scan);
+#endif /* CONFIG_NO_SCAN_PROCESSING */
static int wpas_temp_disabled(struct wpa_supplicant *wpa_s,
@@ -1957,7 +1959,9 @@
int authenticating;
u8 prev_pending_bssid[ETH_ALEN];
struct wpa_bss *fast_reconnect = NULL;
+#ifndef CONFIG_NO_SCAN_PROCESSING
struct wpa_ssid *fast_reconnect_ssid = NULL;
+#endif /* CONFIG_NO_SCAN_PROCESSING */
struct wpa_ssid *last_ssid;
authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING;
@@ -1998,7 +2002,9 @@
* time for some common cases.
*/
fast_reconnect = wpa_s->current_bss;
+#ifndef CONFIG_NO_SCAN_PROCESSING
fast_reconnect_ssid = wpa_s->current_ssid;
+#endif /* CONFIG_NO_SCAN_PROCESSING */
} else if (wpa_s->wpa_state >= WPA_ASSOCIATING)
#ifdef ANDROID
wpa_supplicant_req_scan(wpa_s, 0, 500000);
diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
index 046f181..687c042 100644
--- a/wpa_supplicant/ibss_rsn.c
+++ b/wpa_supplicant/ibss_rsn.c
@@ -296,6 +296,13 @@
}
+static void ibss_rsn_disconnect(void *ctx, const u8 *addr, u16 reason)
+{
+ struct ibss_rsn *ibss_rsn = ctx;
+ wpa_drv_sta_deauth(ibss_rsn->wpa_s, addr, reason);
+}
+
+
static int auth_for_each_sta(void *ctx, int (*cb)(struct wpa_state_machine *sm,
void *ctx),
void *cb_ctx)
@@ -386,6 +393,7 @@
cb.get_psk = auth_get_psk;
cb.set_key = auth_set_key;
cb.for_each_sta = auth_for_each_sta;
+ cb.disconnect = ibss_rsn_disconnect;
ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb);
if (ibss_rsn->auth_group == NULL) {
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index e35628b..36f75a1 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -599,19 +599,29 @@
static int plmn_id_match(struct wpabuf *anqp, const char *imsi, int mnc_len)
{
- u8 plmn[3];
+ u8 plmn[3], plmn2[3];
const u8 *pos, *end;
u8 udhl;
- /* See Annex A of 3GPP TS 24.234 v8.1.0 for description */
+ /*
+ * See Annex A of 3GPP TS 24.234 v8.1.0 for description. The network
+ * operator is allowed to include only two digits of the MNC, so allow
+ * matches based on both two and three digit MNC assumptions. Since some
+ * SIM/USIM cards may not expose MNC length conveniently, we may be
+ * provided the default MNC length 3 here and as such, checking with MNC
+ * length 2 is justifiable even though 3GPP TS 24.234 does not mention
+ * that case. Anyway, MCC/MNC pair where both 2 and 3 digit MNC is used
+ * with otherwise matching values would not be good idea in general, so
+ * this should not result in selecting incorrect networks.
+ */
+ /* Match with 3 digit MNC */
plmn[0] = (imsi[0] - '0') | ((imsi[1] - '0') << 4);
- plmn[1] = imsi[2] - '0';
- /* default to MNC length 3 if unknown */
- if (mnc_len != 2)
- plmn[1] |= (imsi[5] - '0') << 4;
- else
- plmn[1] |= 0xf0;
+ plmn[1] = (imsi[2] - '0') | ((imsi[5] - '0') << 4);
plmn[2] = (imsi[3] - '0') | ((imsi[4] - '0') << 4);
+ /* Match with 2 digit MNC */
+ plmn2[0] = (imsi[0] - '0') | ((imsi[1] - '0') << 4);
+ plmn2[1] = (imsi[2] - '0') | 0xf0;
+ plmn2[2] = (imsi[3] - '0') | ((imsi[4] - '0') << 4);
if (anqp == NULL)
return 0;
@@ -631,6 +641,10 @@
}
end = pos + udhl;
+ wpa_printf(MSG_DEBUG, "Interworking: Matching against MCC/MNC alternatives: %02x:%02x:%02x or %02x:%02x:%02x (IMSI %s, MNC length %d)",
+ plmn[0], plmn[1], plmn[2], plmn2[0], plmn2[1], plmn2[2],
+ imsi, mnc_len);
+
while (pos + 2 <= end) {
u8 iei, len;
const u8 *l_end;
@@ -643,14 +657,20 @@
if (iei == 0 && len > 0) {
/* PLMN List */
u8 num, i;
+ wpa_hexdump(MSG_DEBUG, "Interworking: PLMN List information element",
+ pos, len);
num = *pos++;
for (i = 0; i < num; i++) {
- if (pos + 3 > end)
+ if (pos + 3 > l_end)
break;
- if (os_memcmp(pos, plmn, 3) == 0)
+ if (os_memcmp(pos, plmn, 3) == 0 ||
+ os_memcmp(pos, plmn2, 3) == 0)
return 1; /* Found matching PLMN */
pos += 3;
}
+ } else {
+ wpa_hexdump(MSG_DEBUG, "Interworking: Unrecognized 3GPP information element",
+ pos, len);
}
pos = l_end;
@@ -1337,6 +1357,8 @@
char *sep;
const char *imsi;
int mnc_len;
+ char imsi_buf[16];
+ size_t msin_len;
#ifdef PCSC_FUNCS
if (cred->pcsc && wpa_s->conf->pcsc_reader && wpa_s->scard &&
@@ -1346,6 +1368,13 @@
goto compare;
}
#endif /* PCSC_FUNCS */
+#ifdef CONFIG_EAP_PROXY
+ if (cred->pcsc && wpa_s->mnc_len > 0 && wpa_s->imsi[0]) {
+ imsi = wpa_s->imsi;
+ mnc_len = wpa_s->mnc_len;
+ goto compare;
+ }
+#endif /* CONFIG_EAP_PROXY */
if (cred->imsi == NULL || !cred->imsi[0] ||
cred->milenage == NULL || !cred->milenage[0])
@@ -1356,11 +1385,18 @@
(sep - cred->imsi != 5 && sep - cred->imsi != 6))
continue;
mnc_len = sep - cred->imsi - 3;
- imsi = cred->imsi;
+ os_memcpy(imsi_buf, cred->imsi, 3 + mnc_len);
+ sep++;
+ msin_len = os_strlen(cred->imsi);
+ if (3 + mnc_len + msin_len >= sizeof(imsi_buf) - 1)
+ msin_len = sizeof(imsi_buf) - 3 - mnc_len - 1;
+ os_memcpy(&imsi_buf[3 + mnc_len], sep, msin_len);
+ imsi_buf[3 + mnc_len + msin_len] = '\0';
+ imsi = imsi_buf;
-#ifdef PCSC_FUNCS
+#if defined(PCSC_FUNCS) || defined(CONFIG_EAP_PROXY)
compare:
-#endif /* PCSC_FUNCS */
+#endif /* PCSC_FUNCS || CONFIG_EAP_PROXY */
wpa_printf(MSG_DEBUG, "Interworking: Parsing 3GPP info from "
MACSTR, MAC2STR(bss->bssid));
ret = plmn_id_match(bss->anqp->anqp_3gpp, imsi, mnc_len);
diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c
index 1b3364c..39b837e 100644
--- a/wpa_supplicant/main.c
+++ b/wpa_supplicant/main.c
@@ -14,6 +14,7 @@
#include "common.h"
#include "wpa_supplicant_i.h"
#include "driver_i.h"
+#include "p2p_supplicant.h"
extern struct wpa_driver_ops *wpa_drivers[];
@@ -289,6 +290,8 @@
}
for (i = 0; exitcode == 0 && i < iface_count; i++) {
+ struct wpa_supplicant *wpa_s;
+
if ((ifaces[i].confname == NULL &&
ifaces[i].ctrl_interface == NULL) ||
ifaces[i].ifname == NULL) {
@@ -299,8 +302,18 @@
exitcode = -1;
break;
}
- if (wpa_supplicant_add_iface(global, &ifaces[i]) == NULL)
+ wpa_s = wpa_supplicant_add_iface(global, &ifaces[i]);
+ if (wpa_s == NULL) {
exitcode = -1;
+ break;
+ }
+#ifdef CONFIG_P2P
+ if (wpa_s->global->p2p == NULL &&
+ (wpa_s->drv_flags &
+ WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
+ wpas_p2p_add_p2pdev_interface(wpa_s) < 0)
+ exitcode = -1;
+#endif /* CONFIG_P2P */
}
if (exitcode == 0)
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 3ed826d..f2cbdd7 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -551,6 +551,9 @@
*/
wpas_dbus_signal_p2p_peer_joined(wpa_s, sta);
#endif /* CONFIG_P2P */
+
+ /* Notify listeners a new station has been authorized */
+ wpas_dbus_signal_sta_authorized(wpa_s, sta);
}
@@ -570,6 +573,9 @@
*/
wpas_dbus_signal_p2p_peer_disconnected(wpa_s, sta);
#endif /* CONFIG_P2P */
+
+ /* Notify listeners a station has been deauthorized */
+ wpas_dbus_signal_sta_deauthorized(wpa_s, sta);
}
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index f9193ae..37f5ad3 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -65,6 +65,8 @@
#define P2P_CONCURRENT_SEARCH_DELAY 500
#endif /* P2P_CONCURRENT_SEARCH_DELAY */
+#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-"
+
enum p2p_group_removal_reason {
P2P_GROUP_REMOVAL_UNKNOWN,
P2P_GROUP_REMOVAL_SILENT,
@@ -1013,6 +1015,26 @@
}
+static void wpas_p2p_get_group_ifname(struct wpa_supplicant *wpa_s,
+ char *ifname, size_t len)
+{
+ char *ifname_ptr = wpa_s->ifname;
+
+ if (os_strncmp(wpa_s->ifname, P2P_MGMT_DEVICE_PREFIX,
+ os_strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
+ ifname_ptr = os_strrchr(wpa_s->ifname, '-') + 1;
+ }
+
+ os_snprintf(ifname, len, "p2p-%s-%d", ifname_ptr, wpa_s->p2p_group_idx);
+ if (os_strlen(ifname) >= IFNAMSIZ &&
+ os_strlen(wpa_s->ifname) < IFNAMSIZ) {
+ /* Try to avoid going over the IFNAMSIZ length limit */
+ os_snprintf(ifname, sizeof(ifname), "p2p-%d",
+ wpa_s->p2p_group_idx);
+ }
+}
+
+
static int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s,
enum wpa_driver_if_type type)
{
@@ -1030,14 +1052,7 @@
return 0;
}
- os_snprintf(ifname, sizeof(ifname), "p2p-%s-%d", wpa_s->ifname,
- wpa_s->p2p_group_idx);
- if (os_strlen(ifname) >= IFNAMSIZ &&
- os_strlen(wpa_s->ifname) < IFNAMSIZ) {
- /* Try to avoid going over the IFNAMSIZ length limit */
- os_snprintf(ifname, sizeof(ifname), "p2p-%d",
- wpa_s->p2p_group_idx);
- }
+ wpas_p2p_get_group_ifname(wpa_s, ifname, sizeof(ifname));
force_ifname[0] = '\0';
wpa_printf(MSG_DEBUG, "P2P: Create a new interface %s for the group",
@@ -1107,7 +1122,13 @@
os_memset(&iface, 0, sizeof(iface));
iface.ifname = wpa_s->pending_interface_name;
iface.driver = wpa_s->driver->name;
- iface.ctrl_interface = wpa_s->conf->ctrl_interface;
+ if (wpa_s->conf->ctrl_interface == NULL &&
+ wpa_s->parent != wpa_s &&
+ wpa_s->p2p_mgmt &&
+ (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE))
+ iface.ctrl_interface = wpa_s->parent->conf->ctrl_interface;
+ else
+ iface.ctrl_interface = wpa_s->conf->ctrl_interface;
iface.driver_param = wpa_s->conf->driver_param;
group_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface);
if (group_wpa_s == NULL) {
@@ -1132,6 +1153,14 @@
{
struct wpa_supplicant *wpa_s = eloop_ctx;
wpa_printf(MSG_DEBUG, "P2P: Group Formation timed out");
+ wpas_p2p_group_formation_failed(wpa_s);
+}
+
+
+void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s)
+{
+ eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
+ wpa_s->parent, NULL);
if (wpa_s->global->p2p)
p2p_group_formation_failed(wpa_s->global->p2p);
else if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)
@@ -3048,6 +3077,45 @@
}
+int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_interface iface;
+ struct wpa_supplicant *p2pdev_wpa_s;
+ char ifname[100];
+ char force_name[100];
+ int ret;
+
+ os_snprintf(ifname, sizeof(ifname), P2P_MGMT_DEVICE_PREFIX "%s",
+ wpa_s->ifname);
+ force_name[0] = '\0';
+ wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE;
+ ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, NULL, NULL,
+ force_name, wpa_s->pending_interface_addr, NULL);
+ if (ret < 0) {
+ wpa_printf(MSG_DEBUG, "P2P: Failed to create P2P Device interface");
+ return ret;
+ }
+ os_strlcpy(wpa_s->pending_interface_name, ifname,
+ sizeof(wpa_s->pending_interface_name));
+
+ os_memset(&iface, 0, sizeof(iface));
+ iface.p2p_mgmt = 1;
+ iface.ifname = wpa_s->pending_interface_name;
+ iface.driver = wpa_s->driver->name;
+ iface.driver_param = wpa_s->conf->driver_param;
+ iface.confname = wpa_s->confname;
+ p2pdev_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface);
+ if (!p2pdev_wpa_s) {
+ wpa_printf(MSG_DEBUG, "P2P: Failed to add P2P Device interface");
+ return -1;
+ }
+ p2pdev_wpa_s->parent = wpa_s;
+
+ wpa_s->pending_interface_name[0] = '\0';
+ return 0;
+}
+
+
/**
* wpas_p2p_init - Initialize P2P module for %wpa_supplicant
* @global: Pointer to global data from wpa_supplicant_init()
@@ -3312,7 +3380,8 @@
static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s)
{
- if (wpa_s->conf->p2p_no_group_iface)
+ if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
+ wpa_s->conf->p2p_no_group_iface)
return 0; /* separate interface disabled per configuration */
if (wpa_s->drv_flags &
(WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE |
@@ -5595,14 +5664,7 @@
"session overlap");
if (wpa_s != wpa_s->parent)
wpa_msg_ctrl(wpa_s->parent, MSG_INFO, WPS_EVENT_OVERLAP);
-
- if (wpa_s->global->p2p)
- p2p_group_formation_failed(wpa_s->global->p2p);
-
- eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
- wpa_s->parent, NULL);
-
- wpas_group_formation_completed(wpa_s, 0);
+ wpas_p2p_group_formation_failed(wpa_s);
return 1;
}
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 04ba9b2..3ca6222 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -14,10 +14,12 @@
enum p2p_send_action_result;
struct p2p_peer_info;
struct p2p_channels;
+struct wps_event_fail;
int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s);
void wpas_p2p_deinit(struct wpa_supplicant *wpa_s);
void wpas_p2p_deinit_global(struct wpa_global *global);
+int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s);
int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
const char *pin, enum p2p_wps_method wps_method,
int persistent_group, int auto_join, int join,
@@ -76,6 +78,7 @@
void wpas_dev_found(void *ctx, const u8 *addr,
const struct p2p_peer_info *info,
int new_device);
+void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s);
void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res);
void wpas_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id);
void wpas_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods,
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 27791b3..f6b881b 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -17,6 +17,7 @@
#include "crypto/sha1.h"
#include "eapol_supp/eapol_supp_sm.h"
#include "eap_peer/eap.h"
+#include "eap_peer/eap_proxy.h"
#include "eap_server/eap_methods.h"
#include "rsn_supp/wpa.h"
#include "eloop.h"
@@ -2348,7 +2349,10 @@
const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
if (addr)
os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
- } else if (!(wpa_s->drv_flags &
+ } else if ((!wpa_s->p2p_mgmt ||
+ !(wpa_s->drv_flags &
+ WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
+ !(wpa_s->drv_flags &
WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
l2_packet_deinit(wpa_s->l2);
wpa_s->l2 = l2_packet_init(wpa_s->ifname,
@@ -2368,10 +2372,6 @@
return -1;
}
- wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
- MAC2STR(wpa_s->own_addr));
- wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
-
return 0;
}
@@ -2417,6 +2417,10 @@
if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
return -1;
+ wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
+ MAC2STR(wpa_s->own_addr));
+ wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
+
if (wpa_s->bridge_ifname[0]) {
wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
"interface '%s'", wpa_s->bridge_ifname);
@@ -2855,6 +2859,11 @@
wpa_s->conf->driver_param =
os_strdup(iface->driver_param);
}
+
+ if (iface->p2p_mgmt && !iface->ctrl_interface) {
+ os_free(wpa_s->conf->ctrl_interface);
+ wpa_s->conf->ctrl_interface = NULL;
+ }
} else
wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
iface->driver_param);
@@ -2980,11 +2989,24 @@
if (wpa_s->max_remain_on_chan == 0)
wpa_s->max_remain_on_chan = 1000;
+ /*
+ * Only take p2p_mgmt parameters when P2P Device is supported.
+ * Doing it here as it determines whether l2_packet_init() will be done
+ * during wpa_supplicant_driver_init().
+ */
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
+ wpa_s->p2p_mgmt = iface->p2p_mgmt;
+ else
+ iface->p2p_mgmt = 1;
+
if (wpa_supplicant_driver_init(wpa_s) < 0)
return -1;
#ifdef CONFIG_TDLS
- if (wpa_tdls_init(wpa_s->wpa))
+ if ((!iface->p2p_mgmt ||
+ !(wpa_s->drv_flags &
+ WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
+ wpa_tdls_init(wpa_s->wpa))
return -1;
#endif /* CONFIG_TDLS */
@@ -3022,7 +3044,7 @@
}
#ifdef CONFIG_P2P
- if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
+ if (iface->p2p_mgmt && wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
return -1;
}
@@ -3031,6 +3053,20 @@
if (wpa_bss_init(wpa_s) < 0)
return -1;
+#ifdef CONFIG_EAP_PROXY
+{
+ size_t len;
+ wpa_s->mnc_len = eap_proxy_get_imsi(wpa_s->imsi, &len);
+ if (wpa_s->mnc_len > 0) {
+ wpa_s->imsi[len] = '\0';
+ wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
+ wpa_s->imsi, wpa_s->mnc_len);
+ } else {
+ wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
+ }
+}
+#endif /* CONFIG_EAP_PROXY */
+
if (pcsc_reader_init(wpa_s) < 0)
return -1;
@@ -3422,9 +3458,6 @@
#ifdef CONFIG_WIFI_DISPLAY
wifi_display_deinit(global);
#endif /* CONFIG_WIFI_DISPLAY */
-#ifdef CONFIG_P2P
- wpas_p2p_deinit_global(global);
-#endif /* CONFIG_P2P */
while (global->ifaces)
wpa_supplicant_remove_iface(global, global->ifaces, 1);
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 8e21a3a..d73d371 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -815,6 +815,11 @@
# interface used for EAPOL. The default value is suitable for most
# cases.
#
+# ocsp: Whether to use/require OCSP to check server certificate
+# 0 = do not use OCSP stapling (TLS certificate status extension)
+# 1 = try to use OCSP stapling, but not require response
+# 2 = require valid OCSP stapling response
+#
# EAP-FAST variables:
# pac_file: File path for the PAC entries. wpa_supplicant will need to be able
# to create this file and write updates to it when PAC is being
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index c971ae4..9240863 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -104,6 +104,15 @@
* receiving of EAPOL frames from an additional interface.
*/
const char *bridge_ifname;
+
+ /**
+ * p2p_mgmt - Interface used for P2P management (P2P Device operations)
+ *
+ * Indicates whether wpas_p2p_init() must be called for this interface.
+ * This is used only when the driver supports a dedicated P2P Device
+ * interface that is not a network interface.
+ */
+ int p2p_mgmt;
};
/**
@@ -407,10 +416,8 @@
* previous association event */
struct scard_data *scard;
-#ifdef PCSC_FUNCS
char imsi[20];
int mnc_len;
-#endif /* PCSC_FUNCS */
unsigned char last_eapol_src[ETH_ALEN];
@@ -568,6 +575,8 @@
unsigned int roc_waiting_drv_freq;
int action_tx_wait_time;
+ int p2p_mgmt;
+
#ifdef CONFIG_P2P
struct p2p_go_neg_results *go_params;
int create_p2p_iface;
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 40720c5..61a42bd 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -513,8 +513,6 @@
}
#endif /* CONFIG_IEEE80211R */
-#endif /* CONFIG_NO_WPA */
-
#ifdef CONFIG_TDLS
@@ -596,6 +594,8 @@
#endif /* CONFIG_TDLS */
+#endif /* CONFIG_NO_WPA */
+
enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field)
{
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index d73e023..8e0207c 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -868,9 +868,8 @@
while (ssid) {
if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
if (ssid == wpa_s->current_ssid) {
- wpa_s->current_ssid = NULL;
- if (ssid != NULL)
- wpas_notify_network_changed(wpa_s);
+ wpa_supplicant_deauthenticate(
+ wpa_s, WLAN_REASON_DEAUTH_LEAVING);
}
id = ssid->id;
remove_ssid = ssid;