Date: Sun, 27 Nov 2005 01:15:52 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 87295 for review Message-ID: <200511270115.jAR1Fqql033673@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=87295 Change 87295 by sam@sam_ebb on 2005/11/27 01:15:08 tweak ap selection algorithm: o when comparing rssi cap values to avoid choosing an ap purely by the rssi; this fixes the case of choosing an 11b ap over an 11g ap when both have strong signal o treat ssid and bssid specifications as desired propertys and not requirements; this allows us to fall back to another ap without having to tweak desired ssid/bssid Affected files ... .. //depot/projects/wifi/sys/net80211/ieee80211_scan_sta.c#5 edit Differences ... ==== //depot/projects/wifi/sys/net80211/ieee80211_scan_sta.c#5 (text+ko) ==== @@ -65,6 +65,7 @@ /* XXX tunable */ #define STA_RSSI_MIN 8 /* min acceptable rssi */ +#define STA_RSSI_MAX 40 /* max rssi for comparison */ #define RSSI_LPF_LEN 10 #define RSSI_EP_MULTIPLIER (1<<7) /* pow2 to optimize out * and / */ @@ -85,6 +86,9 @@ u_int8_t se_fails; /* failure to associate count */ u_int8_t se_seen; /* seen during current scan */ u_int8_t se_notseen; /* not seen in previous scans */ + u_int8_t se_flags; +#define STA_SSID_MATCH 0x01 +#define STA_BSSID_MATCH 0x02 u_int32_t se_avgrssi; /* LPF rssi state */ unsigned long se_lastupdate; /* time of last update */ unsigned long se_lastfail; /* time of last failure */ @@ -108,7 +112,7 @@ static void sta_flush_table(struct sta_table *); static int match_bss(struct ieee80211com *, - const struct ieee80211_scan_state *, const struct sta_entry *, int); + const struct ieee80211_scan_state *, struct sta_entry *, int); /* number of references from net80211 layer */ static int nrefs = 0; @@ -602,22 +606,35 @@ sta_compare(const struct sta_entry *a, const struct sta_entry *b) { u_int8_t maxa, maxb; + int8_t rssia, rssib; int weight; - /* privacy support preferred */ - if ((a->base.se_capinfo & IEEE80211_CAPINFO_PRIVACY) && - (b->base.se_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0) - return 1; - if ((a->base.se_capinfo & IEEE80211_CAPINFO_PRIVACY) == 0 && - (b->base.se_capinfo & IEEE80211_CAPINFO_PRIVACY)) - return -1; + /* desired bssid */ + if ((a->se_flags ^ b->se_flags) & STA_BSSID_MATCH) + return (a->se_flags & STA_BSSID_MATCH) ? 1 : -1; + /* desired ssid */ + if ((a->se_flags ^ b->se_flags) & STA_SSID_MATCH) + return (a->se_flags & STA_SSID_MATCH) ? 1 : -1; + /* privacy support */ + if ((a->base.se_capinfo ^ b->base.se_capinfo) & IEEE80211_CAPINFO_PRIVACY) + return (a->se_flags & IEEE80211_CAPINFO_PRIVACY) ? 1 : -1; /* compare count of previous failures */ weight = b->se_fails - a->se_fails; if (abs(weight) > 1) return weight; - if (abs(b->base.se_rssi - a->base.se_rssi) < 5) { + /* + * Compare rssi. If the two are considered equivalent + * then fallback to other criteria. We threshold the + * comparisons to avoid selecting an ap purely by rssi + * when both values may be good but one ap is otherwise + * more desirable (e.g. an 11b-only ap with stronger + * rssi than an 11g ap). + */ + rssia = MIN(a->base.se_rssi, STA_RSSI_MAX); + rssib = MIN(b->base.se_rssi, STA_RSSI_MAX); + if (abs(rssib - rssia) < 5) { /* best/max rate preferred if signal level close enough XXX */ maxa = maxrate(&a->base); maxb = maxrate(&b->base); @@ -710,10 +727,10 @@ */ static int match_bss(struct ieee80211com *ic, - const struct ieee80211_scan_state *ss, const struct sta_entry *se0, + const struct ieee80211_scan_state *ss, struct sta_entry *se0, int debug) { - const struct ieee80211_scan_entry *se = &se0->base; + struct ieee80211_scan_entry *se = &se0->base; u_int8_t rate; int fail; @@ -750,11 +767,15 @@ if (rate & IEEE80211_RATE_BASIC) fail |= 0x08; if (ss->ss_nssid != 0 && - !match_ssid(se->se_ssid, ss->ss_nssid, ss->ss_ssid)) - fail |= 0x10; + match_ssid(se->se_ssid, ss->ss_nssid, ss->ss_ssid)) + se0->se_flags |= STA_SSID_MATCH; + else + se0->se_flags &= ~STA_SSID_MATCH; if ((ic->ic_flags & IEEE80211_F_DESBSSID) && - !IEEE80211_ADDR_EQ(ic->ic_des_bssid, se->se_bssid)) - fail |= 0x20; + IEEE80211_ADDR_EQ(ic->ic_des_bssid, se->se_bssid)) + se0->se_flags |= STA_BSSID_MATCH; + else + se0->se_flags &= ~STA_BSSID_MATCH; if (se0->se_fails >= STA_FAILS_MAX) fail |= 0x40; if (se0->se_notseen >= STA_PURGE_SCANS) @@ -767,7 +788,7 @@ fail & 0x40 ? '=' : fail & 0x80 ? '^' : fail ? '-' : '+', ether_sprintf(se->se_macaddr)); printf(" %s%c", ether_sprintf(se->se_bssid), - fail & 0x20 ? '!' : ' '); + se0->se_flags & STA_BSSID_MATCH ? '!' : ' '); printf(" %3d%c", ieee80211_chan2ieee(ic, se->se_chan), fail & 0x01 ? '!' : ' '); printf(" %+4d%c", se->se_rssi, fail & 0x100 ? '!' : ' '); @@ -783,7 +804,7 @@ "wep" : "no", fail & 0x04 ? '!' : ' '); ieee80211_print_essid(se->se_ssid+2, se->se_ssid[1]); - printf("%s\n", fail & 0x10 ? "!" : ""); + printf("%s\n", se0->se_flags & STA_SSID_MATCH ? "!" : ""); } #endif return fail;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200511270115.jAR1Fqql033673>