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.

Reply via email to