| 1341 | } |
| 1342 | |
| 1343 | static void |
| 1344 | sta_roam_check(struct ieee80211_scan_state *ss, struct ieee80211vap *vap) |
| 1345 | { |
| 1346 | struct ieee80211com *ic = vap->iv_ic; |
| 1347 | struct ieee80211_node *ni = vap->iv_bss; |
| 1348 | struct sta_table *st = ss->ss_priv; |
| 1349 | enum ieee80211_phymode mode; |
| 1350 | struct sta_entry *se, *selbs; |
| 1351 | uint8_t roamRate, curRate, ucastRate; |
| 1352 | int8_t roamRssi, curRssi; |
| 1353 | |
| 1354 | se = sta_lookup(st, ni->ni_macaddr); |
| 1355 | if (se == NULL) { |
| 1356 | /* XXX something is wrong */ |
| 1357 | return; |
| 1358 | } |
| 1359 | |
| 1360 | mode = ieee80211_chan2mode(ic->ic_bsschan); |
| 1361 | roamRate = vap->iv_roamparms[mode].rate; |
| 1362 | roamRssi = vap->iv_roamparms[mode].rssi; |
| 1363 | KASSERT(roamRate != 0 && roamRssi != 0, ("iv_roamparms are not" |
| 1364 | "initialized for %s mode!", ieee80211_phymode_name[mode])); |
| 1365 | |
| 1366 | ucastRate = vap->iv_txparms[mode].ucastrate; |
| 1367 | /* NB: the most up to date rssi is in the node, not the scan cache */ |
| 1368 | curRssi = ic->ic_node_getrssi(ni); |
| 1369 | if (ucastRate == IEEE80211_FIXED_RATE_NONE) { |
| 1370 | curRate = ni->ni_txrate; |
| 1371 | IEEE80211_DPRINTF(vap, IEEE80211_MSG_ROAM, |
| 1372 | "%s: currssi %d currate %u roamrssi %d roamrate %u\n", |
| 1373 | __func__, curRssi, curRate, roamRssi, roamRate); |
| 1374 | } else { |
| 1375 | curRate = roamRate; /* NB: insure compare below fails */ |
| 1376 | IEEE80211_DPRINTF(vap, IEEE80211_MSG_ROAM, |
| 1377 | "%s: currssi %d roamrssi %d\n", __func__, curRssi, roamRssi); |
| 1378 | } |
| 1379 | /* |
| 1380 | * Check if a new ap should be used and switch. |
| 1381 | * XXX deauth current ap |
| 1382 | */ |
| 1383 | if (curRate < roamRate || curRssi < roamRssi) { |
| 1384 | if (ieee80211_time_after(ticks, ic->ic_lastscan + vap->iv_scanvalid)) { |
| 1385 | /* |
| 1386 | * Scan cache contents are too old; force a scan now |
| 1387 | * if possible so we have current state to make a |
| 1388 | * decision with. We don't kick off a bg scan if |
| 1389 | * we're using dynamic turbo and boosted or if the |
| 1390 | * channel is busy. |
| 1391 | * XXX force immediate switch on scan complete |
| 1392 | */ |
| 1393 | if (!IEEE80211_IS_CHAN_DTURBO(ic->ic_curchan) && |
| 1394 | ((vap->iv_flags_ext & IEEE80211_FEXT_SCAN_OFFLOAD) || |
| 1395 | ieee80211_time_after(ticks, ic->ic_lastdata + vap->iv_bgscanidle))) |
| 1396 | ieee80211_bg_scan(vap, 0); |
| 1397 | return; |
| 1398 | } |
| 1399 | se->base.se_rssi = curRssi; |
| 1400 | selbs = select_bss(ss, vap, IEEE80211_MSG_ROAM); |
no test coverage detected