wifi() added available wifi networks

This commit is contained in:
Sebastian Hildebrandt 2019-06-14 22:56:11 +02:00
parent fa077ff94d
commit 41d5b0e399
9 changed files with 438 additions and 20 deletions

View File

@ -30,6 +30,7 @@ For major (breaking) changes - version 3 and 2 see end of page.
| Version | Date | Comment |
| -------------- | -------------- | -------- |
| 4.11.0 | 2019-06-14 | `wifi()` added available wifi networks |
| 4.10.0 | 2019-06-14 | `graphics()` windows multiple display support |
| 4.9.2 | 2019-06-12 | type definitions bug fix |
| 4.9.1 | 2019-06-11 | `networkStats()` bug fix windows |

View File

@ -455,7 +455,22 @@ I also created a nice little command line tool called [mmon][mmon-github-url] (
| | ms | X | X | X | X | X | response time in ms |
| si.inetLatency(host, cb) | : number | X | X | X | X | X | response-time (ms) to external resource<br>host parameter is optional (default 8.8.8.8)|
#### 11. Docker
#### 11. Wifi networks
| Function | Result object | Linux | BSD | Mac | Win | Sun | Comments |
| --------------- | ------------- | ----- | ------- | --- | --- | --- | -------- |
| si.wifi(cb) | [{...}] | X | | X | X | | array of available wifi networks |
| | [0].ssid | X | | X | X | | Wifi network SSID |
| | [0].bssid | X | | X | X | | BSSID (mac) |
| | [0].mode | X | | | | | mode |
| | [0].channel | X | | X | X | | channel |
| | [0].frequency | X | | X | X | | frequengy in MHz |
| | [0].signalLevel | X | | X | X | | signal level in dB |
| | [0].quality | X | | X | X | | quaility in % |
| | [0].security | X | | X | X | | array e.g. WPA, WPA-2 |
| | [0].wpaFlags | X | | X | X | | array of WPA flags |
| | [0].rsnFlags | X | | | | | array of RDN flags |
#### 12. Docker
| Function | Result object | Linux | BSD | Mac | Win | Sun | Comments |
| --------------- | ------------- | ----- | ------- | --- | --- | --- | -------- |
@ -553,7 +568,7 @@ I also created a nice little command line tool called [mmon][mmon-github-url] (
| | [0].command | X | X | X | X | X | command and arguments |
| si.dockerAll(cb) | {...} | X | X | X | X | X | list of all containers including their stats<br>and processes in one single array |
#### 12. Virtual Box
#### 13. Virtual Box
| Function | Result object | Linux | BSD | Mac | Win | Sun | Comments |
| --------------- | ------------- | ----- | ------- | --- | --- | --- | -------- |
@ -595,7 +610,7 @@ I also created a nice little command line tool called [mmon][mmon-github-url] (
| | [0].timeOffset | X | X | X | X | X | time Offset |
| | [0].RTC | X | X | X | X | X | RTC |
#### 13. "Get All at once" - functions
#### 14. "Get All at once" - functions
| Function | Result object | Linux | BSD | Mac | Win | Sun | Comments |
| --------------- | ------------- | ----- | ------- | --- | --- | --- | -------- |

View File

@ -80,6 +80,11 @@
</tr>
</thead>
<tbody>
<tr>
<th scope="row">4.11.0</th>
<td>2019-06-14</td>
<td><span class="code">wifi()</span> added available wifi networks</td>
</tr>
<tr>
<th scope="row">4.10.0</th>
<td>2019-06-14</td>

View File

@ -168,7 +168,7 @@
<img class="logo" src="assets/logo.png">
<div class="title">systeminformation</div>
<div class="subtitle"><span id="typed"></span></div>
<div class="version">Current Version: <span id="version">4.10.0</span></div>
<div class="version">Current Version: <span id="version">4.11.0</span></div>
<button class="btn btn-light" onclick="location.href='https://github.com/sebhildebrandt/systeminformation'">View on Github <i class=" fab fa-github"></i></button>
</div>
<div class="down">
@ -191,7 +191,7 @@
</div>
<div class="row number-section">
<div class="col-xl-4 col-lg-4 col-md-4 col-12">
<div class="numbers">8,833</div>
<div class="numbers">9,082</div>
<div class="title">Lines of code</div>
</div>
<div class="col-xl-4 col-lg-4 col-md-4 col-12">
@ -281,6 +281,12 @@
<div class="icontitle">Network</div>
</div>
</a>
<a href="wifi.html" class="col-xl-3 col-lg-3 col-md-4 col-6 features">
<div class="inner">
<div class="icons"><i class="fal fa-wifi"></i></div>
<div class="icontitle">Wifi</div>
</div>
</a>
<a href="docker.html" class="col-xl-3 col-lg-3 col-md-4 col-6 features">
<div class="inner">
<div class="icons"><i class="fab fa-docker"></i></div>

View File

@ -12,6 +12,7 @@ function createMenu() {
[1, 'processes', 'Processes / Services'],
[1, 'filesystem', 'Disks / FS'],
[1, 'network', 'Network'],
[1, 'wifi', 'Wifi'],
[1, 'docker', 'Docker'],
[1, 'vbox', 'Virtual Box'],
[0, '', 'More'],

228
docs/wifi.html Normal file
View File

@ -0,0 +1,228 @@
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-LRlmVvLKVApDVGuspQFnRQJjkv0P7/YFrw84YYQtmYG4nK8c+M+NlmYDCv0rKWpG" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
<script src="main.js"></script>
<!-- Favicon -->
<link rel="icon" type="image/png" sizes="192x192" href="/assets/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/assets/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.13.1/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<title>systeminformation</title>
</head>
<body>
<nav class="nav">
<div class="container">
<a href="."><img class="logo float-left" src="assets/logo.png">
<div class="title float-left">systeminformation</div>
</a>
<div class="text float-right github"><a href="https://github.com/sebhildebrandt/systeminformation">View on Github <i class="fab fa-github"></i></a></div>
<div class="text float-right todocs"><a href="./#docs">Docs Overview</a></div>
</div>
</nav>
<section class="container">
<div class="row">
<div class="col-12 col-md-4 col-lg-3 col-xl-2 menu" id="menu">
</div>
<div class="col-12 col-md-8 col-lg-9 col-xl-10 content">
<div class="row">
<div class="col-12 sectionheader">
<div class="title">Wifi</div>
<div class="text">
<p>In this section you will learn how to get detailed information about available wifi networks:</p>
<p>For function reference and examples we assume, that we imported <span class="code">systeminformation</span> as follows:</p>
<pre><code class="js">const si = require('systeminformation');</code></pre>
<h2>Wifi Networks</h2>
<p>All functions in this section return a promise or can be called with a callback function (parameter <span class="code">cb</span> in the function reference)</p>
<table class="table table-sm table-bordered table-striped">
<thead>
<tr>
<th>Function</th>
<th>Result object</th>
<th>Linux</th>
<th>BSD</th>
<th>Mac</th>
<th>Win</th>
<th>Sun</th>
<th>Comments</th>
</tr>
</thead>
<tbody>
<tr>
<td>si.wifi(cb)</td>
<td>[{...}]</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>X</td>
<td>array of available wifi networks</td>
</tr>
<tr>
<td></td>
<td>[0].ssid</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>Wifi network SSID</td>
</tr>
<tr>
<td></td>
<td>[0].bssid</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>BSSID (mac)</td>
</tr>
<tr>
<td></td>
<td>[0].mode</td>
<td>X</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>mode</td>
</tr>
<tr>
<td></td>
<td>[0].channel</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>channel</td>
</tr>
<tr>
<td></td>
<td>[0].frequency</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>frequengy in MHz</td>
</tr>
<tr>
<td></td>
<td>[0].signalLevel</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>signal level in dB</td>
</tr>
<tr>
<td></td>
<td>[0].quality</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>quaility in %</td>
</tr>
<tr>
<td></td>
<td>[0].security</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>array e.g. WPA, WPA-2</td>
</tr>
<tr>
<td></td>
<td>[0].wpaFlags</td>
<td>X</td>
<td></td>
<td>X</td>
<td>X</td>
<td></td>
<td>array of WPA flags</td>
</tr>
<tr>
<td></td>
<td>[0].rsnFlags</td>
<td>X</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>array of RDN flags
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<footer class="container-fluid">
<div class="container">
<div class="row">
<div class="col-lg-4 col-12">
<ul class="list-unstyled">
<li><a href=".">Home</a></li>
<li><a href="https://github.com/sebhildebrandt/systeminformation">Github <i class="fab fa-github"></i></a></li>
<li><a href="contributors.html">Contributors</a></li>
<li><a href="https://buymeacoff.ee/systeminfo">Buy me a coffee</a></li>
</ul>
</div>
<div class="col-lg-4 col-12">
<ul class="list-unstyled">
<li><a href="gettingstarted.html">Quick Start</a></li>
<li><a href="issues.html">Known Issues</a></li>
<li><a href="statsfunctions.html">Stats Functions</a></li>
<li><a href="history.html">Version history</a></li>
</ul>
</div>
<div class="col-lg-4 col-12">
<ul class="list-unstyled">
<li><a href="https://www.plus-innovations.com">&copy; 2019 Sebastian Hildebrandt, +innovations</a></li>
<li><a href="copyright.html">Copyright &amp; License</a></li>
<li><a href="trademarks.html">Trademarks</a></li>
<li><a href="https://github.com/sebhildebrandt/systeminformation/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="MIT license" /></a></li>
</ul>
</div>
</div>
</div>
</footer>
<script>
window.onload = function (e) {
createMenu();
}
</script>
</body>
</html>

15
lib/index.d.ts vendored
View File

@ -344,6 +344,19 @@ export namespace Systeminformation {
ms: number;
}
interface WifiNetworkData {
ssid: string;
bssid: string;
mode: string;
channel: number;
frequency: number;
signalLevel: number;
quality: number;
security: string[];
wpaFlags: string[];
rsnFlags: string[];
}
// 7. Current Load, Processes & Services
interface CurrentLoadData {
@ -626,6 +639,8 @@ export function networkConnections(cb?: (data: Systeminformation.NetworkConnecti
export function inetChecksite(url: string, cb?: (data: Systeminformation.InetChecksiteData) => any): Promise<Systeminformation.InetChecksiteData>;
export function inetLatency(host?: string, cb?: (data: number) => any): Promise<number>;
export function wifi(cb?: (data: Systeminformation.WifiNetworkData[]) => any): Promise<Systeminformation.WifiNetworkData[]>;
export function users(cb?: (data: Systeminformation.UserData[]) => any): Promise<Systeminformation.UserData[]>;
export function processes(cb?: (data: Systeminformation.ProcessesData) => any): Promise<Systeminformation.ProcessesData>;

View File

@ -18,6 +18,7 @@ const fs = require('fs');
const spawn = require('child_process').spawn;
const exec = require('child_process').exec;
const execSync = require('child_process').execSync;
const util = require('util');
let _platform = process.platform;
const _linux = (_platform === 'linux');
@ -35,7 +36,8 @@ let codepage = '';
const execOptsWin = {
windowsHide: true,
maxBuffer: 1024 * 2000,
encoding: 'UTF-8'
encoding: 'UTF-8',
env: util._extend(process.env, { LANG: 'en_US.UTF-8' })
};

View File

@ -15,8 +15,6 @@
const os = require('os');
const exec = require('child_process').exec;
const execSync = require('child_process').execSync;
const fs = require('fs');
const util = require('./util');
let _platform = process.platform;
@ -24,10 +22,6 @@ let _platform = process.platform;
const _linux = (_platform === 'linux');
const _darwin = (_platform === 'darwin');
const _windows = (_platform === 'win32');
const _freebsd = (_platform === 'freebsd');
const _openbsd = (_platform === 'openbsd');
const _netbsd = (_platform === 'netbsd');
const _sunos = (_platform === 'sunos');
function wifiDBFromQuality(quality) {
return (parseFloat(quality) / 2 - 100);
@ -37,6 +31,85 @@ function wifiQualityFromDB(db) {
return 2 * (parseFloat(db) + 100);
}
function wifiFrequencyFromChannel(channel) {
const frequencies = {
1: 2412,
2: 2417,
3: 2422,
4: 2427,
5: 2432,
6: 2437,
7: 2442,
8: 2447,
9: 2452,
10: 2457,
11: 2462,
12: 2467,
13: 2472,
14: 2484,
32: 5160,
34: 5170,
36: 5180,
38: 5190,
40: 5200,
42: 5210,
44: 5220,
46: 5230,
48: 5240,
50: 5250,
52: 5260,
54: 5270,
56: 5280,
58: 5290,
60: 5300,
62: 5310,
64: 5320,
68: 5340,
96: 5480,
100: 5500,
102: 5510,
104: 5520,
106: 5530,
108: 5540,
110: 5550,
112: 5560,
114: 5570,
116: 5580,
118: 5590,
120: 5600,
122: 5610,
124: 5620,
126: 5630,
128: 5640,
132: 5660,
134: 5670,
136: 5680,
138: 5690,
140: 5700,
142: 5710,
144: 5720,
149: 5745,
151: 5755,
153: 5765,
155: 5775,
157: 5785,
159: 5795,
161: 5805,
165: 5825,
169: 5845,
173: 5865,
183: 4915,
184: 4920,
185: 4925,
187: 4935,
188: 4940,
189: 4945,
192: 4960,
196: 4980
};
return frequencies.hasOwnProperty(channel) ? frequencies[channel] : -1;
}
function wifi(callback) {
return new Promise((resolve) => {
@ -52,10 +125,10 @@ function wifi(callback) {
part = 'ACTIVE:' + part;
const lines = part.split(os.EOL);
const channel = util.getValue(lines, 'CHAN');
const frequency = util.getValue(lines, 'FREQ').toLowerCase().replace('mhz', '').trim()
const security = util.getValue(lines, 'SECURITY').replace('(', '').replace(')', '')
const wpaFlags = util.getValue(lines, 'WPA-FLAGS').replace('(', '').replace(')', '')
const rsnFlags = util.getValue(lines, 'RSN-FLAGS').replace('(', '').replace(')', '')
const frequency = util.getValue(lines, 'FREQ').toLowerCase().replace('mhz', '').trim();
const security = util.getValue(lines, 'SECURITY').replace('(', '').replace(')', '');
const wpaFlags = util.getValue(lines, 'WPA-FLAGS').replace('(', '').replace(')', '');
const rsnFlags = util.getValue(lines, 'RSN-FLAGS').replace('(', '').replace(')', '');
result.push({
ssid: util.getValue(lines, 'SSID'),
bssid: util.getValue(lines, 'BSSID'),
@ -67,17 +140,89 @@ function wifi(callback) {
security: security && security !== 'none' ? security.split(' ') : [],
wpaFlags: wpaFlags && wpaFlags !== 'none' ? wpaFlags.split(' ') : [],
rsnFlags: rsnFlags && rsnFlags !== 'none' ? rsnFlags.split(' ') : []
})
})
});
});
if (callback) {
callback(result);
}
resolve(result);
});
} else if (_darwinx) {
let cmd = '';
} else if (_darwin) {
let cmd = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s';
exec(cmd, { maxBuffer: 1024 * 2000 }, function (error, stdout) {
const lines = stdout.toString().split(os.EOL);
if (lines && lines.length > 1) {
const parsedhead = util.parseHead(lines[0], 1);
if (parsedhead.length >= 7) {
lines.shift();
lines.forEach(line => {
if (line.trim()) {
const channelStr = line.substring(parsedhead[3].from, parsedhead[3].to).trim();
const channel = channelStr ? parseInt(channelStr, 10) : -1;
const signalLevel = line.substring(parsedhead[2].from, parsedhead[2].to).trim();
const securityAll = line.substring(parsedhead[6].from, 1000).trim().split(' ');
let security = [];
let wpaFlags = [];
securityAll.forEach(securitySingle => {
if (securitySingle.indexOf('(') > 0) {
const parts = securitySingle.split('(');
security.push(parts[0]);
wpaFlags = wpaFlags.concat(parts[1].replace(')', '').split(','));
}
});
wpaFlags = [...new Set(wpaFlags)];
result.push({
ssid: line.substring(parsedhead[0].from, parsedhead[0].to).trim(),
bssid: line.substring(parsedhead[1].from, parsedhead[1].to).trim(),
mode: '',
channel,
frequency: wifiFrequencyFromChannel(channel),
signalLevel: signalLevel ? parseInt(signalLevel, 10) : -1,
quality: wifiQualityFromDB(signalLevel),
security,
wpaFlags,
rsnFlags: []
});
}
});
}
}
if (callback) {
callback(result);
}
resolve(result);
});
} else if (_windows) {
let cmd = 'chcp 65001 && netsh wlan show networks mode=Bssid';
exec(cmd, util.execOptsWin, function (error, stdout) {
const parts = stdout.toString('utf8').split(os.EOL + os.EOL + 'SSID ');
parts.shift();
parts.forEach(part => {
const lines = part.split(os.EOL);
if (lines && lines.length >= 8 && lines[0].indexOf(':') >= 0) {
let bssid = lines[4].split(':');
bssid.shift();
bssid = bssid.join(':').trim();
const channel = lines[7].split(':').pop().trim();
const quality = lines[5].split(':').pop().trim();
result.push({
ssid: lines[0].split(':').pop().trim(),
bssid,
mode: '',
channel: channel ? parseInt(channel, 10) : -1,
frequency: wifiFrequencyFromChannel(channel),
signalLevel: wifiDBFromQuality(quality),
quality: quality ? parseInt(quality, 10) : -1,
security: [lines[2].split(':').pop().trim()],
wpaFlags: [lines[3].split(':').pop().trim()],
rsnFlags: []
});
}
});
if (callback) {
callback(result);
}