From: Jouni Malinen Date: Mon, 16 May 2011 15:35:42 +0000 (+0300) Subject: Accumulative patch from commit 6d28fb9627155929012cda944aacd5a52ce7051a X-Git-Tag: android-x86-4.4-r1~235 X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fexternal-wpa_supplicant_8.git;a=commitdiff_plain;h=87fd279308af3f806848c8f2ab65ef18c6ac4c30 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 --- 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);