mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 09:32:34 +00:00
rrmd: Update scanning for WiFi 7 devices
Update scan module to support WiFi 7 devices which have virtual phys defined. Scanning on the different virtual phys but on the same physical phy isn't allowed. Add NL CBs to notify about scanning progress. Signed-off-by: Marek Kwaczynski <marek@shasta.cloud>
This commit is contained in:
committed by
John Crispin
parent
b791a723ca
commit
52f2e31892
@@ -32,6 +32,17 @@ function channel_to_freq(cur_freq, channel) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function freq2band(freq) {
|
||||
if (freq < 2500) {
|
||||
return "2G";
|
||||
} else if (freq <= 5885) {
|
||||
return "5G";
|
||||
} else if (freq < 7115){
|
||||
return "6G";
|
||||
}
|
||||
return "na"
|
||||
}
|
||||
|
||||
function channel_survey(dev) {
|
||||
/* trigger the nl80211 call that gathers channel survey data */
|
||||
let res = nl80211.request(def.NL80211_CMD_GET_SURVEY, def.NLM_F_DUMP, { dev });
|
||||
@@ -151,6 +162,8 @@ function interfaces_subunsub(path, sub) {
|
||||
interfaces[name][prop] = status[prop];
|
||||
interfaces[name].config = cfg;
|
||||
interfaces[name].phy = status.phy;
|
||||
interfaces[name].virtual_phys = length(split(status.phy, ".")) > 1 ? true : false;
|
||||
interfaces[name].band = freq2band(status?.freq);
|
||||
|
||||
/* ask hostapd for the local neighbourhood report data */
|
||||
let rrm = global.ubus.conn.call(path, 'rrm_nr_get_own');
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
const SCAN_FLAG_AP = (1<<2);
|
||||
const PHY_SCAN_STATE_READY = 0;
|
||||
const PHY_SCAN_STATE_TRIGGERED = 1;
|
||||
const PHY_SCAN_STATE_STARTED = 2;
|
||||
const PHY_SCAN_STATE_COMPLETED = 3;
|
||||
const PHY_SCAN_STATE_BLOCKED = 4;
|
||||
|
||||
let phys = {};
|
||||
let beacons = {};
|
||||
let scan_blocked_cnt = 0;
|
||||
|
||||
function scan(phy, params) {
|
||||
if (params.wiphy_freq) {
|
||||
@@ -17,7 +23,7 @@ function scan(phy, params) {
|
||||
printf("Unable to trigger scan: " + global.nl80211.error() + "\n");
|
||||
else
|
||||
printf('triggered scan on %s\n', params?.dev);
|
||||
phys[phy].pending = true;
|
||||
phys[phy].state = PHY_SCAN_STATE_TRIGGERED;
|
||||
phys[phy].last = time();
|
||||
}
|
||||
|
||||
@@ -70,21 +76,56 @@ function scan_parse(data) {
|
||||
printf('%.J\n', beacons);
|
||||
}
|
||||
|
||||
function get_scan_res(dev) {
|
||||
let res = global.nl80211.request(global.nl80211.const.NL80211_CMD_GET_SCAN, global.nl80211.const.NLM_F_DUMP, { dev });
|
||||
if (!res || res == false) {
|
||||
ulog_err("Unable to get scan results: " + global.nl80211.error() + "\n");
|
||||
return;
|
||||
}
|
||||
scan_parse(res);
|
||||
}
|
||||
|
||||
function scan_timer() {
|
||||
try {
|
||||
let scan_trigger = false;
|
||||
let cur_blocked = 0;
|
||||
let last_blocked = 0;
|
||||
for (let k, v in phys) {
|
||||
if (v.pending && time() - v.last >= v.delay) {
|
||||
let scan_pending = (v.state == PHY_SCAN_STATE_TRIGGERED || v.state == PHY_SCAN_STATE_STARTED) ? true : false;
|
||||
|
||||
/* It should not happen, get_scan is handled by NL CB */
|
||||
if (scan_pending && time() - v.last >= v.delay) {
|
||||
ulog_warn("Scanning process too long, phy state: %s\n", phys[k]);
|
||||
let dev = global.local.lookup(k);
|
||||
if (dev) {
|
||||
let res = global.nl80211.request(global.nl80211.const.NL80211_CMD_GET_SCAN, global.nl80211.const.NLM_F_DUMP, { dev });
|
||||
scan_parse(res);
|
||||
}
|
||||
v.pending = false;
|
||||
v.state = PHY_SCAN_STATE_READY;
|
||||
scan_pending = false;
|
||||
v.last = time();
|
||||
v.delay = 1;
|
||||
}
|
||||
|
||||
if (!v.pending && time() - v.last >= global.config.scan_interval) {
|
||||
if (!v?.channels || !v?.num_chan)
|
||||
continue;
|
||||
|
||||
/* Running scanning parallel on virtual phys not allowed */
|
||||
if (v?.virtual_phys) {
|
||||
if (v?.state == PHY_SCAN_STATE_BLOCKED)
|
||||
last_blocked++;
|
||||
else if (scan_blocked_cnt > 0)
|
||||
continue;
|
||||
|
||||
if (scan_trigger) {
|
||||
v.state = PHY_SCAN_STATE_BLOCKED;
|
||||
cur_blocked++;
|
||||
continue;
|
||||
} else if (v.state == PHY_SCAN_STATE_BLOCKED) {
|
||||
v.state = PHY_SCAN_STATE_READY;
|
||||
}
|
||||
}
|
||||
|
||||
if (!scan_pending && time() - v.last >= global.config.scan_interval) {
|
||||
let dev = global.local.lookup(k);
|
||||
scan(k, {
|
||||
dev,
|
||||
@@ -92,8 +133,17 @@ function scan_timer() {
|
||||
measurement_duration: global.config.scan_dwell_time,
|
||||
|
||||
});
|
||||
v.state = PHY_SCAN_STATE_TRIGGERED;
|
||||
scan_trigger = true;
|
||||
v.curr_chan = (v.curr_chan + 1) % v.num_chan;
|
||||
}
|
||||
/* Shouldn't never happen */
|
||||
if (scan_blocked_cnt > 0 && scan_blocked_cnt != last_blocked) {
|
||||
log_warn("Mismatch in blocked phys config: %s -> %s\n", phys.blocked, last_blocked);
|
||||
scan_blocked_cnt = 0;
|
||||
} else {
|
||||
scan_blocked_cnt = cur_blocked;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,17 +153,79 @@ function scan_timer() {
|
||||
// return 1000;
|
||||
}
|
||||
|
||||
function get_phy_from_msg(msg) {
|
||||
if (!msg?.msg)
|
||||
return;
|
||||
|
||||
let phy = "phy" + msg.msg.wiphy;
|
||||
let dev = msg.msg?.dev;
|
||||
if (!dev)
|
||||
dev = global.local.lookup(phy);
|
||||
if (!dev)
|
||||
return null;
|
||||
|
||||
if (global.local.interfaces[dev]?.virtual_phys)
|
||||
phy = global.local.interfaces[dev].phy;
|
||||
|
||||
if (!phy)
|
||||
return null;
|
||||
|
||||
return phy;
|
||||
}
|
||||
|
||||
function nl_handle_scan_msg(msg) {
|
||||
let phy = get_phy_from_msg(msg);
|
||||
if (!phy)
|
||||
return;
|
||||
|
||||
phys[phy].last = time();
|
||||
phys[phy].state = PHY_SCAN_STATE_COMPLETED;
|
||||
//get_scan_res(msg.msg?.dev);
|
||||
}
|
||||
|
||||
function nl_scan_res_cb(msg) {
|
||||
nl_handle_scan_msg(msg);
|
||||
}
|
||||
|
||||
function nl_scan_abort_cb(msg) {
|
||||
nl_handle_scan_msg(msg);
|
||||
}
|
||||
|
||||
function nl_scan_start_cb(msg) {
|
||||
let phy = get_phy_from_msg(msg);
|
||||
if (!phy)
|
||||
return;
|
||||
|
||||
if (!phys[phy])
|
||||
return;
|
||||
|
||||
if (phys[phy].state != PHY_SCAN_STATE_TRIGGERED) {
|
||||
ulog_warn("Skip scan results not started by scan module: %s\n", msg);
|
||||
return;
|
||||
}
|
||||
|
||||
phys[phy].state = PHY_SCAN_STATE_STARTED;
|
||||
}
|
||||
|
||||
return {
|
||||
beacons,
|
||||
|
||||
add_wdev: function(dev, phy) {
|
||||
if (phys[phy])
|
||||
return;
|
||||
|
||||
let p = split(phy, '.');
|
||||
let virtual_phys = length(p) > 1 ? true : false;
|
||||
let bands = global.phy.phys[phy]?.band;
|
||||
if (!bands)
|
||||
bands = [ global.local.interfaces[dev].band ];
|
||||
|
||||
if (!bands)
|
||||
return;
|
||||
let channels;
|
||||
let offset = 0;
|
||||
if (!global.phy.phys[phy])
|
||||
return;
|
||||
switch (global.phy.phys[phy].band[0]) {
|
||||
|
||||
switch (bands[0]) {
|
||||
case '2G':
|
||||
channels = global.config.channels_2g;
|
||||
break;
|
||||
@@ -132,8 +244,12 @@ return {
|
||||
channels,
|
||||
offset,
|
||||
num_chan,
|
||||
bands,
|
||||
curr_chan: 0,
|
||||
delay: 5,
|
||||
virtual_phys,
|
||||
delay: 25,
|
||||
state: PHY_SCAN_STATE_READY,
|
||||
parent_phy: p[0],
|
||||
};
|
||||
},
|
||||
|
||||
@@ -143,5 +259,8 @@ return {
|
||||
|
||||
init: function() {
|
||||
uloop_timeout(scan_timer, 5000);
|
||||
nl80211.listener(nl_scan_start_cb, [ nl80211.const.NL80211_CMD_TRIGGER_SCAN ]);
|
||||
nl80211.listener(nl_scan_res_cb, [ nl80211.const.NL80211_CMD_NEW_SCAN_RESULTS ]);
|
||||
nl80211.listener(nl_scan_abort_cb, [ nl80211.const.NL80211_CMD_SCAN_ABORTED ]);
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user