]> code.delx.au - monosys/blob - wifi-scan
multiboot-setup: support Debian10 installer
[monosys] / wifi-scan
1 #!/usr/bin/env node
2 'use strict'
3
4 const {exec} = require('child_process');
5
6 function execAsync(command, opts) {
7 return new Promise((resolve, reject) => {
8 exec(command, opts, (error, stdout, stderr) => {
9 if (error) {
10 reject(error);
11 } else {
12 resolve({stdout, stderr});
13 }
14 });
15 });
16 }
17
18 function sleep(n) {
19 return new Promise((resolve) => setTimeout(resolve, n));
20 }
21
22 async function findInterface() {
23 const {stdout} = await execAsync('iw dev');
24 const lines = stdout.split('\n')
25 .map((line) => line.trim())
26 .filter((line) => line.startsWith('Interface '))
27 .map((line) => line.split(' ')[1]);
28 return lines[0];
29 }
30
31 async function scanInterface(iface) {
32 const {stdout} = await execAsync(`sudo iw dev ${iface} scan`);
33
34 const results = [];
35 let partial = null;
36
37 for (let line of stdout.split('\n')) {
38 if (line.startsWith('BSS ')) {
39 finishPartial();
40 partial = {};
41 partial.bssid = line.match(/[a-z0-9:]+/)[0];
42 }
43
44 line = line.trim()
45 if (line.startsWith('SSID: ')) {
46 partial.ssid = line.split(':')[1].trim();
47 }
48 if (line.startsWith('signal: ')) {
49 partial.signal = line.split(':')[1].trim();
50 }
51 if (line.startsWith('DS Parameter set: channel')) {
52 partial.channel = line.split(':')[1].trim();
53 }
54 if (line.startsWith('freq: ')) {
55 partial.freq = 'freq ' + line.split(':')[1].trim();
56 }
57 }
58
59 function finishPartial() {
60 if (!partial) {
61 return;
62 }
63
64 partial.ssid = partial.ssid || '';
65 partial.channel = partial.channel || partial.freq || '';
66
67 const sortKey = [
68 parseFloat(partial.signal),
69 parseInt(partial.channel.split(' ')[1])
70 ];
71
72 results.push([sortKey, partial]);
73 }
74
75 return results
76 .sort()
77 .map(([, {bssid, ssid, signal, channel}]) => {
78 ssid = ssid.padStart(40, ' ');
79 channel = channel.padEnd(10, ' ');
80 return `${signal} ${channel} ${ssid} ${bssid}`;
81 })
82 .join('\n') + '\n';
83 }
84
85 async function main() {
86 const iface = await findInterface();
87
88 for (;;) {
89 const scanResult = await scanInterface(iface).catch((err) => err.toString());
90 process.stdout.write('\x1b[2J\x1b[0f');
91 process.stdout.write(scanResult);
92 await sleep(3000);
93 }
94 }
95
96 main().catch((err) => {
97 console.log('Unhandled error!', err);
98 process.exit(1);
99 });