UNPKG

7.85 kBJavaScriptView Raw
1'use strict';
2// @ts-check
3// ==================================================================================
4// wifi.js
5// ----------------------------------------------------------------------------------
6// Description: System Information - library
7// for Node.js
8// Copyright: (c) 2014 - 2020
9// Author: Sebastian Hildebrandt
10// ----------------------------------------------------------------------------------
11// License: MIT
12// ==================================================================================
13// 9. wifi
14// ----------------------------------------------------------------------------------
15
16const os = require('os');
17const exec = require('child_process').exec;
18const util = require('./util');
19
20let _platform = process.platform;
21
22const _linux = (_platform === 'linux');
23const _darwin = (_platform === 'darwin');
24const _windows = (_platform === 'win32');
25
26function wifiDBFromQuality(quality) {
27 return (parseFloat(quality) / 2 - 100);
28}
29
30function wifiQualityFromDB(db) {
31 const result = 2 * (parseFloat(db) + 100);
32 return result <= 100 ? result : 100;
33}
34
35function wifiFrequencyFromChannel(channel) {
36 const frequencies = {
37 1: 2412,
38 2: 2417,
39 3: 2422,
40 4: 2427,
41 5: 2432,
42 6: 2437,
43 7: 2442,
44 8: 2447,
45 9: 2452,
46 10: 2457,
47 11: 2462,
48 12: 2467,
49 13: 2472,
50 14: 2484,
51 32: 5160,
52 34: 5170,
53 36: 5180,
54 38: 5190,
55 40: 5200,
56 42: 5210,
57 44: 5220,
58 46: 5230,
59 48: 5240,
60 50: 5250,
61 52: 5260,
62 54: 5270,
63 56: 5280,
64 58: 5290,
65 60: 5300,
66 62: 5310,
67 64: 5320,
68 68: 5340,
69 96: 5480,
70 100: 5500,
71 102: 5510,
72 104: 5520,
73 106: 5530,
74 108: 5540,
75 110: 5550,
76 112: 5560,
77 114: 5570,
78 116: 5580,
79 118: 5590,
80 120: 5600,
81 122: 5610,
82 124: 5620,
83 126: 5630,
84 128: 5640,
85 132: 5660,
86 134: 5670,
87 136: 5680,
88 138: 5690,
89 140: 5700,
90 142: 5710,
91 144: 5720,
92 149: 5745,
93 151: 5755,
94 153: 5765,
95 155: 5775,
96 157: 5785,
97 159: 5795,
98 161: 5805,
99 165: 5825,
100 169: 5845,
101 173: 5865,
102 183: 4915,
103 184: 4920,
104 185: 4925,
105 187: 4935,
106 188: 4940,
107 189: 4945,
108 192: 4960,
109 196: 4980
110 };
111 return {}.hasOwnProperty.call(frequencies, channel) ? frequencies[channel] : -1;
112}
113
114function wifiNetworks(callback) {
115
116 return new Promise((resolve) => {
117 process.nextTick(() => {
118 let result = [];
119 if (_linux) {
120 let cmd = 'nmcli --terse --fields active,ssid,bssid,mode,chan,freq,signal,security,wpa-flags,rsn-flags device wifi list 2>/dev/null';
121 exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
122
123 const parts = stdout.toString().split('ACTIVE:');
124 parts.shift();
125 parts.forEach(part => {
126 part = 'ACTIVE:' + part;
127 const lines = part.split(os.EOL);
128 const channel = util.getValue(lines, 'CHAN');
129 const frequency = util.getValue(lines, 'FREQ').toLowerCase().replace('mhz', '').trim();
130 const security = util.getValue(lines, 'SECURITY').replace('(', '').replace(')', '');
131 const wpaFlags = util.getValue(lines, 'WPA-FLAGS').replace('(', '').replace(')', '');
132 const rsnFlags = util.getValue(lines, 'RSN-FLAGS').replace('(', '').replace(')', '');
133 result.push({
134 ssid: util.getValue(lines, 'SSID'),
135 bssid: util.getValue(lines, 'BSSID'),
136 mode: util.getValue(lines, 'MODE'),
137 channel: channel ? parseInt(channel, 10) : -1,
138 frequency: frequency ? parseInt(frequency, 10) : -1,
139 signalLevel: wifiDBFromQuality(util.getValue(lines, 'SIGNAL')),
140 quality: parseFloat(util.getValue(lines, 'SIGNAL')),
141 security: security && security !== 'none' ? security.split(' ') : [],
142 wpaFlags: wpaFlags && wpaFlags !== 'none' ? wpaFlags.split(' ') : [],
143 rsnFlags: rsnFlags && rsnFlags !== 'none' ? rsnFlags.split(' ') : []
144 });
145 });
146
147 if (callback) {
148 callback(result);
149 }
150 resolve(result);
151 });
152 } else if (_darwin) {
153 let cmd = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s';
154 exec(cmd, { maxBuffer: 1024 * 20000 }, function (error, stdout) {
155 const lines = stdout.toString().split(os.EOL);
156 if (lines && lines.length > 1) {
157 const parsedhead = util.parseHead(lines[0], 1);
158 if (parsedhead.length >= 7) {
159 lines.shift();
160 lines.forEach(line => {
161 if (line.trim()) {
162 const channelStr = line.substring(parsedhead[3].from, parsedhead[3].to).trim();
163 const channel = channelStr ? parseInt(channelStr, 10) : -1;
164 const signalLevel = line.substring(parsedhead[2].from, parsedhead[2].to).trim();
165 const securityAll = line.substring(parsedhead[6].from, 1000).trim().split(' ');
166 let security = [];
167 let wpaFlags = [];
168 securityAll.forEach(securitySingle => {
169 if (securitySingle.indexOf('(') > 0) {
170 const parts = securitySingle.split('(');
171 security.push(parts[0]);
172 wpaFlags = wpaFlags.concat(parts[1].replace(')', '').split(','));
173 }
174 });
175 wpaFlags = Array.from(new Set(wpaFlags));
176 result.push({
177 ssid: line.substring(parsedhead[0].from, parsedhead[0].to).trim(),
178 bssid: line.substring(parsedhead[1].from, parsedhead[1].to).trim(),
179 mode: '',
180 channel,
181 frequency: wifiFrequencyFromChannel(channel),
182 signalLevel: signalLevel ? parseInt(signalLevel, 10) : -1,
183 quality: wifiQualityFromDB(signalLevel),
184 security,
185 wpaFlags,
186 rsnFlags: []
187 });
188 }
189 });
190 }
191 }
192 if (callback) {
193 callback(result);
194 }
195 resolve(result);
196 });
197 } else if (_windows) {
198 let cmd = 'chcp 65001 && netsh wlan show networks mode=Bssid';
199 exec(cmd, util.execOptsWin, function (error, stdout) {
200
201 const parts = stdout.toString('utf8').split(os.EOL + os.EOL + 'SSID ');
202 parts.shift();
203
204 parts.forEach(part => {
205 const lines = part.split(os.EOL);
206 if (lines && lines.length >= 8 && lines[0].indexOf(':') >= 0) {
207 let bssid = lines[4].split(':');
208 bssid.shift();
209 bssid = bssid.join(':').trim();
210 const channel = lines[7].split(':').pop().trim();
211 const quality = lines[5].split(':').pop().trim();
212 result.push({
213 ssid: lines[0].split(':').pop().trim(),
214 bssid,
215 mode: '',
216 channel: channel ? parseInt(channel, 10) : -1,
217 frequency: wifiFrequencyFromChannel(channel),
218 signalLevel: wifiDBFromQuality(quality),
219 quality: quality ? parseInt(quality, 10) : -1,
220 security: [lines[2].split(':').pop().trim()],
221 wpaFlags: [lines[3].split(':').pop().trim()],
222 rsnFlags: []
223 });
224 }
225 });
226
227 if (callback) {
228 callback(result);
229 }
230 resolve(result);
231 });
232 } else {
233 if (callback) {
234 callback(result);
235 }
236 resolve(result);
237 }
238 });
239 });
240}
241
242exports.wifiNetworks = wifiNetworks;