PERFORCE change 87295 for review
Sam Leffler
sam at FreeBSD.org
Sun Nov 27 01:16:06 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=87295
Change 87295 by sam at 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;
More information about the p4-projects
mailing list