wifiNetworks() adaption for Apple silicon (mac OS)
This commit is contained in:
parent
aaedb03037
commit
98281bab48
@ -80,6 +80,7 @@ For major (breaking) changes - **version 4, 3 and 2** - see end of page.
|
||||
|
||||
| Version | Date | Comment |
|
||||
| -------------- | -------------- | -------- |
|
||||
| 5.9.16 | 2021-12-05 | `wifiNetworks()` adaption for Apple silicon (mac OS) |
|
||||
| 5.9.15 | 2021-11-19 | `cpuCache()` fix (windows) |
|
||||
| 5.9.14 | 2021-11-17 | `versions()` python 2 monterey (deprecated warning) fix (mac OS) |
|
||||
| 5.9.13 | 2021-11-14 | `time()` timezone name, `l1 cache` improvements |
|
||||
|
||||
@ -57,6 +57,11 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">5.9.16</th>
|
||||
<td>2021-12-05</td>
|
||||
<td><span class="code">wifiNetworks()</span> adaption for Apple silicon (mac OS)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">5.9.15</th>
|
||||
<td>2021-11-19</td>
|
||||
|
||||
@ -170,7 +170,7 @@
|
||||
<img class="logo" src="assets/logo.png">
|
||||
<div class="title">systeminformation</div>
|
||||
<div class="subtitle"><span id="typed"></span> </div>
|
||||
<div class="version">New Version: <span id="version">5.9.15</span></div>
|
||||
<div class="version">New Version: <span id="version">5.9.16</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">
|
||||
|
||||
153
lib/util.js
153
lib/util.js
@ -1111,91 +1111,98 @@ function linuxVersion() {
|
||||
}
|
||||
|
||||
function plistParser(xmlStr) {
|
||||
const tags = ['array', 'dict', 'key', 'string', 'integer', 'date', 'real', 'data'];
|
||||
const tags = ['array', 'dict', 'key', 'string', 'integer', 'date', 'real', 'data', 'boolean', 'arrayEmpty'];
|
||||
const startStr = '<plist version';
|
||||
|
||||
function getNextTagPos() {
|
||||
let result = {
|
||||
pos: 999999,
|
||||
tag: ''
|
||||
};
|
||||
tags.forEach((tag) => {
|
||||
const ii = xmlStr.indexOf(`<${tag}>`);
|
||||
if (ii !== -1 && ii < result.pos) {
|
||||
result = {
|
||||
pos: ii,
|
||||
tag
|
||||
};
|
||||
}
|
||||
});
|
||||
return result;
|
||||
let pos = xmlStr.indexOf(startStr);
|
||||
let len = xmlStr.length;
|
||||
while (xmlStr[pos] !== '>' && pos < len) {
|
||||
pos++;
|
||||
}
|
||||
|
||||
function getNextClosingTagPos(tag) {
|
||||
return xmlStr.indexOf(`</${tag}>`);
|
||||
}
|
||||
let depth = 0;
|
||||
let inTagStart = false;
|
||||
let inTagContent = false;
|
||||
let inTagEnd = false;
|
||||
let metaData = [{ tagStart: '', tagEnd: '', tagContent: '', key: '', data: null }];
|
||||
let c = '';
|
||||
let cn = xmlStr[pos];
|
||||
|
||||
function parseXmlTree(isArray, closingTag) {
|
||||
// start parsing
|
||||
let obj = {};
|
||||
let arr = [];
|
||||
let cpos = getNextTagPos();
|
||||
let key = '';
|
||||
let valueStr = null;
|
||||
|
||||
while (cpos.pos >= 0 && cpos.tag) {
|
||||
let nextTagPos = getNextTagPos();
|
||||
// let nextClosePos = getNextClosingTagPos(cpos.tag);
|
||||
let nextClosePosBlock = closingTag ? getNextClosingTagPos(closingTag) : 999999;
|
||||
if (nextClosePosBlock <= nextTagPos.pos) {
|
||||
return (isArray ? arr : obj);
|
||||
while (pos < len) {
|
||||
c = cn;
|
||||
if (pos + 1 < len) { cn = xmlStr[pos + 1]; }
|
||||
if (c === '<') {
|
||||
inTagContent = false;
|
||||
if (cn === '/') { inTagEnd = true; }
|
||||
else if (metaData[depth].tagStart) {
|
||||
metaData[depth].tagContent = '';
|
||||
if (!metaData[depth].data) { metaData[depth].data = metaData[depth].tagStart === 'array' ? [] : {}; }
|
||||
depth++;
|
||||
metaData.push({ tagStart: '', tagEnd: '', tagContent: '', key: null, data: null });
|
||||
inTagStart = true;
|
||||
inTagContent = false;
|
||||
}
|
||||
xmlStr = xmlStr.substring((cpos.pos + cpos.tag.length + 2));
|
||||
if (cpos.tag === 'array') {
|
||||
const res = parseXmlTree(true, cpos.tag);
|
||||
if (key) {
|
||||
obj[key] = res;
|
||||
} else {
|
||||
obj = res;
|
||||
else if (!inTagStart) { inTagStart = true; }
|
||||
} else if (c === '>') {
|
||||
if (metaData[depth].tagStart === 'true/') { inTagStart = false; inTagEnd = true; metaData[depth].tagStart = ''; metaData[depth].tagEnd = '/boolean'; metaData[depth].data = true; }
|
||||
if (metaData[depth].tagStart === 'false/') { inTagStart = false; inTagEnd = true; metaData[depth].tagStart = ''; metaData[depth].tagEnd = '/boolean'; metaData[depth].data = false; }
|
||||
if (metaData[depth].tagStart === 'array/') { inTagStart = false; inTagEnd = true; metaData[depth].tagStart = ''; metaData[depth].tagEnd = '/arrayEmpty'; metaData[depth].data = []; }
|
||||
if (inTagContent) { inTagContent = false; }
|
||||
if (inTagStart) {
|
||||
inTagStart = false;
|
||||
inTagContent = true;
|
||||
if (metaData[depth].tagStart === 'array') {
|
||||
metaData[depth].data = [];
|
||||
}
|
||||
} else if (cpos.tag === 'dict') {
|
||||
const res = parseXmlTree(false, cpos.tag);
|
||||
if (!isArray) {
|
||||
obj[key] = res;
|
||||
} else {
|
||||
arr.push(res);
|
||||
if (metaData[depth].tagStart === 'dict') {
|
||||
metaData[depth].data = {};
|
||||
}
|
||||
xmlStr = xmlStr.substring((cpos.pos + cpos.tag.length + 3));
|
||||
} else {
|
||||
let nextTagPos = getNextTagPos();
|
||||
let nextClosePos = getNextClosingTagPos(cpos.tag);
|
||||
// nextClosePosBlock = closingTag ? getNextClosingTagPos(closingTag) : 999999;
|
||||
if (nextClosePos < nextTagPos.pos) {
|
||||
if (cpos.tag === 'key') {
|
||||
key = xmlStr.substring(0, nextClosePos);
|
||||
xmlStr = xmlStr.substring(key.length + cpos.tag.length + 3); // key done
|
||||
} else {
|
||||
valueStr = xmlStr.substring(0, nextClosePos).replace(/\t/g, '');
|
||||
if (cpos.tag === 'string') { if (!isArray) { obj[key] = valueStr; } else { arr.push(valueStr); } }
|
||||
if (cpos.tag === 'integer') { if (!isArray) { obj[key] = parseInt(valueStr); } else { arr.push(parseInt(valueStr)); } }
|
||||
if (cpos.tag === 'date') { if (!isArray) { obj[key] = valueStr; } else { arr.push(valueStr); } }
|
||||
if (cpos.tag === 'data') { if (!isArray) { obj[key] = valueStr; } else { arr.push(valueStr); } }
|
||||
if (cpos.tag === 'real') { if (!isArray) { obj[key] = parseFloat(valueStr); } else { arr.push(parseFloat(valueStr)); } }
|
||||
|
||||
key = '';
|
||||
xmlStr = xmlStr.substring(valueStr.length + cpos.tag.length + 3); // property done
|
||||
}
|
||||
if (inTagEnd) {
|
||||
inTagEnd = false;
|
||||
if (metaData[depth].tagEnd && tags.indexOf(metaData[depth].tagEnd.substr(1)) >= 0) {
|
||||
if (metaData[depth].tagEnd === '/dict' || metaData[depth].tagEnd === '/array') {
|
||||
if (depth > 1 && metaData[depth - 2].tagStart === 'array') {
|
||||
metaData[depth - 2].data.push(metaData[depth - 1].data);
|
||||
}
|
||||
if (depth > 1 && metaData[depth - 2].tagStart === 'dict') {
|
||||
metaData[depth - 2].data[metaData[depth - 1].key] = metaData[depth - 1].data;
|
||||
}
|
||||
depth--;
|
||||
metaData.pop();
|
||||
metaData[depth].tagContent = '';
|
||||
metaData[depth].tagStart = '';
|
||||
metaData[depth].tagEnd = '';
|
||||
}
|
||||
else {
|
||||
if (metaData[depth].tagEnd === '/key' && metaData[depth].tagContent) {
|
||||
metaData[depth].key = metaData[depth].tagContent;
|
||||
} else {
|
||||
if (metaData[depth].tagEnd === '/real' && metaData[depth].tagContent) { metaData[depth].data = parseFloat(metaData[depth].tagContent) || 0; }
|
||||
if (metaData[depth].tagEnd === '/integer' && metaData[depth].tagContent) { metaData[depth].data = parseInt(metaData[depth].tagContent) || 0; }
|
||||
if (metaData[depth].tagEnd === '/string' && metaData[depth].tagContent) { metaData[depth].data = metaData[depth].tagContent || ''; }
|
||||
if (metaData[depth].tagEnd === '/boolean') { metaData[depth].data = metaData[depth].tagContent || false; }
|
||||
if (metaData[depth].tagEnd === '/arrayEmpty') { metaData[depth].data = metaData[depth].tagContent || []; }
|
||||
if (depth > 0 && metaData[depth - 1].tagStart === 'array') { metaData[depth - 1].data.push(metaData[depth].data); }
|
||||
if (depth > 0 && metaData[depth - 1].tagStart === 'dict') { metaData[depth - 1].data[metaData[depth].key] = metaData[depth].data; }
|
||||
}
|
||||
metaData[depth].tagContent = '';
|
||||
metaData[depth].tagStart = '';
|
||||
metaData[depth].tagEnd = '';
|
||||
}
|
||||
}
|
||||
metaData[depth].tagEnd = '';
|
||||
inTagStart = false;
|
||||
inTagContent = false;
|
||||
}
|
||||
cpos = getNextTagPos();
|
||||
} else {
|
||||
if (inTagStart) { metaData[depth].tagStart += c; }
|
||||
if (inTagEnd) { metaData[depth].tagEnd += c; }
|
||||
if (inTagContent) { metaData[depth].tagContent += c; }
|
||||
}
|
||||
return (isArray ? arr : obj);
|
||||
}
|
||||
try {
|
||||
const result = parseXmlTree(false, '');
|
||||
return result;
|
||||
} catch (e) {
|
||||
return {};
|
||||
pos++;
|
||||
}
|
||||
return metaData[0].data;
|
||||
}
|
||||
|
||||
function semverCompare(v1, v2) {
|
||||
|
||||
112
lib/wifi.js
112
lib/wifi.js
@ -315,8 +315,75 @@ function getWifiNetworkListIw(iface) {
|
||||
}
|
||||
}
|
||||
|
||||
function wifiNetworks(callback) {
|
||||
/*
|
||||
ssid: line.substring(parsedhead[0].from, parsedhead[0].to).trim(),
|
||||
bssid: line.substring(parsedhead[1].from, parsedhead[1].to).trim().toLowerCase(),
|
||||
mode: '',
|
||||
channel,
|
||||
frequency: wifiFrequencyFromChannel(channel),
|
||||
signalLevel: signalLevel ? parseInt(signalLevel, 10) : null,
|
||||
quality: wifiQualityFromDB(signalLevel),
|
||||
security,
|
||||
wpaFlags,
|
||||
rsnFlags: []
|
||||
|
||||
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(','));
|
||||
}
|
||||
});
|
||||
|
||||
*/
|
||||
function parseWifiDarwin(wifiObj) {
|
||||
const result = [];
|
||||
wifiObj.forEach(function (wifiItem) {
|
||||
const signalLevel = wifiItem.RSSI;
|
||||
let security = [];
|
||||
let wpaFlags = [];
|
||||
if (wifiItem.WPA_IE) {
|
||||
security.push('WPA');
|
||||
if (wifiItem.WPA_IE.IE_KEY_WPA_UCIPHERS) {
|
||||
wifiItem.WPA_IE.IE_KEY_WPA_UCIPHERS.forEach(function (ciphers) {
|
||||
if (ciphers === 0 && wpaFlags.indexOf('unknown/TKIP') === -1) { wpaFlags.push('unknown/TKIP'); }
|
||||
if (ciphers === 2 && wpaFlags.indexOf('PSK/TKIP') === -1) { wpaFlags.push('PSK/TKIP'); }
|
||||
if (ciphers === 4 && wpaFlags.indexOf('PSK/AES') === -1) { wpaFlags.push('PSK/AES'); }
|
||||
});
|
||||
}
|
||||
}
|
||||
if (wifiItem.RSN_IE) {
|
||||
security.push('WPA2');
|
||||
if (wifiItem.RSN_IE.IE_KEY_RSN_UCIPHERS) {
|
||||
wifiItem.RSN_IE.IE_KEY_RSN_UCIPHERS.forEach(function (ciphers) {
|
||||
if (ciphers === 0 && wpaFlags.indexOf('unknown/TKIP') === -1) { wpaFlags.push('unknown/TKIP'); }
|
||||
if (ciphers === 2 && wpaFlags.indexOf('TKIP/TKIP') === -1) { wpaFlags.push('TKIP/TKIP'); }
|
||||
if (ciphers === 4 && wpaFlags.indexOf('PSK/AES') === -1) { wpaFlags.push('PSK/AES'); }
|
||||
});
|
||||
}
|
||||
}
|
||||
result.push({
|
||||
ssid: wifiItem.SSID_STR,
|
||||
bssid: wifiItem.BSSID,
|
||||
mode: '',
|
||||
channel: wifiItem.CHANNEL,
|
||||
frequency: wifiFrequencyFromChannel(wifiItem.CHANNEL),
|
||||
signalLevel: signalLevel ? parseInt(signalLevel, 10) : null,
|
||||
quality: wifiQualityFromDB(signalLevel),
|
||||
security,
|
||||
wpaFlags,
|
||||
rsnFlags: []
|
||||
|
||||
});
|
||||
wifiItem.BSSID;
|
||||
|
||||
});
|
||||
return result;
|
||||
}
|
||||
function wifiNetworks(callback) {
|
||||
return new Promise((resolve) => {
|
||||
process.nextTick(() => {
|
||||
let result = [];
|
||||
@ -369,45 +436,10 @@ function wifiNetworks(callback) {
|
||||
resolve(result);
|
||||
}
|
||||
} else if (_darwin) {
|
||||
let cmd = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s';
|
||||
exec(cmd, { maxBuffer: 1024 * 20000 }, 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) : null;
|
||||
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 = Array.from(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().toLowerCase(),
|
||||
mode: '',
|
||||
channel,
|
||||
frequency: wifiFrequencyFromChannel(channel),
|
||||
signalLevel: signalLevel ? parseInt(signalLevel, 10) : null,
|
||||
quality: wifiQualityFromDB(signalLevel),
|
||||
security,
|
||||
wpaFlags,
|
||||
rsnFlags: []
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
let cmd = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s -x';
|
||||
exec(cmd, { maxBuffer: 1024 * 40000 }, function (error, stdout) {
|
||||
const output = stdout.toString();
|
||||
result = parseWifiDarwin(util.plistParser(output));
|
||||
if (callback) {
|
||||
callback(result);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user