diff -ur wpa_supplicant-0.6.4/src/drivers/driver.h wpa_supplicant-0.6.4_us//src/drivers/driver.h --- wpa_supplicant-0.6.4/src/drivers/driver.h 2008-08-10 19:33:12.000000000 +0200 +++ wpa_supplicant-0.6.4_us//src/drivers/driver.h 2008-09-24 10:02:00.000000000 +0200 @@ -1052,7 +1052,13 @@ * FT authentication sequence from the AP. The FT IEs are included in * the extra information in union wpa_event_data::ft_ies. */ - EVENT_FT_RESPONSE + EVENT_FT_RESPONSE, + + /** + * EVENT_ROAMING_THRESHOLD - Roaming threshold exceeded + */ + EVENT_ROAMING_THRESHOLD + } wpa_event_type; Nur in wpa_supplicant-0.6.4_us//src/drivers: driver_hostap.d. Nur in wpa_supplicant-0.6.4_us//src/drivers: driver_hostap.o. Nur in wpa_supplicant-0.6.4_us//src/drivers: drivers.d. Nur in wpa_supplicant-0.6.4_us//src/drivers: drivers.o. diff -ur wpa_supplicant-0.6.4/src/drivers/driver_wext.c wpa_supplicant-0.6.4_us//src/drivers/driver_wext.c --- wpa_supplicant-0.6.4/src/drivers/driver_wext.c 2008-08-10 19:33:12.000000000 +0200 +++ wpa_supplicant-0.6.4_us//src/drivers/driver_wext.c 2008-09-29 13:08:54.000000000 +0200 @@ -643,10 +642,18 @@ drv->assoc_req_ies = NULL; os_free(drv->assoc_resp_ies); drv->assoc_resp_ies = NULL; + + /* stop monitoring the signal quality */ + eloop_cancel_timeout(wpa_driver_wext_monitor_quality, drv, drv->ctx); + wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL); } else { + /* start monitoring the signal quality */ + eloop_register_timeout(5, 0, wpa_driver_wext_monitor_quality, drv, + drv->ctx); + wpa_driver_wext_event_assoc_ies(drv); wpa_supplicant_event(ctx, EVENT_ASSOC, NULL); } @@ -1206,6 +1213,60 @@ wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); } +/** + * wpa_driver_wext_monitor_quality - Monitor the signal quality + * @eloop_ctx: Unused + * @timeout_ctx: ctx argument given to wpa_driver_wext_init() + */ +void wpa_driver_wext_monitor_quality(void *eloop_ctx, void *timeout_ctx) +{ + struct iwreq iwr; + struct iw_statistics stats; + struct wpa_driver_wext_data *drv = (struct wpa_driver_wext_data *) eloop_ctx; + int timeout_sec; + + os_memset(&iwr, 0, sizeof(iwr)); + os_memset(&stats, 0, sizeof(stats)); + + os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); + + iwr.u.data.pointer = (caddr_t) &stats; + iwr.u.data.length = sizeof(stats); + iwr.u.data.flags = 1; + + if (ioctl(drv->ioctl_sock, SIOCGIWSTATS, &iwr) < 0) { + perror("ioctl[SIOCGIWSTATS]"); + return; + } + + if (stats.qual.qual < (int) (0.4f * (float)drv->max_qual)) + { + if (++drv->low_signal_count >= 3) + { + wpa_printf(MSG_DEBUG, "Signal quality low (%i/%i)", stats.qual.qual, drv->max_qual); + drv->low_signal_count = 0; + wpa_supplicant_event(drv->ctx, EVENT_ROAMING_THRESHOLD, NULL); + /* next measurement in 5 seconds */ + eloop_register_timeout(5, 0, wpa_driver_wext_monitor_quality, drv, drv->ctx); + } + else + { + /* next measurment in 100ms */ + eloop_register_timeout(0, 100000, wpa_driver_wext_monitor_quality, drv, drv->ctx); + } + return; + } + drv->low_signal_count = 0; + + if (stats.qual.qual < (int) (0.6f * (float)drv->max_qual)) + timeout_sec = 2; + else if (stats.qual.qual < (int) (0.8f * (float)drv->max_qual)) + timeout_sec = 5; + else + timeout_sec = 10; + + eloop_register_timeout(timeout_sec, 0, wpa_driver_wext_monitor_quality, drv, drv->ctx); +} /** * wpa_driver_wext_scan - Request the driver to initiate scan @@ -1753,6 +1813,7 @@ if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE) drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE; + drv->max_qual = range->max_qual.qual; wpa_printf(MSG_DEBUG, " capabilities: key_mgmt 0x%x enc 0x%x " "flags 0x%x", drv->capa.key_mgmt, drv->capa.enc, drv->capa.flags); Nur in wpa_supplicant-0.6.4_us//src/drivers: driver_wext.d. diff -ur wpa_supplicant-0.6.4/src/drivers/driver_wext.h wpa_supplicant-0.6.4_us//src/drivers/driver_wext.h --- wpa_supplicant-0.6.4/src/drivers/driver_wext.h 2008-08-10 19:33:12.000000000 +0200 +++ wpa_supplicant-0.6.4_us//src/drivers/driver_wext.h 2008-09-24 10:52:23.000000000 +0200 @@ -43,6 +43,8 @@ char mlmedev[IFNAMSIZ + 1]; int scan_complete_events; + int low_signal_count; + int max_qual; }; int wpa_driver_wext_get_ifflags(struct wpa_driver_wext_data *drv, int *flags); @@ -61,6 +63,7 @@ struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv); void wpa_driver_wext_scan_timeout(void *eloop_ctx, void *timeout_ctx); +void wpa_driver_wext_monitor_quality(void *eloop_ctx, void *timeout_ctx); int wpa_driver_wext_alternative_ifindex(struct wpa_driver_wext_data *drv, const char *ifname); diff -ur wpa_supplicant-0.6.4/wpa_supplicant/config.c wpa_supplicant-0.6.4_us//wpa_supplicant/config.c --- wpa_supplicant-0.6.4/wpa_supplicant/config.c 2008-08-10 19:33:12.000000000 +0200 +++ wpa_supplicant-0.6.4_us//wpa_supplicant/config.c 2008-09-29 13:13:31.000000000 +0200 @@ -1883,6 +1883,7 @@ config->eapol_version = DEFAULT_EAPOL_VERSION; config->ap_scan = DEFAULT_AP_SCAN; config->fast_reauth = DEFAULT_FAST_REAUTH; + config->roaming = DEFAULT_ROAMING; if (ctrl_interface) config->ctrl_interface = os_strdup(ctrl_interface); Nur in wpa_supplicant-0.6.4_us//wpa_supplicant: config.d. diff -ur wpa_supplicant-0.6.4/wpa_supplicant/config_file.c wpa_supplicant-0.6.4_us//wpa_supplicant/config_file.c --- wpa_supplicant-0.6.4/wpa_supplicant/config_file.c 2008-08-10 19:33:12.000000000 +0200 +++ wpa_supplicant-0.6.4_us//wpa_supplicant/config_file.c 2008-09-29 13:20:10.000000000 +0200 @@ -312,6 +312,12 @@ return 0; } +static int wpa_config_process_roaming(struct wpa_config *config, char *pos) +{ + config->roaming = atoi(pos); + wpa_printf(MSG_DEBUG, "roaming=%d", config->roaming); + return 0; +} static int wpa_config_process_fast_reauth(struct wpa_config *config, char *pos) { @@ -445,6 +451,9 @@ if (os_strncmp(pos, "ap_scan=", 8) == 0) return wpa_config_process_ap_scan(config, pos + 8); + if (os_strncmp(pos, "roaming=", 8) == 0) + return wpa_config_process_roaming(config, pos + 8); + if (os_strncmp(pos, "fast_reauth=", 12) == 0) return wpa_config_process_fast_reauth(config, pos + 12); Nur in wpa_supplicant-0.6.4_us//wpa_supplicant: config_file.d. Nur in wpa_supplicant-0.6.4_us//wpa_supplicant: config_file.o. diff -ur wpa_supplicant-0.6.4/wpa_supplicant/config.h wpa_supplicant-0.6.4_us//wpa_supplicant/config.h --- wpa_supplicant-0.6.4/wpa_supplicant/config.h 2008-08-10 19:33:12.000000000 +0200 +++ wpa_supplicant-0.6.4_us//wpa_supplicant/config.h 2008-09-29 13:13:49.000000000 +0200 @@ -22,6 +22,7 @@ #define DEFAULT_AP_SCAN 1 #endif /* CONFIG_NO_SCAN_PROCESSING */ #define DEFAULT_FAST_REAUTH 1 +#define DEFAULT_ROAMING 0 #include "config_ssid.h" @@ -244,6 +245,11 @@ int update_config; /** + * roaming + */ + int roaming; + + /** * blobs - Configuration blobs */ struct wpa_config_blob *blobs; Nur in wpa_supplicant-0.6.4_us//wpa_supplicant: config.o. Nur in wpa_supplicant-0.6.4_us//wpa_supplicant: ctrl_iface.d. Nur in wpa_supplicant-0.6.4_us//wpa_supplicant: ctrl_iface.o. Nur in wpa_supplicant-0.6.4_us//wpa_supplicant: ctrl_iface_unix.d. Nur in wpa_supplicant-0.6.4_us//wpa_supplicant: ctrl_iface_unix.o. diff -ur wpa_supplicant-0.6.4/wpa_supplicant/events.c wpa_supplicant-0.6.4_us//wpa_supplicant/events.c --- wpa_supplicant-0.6.4/wpa_supplicant/events.c 2008-08-10 19:33:12.000000000 +0200 +++ wpa_supplicant-0.6.4_us//wpa_supplicant/events.c 2008-09-29 13:16:12.000000000 +0200 @@ -613,6 +613,11 @@ } #endif /* CONFIG_NO_SCAN_PROCESSING */ +static void wpa_supplicant_event_roaming_threshold(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->conf->roaming > 0) + wpa_supplicant_req_scan(wpa_s, 0, 0); +} static void wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, union wpa_event_data *data) @@ -955,6 +960,9 @@ wpa_supplicant_event_ft_response(wpa_s, data); break; #endif /* CONFIG_IEEE80211R */ + case EVENT_ROAMING_THRESHOLD: + wpa_supplicant_event_roaming_threshold(wpa_s); + break; default: wpa_printf(MSG_INFO, "Unknown event %d", event); break;