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