-
Notifications
You must be signed in to change notification settings - Fork 0
/
walk.js
executable file
·107 lines (103 loc) · 3.72 KB
/
walk.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
const out = {
date: Date.now(),
nodeInfo: []
};
const pending = [ "localnode" ];
const found = {};
async function readNode(name) {
return new Promise(async resolve => {
try {
const res = await fetch(`http://${name}.local.mesh/cgi-bin/sysinfo.json?link_info=1&lqm=1`);
resolve(await res.json());
return;
}
catch (_) {
}
resolve(null);
});
}
async function walkOne() {
return new Promise(async resolve => {
const name = pending.shift();
if (name) {
const node = await readNode(name);
if (node) {
if (name !== "localnode" && node.lat && node.lon) {
const d = node.node_details;
const m = node.meshrf;
const link_info = {};
for (k in node.link_info) {
const l = node.link_info[k];
link_info[k] = {
hostname: l.hostname.replace(/^xlink\d+\./i, ""),
linkType: l.linkType === "" && l.hostname.indexOf("xlink") === 0 ? "XLINK" : l.linkType,
signal: l.signal,
noise: l.noise
}
}
out.nodeInfo.push({
data: {
node: node.node,
lat: parseFloat(node.lat),
lon: parseFloat(node.lon),
grid_square: node.grid_square,
api_version: node.api_version,
lastseen: Math.floor(Date.now() / 1000),
node_details: {
description: d.description,
hardware: d.hardware,
firmware_version: d.firmware_version,
mesh_supernode: d.mesh_supernode
},
meshrf: {
status: m.status,
ssid: m.ssid,
channel: m.channel,
freq: m.freq,
chanbw: m.chanbw,
height: m.height,
azimuth: m.azimuth,
elevation: m.elevation,
antenna: m.antenna ? { description : m.antenna.description } : undefined
},
interfaces: [
{ mac: node.interfaces.find(i => i.mac ).mac }
],
link_info: link_info
}
});
}
if (!node.node_details.mesh_supernode) {
Object.values(node.link_info || {}).forEach(l => {
const hostname = canonicalHostname(l.hostname);
if (!found[hostname]) {
found[hostname] = true;
pending.push(hostname);
}
});
}
}
}
resolve();
});
}
function walk(update) {
let running = 0;
let count = 0;
function run() {
while (running < pending.length && running < 32) {
running++;
walkOne().then(() => {
running--;
if (++count % 8 === 0) {
update();
}
run();
});
}
if (running === 0) {
update();
}
}
run();
}