-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: John Crispin <[email protected]>
- Loading branch information
Showing
1 changed file
with
173 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,177 @@ | ||
{% | ||
let verbose = args.verbose ? true : false; | ||
let active = args.active ? true : false; | ||
ctx.call("wifi", "scan", { active }); | ||
system("sleep 5"); | ||
let scan = ctx.call("wifi", "scan_dump", {verbose}); | ||
let verbose = args?.verbose ? true : false; | ||
let active = args?.active ? true : false; | ||
let nl = require("nl80211"); | ||
let def = nl.const; | ||
|
||
const SCAN_FLAG_AP = (1<<2); | ||
const frequency_list_2g = [ 2412, 2417, 2422, 2427, 2432, 2437, 2442, | ||
2447, 2452, 2457, 2462, 2467, 2472, 2484 ]; | ||
const frequency_list_5g = { '3': [ 5180, 5260, 5500, 5580, 5660, 5745 ], | ||
'2': [ 5180, 5220, 5260, 5300, 5500, 5540, | ||
5580, 5620, 5660, 5745, 5785, 5825, | ||
5865, 5920, 5960 ], | ||
'1': [ 5180, 5200, 5220, 5240, 5260, 5280, | ||
5300, 5320, 5500, 5520, 5540, 5560, | ||
5580, 5600, 5620, 5640, 5660, 5680, | ||
5700, 5720, 5745, 5765, 5785, 5805, | ||
5825, 5845, 5865, 5885 ], | ||
}; | ||
const frequency_offset = { '80': 30, '40': 10 }; | ||
const frequency_width = { '80': 3, '40': 20, '20': 1 }; | ||
const IFTYPE_STATION = 2; | ||
const IFTYPE_AP = 3; | ||
const IFTYPE_MESH = 7; | ||
|
||
function iface_get(wdev) { | ||
let params = { dev: wdev }; | ||
let res = nl.request(def.NL80211_CMD_GET_INTERFACE, wdev ? null : def.NLM_F_DUMP, wdev ? params : null); | ||
|
||
if (res === false) | ||
warn("Unable to lookup interface: " + nl.error() + "\n"); | ||
return res || []; | ||
} | ||
|
||
function iface_find(wiphy, types, ifaces) { | ||
if (!ifaces) | ||
ifaces = iface_get(); | ||
for (let iface in ifaces) { | ||
if (iface.wiphy != wiphy) | ||
continue; | ||
if (iface.iftype in types) | ||
return iface; | ||
} | ||
return; | ||
} | ||
|
||
function scan_trigger(wdev, frequency, width) { | ||
let params = { dev: wdev, scan_flags: SCAN_FLAG_AP }; | ||
|
||
if (frequency && type(frequency) == 'array') { | ||
params.scan_frequencies = frequency; | ||
} | ||
else if (frequency && width) { | ||
params.wiphy_freq = frequency; | ||
params.center_freq1 = frequency + frequency_offset[width]; | ||
params.channel_width = frequency_width[width]; | ||
} | ||
|
||
if (active) | ||
params.scan_ssids = [ '' ]; | ||
|
||
//printf("%.J\n", params); | ||
let res = nl.request(def.NL80211_CMD_TRIGGER_SCAN, 0, params); | ||
|
||
if (res === false) | ||
die("Unable to trigger scan: " + nl.error() + "\n"); | ||
|
||
res = nl.waitfor([ | ||
def.NL80211_CMD_NEW_SCAN_RESULTS, | ||
def.NL80211_CMD_SCAN_ABORTED | ||
], (frequency && width) ? 500 : 5000); | ||
|
||
if (!res) | ||
warn("Netlink error while awaiting scan results: " + nl.error() + "\n"); | ||
|
||
else if (res.cmd == def.NL80211_CMD_SCAN_ABORTED) | ||
warn("Scan aborted by kernel\n"); | ||
} | ||
|
||
function trigger_scan_width(wdev, freqs, width) { | ||
for (let freq in freqs) | ||
scan_trigger(wdev, freq, width); | ||
} | ||
|
||
function phy_get(wdev) { | ||
let res = nl.request(def.NL80211_CMD_GET_WIPHY, def.NLM_F_DUMP, { split_wiphy_dump: true }); | ||
|
||
if (res === false) | ||
warn("Unable to lookup phys: " + nl.error() + "\n"); | ||
|
||
return res; | ||
} | ||
|
||
function phy_get_frequencies(phy) { | ||
let freqs = []; | ||
|
||
for (let band in phy.wiphy_bands) { | ||
for (let freq in band?.freqs || []) | ||
if (!freq.disabled) | ||
push(freqs, freq.freq); | ||
} | ||
return freqs; | ||
} | ||
|
||
let phys = phy_get(); | ||
let ifaces = iface_get(); | ||
|
||
function intersect(list, filter) { | ||
let res = []; | ||
|
||
for (let item in list) | ||
if (index(filter, item) >= 0) | ||
push(res, item); | ||
return res; | ||
} | ||
|
||
function wifi_scan() { | ||
let scan = []; | ||
|
||
for (let phy in phys) { | ||
let iface = iface_find(phy.wiphy, [ IFTYPE_STATION, IFTYPE_AP ], ifaces); | ||
if (!iface) { | ||
warn('no valid interface found for phy' + phy.wiphy + '\n'); | ||
break; | ||
} | ||
|
||
let freqs = phy_get_frequencies(phy); | ||
if (length(intersect(freqs, frequency_list_2g))) | ||
scan_trigger(iface.dev, frequency_list_2g); | ||
|
||
let freqs_5g = intersect(freqs, frequency_list_5g[iface.channel_width]); | ||
if (length(freqs_5g)) | ||
trigger_scan_width(iface.dev, freqs_5g, iface.channel_width); | ||
let res = nl.request(def.NL80211_CMD_GET_SCAN, def.NLM_F_DUMP, { dev: iface.dev }); | ||
for (let bss in res) { | ||
bss = bss.bss; | ||
let res = { | ||
bssid: bss.bssid, | ||
tsf: +bss.tsf, | ||
frequency: +bss.frequency, | ||
signal: +bss.signal_mbm / 100, | ||
last_seen: +bss.seen_ms_ago, | ||
capability: +bss.capability, | ||
}; | ||
|
||
for (let ie in bss.beacon_ies) { | ||
switch (ie.type) { | ||
case 0: | ||
case 114: | ||
res.ssid = ie.data; | ||
break; | ||
case 0x3d: | ||
res.ht_oper = b64enc(ie.data); | ||
break; | ||
case 0xc0: | ||
res.vht_oper = b64enc(ie.data); | ||
break; | ||
} | ||
} | ||
|
||
push(scan, res); | ||
} | ||
// printf("%.J\n", nl.request(def.NL80211_CMD_GET_SCAN, def.NLM_F_DUMP, { dev: iface.dev })); | ||
} | ||
printf("%.J\n", scan); | ||
return scan; | ||
} | ||
|
||
let scan = wifi_scan(); | ||
|
||
result_json({ | ||
"error": 0, | ||
"text": "Success", | ||
"resultCode": 1, | ||
scan: scan.scan | ||
error: 0, | ||
text: "Success", | ||
resultCode: 1, | ||
scan, | ||
}); | ||
%} |