On 2018 Apr 29 (Sun) at 11:51:26 +0200 (+0200), Stefan Sperling wrote:
:This diff tries to avoid situations where background scans play
:ping-pong between different APs with nearly equal RSSI, as
:observed by phessler.
:
:Not all drivers represent RSSI values in dBm or percentage, so the
:diff includes the possibility for drivers to override the new RSSI
:comparison function. However, since the threshold is rather low
:applying this to all drivers for now should not do any harm, unless
:there is a driver where the RSSI value range is ridiculously small.
:I'm not aware of any such driver at present.
:
I'm concerned about two things.
The usage is confusing, because you pass two incompatible things to be
compared. I would prefer ieee80211_node_cmprssi(ic, rssi_one, rssi_two).
Also, in the case where ni->ni_rssi has a very weak signal, the second
comparison can underflow.
:@@ -991,6 +1000,31 @@ ieee80211_node_checkrssi(struct ieee8021
: return (ni->ni_rssi >= (u_int8_t)thres);
: }
:
:+/*
:+ * Determine if an RSSI value is significantly different from the
:+ * RSSI stored in a node structure. This function assumes RSSI values
:+ * are represented either dBm or as a percentage of ic_max_rssi.
:+ * Drivers should override this function in case their RSSI
:+ * values use a different representation.
:+ */
:+int
:+ieee80211_node_cmprssi(struct ieee80211com *ic,
:+ const struct ieee80211_node *ni, uint8_t rssi)
:+{
:+ uint8_t thres;
:+
:+ if (ic->ic_max_rssi)
:+ thres = IEEE80211_RSSI_CMP_THRES_RATIO;
:+ else
:+ thres = IEEE80211_RSSI_CMP_THRES;
:+
:+ if (ni->ni_rssi + thres < rssi)
:+ return -1;
:+ if (ni->ni_rssi - thres > rssi)
:+ return 1;
:+ return 0;
:+}
:+
: void
: ieee80211_setup_node(struct ieee80211com *ic,
: struct ieee80211_node *ni, const u_int8_t *macaddr)
:@@ -1259,7 +1293,8 @@ ieee80211_find_node_for_beacon(struct ie
: if ((ni = ieee80211_find_node(ic, macaddr)) != NULL) {
: s = splnet();
:
:- if (ni->ni_chan != chan && ni->ni_rssi >= rssi)
:+ if (ni->ni_chan != chan &&
:+ ic->ic_node_cmprssi(ic, ni, rssi) >= 0)
: score++;
: if (ssid[1] == 0 && ni->ni_esslen != 0)
: score++;
:Index: ieee80211_var.h
:===================================================================
:RCS file: /cvs/src/sys/net80211/ieee80211_var.h,v
:retrieving revision 1.85
:diff -u -p -r1.85 ieee80211_var.h
:--- ieee80211_var.h 26 Apr 2018 12:50:07 -0000 1.85
:+++ ieee80211_var.h 29 Apr 2018 08:54:20 -0000
:@@ -62,6 +62,9 @@
: #define IEEE80211_RSSI_THRES_RATIO_2GHZ 60 /* in percent */
: #define IEEE80211_RSSI_THRES_RATIO_5GHZ 50 /* in percent */
:
:+#define IEEE80211_RSSI_CMP_THRES 8 /* in dBm */
:+#define IEEE80211_RSSI_CMP_THRES_RATIO 5 /* in percent */
:+
: #define IEEE80211_BGSCAN_FAIL_MAX 360 /* units of 500 msec */
:
: enum ieee80211_phytype {
:@@ -270,6 +273,8 @@ struct ieee80211com {
: const struct ieee80211_node *);
: int (*ic_node_checkrssi)(struct ieee80211com *,
: const struct ieee80211_node *);
:+ int (*ic_node_cmprssi)(struct ieee80211com *,
:+ const struct ieee80211_node *, uint8_t);
: u_int8_t ic_max_rssi;
: struct ieee80211_tree ic_tree;
: int ic_nnodes; /* length of ic_nnodes */
:
--
Illinois isn't exactly the land that God forgot -- it's more like the
land He's trying to ignore.