Linux kernel - NL80211 scan
net/wireless/nl80211.c
{
.cmd = NL80211_CMD_TRIGGER_SCAN,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = nl80211_trigger_scan,
.flags = GENL_UNS_ADMIN_PERM,
.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
{
.cmd = NL80211_CMD_ABORT_SCAN,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = nl80211_abort_scan,
.flags = GENL_UNS_ADMIN_PERM,
.internal_flags = NL80211_FLAG_NEED_WDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
在同一個 wiphy 下的 interfaces, kernel 一次只會做一個 scan:
這是因為 cfg80211_registered_device *rdev 是在 wiphy_new() 這邊 alloc,
所以同個 wiphy 下, 透過 wiphy_to_rdev() 所得到的 rdev, 都會是相同的.
nl80211_trigger_scan()
如果已經有做 scan, 會回 -EBUSY
if (rdev->scan_req || rdev->scan_msg)
return -EBUSY;
...
err = cfg80211_scan(rdev); -> rdev_scan(rdev, request)
nl80211_abort_scan()
只有在目前正在做 scan 的狀況下, 才能做 abort scan
if (!rdev->scan_req)
return -ENOENT;
rdev_abort_scan(rdev, wdev);
net/wireless/scan.c::cfg80211_scan_done()
正常來說 mac80211 一次只會有一個 scan, 所以會看 scan request 是否是相同符合預期
WARN_ON(request != wiphy_to_rdev(request->wiphy)->scan_req &&
request != wiphy_to_rdev(request->wiphy)->int_scan_req);
net/wireless/scan.c::___cfg80211_scan_done()
cfg80211_scan_done() 若info.abort 不為 true,
kernel 會視其為完整的scan 結果, 而將前一次 scan 結果 flush
if (!request->info.aborted &&
request->flags & NL80211_SCAN_FLAG_FLUSH) {
/* flush entries from previous scans */
spin_lock_bh(&rdev->bss_lock);
__cfg80211_bss_expire(rdev, request->scan_start);
spin_unlock_bh(&rdev->bss_lock);
}
留言
張貼留言