]> code.delx.au - monosys/blobdiff - wifi-scan
lib-ext-backup
[monosys] / wifi-scan
index a474c360f160d972d0b5561bb9774c22ab59750e..344581ad5809ff0ed65ed91a0dd3d02dfc1b75e3 100755 (executable)
--- a/wifi-scan
+++ b/wifi-scan
@@ -1,9 +1,99 @@
-#!/bin/bash
+#!/usr/bin/env node
+'use strict'
 
-iface="$(iw dev|grep Interface|awk '{print $2}')"
-sudo /bin/true
-sudo iw dev "$iface" scan |\
-egrep '^BSS|SSID|signal|DS Parameter set' |\
-sed 's/BSS/\nBSS/' |\
-less
+const {exec} = require('child_process');
 
+function execAsync(command, opts) {
+    return new Promise((resolve, reject) => {
+        exec(command, opts, (error, stdout, stderr) => {
+            if (error) {
+                reject(error);
+            } else {
+                resolve({stdout, stderr});
+            }
+        });
+    });
+}
+
+function sleep(n) {
+    return new Promise((resolve) => setTimeout(resolve, n));
+}
+
+async function findInterface() {
+    const {stdout} = await execAsync('iw dev');
+    const lines = stdout.split('\n')
+        .map((line) => line.trim())
+        .filter((line) => line.startsWith('Interface '))
+        .map((line) => line.split(' ')[1]);
+    return lines[0];
+}
+
+async function scanInterface(iface) {
+    const {stdout} = await execAsync(`sudo iw dev ${iface} scan`);
+
+    const results = [];
+    let partial = null;
+
+    for (let line of stdout.split('\n')) {
+        if (line.startsWith('BSS ')) {
+            finishPartial();
+            partial = {};
+            partial.bssid = line.match(/[a-z0-9:]+/)[0];
+        }
+
+        line = line.trim()
+        if (line.startsWith('SSID: ')) {
+            partial.ssid = line.split(':')[1].trim();
+        }
+        if (line.startsWith('signal: ')) {
+            partial.signal = line.split(':')[1].trim();
+        }
+        if (line.startsWith('DS Parameter set: channel')) {
+            partial.channel = line.split(':')[1].trim();
+        }
+        if (line.startsWith('freq: ')) {
+            partial.freq = 'freq ' + line.split(':')[1].trim();
+        }
+    }
+
+    function finishPartial() {
+        if (!partial) {
+            return;
+        }
+
+        partial.ssid = partial.ssid || '';
+        partial.channel = partial.channel || partial.freq || '';
+
+        const sortKey = [
+            parseFloat(partial.signal),
+            parseInt(partial.channel.split(' ')[1])
+        ];
+
+        results.push([sortKey, partial]);
+    }
+
+    return results
+        .sort()
+        .map(([, {bssid, ssid, signal, channel}]) => {
+            ssid = ssid.padStart(40, ' ');
+            channel = channel.padEnd(10, ' ');
+            return `${signal}  ${channel}  ${ssid}  ${bssid}`;
+        })
+        .join('\n') + '\n';
+}
+
+async function main() {
+    const iface = await findInterface();
+
+    for (;;) {
+        const scanResult = await scanInterface(iface).catch((err) => err.toString());
+        process.stdout.write('\x1b[2J\x1b[0f');
+        process.stdout.write(scanResult);
+        await sleep(3000);
+    }
+}
+
+main().catch((err) => {
+    console.log('Unhandled error!', err);
+    process.exit(1);
+});