From d009a9dac6d0adc71f9cd1810ad44d01f1694d19 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 28 Dec 2009 13:34:03 +0200 Subject: [PATCH] Add scan parameter support for client MLME --- wpa_supplicant/mlme.c | 51 ++++++++++++++++++++++++++++--- wpa_supplicant/mlme.h | 15 ++------- wpa_supplicant/scan.c | 9 ++---- wpa_supplicant/wpa_supplicant_i.h | 1 + 4 files changed, 53 insertions(+), 23 deletions(-) diff --git a/wpa_supplicant/mlme.c b/wpa_supplicant/mlme.c index 54dfc0e2f..ee2df2b81 100644 --- a/wpa_supplicant/mlme.c +++ b/wpa_supplicant/mlme.c @@ -96,6 +96,8 @@ static int ieee80211_sta_wep_configured(struct wpa_supplicant *wpa_s); static void ieee80211_sta_timer(void *eloop_ctx, void *timeout_ctx); static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx); static void ieee80211_build_tspec(struct wpabuf *buf); +static int ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s, + const u8 *ies, size_t ies_len); static int ieee80211_sta_set_channel(struct wpa_supplicant *wpa_s, @@ -202,6 +204,7 @@ static void ieee80211_set_associated(struct wpa_supplicant *wpa_s, int assoc) data.assoc_info.req_ies_len = wpa_s->mlme.assocreq_ies_len; data.assoc_info.resp_ies = wpa_s->mlme.assocresp_ies; data.assoc_info.resp_ies_len = wpa_s->mlme.assocresp_ies_len; + data.assoc_info.freq = wpa_s->mlme.freq; wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data); } else { wpa_supplicant_event(wpa_s, EVENT_DISASSOC, NULL); @@ -2131,6 +2134,8 @@ static void ieee80211_sta_expire(struct wpa_supplicant *wpa_s) static void ieee80211_sta_merge_ibss(struct wpa_supplicant *wpa_s) { + struct wpa_driver_scan_params params; + ieee80211_reschedule_timer(wpa_s, IEEE80211_IBSS_MERGE_INTERVAL); ieee80211_sta_expire(wpa_s); @@ -2139,7 +2144,11 @@ static void ieee80211_sta_merge_ibss(struct wpa_supplicant *wpa_s) wpa_printf(MSG_DEBUG, "MLME: No active IBSS STAs - trying to scan for " "other IBSS networks with same SSID (merge)"); - ieee80211_sta_req_scan(wpa_s, wpa_s->mlme.ssid, wpa_s->mlme.ssid_len); + os_memset(¶ms, 0, sizeof(params)); + params.ssids[0].ssid = wpa_s->mlme.ssid; + params.ssids[0].ssid_len = wpa_s->mlme.ssid_len; + params.num_ssids = wpa_s->mlme.ssid ? 1 : 0; + ieee80211_sta_req_scan(wpa_s, ¶ms); } @@ -2763,6 +2772,17 @@ static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx) mode->mode == HOSTAPD_MODE_IEEE80211B && wpa_s->mlme.scan_skip_11b)) skip = 1; + if (!skip && wpa_s->mlme.scan_freqs) { + int i, found = 0; + for (i = 0; wpa_s->mlme.scan_freqs[i]; i++) { + if (wpa_s->mlme.scan_freqs[i] == chan->freq) { + found = 1; + break; + } + } + if (!found) + skip = 1; + } if (!skip) { wpa_printf(MSG_MSGDUMP, @@ -2816,9 +2836,12 @@ static void ieee80211_sta_scan_timer(void *eloop_ctx, void *timeout_ctx) } -int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, const u8 *ssid, - size_t ssid_len) +int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, + struct wpa_driver_scan_params *params) { + const u8 *ssid = params->ssids[0].ssid; + size_t ssid_len = params->ssids[0].ssid_len; + if (ssid_len > MAX_SSID_LEN) return -1; @@ -2847,6 +2870,21 @@ int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, const u8 *ssid, wpa_printf(MSG_DEBUG, "MLME: starting scan"); + ieee80211_sta_set_probe_req_ie(wpa_s, params->extra_ies, + params->extra_ies_len); + + os_free(wpa_s->mlme.scan_freqs); + if (params->freqs) { + int i; + for (i = 0; params->freqs[i]; i++) + ; + wpa_s->mlme.scan_freqs = os_malloc((i + 1) * sizeof(int)); + if (wpa_s->mlme.scan_freqs) + os_memcpy(wpa_s->mlme.scan_freqs, params->freqs, + (i + 1) * sizeof(int)); + } else + wpa_s->mlme.scan_freqs = NULL; + ieee80211_sta_save_oper_chan(wpa_s); wpa_s->mlme.sta_scanning = 1; @@ -3084,6 +3122,9 @@ void ieee80211_sta_deinit(struct wpa_supplicant *wpa_s) wpa_s->mlme.ft_ies = NULL; wpa_s->mlme.ft_ies_len = 0; #endif /* CONFIG_IEEE80211R */ + + os_free(wpa_s->mlme.scan_freqs); + wpa_s->mlme.scan_freqs = NULL; } @@ -3167,8 +3208,8 @@ int ieee80211_sta_send_ft_action(struct wpa_supplicant *wpa_s, u8 action, #endif /* CONFIG_IEEE80211R */ -int ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s, const u8 *ies, - size_t ies_len) +static int ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s, + const u8 *ies, size_t ies_len) { os_free(wpa_s->mlme.extra_probe_ie); wpa_s->mlme.extra_probe_ie = NULL; diff --git a/wpa_supplicant/mlme.h b/wpa_supplicant/mlme.h index 5d8975291..ee57dfbd9 100644 --- a/wpa_supplicant/mlme.h +++ b/wpa_supplicant/mlme.h @@ -23,8 +23,8 @@ struct wpa_supplicant; int ieee80211_sta_init(struct wpa_supplicant *wpa_s); void ieee80211_sta_deinit(struct wpa_supplicant *wpa_s); -int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, const u8 *ssid, - size_t ssid_len); +int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, + struct wpa_driver_scan_params *params); int ieee80211_sta_deauthenticate(struct wpa_supplicant *wpa_s, u16 reason); int ieee80211_sta_disassociate(struct wpa_supplicant *wpa_s, u16 reason); int ieee80211_sta_associate(struct wpa_supplicant *wpa_s, @@ -42,8 +42,6 @@ int ieee80211_sta_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md, int ieee80211_sta_send_ft_action(struct wpa_supplicant *wpa_s, u8 action, const u8 *target_ap, const u8 *ies, size_t ies_len); -int ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s, const u8 *ies, - size_t ies_len); #else /* CONFIG_CLIENT_MLME */ @@ -57,7 +55,7 @@ static inline void ieee80211_sta_deinit(struct wpa_supplicant *wpa_s) } static inline int ieee80211_sta_req_scan(struct wpa_supplicant *wpa_s, - const u8 *ssid, size_t ssid_len) + struct wpa_driver_scan_params *params) { return -1; } @@ -120,13 +118,6 @@ ieee80211_sta_send_ft_action(struct wpa_supplicant *wpa_s, u8 action, return -1; } -static inline int -ieee80211_sta_set_probe_req_ie(struct wpa_supplicant *wpa_s, const u8 *ies, - size_t ies_len) -{ - return -1; -} - #endif /* CONFIG_CLIENT_MLME */ #endif /* MLME_H */ diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index 895bf4ce6..71290906f 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -186,12 +186,9 @@ int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s, wpa_supplicant_notify_scanning(wpa_s, 1); - if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) { - ieee80211_sta_set_probe_req_ie(wpa_s, params->extra_ies, - params->extra_ies_len); - ret = ieee80211_sta_req_scan(wpa_s, params->ssids[0].ssid, - params->ssids[0].ssid_len); - } else + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) + ret = ieee80211_sta_req_scan(wpa_s, params); + else ret = wpa_drv_scan(wpa_s, params); if (ret) { diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 18d0bf6e2..24c349d5c 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -262,6 +262,7 @@ struct wpa_client_mlme { u8 scan_ssid[32]; size_t scan_ssid_len; int scan_skip_11b; + int *scan_freqs; struct ieee80211_sta_bss *sta_bss_list; #define STA_HASH_SIZE 256