aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2011-05-16 18:35:42 +0300
committerDmitry Shmidt <dimitrysh@google.com>2011-05-24 15:58:05 -0700
commit87fd279308af3f806848c8f2ab65ef18c6ac4c30 (patch)
tree0bd20d56a780a19f210bca634500e8f5f66f52e2
parent29991f40caccd6c45cd7c56ca597f370a4f2b9eb (diff)
downloadexternal_wpa_supplicant_8-87fd279308af3f806848c8f2ab65ef18c6ac4c30.zip
external_wpa_supplicant_8-87fd279308af3f806848c8f2ab65ef18c6ac4c30.tar.gz
external_wpa_supplicant_8-87fd279308af3f806848c8f2ab65ef18c6ac4c30.tar.bz2
Accumulative patch from commit 6d28fb9627155929012cda944aacd5a52ce7051a
nl80211: Fetch assoc_freq from scan table for connect event nl80211: Filter out duplicated BSS table entries from scan results Update BSS table entry if roaming event indicates frequency change WPS: Remove obsolete note about lack for WPS ER support P2P: Include operating class 124 (channels 149,153,157,161) Include nl80211 driver wrapper in default configuration for hostapd Better messages when channel cannot be used in AP mode WPS: Add a workaround for Windows 7 capability discovery for PBC WPS UPnP: Fix UPnP initialization for non-bridge case with some drivers Fix regression in RSN pre-authentication candidate list generation commit 6d28fb9627155929012cda944aacd5a52ce7051a Change-Id: I3c68dad5fe323b1d86aa585c564a75e4fc1a2ea1
-rw-r--r--hostapd/config_file.c2
-rw-r--r--hostapd/defconfig2
-rw-r--r--hostapd/hostapd.conf12
-rw-r--r--src/ap/ap_config.h1
-rw-r--r--src/ap/hostapd.c11
-rw-r--r--src/ap/hw_features.c22
-rw-r--r--src/ap/hw_features.h2
-rw-r--r--src/ap/ieee802_1x.c1
-rw-r--r--src/ap/wps_hostapd.c22
-rw-r--r--src/ap/wps_hostapd.h6
-rw-r--r--src/drivers/driver_nl80211.c94
-rw-r--r--src/eap_server/eap.h2
-rw-r--r--src/eap_server/eap_i.h2
-rw-r--r--src/eap_server/eap_server.c1
-rw-r--r--src/eap_server/eap_server_wsc.c1
-rw-r--r--src/eapol_auth/eapol_auth_sm.c2
-rw-r--r--src/eapol_auth/eapol_auth_sm.h1
-rw-r--r--src/wps/wps.c1
-rw-r--r--src/wps/wps.h8
-rw-r--r--src/wps/wps_enrollee.c9
-rw-r--r--src/wps/wps_i.h1
-rw-r--r--wpa_supplicant/README-WPS4
-rw-r--r--wpa_supplicant/events.c27
-rw-r--r--wpa_supplicant/p2p_supplicant.c2
24 files changed, 201 insertions, 35 deletions
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 11c8bf0..835f050 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2021,6 +2021,8 @@ struct hostapd_config * hostapd_config_read(const char *fname)
} else if (os_strcmp(buf, "upc") == 0) {
os_free(bss->upc);
bss->upc = os_strdup(pos);
+ } else if (os_strcmp(buf, "pbc_in_m1") == 0) {
+ bss->pbc_in_m1 = atoi(pos);
#endif /* CONFIG_WPS */
#ifdef CONFIG_P2P_MANAGER
} else if (os_strcmp(buf, "manage_p2p") == 0) {
diff --git a/hostapd/defconfig b/hostapd/defconfig
index b52e510..38d3284 100644
--- a/hostapd/defconfig
+++ b/hostapd/defconfig
@@ -20,7 +20,7 @@ CONFIG_DRIVER_HOSTAP=y
#CFLAGS += -I../../madwifi # change to the madwifi source directory
# Driver interface for drivers using the nl80211 kernel interface
-#CONFIG_DRIVER_NL80211=y
+CONFIG_DRIVER_NL80211=y
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
#CONFIG_DRIVER_BSD=y
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 6d7263a..e0525e4 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -921,6 +921,18 @@ own_ip_addr=127.0.0.1
# virtual_push_button physical_push_button
#config_methods=label virtual_display virtual_push_button keypad
+# WPS capability discovery workaround for PBC with Windows 7
+# Windows 7 uses incorrect way of figuring out AP's WPS capabilities by acting
+# as a Registrar and using M1 from the AP. The config methods attribute in that
+# message is supposed to indicate only the configuration method supported by
+# the AP in Enrollee role, i.e., to add an external Registrar. For that case,
+# PBC shall not be used and as such, the PushButton config method is removed
+# from M1 by default. If pbc_in_m1=1 is included in the configuration file,
+# the PushButton config method is left in M1 (if included in config_methods
+# parameter) to allow Windows 7 to use PBC instead of PIN (e.g., from a label
+# in the AP).
+#pbc_in_m1=1
+
# Static access point PIN for initial configuration and adding Registrars
# If not set, hostapd will not allow external WPS Registrars to control the
# access point. The AP PIN can also be set at runtime with hostapd_cli
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 25720b8..0a3e76e 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -318,6 +318,7 @@ struct hostapd_bss_config {
char *upc;
struct wpabuf *wps_vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
#endif /* CONFIG_WPS */
+ int pbc_in_m1;
#define P2P_ENABLED BIT(0)
#define P2P_GROUP_OWNER BIT(1)
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 4e5eb01..32db668 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -784,6 +784,17 @@ int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
return -1;
}
+ /*
+ * WPS UPnP module can be initialized only when the "upnp_iface" is up.
+ * If "interface" and "upnp_iface" are the same (e.g., non-bridge
+ * mode), the interface is up only after driver_commit, so initialize
+ * WPS after driver_commit.
+ */
+ for (j = 0; j < iface->num_bss; j++) {
+ if (hostapd_init_wps_complete(iface->bss[j]))
+ return -1;
+ }
+
if (hapd->setup_complete_cb)
hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index f3fffd7..86f6811 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -603,7 +603,7 @@ int hostapd_check_ht_capab(struct hostapd_iface *iface)
/**
* hostapd_select_hw_mode - Select the hardware mode
* @iface: Pointer to interface data.
- * Returns: 0 on success, -1 on failure
+ * Returns: 0 on success, < 0 on failure
*
* Sets up the hardware mode, channel, rates, and passive scanning
* based on the configuration.
@@ -631,17 +631,23 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface)
HOSTAPD_LEVEL_WARNING,
"Hardware does not support configured mode "
"(%d)", (int) iface->conf->hw_mode);
- return -1;
+ return -2;
}
ok = 0;
for (j = 0; j < iface->current_mode->num_channels; j++) {
struct hostapd_channel_data *chan =
&iface->current_mode->channels[j];
- if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
- (chan->chan == iface->conf->channel)) {
- ok = 1;
- break;
+ if (chan->chan == iface->conf->channel) {
+ if (chan->flag & HOSTAPD_CHAN_DISABLED) {
+ wpa_printf(MSG_ERROR,
+ "channel [%i] (%i) is disabled for "
+ "use in AP mode, flags: 0x%x",
+ j, chan->chan, chan->flag);
+ } else {
+ ok = 1;
+ break;
+ }
}
}
if (ok && iface->conf->secondary_channel) {
@@ -675,7 +681,7 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface)
* the channel automatically */
wpa_printf(MSG_ERROR, "Channel not configured "
"(hw_mode/channel in hostapd.conf)");
- return -1;
+ return -3;
}
if (ok == 0 && iface->conf->channel != 0) {
hostapd_logger(iface->bss[0], NULL,
@@ -693,7 +699,7 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface)
hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_WARNING,
"Hardware does not support configured channel");
- return -1;
+ return -4;
}
return 0;
diff --git a/src/ap/hw_features.h b/src/ap/hw_features.h
index 88c2322..b84bca6 100644
--- a/src/ap/hw_features.h
+++ b/src/ap/hw_features.h
@@ -41,7 +41,7 @@ static inline int hostapd_get_hw_features(struct hostapd_iface *iface)
static inline int hostapd_select_hw_mode(struct hostapd_iface *iface)
{
- return -1;
+ return -100;
}
static inline const char * hostapd_hw_mode_txt(int mode)
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index ac0c127..217f9f9 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -1701,6 +1701,7 @@ int ieee802_1x_init(struct hostapd_data *hapd)
conf.wps = hapd->wps;
conf.fragment_size = hapd->conf->fragment_size;
conf.pwd_group = hapd->conf->pwd_group;
+ conf.pbc_in_m1 = hapd->conf->pbc_in_m1;
os_memset(&cb, 0, sizeof(cb));
cb.eapol_send = ieee802_1x_eapol_send;
diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c
index fcbd89b..fc927f9 100644
--- a/src/ap/wps_hostapd.c
+++ b/src/ap/wps_hostapd.c
@@ -876,20 +876,34 @@ int hostapd_init_wps(struct hostapd_data *hapd,
wps->model_description = hapd->conf->model_description;
wps->model_url = hapd->conf->model_url;
wps->upc = hapd->conf->upc;
+#endif /* CONFIG_WPS_UPNP */
+
+ hostapd_register_probereq_cb(hapd, hostapd_wps_probe_req_rx, hapd);
+
+ hapd->wps = wps;
+
+ return 0;
+}
+
+
+int hostapd_init_wps_complete(struct hostapd_data *hapd)
+{
+ struct wps_context *wps = hapd->wps;
+
+ if (hapd->wps == NULL)
+ return 0;
+#ifdef CONFIG_WPS_UPNP
if (hostapd_wps_upnp_init(hapd, wps) < 0) {
wpa_printf(MSG_ERROR, "Failed to initialize WPS UPnP");
wps_registrar_deinit(wps->registrar);
os_free(wps->network_key);
os_free(wps);
+ hapd->wps = NULL;
return -1;
}
#endif /* CONFIG_WPS_UPNP */
- hostapd_register_probereq_cb(hapd, hostapd_wps_probe_req_rx, hapd);
-
- hapd->wps = wps;
-
return 0;
}
diff --git a/src/ap/wps_hostapd.h b/src/ap/wps_hostapd.h
index 338a220..6b28c13 100644
--- a/src/ap/wps_hostapd.h
+++ b/src/ap/wps_hostapd.h
@@ -19,6 +19,7 @@
int hostapd_init_wps(struct hostapd_data *hapd,
struct hostapd_bss_config *conf);
+int hostapd_init_wps_complete(struct hostapd_data *hapd);
void hostapd_deinit_wps(struct hostapd_data *hapd);
void hostapd_update_wps(struct hostapd_data *hapd);
int hostapd_wps_add_pin(struct hostapd_data *hapd, const u8 *addr,
@@ -50,6 +51,11 @@ static inline void hostapd_deinit_wps(struct hostapd_data *hapd)
{
}
+static inline int hostapd_init_wps_complete(struct hostapd_data *hapd)
+{
+ return 0;
+}
+
static inline void hostapd_update_wps(struct hostapd_data *hapd)
{
}
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 90b3f20..b4f01fa 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -220,6 +220,15 @@ static int nl80211_disable_11b_rates(struct wpa_driver_nl80211_data *drv,
static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv);
+struct nl80211_bss_info_arg {
+ struct wpa_driver_nl80211_data *drv;
+ struct wpa_scan_results *res;
+ unsigned int assoc_freq;
+};
+
+static int bss_info_handler(struct nl_msg *msg, void *arg);
+
+
/* nl80211 code */
static int ack_handler(struct nl_msg *msg, void *arg)
{
@@ -589,6 +598,38 @@ static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
}
+static unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv)
+{
+ struct nl_msg *msg;
+ int ret;
+ struct nl80211_bss_info_arg arg;
+
+ os_memset(&arg, 0, sizeof(arg));
+ msg = nlmsg_alloc();
+ if (!msg)
+ goto nla_put_failure;
+
+ genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, NLM_F_DUMP,
+ NL80211_CMD_GET_SCAN, 0);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
+
+ arg.drv = drv;
+ ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
+ msg = NULL;
+ if (ret == 0) {
+ wpa_printf(MSG_DEBUG, "nl80211: Operating frequency for the "
+ "associated BSS from scan results: %u MHz",
+ arg.assoc_freq);
+ return arg.assoc_freq ? arg.assoc_freq : drv->assoc_freq;
+ }
+ wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
+ "(%s)", ret, strerror(-ret));
+nla_put_failure:
+ nlmsg_free(msg);
+ return drv->assoc_freq;
+}
+
+
static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
const u8 *frame, size_t len)
{
@@ -679,6 +720,8 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
event.assoc_info.resp_ies_len = nla_len(resp_ie);
}
+ event.assoc_info.freq = nl80211_get_assoc_freq(drv);
+
wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
}
@@ -2347,11 +2390,6 @@ static int nl80211_scan_filtered(struct wpa_driver_nl80211_data *drv,
}
-struct nl80211_bss_info_arg {
- struct wpa_driver_nl80211_data *drv;
- struct wpa_scan_results *res;
-};
-
static int bss_info_handler(struct nl_msg *msg, void *arg)
{
struct nlattr *tb[NL80211_ATTR_MAX + 1];
@@ -2377,6 +2415,7 @@ static int bss_info_handler(struct nl_msg *msg, void *arg)
const u8 *ie, *beacon_ie;
size_t ie_len, beacon_ie_len;
u8 *pos;
+ size_t i;
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
@@ -2385,6 +2424,19 @@ static int bss_info_handler(struct nl_msg *msg, void *arg)
if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
bss_policy))
return NL_SKIP;
+ if (bss[NL80211_BSS_STATUS]) {
+ enum nl80211_bss_status status;
+ status = nla_get_u32(bss[NL80211_BSS_STATUS]);
+ if (status == NL80211_BSS_STATUS_ASSOCIATED &&
+ bss[NL80211_BSS_FREQUENCY]) {
+ _arg->assoc_freq =
+ nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
+ wpa_printf(MSG_DEBUG, "nl80211: Associated on %u MHz",
+ _arg->assoc_freq);
+ }
+ }
+ if (!res)
+ return NL_SKIP;
if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
@@ -2455,6 +2507,38 @@ static int bss_info_handler(struct nl_msg *msg, void *arg)
}
}
+ /*
+ * cfg80211 maintains separate BSS table entries for APs if the same
+ * BSSID,SSID pair is seen on multiple channels. wpa_supplicant does
+ * not use frequency as a separate key in the BSS table, so filter out
+ * duplicated entries. Prefer associated BSS entry in such a case in
+ * order to get the correct frequency into the BSS table.
+ */
+ for (i = 0; i < res->num; i++) {
+ const u8 *s1, *s2;
+ if (os_memcmp(res->res[i]->bssid, r->bssid, ETH_ALEN) != 0)
+ continue;
+
+ s1 = nl80211_get_ie((u8 *) (res->res[i] + 1),
+ res->res[i]->ie_len, WLAN_EID_SSID);
+ s2 = nl80211_get_ie((u8 *) (r + 1), r->ie_len, WLAN_EID_SSID);
+ if (s1 == NULL || s2 == NULL || s1[1] != s2[1] ||
+ os_memcmp(s1, s2, 2 + s1[1]) != 0)
+ continue;
+
+ /* Same BSSID,SSID was already included in scan results */
+ wpa_printf(MSG_DEBUG, "nl80211: Remove duplicated scan result "
+ "for " MACSTR, MAC2STR(r->bssid));
+
+ if ((r->flags & WPA_SCAN_ASSOCIATED) &&
+ !(res->res[i]->flags & WPA_SCAN_ASSOCIATED)) {
+ os_free(res->res[i]);
+ res->res[i] = r;
+ } else
+ os_free(r);
+ return NL_SKIP;
+ }
+
tmp = os_realloc(res->res,
(res->num + 1) * sizeof(struct wpa_scan_res *));
if (tmp == NULL) {
diff --git a/src/eap_server/eap.h b/src/eap_server/eap.h
index 6b29075..e1f500a 100644
--- a/src/eap_server/eap.h
+++ b/src/eap_server/eap.h
@@ -110,6 +110,8 @@ struct eap_config {
const struct wpabuf *assoc_p2p_ie;
const u8 *peer_addr;
int fragment_size;
+
+ int pbc_in_m1;
};
diff --git a/src/eap_server/eap_i.h b/src/eap_server/eap_i.h
index daac746..3cba5aa 100644
--- a/src/eap_server/eap_i.h
+++ b/src/eap_server/eap_i.h
@@ -192,6 +192,8 @@ struct eap_sm {
/* Fragmentation size for EAP method init() handler */
int fragment_size;
+
+ int pbc_in_m1;
};
int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,
diff --git a/src/eap_server/eap_server.c b/src/eap_server/eap_server.c
index 41416b1..0f0da29 100644
--- a/src/eap_server/eap_server.c
+++ b/src/eap_server/eap_server.c
@@ -1261,6 +1261,7 @@ struct eap_sm * eap_server_sm_init(void *eapol_ctx,
os_memcpy(sm->peer_addr, conf->peer_addr, ETH_ALEN);
sm->fragment_size = conf->fragment_size;
sm->pwd_group = conf->pwd_group;
+ sm->pbc_in_m1 = conf->pbc_in_m1;
wpa_printf(MSG_DEBUG, "EAP: Server state machine created");
diff --git a/src/eap_server/eap_server_wsc.c b/src/eap_server/eap_server_wsc.c
index e944a4d..556882d 100644
--- a/src/eap_server/eap_server_wsc.c
+++ b/src/eap_server/eap_server_wsc.c
@@ -144,6 +144,7 @@ static void * eap_wsc_init(struct eap_sm *sm)
cfg.p2p_dev_addr = p2p_get_go_dev_addr(sm->assoc_p2p_ie);
}
#endif /* CONFIG_P2P */
+ cfg.pbc_in_m1 = sm->pbc_in_m1;
data->wps = wps_init(&cfg);
if (data->wps == NULL) {
os_free(data);
diff --git a/src/eapol_auth/eapol_auth_sm.c b/src/eapol_auth/eapol_auth_sm.c
index 841a1c5..4aa71ad 100644
--- a/src/eapol_auth/eapol_auth_sm.c
+++ b/src/eapol_auth/eapol_auth_sm.c
@@ -834,6 +834,7 @@ eapol_auth_alloc(struct eapol_authenticator *eapol, const u8 *addr,
eap_conf.peer_addr = addr;
eap_conf.fragment_size = eapol->conf.fragment_size;
eap_conf.pwd_group = eapol->conf.pwd_group;
+ eap_conf.pbc_in_m1 = eapol->conf.pbc_in_m1;
sm->eap = eap_server_sm_init(sm, &eapol_cb, &eap_conf);
if (sm->eap == NULL) {
eapol_auth_free(sm);
@@ -1039,6 +1040,7 @@ static int eapol_auth_conf_clone(struct eapol_auth_config *dst,
dst->eap_sim_db_priv = src->eap_sim_db_priv;
os_free(dst->eap_req_id_text);
dst->pwd_group = src->pwd_group;
+ dst->pbc_in_m1 = src->pbc_in_m1;
if (src->eap_req_id_text) {
dst->eap_req_id_text = os_malloc(src->eap_req_id_text_len);
if (dst->eap_req_id_text == NULL)
diff --git a/src/eapol_auth/eapol_auth_sm.h b/src/eapol_auth/eapol_auth_sm.h
index 59a10b4..724bf8b 100644
--- a/src/eapol_auth/eapol_auth_sm.h
+++ b/src/eapol_auth/eapol_auth_sm.h
@@ -42,6 +42,7 @@ struct eapol_auth_config {
struct wps_context *wps;
int fragment_size;
u16 pwd_group;
+ int pbc_in_m1;
/* Opaque context pointer to owner data for callback functions */
void *ctx;
diff --git a/src/wps/wps.c b/src/wps/wps.c
index 7564d60..5c8c25f 100644
--- a/src/wps/wps.c
+++ b/src/wps/wps.c
@@ -113,6 +113,7 @@ struct wps_data * wps_init(const struct wps_config *cfg)
os_memcpy(data->p2p_dev_addr, cfg->p2p_dev_addr, ETH_ALEN);
data->use_psk_key = cfg->use_psk_key;
+ data->pbc_in_m1 = cfg->pbc_in_m1;
return data;
}
diff --git a/src/wps/wps.h b/src/wps/wps.h
index 918273d..3e4c218 100644
--- a/src/wps/wps.h
+++ b/src/wps/wps.h
@@ -187,6 +187,14 @@ struct wps_config {
* to %NULL to indicate the station does not have a P2P Device Address.
*/
const u8 *p2p_dev_addr;
+
+ /**
+ * pbc_in_m1 - Do not remove PushButton config method in M1 (AP)
+ *
+ * This can be used to enable a workaround to allow Windows 7 to use
+ * PBC with the AP.
+ */
+ int pbc_in_m1;
};
struct wps_data * wps_init(const struct wps_config *cfg);
diff --git a/src/wps/wps_enrollee.c b/src/wps/wps_enrollee.c
index 390254e..5b3c045 100644
--- a/src/wps/wps_enrollee.c
+++ b/src/wps/wps_enrollee.c
@@ -133,10 +133,17 @@ static struct wpabuf * wps_build_m1(struct wps_data *wps)
return NULL;
config_methods = wps->wps->config_methods;
- if (wps->wps->ap) {
+ if (wps->wps->ap && !wps->pbc_in_m1 &&
+ (wps->dev_password_len != 0 ||
+ (config_methods & WPS_CONFIG_DISPLAY))) {
/*
* These are the methods that the AP supports as an Enrollee
* for adding external Registrars, so remove PushButton.
+ *
+ * As a workaround for Windows 7 mechanism for probing WPS
+ * capabilities from M1, leave PushButton option if no PIN
+ * method is available or if WPS configuration enables PBC
+ * workaround.
*/
config_methods &= ~WPS_CONFIG_PUSHBUTTON;
#ifdef CONFIG_WPS2
diff --git a/src/wps/wps_i.h b/src/wps/wps_i.h
index 437999b..bdb6da2 100644
--- a/src/wps/wps_i.h
+++ b/src/wps/wps_i.h
@@ -119,6 +119,7 @@ struct wps_data {
int use_psk_key;
u8 p2p_dev_addr[ETH_ALEN]; /* P2P Device Address of the client or
* 00:00:00:00:00:00 if not a P2p client */
+ int pbc_in_m1;
};
diff --git a/wpa_supplicant/README-WPS b/wpa_supplicant/README-WPS
index 6aa3a7b..93184e4 100644
--- a/wpa_supplicant/README-WPS
+++ b/wpa_supplicant/README-WPS
@@ -47,9 +47,7 @@ wpa_supplicant implementation
wpa_supplicant includes an optional WPS component that can be used as
an Enrollee to enroll new network credential or as a Registrar to
-configure an AP. The current version of wpa_supplicant does not
-support operation as an external WLAN Management Registrar for adding
-new client devices or configuring the AP over UPnP.
+configure an AP.
wpa_supplicant configuration
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index c540bd4..495f81d 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -757,28 +757,25 @@ wpa_supplicant_pick_new_network(struct wpa_supplicant *wpa_s)
/* TODO: move the rsn_preauth_scan_result*() to be called from notify.c based
* on BSS added and BSS changed events */
static void wpa_supplicant_rsn_preauth_scan_results(
- struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res)
+ struct wpa_supplicant *wpa_s)
{
- int i;
+ struct wpa_bss *bss;
if (rsn_preauth_scan_results(wpa_s->wpa) < 0)
return;
- for (i = scan_res->num - 1; i >= 0; i--) {
+ dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
const u8 *ssid, *rsn;
- struct wpa_scan_res *r;
-
- r = scan_res->res[i];
- ssid = wpa_scan_get_ie(r, WLAN_EID_SSID);
+ ssid = wpa_bss_get_ie(bss, WLAN_EID_SSID);
if (ssid == NULL)
continue;
- rsn = wpa_scan_get_ie(r, WLAN_EID_RSN);
+ rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
if (rsn == NULL)
continue;
- rsn_preauth_scan_result(wpa_s->wpa, r->bssid, ssid, rsn);
+ rsn_preauth_scan_result(wpa_s->wpa, bss->bssid, ssid, rsn);
}
}
@@ -946,8 +943,6 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
return 0;
}
- wpa_supplicant_rsn_preauth_scan_results(wpa_s, scan_res);
-
selected = wpa_supplicant_pick_network(wpa_s, scan_res, &ssid);
if (selected) {
@@ -958,6 +953,7 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
if (skip)
return 0;
wpa_supplicant_connect(wpa_s, selected, ssid);
+ wpa_supplicant_rsn_preauth_scan_results(wpa_s);
} else {
wpa_scan_results_free(scan_res);
wpa_dbg(wpa_s, MSG_DEBUG, "No suitable network found");
@@ -965,6 +961,7 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
if (ssid) {
wpa_dbg(wpa_s, MSG_DEBUG, "Setup a new network");
wpa_supplicant_associate(wpa_s, NULL, ssid);
+ wpa_supplicant_rsn_preauth_scan_results(wpa_s);
} else {
int timeout_sec = wpa_s->scan_interval;
int timeout_usec = 0;
@@ -1186,6 +1183,14 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
if (wpa_found || rsn_found)
wpa_s->ap_ies_from_associnfo = 1;
+ if (wpa_s->assoc_freq && data->assoc_info.freq &&
+ wpa_s->assoc_freq != data->assoc_info.freq) {
+ wpa_printf(MSG_DEBUG, "Operating frequency changed from "
+ "%u to %u MHz",
+ wpa_s->assoc_freq, data->assoc_info.freq);
+ wpa_supplicant_update_scan_results(wpa_s);
+ }
+
wpa_s->assoc_freq = data->assoc_info.freq;
return 0;
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index d7f7473..03d1672 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -3110,7 +3110,7 @@ static void wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured "
"frequency %d MHz", params->freq);
} else if (wpa_s->conf->p2p_oper_reg_class == 115 ||
- wpa_s->conf->p2p_oper_reg_class == 118) {
+ wpa_s->conf->p2p_oper_reg_class == 124) {
params->freq = 5000 + 5 * wpa_s->conf->p2p_oper_channel;
wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured "
"frequency %d MHz", params->freq);