}
-void scan_est_throughput(struct wpa_supplicant *wpa_s,
- struct wpa_scan_res *res)
+unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
+ const u8 *ies, size_t ies_len, int rate,
+ int snr)
{
enum local_hw_capab capab = wpa_s->hw_capab;
- int rate; /* max legacy rate in 500 kb/s units */
- const u8 *ie;
unsigned int est, tmp;
- int snr = res->snr;
-
- if (res->est_throughput)
- return;
-
- /* Get maximum legacy rate */
- rate = wpa_scan_get_max_rate(res);
+ const u8 *ie;
/* Limit based on estimated SNR */
if (rate > 1 * 2 && snr < 1)
est = rate * 500;
if (capab == CAPAB_HT || capab == CAPAB_HT40 || capab == CAPAB_VHT) {
- ie = wpa_scan_get_ie(res, WLAN_EID_HT_CAP);
+ ie = get_ie(ies, ies_len, WLAN_EID_HT_CAP);
if (ie) {
tmp = max_ht20_rate(snr);
if (tmp > est)
}
if (capab == CAPAB_HT40 || capab == CAPAB_VHT) {
- ie = wpa_scan_get_ie(res, WLAN_EID_HT_OPERATION);
+ ie = get_ie(ies, ies_len, WLAN_EID_HT_OPERATION);
if (ie && ie[1] >= 2 &&
(ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
tmp = max_ht40_rate(snr);
if (capab == CAPAB_VHT) {
/* Use +1 to assume VHT is always faster than HT */
- ie = wpa_scan_get_ie(res, WLAN_EID_VHT_CAP);
+ ie = get_ie(ies, ies_len, WLAN_EID_VHT_CAP);
if (ie) {
tmp = max_ht20_rate(snr) + 1;
if (tmp > est)
est = tmp;
- ie = wpa_scan_get_ie(res, WLAN_EID_HT_OPERATION);
+ ie = get_ie(ies, ies_len, WLAN_EID_HT_OPERATION);
if (ie && ie[1] >= 2 &&
(ie[3] &
HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
est = tmp;
}
- ie = wpa_scan_get_ie(res, WLAN_EID_VHT_OPERATION);
+ ie = get_ie(ies, ies_len, WLAN_EID_VHT_OPERATION);
if (ie && ie[1] >= 1 &&
(ie[2] & VHT_OPMODE_CHANNEL_WIDTH_MASK)) {
tmp = max_vht80_rate(snr) + 1;
}
}
- /* TODO: channel utilization and AP load (e.g., from AP Beacon) */
+ return est;
+}
+
+
+void scan_est_throughput(struct wpa_supplicant *wpa_s,
+ struct wpa_scan_res *res)
+{
+ int rate; /* max legacy rate in 500 kb/s units */
+ int snr = res->snr;
+ const u8 *ies = (const void *) (res + 1);
+ size_t ie_len = res->ie_len;
+
+ if (res->est_throughput)
+ return;
+
+ /* Get maximum legacy rate */
+ rate = wpa_scan_get_max_rate(res);
- res->est_throughput = est;
+ if (!ie_len)
+ ie_len = res->beacon_ie_len;
+ res->est_throughput =
+ wpas_get_est_tpt(wpa_s, ies, res->ie_len, rate, snr);
+
+ /* TODO: channel utilization and AP load (e.g., from AP Beacon) */
}