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);
}

留言

熱門文章