* Compare the capabilities of two entries and decide which is * more desirable (return >0 if a is considered better). Note * that we assume compatibility/usability has already been checked * so we don't need to (e.g. validate whether privacy is supported). * Used to select the best scan candidate for association in a BSS. * * TODO: should we take 11n, 11ac into account when selecting the *
| 868 | * best? Right now it just compares frequency band and RSSI. |
| 869 | */ |
| 870 | static int |
| 871 | sta_compare(const struct sta_entry *a, const struct sta_entry *b) |
| 872 | { |
| 873 | #define PREFER(_a,_b,_what) do { \ |
| 874 | if (((_a) ^ (_b)) & (_what)) \ |
| 875 | return ((_a) & (_what)) ? 1 : -1; \ |
| 876 | } while (0) |
| 877 | int maxa, maxb; |
| 878 | int8_t rssia, rssib; |
| 879 | int weight; |
| 880 | |
| 881 | /* privacy support */ |
| 882 | PREFER(a->base.se_capinfo, b->base.se_capinfo, |
| 883 | IEEE80211_CAPINFO_PRIVACY); |
| 884 | |
| 885 | /* compare count of previous failures */ |
| 886 | weight = b->se_fails - a->se_fails; |
| 887 | if (abs(weight) > 1) |
| 888 | return weight; |
| 889 | |
| 890 | /* |
| 891 | * Compare rssi. If the two are considered equivalent |
| 892 | * then fallback to other criteria. We threshold the |
| 893 | * comparisons to avoid selecting an ap purely by rssi |
| 894 | * when both values may be good but one ap is otherwise |
| 895 | * more desirable (e.g. an 11b-only ap with stronger |
| 896 | * signal than an 11g ap). |
| 897 | */ |
| 898 | rssia = MIN(a->base.se_rssi, STA_RSSI_MAX); |
| 899 | rssib = MIN(b->base.se_rssi, STA_RSSI_MAX); |
| 900 | if (abs(rssib - rssia) < 5) { |
| 901 | /* best/max rate preferred if signal level close enough XXX */ |
| 902 | maxa = maxrate(&a->base); |
| 903 | maxb = maxrate(&b->base); |
| 904 | if (maxa != maxb) |
| 905 | return maxa - maxb; |
| 906 | /* XXX use freq for channel preference */ |
| 907 | /* for now just prefer 5Ghz band to all other bands */ |
| 908 | PREFER(IEEE80211_IS_CHAN_5GHZ(a->base.se_chan), |
| 909 | IEEE80211_IS_CHAN_5GHZ(b->base.se_chan), 1); |
| 910 | } |
| 911 | /* all things being equal, use signal level */ |
| 912 | return a->base.se_rssi - b->base.se_rssi; |
| 913 | #undef PREFER |
| 914 | } |
| 915 | |
| 916 | /* |
| 917 | * Check rate set suitability and return the best supported rate. |
no test coverage detected