diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index c6538c9ed..a057880f0 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -990,6 +990,31 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, return 1; } + +static int wpa_supplicant_assoc_update_ie(struct wpa_supplicant *wpa_s) +{ + const u8 *bss_wpa = NULL, *bss_rsn = NULL; + + if (!wpa_s->current_bss || !wpa_s->current_ssid) + return -1; + + if (!wpa_key_mgmt_wpa_any(wpa_s->current_ssid->key_mgmt)) + return 0; + + bss_wpa = wpa_bss_get_vendor_ie(wpa_s->current_bss, + WPA_IE_VENDOR_TYPE); + bss_rsn = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_RSN); + + if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa, + bss_wpa ? 2 + bss_wpa[1] : 0) || + wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn, + bss_rsn ? 2 + bss_rsn[1] : 0)) + return -1; + + return 0; +} + + /* Return < 0 if no scan results could be fetched. */ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, union wpa_event_data *data) @@ -1356,6 +1381,21 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, } +static struct wpa_bss * wpa_supplicant_get_new_bss( + struct wpa_supplicant *wpa_s, const u8 *bssid) +{ + struct wpa_bss *bss = NULL; + struct wpa_ssid *ssid = wpa_s->current_ssid; + + if (ssid->ssid_len > 0) + bss = wpa_bss_get(wpa_s, bssid, ssid->ssid, ssid->ssid_len); + if (!bss) + bss = wpa_bss_get_bssid(wpa_s, bssid); + + return bss; +} + + static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { @@ -1401,15 +1441,25 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, } if (wpa_s->current_ssid) { struct wpa_bss *bss = NULL; - struct wpa_ssid *ssid = wpa_s->current_ssid; - if (ssid->ssid_len > 0) - bss = wpa_bss_get(wpa_s, bssid, - ssid->ssid, ssid->ssid_len); - if (!bss) - bss = wpa_bss_get_bssid(wpa_s, bssid); + + bss = wpa_supplicant_get_new_bss(wpa_s, bssid); + if (!bss) { + wpa_supplicant_update_scan_results(wpa_s); + + /* Get the BSS from the new scan results */ + bss = wpa_supplicant_get_new_bss(wpa_s, bssid); + } + if (bss) wpa_s->current_bss = bss; } + + if (wpa_s->conf->ap_scan == 1 && + wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION) { + if (wpa_supplicant_assoc_update_ie(wpa_s) < 0) + wpa_msg(wpa_s, MSG_WARNING, + "WPA/RSN IEs not updated"); + } } #ifdef CONFIG_SME