The current roaming algorithm is incorrect. The main issue is the presence of roaming gaps in specific regions of the defined signal levels in wpa_supplicant_need_to_roam(). The following table illustrates these gaps. These gaps are introduced due to the comparison of absolute integer values instead of a signed comparison. For example, in the preferred 5 GHz signal level range (-80,-75) roaming will occur at delta (selected - current) levels of -2, -1 and > 1 dBm. In this case, no roaming is permitted with the delta value equal to 0. Similar circumstances occur in the range (-75,-70). The second issue is related to the handling of positive signal levels. Although, this is not a physically common use case due to the limit on the WiFi signal power level. Nevertheless, it is being handled incorrectly by the algorithm. First, for the preferred 5GHz signal levels, roaming will happen at any value, as the calculated absolute |current - select| is never < 0. Second, when operating frequency is similar, i.e. both are 5 or both 2.4 GHz, roaming with positive signal level will occur at a signal level delta of <-2 and >2. Hence, a gap is present where no roaming is possible at -1, 0 and 1 dBm. Current Broken State ==================== Standard Roam Criteria (both select and current frequences are either 2.4 or 5 GHz) ----------------------------------------------------------------------------------------------------------------- Current Level < -85 selected - current >= 1 min_diff = 1 -85 < Current Level < -80 selected - current >= 2 min_diff = 2 -80 < Current Level < -75 selected - current >= 3 min_diff = 3 -75 < Current Level < -70 selected - current >= 4 min_diff = 4 -70 < Current Level < 0 selected - current >= 5 min_diff = 5 Current Level > 0 selected - current >= 2 min_diff = 2 ( Roams at delta < -2, > 2 , gap at delta -1 0 1 ) Preferred 5GHz ( current channel frequency 2.4 and select frequency is 5.0 GHz) ------------------------------------------------------------------------------------------------------------- Current Level < -85 selected - current >= -2 min_diff = 0 -85 < Current Level < -80 selected - current >= -2 min_diff = 0 -80 < Current Level < -75 selected - current >= 1 min_diff = 1 ( roams at delta -2, -1 and > 1, does not roam at delta 0 ) -75 < Current Level < -70 selected - current >= 2 min_diff = 2 ( roams at delta -2 and > 2, does not roam at delta -1 0 1 ) -70 < Current Level < 0 selected - current >= 3 min_diff = 3 Current Level > 0 selected - current >= any min_diff = 0 The proposed fix in the attached patch eliminates incorrect roams. The following data was collected from the revised algorithm implementation. Proposed Fix ============ Standard Roam Criteria (both select and current frequences are either 2.4 or 5 GHz) ------------------------------------------------------------------------------------ Current Level < -85 selected - current >= 1 min_diff = 1 -85 < Current Level < -80 selected - current >= 2 min_diff = 2 -80 < Current Level < -75 selected - current >= 3 min_diff = 3 -75 < Current Level < -70 selected - current >= 4 min_diff = 4 Current Level > -70 selected - current >= 5 min_diff = 5 Preferred 5GHz ( current channel frequency 2.4 and select frequency is 5.0 GHz) ------------------------------------------------------------------------------------ Current Level < -85 selected - current >= -2 min_diff = -2 -85 < Current Level < -80 selected - current >= -2 min_diff = -2 -80 < Current Level < -75 selected - current >= 1 min_diff = 1 -75 < Current Level < -70 selected - current >= 2 min_diff = 2 Current Level > -70 selected - current >= 3 min_diff = 3 Signed-off-by: Iyad Qumei <iyad.qumei@xxxxxxxxxxx> --- wpa_supplicant/events.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index fb77f1d..64a2a54 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1700,7 +1700,7 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, cur_est = current_bss->est_throughput; sel_est = selected->est_throughput; min_diff = 2; - if (current_bss->level < 0) { + { if (current_bss->level < -85) min_diff = 1; else if (current_bss->level < -80) @@ -1734,9 +1734,9 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, if (min_diff > reduce) min_diff -= reduce; else - min_diff = 0; + min_diff = -2; } - diff = abs(current_bss->level - selected->level); + diff = (selected->level - current_bss->level); if (diff < min_diff) { wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - too small difference in signal level (%d < %d)", -- 2.7.4 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap