On Sun, Apr 29, 2018 at 11:51:26AM +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.
> 
> Paul, do you think this is approach fits into the larger context
> of your plans for RSSI? Or would it disturb you?

A first read suggest this is a good step in the direction I was planing
to go. I will look deeper into this the following days and come back
with a reply to this and the other emails from you here.

> 
> Index: ieee80211_node.c
> ===================================================================
> RCS file: /cvs/src/sys/net80211/ieee80211_node.c,v
> retrieving revision 1.129
> diff -u -p -r1.129 ieee80211_node.c
> --- ieee80211_node.c  28 Apr 2018 14:49:07 -0000      1.129
> +++ ieee80211_node.c  29 Apr 2018 09:08:05 -0000
> @@ -67,6 +67,8 @@ u_int8_t ieee80211_node_getrssi(struct i
>      const struct ieee80211_node *);
>  int ieee80211_node_checkrssi(struct ieee80211com *,
>      const struct ieee80211_node *);
> +int ieee80211_node_cmprssi(struct ieee80211com *,
> +    const struct ieee80211_node *, uint8_t);
>  void ieee80211_setup_node(struct ieee80211com *, struct ieee80211_node *,
>      const u_int8_t *);
>  void ieee80211_free_node(struct ieee80211com *, struct ieee80211_node *);
> @@ -133,6 +135,7 @@ ieee80211_node_attach(struct ifnet *ifp)
>       ic->ic_node_copy = ieee80211_node_copy;
>       ic->ic_node_getrssi = ieee80211_node_getrssi;
>       ic->ic_node_checkrssi = ieee80211_node_checkrssi;
> +     ic->ic_node_cmprssi = ieee80211_node_cmprssi;
>       ic->ic_scangen = 1;
>       ic->ic_max_nnodes = ieee80211_cache_size;
>  
> @@ -761,12 +764,15 @@ ieee80211_end_scan(struct ifnet *ifp)
>  
>               if (ic->ic_caps & IEEE80211_C_SCANALLBAND) {
>                       if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan) &&
> -                         (selbs2 == NULL || ni->ni_rssi > selbs2->ni_rssi))
> +                         (selbs2 == NULL ||
> +                         ic->ic_node_cmprssi(ic, ni, selbs2->ni_rssi) > 0))
>                               selbs2 = ni;
>                       else if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) &&
> -                         (selbs5 == NULL || ni->ni_rssi > selbs5->ni_rssi))
> +                         (selbs5 == NULL ||
> +                         ic->ic_node_cmprssi(ic, ni, selbs5->ni_rssi) > 0))
>                               selbs5 = ni;
> -             } else if (selbs == NULL || ni->ni_rssi > selbs->ni_rssi)
> +             } else if (selbs == NULL ||
> +                 ic->ic_node_cmprssi(ic, ni, selbs->ni_rssi) > 0)
>                       selbs = ni;
>       }
>  
> @@ -782,9 +788,12 @@ ieee80211_end_scan(struct ifnet *ifp)
>        */
>       if (selbs5 && selbs5->ni_rssi > min_5ghz_rssi)
>               selbs = selbs5;
> -     else if (selbs5 && selbs2)
> -             selbs = (selbs5->ni_rssi >= selbs2->ni_rssi ? selbs5 : selbs2);
> -     else if (selbs2)
> +     else if (selbs5 && selbs2) {
> +             if (ic->ic_node_cmprssi(ic, selbs5, selbs2->ni_rssi) >= 0)
> +                     selbs = selbs5;
> +             else
> +                     selbs = selbs2;
> +     } else if (selbs2)
>               selbs = selbs2;
>       else if (selbs5)
>               selbs = selbs5;
> @@ -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 */

Reply via email to