Compile ble and wifi as is.

This commit is contained in:
mmcwilliams 2019-11-26 10:44:08 -05:00
parent 9d1163926f
commit 84ee49a71c
4 changed files with 422 additions and 445 deletions

View File

@ -1,254 +1,230 @@
'use strict' 'use strict';
/** @module ble */ /** @module ble */
/** Bluetooth Low Energy module */ /** Bluetooth Low Energy module */
const util = require('util');
const util = require('util') const os = require('os');
const os = require('os') const log = require('../log')('ble');
const wifi = require('../wifi');
const log = require('../log')('ble') const DEVICE_NAME = process.env.DEVICE_NAME || 'intval3';
const wifi = require('../wifi') const SERVICE_ID = process.env.SERVICE_ID || 'intval3_ble';
const CHAR_ID = process.env.CHAR_ID || 'intval3char';
const DEVICE_NAME = process.env.DEVICE_NAME || 'intval3' const WIFI_ID = process.env.WIFI_ID || 'wifichar';
const SERVICE_ID = process.env.SERVICE_ID || 'intval3_ble' const NETWORK = os.networkInterfaces();
const CHAR_ID = process.env.CHAR_ID || 'intval3char' const MAC = getMac() || spoofMac();
const WIFI_ID = process.env.WIFI_ID || 'wifichar'
const NETWORK = os.networkInterfaces()
const MAC = getMac() || spoofMac()
//Give the device a unique device name, needs to be in env //Give the device a unique device name, needs to be in env
process.env.BLENO_DEVICE_NAME += '_' + MAC process.env.BLENO_DEVICE_NAME += '_' + MAC;
const bleno = require('bleno') const bleno = require('bleno');
let currentWifi = 'disconnected';
let currentAddr = null;
let currentWifi = 'disconnected' let getState;
let currentAddr = null const chars = [];
let getState
const chars = []
function createChar(name, uuid, prop, write, read) { function createChar(name, uuid, prop, write, read) {
function characteristic () { function characteristic() {
bleno.Characteristic.call(this, { bleno.Characteristic.call(this, {
uuid : uuid, uuid: uuid,
properties: prop properties: prop
}) });
} }
util.inherits(characteristic, bleno.Characteristic) util.inherits(characteristic, bleno.Characteristic);
if (prop.indexOf('read') !== -1) { if (prop.indexOf('read') !== -1) {
//data, offset, withoutResponse, callback //data, offset, withoutResponse, callback
characteristic.prototype.onReadRequest = read characteristic.prototype.onReadRequest = read;
} }
if (prop.indexOf('write') !== -1) { if (prop.indexOf('write') !== -1) {
characteristic.prototype.onWriteRequest = write characteristic.prototype.onWriteRequest = write;
} }
chars.push(new characteristic()) chars.push(new characteristic());
} }
function createChars(onWrite, onRead) {
function createChars (onWrite, onRead) { createChar('intval3', CHAR_ID, ['read', 'write'], onWrite, onRead);
createChar('intval3', CHAR_ID, ['read', 'write'], onWrite, onRead) createChar('wifi', WIFI_ID, ['read', 'write'], onWifiWrite, onWifiRead);
createChar('wifi', WIFI_ID, ['read', 'write'], onWifiWrite, onWifiRead)
} }
function onWifiWrite(data, offset, withoutResponse, callback) {
function onWifiWrite (data, offset, withoutResponse, callback) { let result;
let result let utf8;
let utf8 let obj;
let obj let ssid;
let ssid let pwd;
let pwd if (offset) {
if (offset) { log.warn(`Offset scenario`);
log.warn(`Offset scenario`) result = bleno.Characteristic.RESULT_ATTR_NOT_LONG;
result = bleno.Characteristic.RESULT_ATTR_NOT_LONG return callback(result);
return callback(result) }
} utf8 = data.toString('utf8');
utf8 = data.toString('utf8') obj = JSON.parse(utf8);
obj = JSON.parse(utf8) ssid = obj.ssid;
ssid = obj.ssid pwd = obj.pwd;
pwd = obj.pwd log.info(`connecting to AP`, { ssid: ssid });
log.info(`connecting to AP`, { ssid : ssid }) return wifi.createPSK(ssid, pwd, (err, hash, plaintext) => {
return wifi.createPSK(ssid, pwd, (err, hash, plaintext) => { if (err) {
if (err) { log.error('Error hashing wifi password', err);
log.error('Error hashing wifi password', err) result = bleno.Characteristic.RESULT_UNLIKELY_ERROR;
result = bleno.Characteristic.RESULT_UNLIKELY_ERROR return callback(result);
return callback(result) }
} return wifi.setNetwork(ssid, plaintext, hash, (err, data) => {
return wifi.setNetwork(ssid, plaintext, hash, (err, data) => { if (err) {
if (err) { log.error('Error configuring wifi', err);
log.error('Error configuring wifi', err) result = bleno.Characteristic.RESULT_UNLIKELY_ERROR;
result = bleno.Characteristic.RESULT_UNLIKELY_ERROR return callback(result);
return callback(result) }
} currentWifi = ssid;
currentWifi = ssid currentAddr = getIp();
currentAddr = getIp() log.info(`Connected to AP`, { ssid: ssid, ip: currentAddr });
log.info(`Connected to AP`, { ssid : ssid, ip : currentAddr }) result = bleno.Characteristic.RESULT_SUCCESS;
result = bleno.Characteristic.RESULT_SUCCESS return callback(result);
return callback(result) });
}) });
})
} }
function onWifiRead(offset, callback) {
function onWifiRead (offset, callback) { let result = bleno.Characteristic.RESULT_SUCCESS;
let result = bleno.Characteristic.RESULT_SUCCESS let wifiRes = {};
let wifiRes = {} let data;
let data wifi.list((err, list) => {
wifi.list((err, list) => { if (err) {
if (err) { result = bleno.Characteristic.RESULT_UNLIKELY_ERROR;
result = bleno.Characteristic.RESULT_UNLIKELY_ERROR return callback(result);
return callback(result) }
} wifiRes.available = list;
wifiRes.available = list wifiRes.current = currentWifi;
wifiRes.current = currentWifi wifiRes.ip = currentAddr;
wifiRes.ip = currentAddr log.info('Discovered available APs', { found: list.length });
log.info('Discovered available APs', { found : list.length }) data = new Buffer(JSON.stringify(wifiRes));
data = new Buffer(JSON.stringify(wifiRes)) callback(result, data.slice(offset, data.length));
callback(result, data.slice(offset, data.length)) });
})
} }
function getMac() {
function getMac () { const colonRe = new RegExp(':', 'g');
const colonRe = new RegExp(':', 'g') if (NETWORK && NETWORK.wlan0 && NETWORK.wlan0[0] && NETWORK.wlan0[0].mac) {
if (NETWORK && NETWORK.wlan0 && NETWORK.wlan0[0] && NETWORK.wlan0[0].mac) { return NETWORK.wlan0[0].mac.replace(colonRe, '');
return NETWORK.wlan0[0].mac.replace(colonRe, '') }
} return undefined;
return undefined
} }
function spoofMac() {
function spoofMac () { const fs = require('fs');
const fs = require('fs') const FSPATH = require.resolve('uuid');
const FSPATH = require.resolve('uuid') const IDFILE = os.homedir() + '/.intval3id';
const IDFILE = os.homedir() + '/.intval3id' let uuid;
let uuid let UUIDPATH;
let UUIDPATH let TMP;
let TMP let MACTMP;
let MACTMP let dashRe;
let dashRe delete require.cache[FSPATH];
delete require.cache[FSPATH] if (fs.existsSync(IDFILE)) {
if (fs.existsSync(IDFILE)) { return fs.readFileSync(IDFILE, 'utf8');
return fs.readFileSync(IDFILE, 'utf8') }
} uuid = require('uuid').v4;
uuid = require('uuid').v4 UUIDPATH = require.resolve('uuid');
UUIDPATH = require.resolve('uuid') delete require.cache[UUIDPATH];
delete require.cache[UUIDPATH] TMP = uuid();
TMP = uuid() MACTMP = TMP.replace(dashRe, '').substring(0, 12);
MACTMP = TMP.replace(dashRe, '').substring(0, 12) dashRe = new RegExp('-', 'g');
dashRe = new RegExp('-', 'g') fs.writeFileSync(IDFILE, MACTMP, 'utf8');
fs.writeFileSync(IDFILE, MACTMP, 'utf8') return MACTMP;
return MACTMP
} }
function getIp() {
function getIp () { let addr = null;
let addr = null let ipv4;
let ipv4 const ifaces = os.networkInterfaces();
const ifaces = os.networkInterfaces() if (ifaces && ifaces.wlan0) {
if (ifaces && ifaces.wlan0) { ipv4 = ifaces.wlan0.filter(iface => {
ipv4 = ifaces.wlan0.filter(iface => { if (iface.family === 'IPv4') {
if (iface.family === 'IPv4') { return iface;
return iface }
} });
}) if (ipv4.length === 1) {
if (ipv4.length === 1) { addr = ipv4[0].address;
addr = ipv4[0].address }
} }
} return addr;
return addr
} }
function capitalize(s) {
return s[0].toUpperCase() + s.slice(1);
function capitalize (s) {
return s[0].toUpperCase() + s.slice(1)
} }
/** Class representing the bluetooth interface */ /** Class representing the bluetooth interface */
class BLE { class BLE {
/** /**
* Establishes Bluetooth Low Energy services, accessible to process through this class * Establishes Bluetooth Low Energy services, accessible to process through this class
* *
* @constructor * @constructor
*/ */
constructor (bleGetState) { constructor(bleGetState) {
log.info('Starting bluetooth service') log.info('Starting bluetooth service');
getState = bleGetState;
getState = bleGetState bleno.on('stateChange', state => {
log.info('stateChange', { state: state });
bleno.on('stateChange', state => { if (state === 'poweredOn') {
log.info('stateChange', { state : state }) log.info('Starting advertising', { DEVICE_NAME, DEVICE_ID: process.env.BLENO_DEVICE_NAME });
if (state === 'poweredOn') { bleno.startAdvertising(DEVICE_NAME, [CHAR_ID]);
log.info('Starting advertising', { DEVICE_NAME, DEVICE_ID : process.env.BLENO_DEVICE_NAME }) }
bleno.startAdvertising(DEVICE_NAME, [CHAR_ID]) else {
} else { bleno.stopAdvertising();
bleno.stopAdvertising() }
} });
}) bleno.on('advertisingStart', err => {
log.info('advertisingStart', { res: (err ? 'error ' + err : 'success') });
bleno.on('advertisingStart', err => { createChars(this._onWrite.bind(this), this._onRead.bind(this));
log.info('advertisingStart', { res : (err ? 'error ' + err : 'success') }) if (!err) {
createChars(this._onWrite.bind(this), this._onRead.bind(this)) bleno.setServices([
if (!err) { new bleno.PrimaryService({
bleno.setServices([ uuid: SERVICE_ID,
new bleno.PrimaryService({ characteristics: chars
uuid : SERVICE_ID, //hardcoded across panels })
characteristics : chars ]);
}) }
]) });
} bleno.on('accept', clientAddress => {
}) log.info('accept', { clientAddress: clientAddress });
});
bleno.on('accept', clientAddress => { bleno.on('disconnect', clientAddress => {
log.info('accept', { clientAddress : clientAddress }) log.info('disconnect', { clientAddress: clientAddress });
}) });
wifi.getNetwork((err, ssid) => {
bleno.on('disconnect', clientAddress => { if (err) {
log.info('disconnect', { clientAddress : clientAddress }) return log.error('wifi.getNetwork', err);
}) }
currentWifi = ssid;
wifi.getNetwork((err, ssid) => { currentAddr = getIp();
if (err) { log.info('wifi.getNetwork', { ssid: ssid, ip: currentAddr });
return log.error('wifi.getNetwork', err) });
} }
currentWifi = ssid _onWrite(data, offset, withoutResponse, callback) {
currentAddr = getIp() let result = {};
log.info('wifi.getNetwork', {ssid : ssid, ip : currentAddr }) let utf8;
}) let obj;
} let fn;
_onWrite (data, offset, withoutResponse, callback) { if (offset) {
let result = {} log.warn(`Offset scenario`);
let utf8 result = bleno.Characteristic.RESULT_ATTR_NOT_LONG;
let obj return callback(result);
let fn }
if (offset) { utf8 = data.toString('utf8');
log.warn(`Offset scenario`) obj = JSON.parse(utf8);
result = bleno.Characteristic.RESULT_ATTR_NOT_LONG result = bleno.Characteristic.RESULT_SUCCESS;
return callback(result) fn = `_on${capitalize(obj.type)}`;
} if (obj.type && this[fn]) {
utf8 = data.toString('utf8') return this[fn](obj, () => {
obj = JSON.parse(utf8) callback(result);
result = bleno.Characteristic.RESULT_SUCCESS });
fn = `_on${capitalize(obj.type)}` }
if (obj.type && this[fn]) { else {
return this[fn](obj, () => { return callback(result);
callback(result) }
}) }
} else { _onRead(offset, callback) {
return callback(result) const result = bleno.Characteristic.RESULT_SUCCESS;
} const state = getState();
const data = new Buffer(JSON.stringify(state));
} callback(result, data.slice(offset, data.length));
_onRead (offset, callback) { }
const result = bleno.Characteristic.RESULT_SUCCESS /**
const state = getState() * Binds functions to events that are triggered by BLE messages
const data = new Buffer(JSON.stringify( state )) *
callback(result, data.slice(offset, data.length)) * @param {string} eventName Name of the event to to bind
} * @param {function} callback Invoked when the event is triggered
/** */
* Binds functions to events that are triggered by BLE messages on(eventName, callback) {
* this[`_on${capitalize(eventName)}`] = callback;
* @param {string} eventName Name of the event to to bind }
* @param {function} callback Invoked when the event is triggered
*/
on (eventName, callback) {
this[`_on${capitalize(eventName)}`] = callback
}
} }
module.exports = BLE;
module.exports = BLE //# sourceMappingURL=index.js.map

1
lib/ble/index.js.map Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,209 +1,208 @@
'use strict' 'use strict';
const networkPattern = /network[\s\S]*?=[\s\S]*?{([\s\S]*?)}/gi;
const networkPattern = /network[\s\S]*?=[\s\S]*?{([\s\S]*?)}/gi const quoteRe = new RegExp('"', 'g');
const quoteRe = new RegExp('"', 'g') const filePath = '/etc/wpa_supplicant/wpa_supplicant.conf';
const reconfigure = '/sbin/wpa_cli reconfigure';
const filePath = '/etc/wpa_supplicant/wpa_supplicant.conf' const refresh = 'ip link set wlan0 down && ip link set wlan0 up';
const reconfigure = '/sbin/wpa_cli reconfigure' const iwlist = '/sbin/iwlist wlan0 scanning | grep "ESSID:"';
const refresh = 'ip link set wlan0 down && ip link set wlan0 up' const iwgetid = '/sbin/iwgetid';
const iwlist = '/sbin/iwlist wlan0 scanning | grep "ESSID:"' const log = require('../log')('wifi');
const iwgetid = '/sbin/iwgetid' const exec = require('child_process').exec;
const fs = require('fs');
const log = require('../log')('wifi') let _entry = null;
const exec = require('child_process').exec let _ssid = null;
const fs = require('fs') let _cb = null;
let _entry = null
let _ssid = null
let _cb = null
/** Class representing the wifi features */ /** Class representing the wifi features */
class Wifi { class Wifi {
constructor () { constructor() {
}
} /**
/** * List available wifi access points
* List available wifi access points *
* * @param {function} callback Function which gets invoked after list is returned
* @param {function} callback Function which gets invoked after list is returned */
*/ list(callback) {
list (callback) { exec(iwlist, (err, stdout, stderr) => {
exec(iwlist, (err, stdout, stderr) => { if (err) {
if (err) { console.error(err);
console.error(err) return callback(err);
return callback(err) }
} const limit = 20;
const limit = 20; const lines = stdout.split('\n');
const lines = stdout.split('\n') let output = [];
let output = [] let line;
let line let i = 0;
let i = 0 for (let l of lines) {
for (let l of lines) { line = l.replace('ESSID:', '').trim();
line = l.replace('ESSID:', '').trim() if (line !== '""' && i < limit) {
if (line !== '""' && i < limit) { line = line.replace(quoteRe, '');
line = line.replace(quoteRe, '') output.push(line);
output.push(line) }
} i++;
i++ }
} output = output.filter(ap => {
output = output.filter(ap => { if (ap !== '')
if (ap !== '') return ap return ap;
}) });
return callback(null, output) return callback(null, output);
}) });
} }
/** /**
* (internal function) Invoked after config file is read, * (internal function) Invoked after config file is read,
* then invokes file write on the config file * then invokes file write on the config file
* *
* @param {object} err (optional) Error object only present if problem reading config file * @param {object} err (optional) Error object only present if problem reading config file
* @param {string} data Contents of the config file * @param {string} data Contents of the config file
*/ */
_readConfigCb (err, data) { _readConfigCb(err, data) {
let parsed let parsed;
let current let current;
if (err) { if (err) {
console.error(err) console.error(err);
return _cb(err) return _cb(err);
} }
parsed = this._parseConfig(data) parsed = this._parseConfig(data);
current = parsed.find(network => { current = parsed.find(network => {
return network.ssid === _ssid return network.ssid === _ssid;
}) });
if (typeof current !== 'undefined') { if (typeof current !== 'undefined') {
data = data.replace(current.raw, _entry) data = data.replace(current.raw, _entry);
} else { }
data += '\n\n' + _entry else {
} data += '\n\n' + _entry;
_entry = null }
fs.writeFile(filePath, data, 'utf8', this._writeConfigCb.bind(this)) _entry = null;
} fs.writeFile(filePath, data, 'utf8', this._writeConfigCb.bind(this));
/** }
* (internal function) Invoked after config file is written, /**
* then executes reconfiguration command * (internal function) Invoked after config file is written,
* * then executes reconfiguration command
* @param {object} err (optional) Error object only present if problem writing config file *
*/ * @param {object} err (optional) Error object only present if problem writing config file
_writeConfigCb (err) { */
if (err) { _writeConfigCb(err) {
console.error(err) if (err) {
return _cb(err) console.error(err);
} return _cb(err);
exec(reconfigure, this._reconfigureCb.bind(this)) }
} exec(reconfigure, this._reconfigureCb.bind(this));
/** }
* (internal function) Invoked after reconfiguration command is complete /**
* * (internal function) Invoked after reconfiguration command is complete
* @param {object} err (optional) Error object only present if configuration command fails *
* @param {string} stdout Standard output from reconfiguration command * @param {object} err (optional) Error object only present if configuration command fails
* @param {string} stderr Error output from command if fails * @param {string} stdout Standard output from reconfiguration command
*/ * @param {string} stderr Error output from command if fails
_reconfigureCb (err, stdout, stderr) { */
if (err) { _reconfigureCb(err, stdout, stderr) {
console.error(err) if (err) {
return _cb(err) console.error(err);
} return _cb(err);
console.log('Wifi reconfigured') }
exec(refresh, this._refreshCb.bind(this)) console.log('Wifi reconfigured');
} exec(refresh, this._refreshCb.bind(this));
/** }
* (internal function) Invoked after wifi refresh command is complete /**
* * (internal function) Invoked after wifi refresh command is complete
* @param {object} err (optional) Error object only present if refresh command fails *
* @param {string} stdout Standard output from refresh command * @param {object} err (optional) Error object only present if refresh command fails
* @param {string} stderr Error output from command if fails * @param {string} stdout Standard output from refresh command
*/ * @param {string} stderr Error output from command if fails
_refreshCb (err, stdout, stderr) { */
if (err) { _refreshCb(err, stdout, stderr) {
console.error(err) if (err) {
return _cb(err) console.error(err);
} return _cb(err);
console.log('Wifi refreshed') }
_cb(null, { ssid : _ssid }) console.log('Wifi refreshed');
_cb = () => {} _cb(null, { ssid: _ssid });
} _cb = () => { };
_parseConfig (str) { }
const networks = [] _parseConfig(str) {
const lines = str.split('\n') const networks = [];
let network = {} const lines = str.split('\n');
for (let line of lines) { let network = {};
if (line.substring(0, 9) === 'network={') { for (let line of lines) {
network = {} if (line.substring(0, 9) === 'network={') {
network.raw = line network = {};
} else if (network.raw && line.indexOf('ssid=') !== -1) { network.raw = line;
network.ssid = line.replace('ssid=', '').trim().replace(quoteRe, '') }
if (network.raw) { else if (network.raw && line.indexOf('ssid=') !== -1) {
network.raw += '\n' + line network.ssid = line.replace('ssid=', '').trim().replace(quoteRe, '');
} if (network.raw) {
} else if (network.raw && line.substring(0, 1) === '}') { network.raw += '\n' + line;
network.raw += '\n' + line }
networks.push(network) }
network = {} else if (network.raw && line.substring(0, 1) === '}') {
} else if (network.raw) { network.raw += '\n' + line;
network.raw += '\n' + line networks.push(network);
} network = {};
} }
return networks else if (network.raw) {
} network.raw += '\n' + line;
/** }
* Create sanitized wpa_supplicant.conf stanza for }
* configuring wifi without storing plaintext passwords return networks;
* @example }
* network={ /**
* ssid="YOUR_SSID" * Create sanitized wpa_supplicant.conf stanza for
* #psk="YOUR_PASSWORD" * configuring wifi without storing plaintext passwords
* psk=6a24edf1592aec4465271b7dcd204601b6e78df3186ce1a62a31f40ae9630702 * @example
* } * network={
* * ssid="YOUR_SSID"
* @param {string} ssid SSID of wifi network * #psk="YOUR_PASSWORD"
* @param {string} pwd Plaintext passphrase of wifi network * psk=6a24edf1592aec4465271b7dcd204601b6e78df3186ce1a62a31f40ae9630702
* @param {function} callback Function called after psk hash is generated * }
*/ *
createPSK (ssid, pwd, callback) { * @param {string} ssid SSID of wifi network
const cmd = `wpa_passphrase '${ssid.replace(/'/g, `'\\''`)}' '${pwd.replace(/'/g, `'\\''`)}' | grep "psk="` * @param {string} pwd Plaintext passphrase of wifi network
let lines * @param {function} callback Function called after psk hash is generated
let hash */
let plaintext createPSK(ssid, pwd, callback) {
exec(cmd, (err, stdout, stderr) => { const cmd = `wpa_passphrase '${ssid.replace(/'/g, `'\\''`)}' '${pwd.replace(/'/g, `'\\''`)}' | grep "psk="`;
if (err) { let lines;
return callback(err) let hash;
} let plaintext;
lines = stdout.replace('#psk=', '').split('psk=') exec(cmd, (err, stdout, stderr) => {
hash = lines[1] if (err) {
plaintext = lines[0] return callback(err);
callback(null, hash.trim(), plaintext.trim()) }
}) lines = stdout.replace('#psk=', '').split('psk=');
} hash = lines[1];
/** plaintext = lines[0];
* Function which initializes the processes for adding a wifi access point authentication callback(null, hash.trim(), plaintext.trim());
* });
* @param {string} ssid SSID of network to configure }
* @param {string} pwd Password of access point, plaintext to be masked /**
* @param {string} hash Password/SSID of access point, securely hashed * Function which initializes the processes for adding a wifi access point authentication
* @param {function} callback Function invoked after process is complete, or fails *
*/ * @param {string} ssid SSID of network to configure
setNetwork (ssid, pwd, hash, callback) { * @param {string} pwd Password of access point, plaintext to be masked
let masked = pwd.split('').map(char => { return char !== '"' ? '*' : '"' }).join('') * @param {string} hash Password/SSID of access point, securely hashed
_entry = `network={\n\tssid="${ssid}"\n\t#psk=${masked}\n\tpsk=${hash}\n}\n` * @param {function} callback Function invoked after process is complete, or fails
_cb = callback */
_ssid = ssid setNetwork(ssid, pwd, hash, callback) {
fs.readFile(filePath, 'utf8', this._readConfigCb.bind(this)) let masked = pwd.split('').map(char => { return char !== '"' ? '*' : '"'; }).join('');
} _entry = `network={\n\tssid="${ssid}"\n\t#psk=${masked}\n\tpsk=${hash}\n}\n`;
/** _cb = callback;
* Executes command which gets the currently connected network _ssid = ssid;
* fs.readFile(filePath, 'utf8', this._readConfigCb.bind(this));
* @param {function} callback Function which is invoked after command is completed }
*/ /**
getNetwork (callback) { * Executes command which gets the currently connected network
let output *
exec(iwgetid, (err, stdout, stderr) => { * @param {function} callback Function which is invoked after command is completed
if (err) { */
return callback(err) getNetwork(callback) {
} let output;
output = stdout.split('ESSID:')[1].replace(quoteRe, '').trim() exec(iwgetid, (err, stdout, stderr) => {
callback(null, output) if (err) {
}) return callback(err);
} }
output = stdout.split('ESSID:')[1].replace(quoteRe, '').trim();
callback(null, output);
});
}
} }
module.exports = new Wifi();
module.exports = new Wifi() //# sourceMappingURL=index.js.map

1
lib/wifi/index.js.map Normal file

File diff suppressed because one or more lines are too long