18 Commits

Author SHA1 Message Date
5305124084 New version added v1.1.0 2016-12-09 19:12:16 +01:00
cfacdd6438 node 4 compliant again 2016-12-09 17:53:43 +01:00
8a8005e2ef Windows fixes (work still in progress) 2016-12-09 17:04:27 +01:00
6ce58993a2 Refactoring tool detection, work in progress 2016-12-09 16:55:17 +01:00
834dc4210e Test for GitHub issue #1: removed absolute path for iwlist 2016-12-09 09:25:20 +01:00
b33de0ce94 Lint issues only 2016-06-08 19:41:44 +02:00
26fff7e5d8 New version added v1.0.0 2016-05-03 14:53:52 +02:00
6f44b5b039 New version added v0.1.0 2016-04-12 17:22:28 +02:00
2caacc853a mmcli removed: using iwlist on linux systems, output was not really comparable to other tools 2016-04-12 17:22:11 +02:00
de5cde2ca9 New version added v0.0.5 2016-04-07 14:39:08 +02:00
7cf077d527 Windows Bugfix 2016-04-07 14:38:42 +02:00
253b375923 Another tags added 2016-04-07 13:25:28 +02:00
f22300b438 Build status added 2016-04-07 13:19:42 +02:00
a15dd29c53 travis added, package.json fixes 2016-04-07 13:14:27 +02:00
d01b3cc124 New version added v0.0.4 2016-04-07 06:20:37 +02:00
31d80834a7 npm and node version where to strict 2016-04-07 06:20:18 +02:00
1aff4ba049 Installation info added 2016-04-06 22:02:32 +02:00
4f693c9859 New version added v0.0.3 2016-04-06 21:48:38 +02:00
12 changed files with 101 additions and 168 deletions

8
.travis.yml Normal file
View File

@ -0,0 +1,8 @@
language: node_js
branches:
only:
- master
- develop
node_js:
- "4"
- "5"

View File

@ -1,6 +1,9 @@
/**
* Grunt file for node-wifi-scanner
* Grunt file for the ZigBeeSiteSurvey
*
* grunt update
* Updates the local common files with the ones from the editor project
* Create a new bugfix version (x.y.++):
* grunt v:patch
*
@ -10,7 +13,7 @@
* Create a new major version (++.0.0)
* grunt v:major
*
* Created by kc on 06.04.16
* Created by kc on 27.06.15.
*/
module.exports = function (grunt) {
@ -26,43 +29,18 @@ module.exports = function (grunt) {
commitFiles: ['-a'],
tagName: 'v%VERSION%',
tagMessage: 'Version %VERSION%',
push: true,
pushTo: 'git@github.com:ancasicolica/ZigBeeSiteSurvey.git',
push: false,
gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d',
globalReplace: false,
prereleaseName: false,
regExp: false
}
},
zip: {
'make': {
src: ['./**/**'],
dest: '../ZigBeeSiteSurvey_x.y.z_OS_.zip',
compression: 'DEFLATE'
}
},
compress: {
main: {
options: {
archive: 'dist/ZigBeeSiteSurvey-' + grunt.file.readJSON('package.json').version + '-Win-x64.zip'
},
files: [{
src: ['*.js', 'LICENSE', '*.json', 'node.exe', '*.md', 'lib/**', 'node_modules/**', 'public/**', 'routes/**', 'views/**'],
dest: 'ZigBeeSiteSurvey-' + grunt.file.readJSON('package.json').version + '-Win-x64'
}]
}
}
});
grunt.loadNpmTasks('grunt-bump');
grunt.loadNpmTasks('grunt-zip');
grunt.loadNpmTasks('grunt-contrib-compress');
grunt.registerTask('minify', ['concat', 'uglify:js']);
grunt.registerTask('v:patch', ['bump:patch']);
grunt.registerTask('v:minor', ['bump:minor']);
grunt.registerTask('v:major', ['bump:major']);
grunt.registerTask('make', ['zip:make']);
};

View File

@ -1,5 +1,9 @@
#node-wifi-scanner
[![Build Status](https://travis-ci.org/ancasicolica/node-wifi-scanner.svg?branch=master)](https://travis-ci.org/ancasicolica/node-wifi-scanner)
[![npm](https://img.shields.io/npm/v/node-wifi-scanner.svg)]()
[![npm](https://img.shields.io/npm/dt/node-wifi-scanner.svg)](https://www.npmjs.com/package/node-wifi-scanner)
This module for node.js scans available wifi networks. The main purpose was to enhance my node.js based
[ZigBee Site Survey Tool](http://ancasicolica.github.io/ZigBeeSiteSurvey/) with WiFi coexistence charts. This tool
claims to be compatible with current versions of Mac OS-X, Windows and Linux so I'll fix bugs as fast as possible.
@ -9,8 +13,6 @@ The module was inspired from Maurice Sways "[node-wifiscanner](https://github.co
had to handle much more complex network environments and also wanted to be independent of the operating
system language. The adaptions needed would have been too comprehensive for a pull request so I decided to write an own module.
**The module is currently in BETA testing, changes in functionality and interface are possible. Please report bugs on the projects GitHub page, Thanks!**
## Operating Systems
It was tested with the following operating systems:
@ -19,6 +21,10 @@ It was tested with the following operating systems:
* Ubuntu 14.04
* Raspbian "Jessie"
## Installation
npm i node-wifi-scanner
## Usage
const scanner = require('node-wifi-scanner');
@ -48,7 +54,6 @@ The module uses command line tools for gathering the network information:
* airport on Mac OS-X: `airport -s`
* netsh on Windows: `netsh wlan show networks mode=Bssid`
* iwlist (1st choice) on Linux: `iwlist scan`
* nmcli (fallback only) on Linux: `nmcli -m tabular -f SSID,BSSID,SIGNAL,FREQ device wifi`
Unfortunately, Mac OS-X and Windows use the system language for the output which requires a quite
generic way of parsing the data. If you experience any troubles, please create a GitHub issue and supply
@ -77,3 +82,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -5,43 +5,61 @@
const fs = require('fs');
const exec = require('child_process').exec;
const async = require('async');
const _ = require('lodash');
// The tools
const airport = require('./lib/airport');
const iwlist = require('./lib/iwlist');
const nmcli = require('./lib/nmcli');
const netsh = require('./lib/netsh');
var scanner;
// Initializing the tools
function initTools(callback) {
fs.stat(airport.tool, function (err, stats) {
if (stats) {
return callback(null, airport);
}
fs.stat(iwlist.tool, function (err, stats) {
if (stats) {
return callback(null, iwlist);
}
fs.stat(nmcli.tool, function (err, stats) {
if (stats) {
return callback(null, nmcli);
}
fs.stat(netsh.tool, function (err, stats) {
if (stats) {
return callback(null, netsh);
// When a command is not found, an error is issued and async would finish. Therefore we pack
// the error into the result and check it later on.
async.parallel([
function (cb) {
exec(airport.detector, function (err) {
cb(null, {err: err, scanner: airport}
)
}
callback(new Error('No scanner found'));
);
},
function (cb) {
exec(iwlist.detector, function (err) {
cb(null, {err: err, scanner: iwlist}
)
}
);
},
function (cb) {
exec(netsh.detector, function (err) {
cb(null, {err: err, scanner: netsh}
)
}
);
}
],
function (err, results) {
var res = _.find(results,
function (f) {
return !f.err
});
});
});
});
if (res) {
return callback(null, res.scanner);
}
callback(new Error('No scanner found'));
}
);
}
/**
* Scan the networks with the scanner detected before
* @param callback
*/
function scanNetworks(callback) {
exec(scanner.cmdLine, function (err, stdout) {
if (err) {
@ -59,7 +77,7 @@ module.exports = {
*/
scan: function (callback) {
if (!scanner) {
initTools((err, s) => {
initTools(function (err, s) {
if (err) {
return callback(err);
}
@ -70,4 +88,4 @@ module.exports = {
}
scanNetworks(callback);
}
};
};

View File

@ -5,6 +5,7 @@
const tool = '/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport';
const cmdLine = tool + ' -s';
const detector = tool + ' -getInfo';
const macRegex = /([0-9a-zA-Z]{1}[0-9a-zA-Z]{1}[:]{1}){5}[0-9a-zA-Z]{1}[0-9a-zA-Z]{1}/;
/**
@ -30,7 +31,7 @@ function parseOutput(str, callback) {
'ssid' : lines[i].substr(0, macStart).trim(),
'mac' : elements[0].trim(),
'channel' : parseInt(elements[2].trim(), 10),
'rssi' : parseInt(elements[1].trim())
'rssi' : parseInt(elements[1].trim(), 10)
});
}
}
@ -45,5 +46,6 @@ function parseOutput(str, callback) {
module.exports = {
parseOutput: parseOutput,
cmdLine : cmdLine,
detector : detector,
tool : tool
};

View File

@ -4,8 +4,12 @@
*/
const _ = require('lodash');
const tool = '/usr/bin/iwlist';
// usually located in /usr/bin/ but as it could be at another location, allow all found in PATH (but we're in trouble
// when the default location, /usr/bin/ is not in the PATH!). GitHub issue #1
const tool = 'iwlist';
const cmdLine = tool + ' scan';
const detector = tool + ' --help';
const macRegex = /([0-9a-zA-Z]{1}[0-9a-zA-Z]{1}[:]{1}){5}[0-9a-zA-Z]{1}[0-9a-zA-Z]{1}/;
const cellRegex = /Cell [0-9]{2,} - Address:/;
@ -79,5 +83,6 @@ function parseOutput(str, callback) {
module.exports = {
parseOutput: parseOutput,
cmdLine : cmdLine,
detector : detector,
tool : tool
};

View File

@ -6,6 +6,7 @@
const systemRoot = process.env.SystemRoot || 'C:\\Windows';
const tool = systemRoot + '\\System32\\netsh.exe';
const cmdLine = tool + ' wlan show networks mode=Bssid';
const detector = tool + ' show alias';
/**
* Parsing netnsh output. Unfortunately netsh supplies the network information
@ -18,9 +19,13 @@ function parseOutput(str, callback) {
var wifis = [];
var err = null;
try {
if (blocks.length < 2) {
// 2nd try, with \r\n
blocks = str.split('\r\n\r\n')
}
if (!blocks || blocks.length === 1) {
// No WiFis found
return [];
return callback(null, []);
}
// Each block has the same structure, while some parts might be available and others
@ -67,7 +72,7 @@ function parseOutput(str, callback) {
// A tricky one: the channel is the first one having just ONE number. Set only
// if the channel is not already set ("Basic Rates" can be a single number also)
if (regexChannel.exec(lines[t].trim())) {
network.channel = parseInt(lines[t].split(':')[1].trim());
network.channel = parseInt(lines[t].split(':')[1].trim(), 10);
}
}
}
@ -86,5 +91,6 @@ function parseOutput(str, callback) {
module.exports = {
parseOutput: parseOutput,
cmdLine : cmdLine,
detector : detector,
tool : tool
};

View File

@ -1,50 +0,0 @@
/**
* Scanning WiFis on Mac OS X using nmcli
* Created by kc on 04.04.16.
*/
const _ = require('lodash');
const tool = '/usr/bin/nmcli';
const cmdLine = tool + ' -m tabular -f SSID,BSSID,SIGNAL,FREQ device wifi';
const macRegex = /([0-9a-zA-Z]{1}[0-9a-zA-Z]{1}[:]{1}){5}[0-9a-zA-Z]{1}[0-9a-zA-Z]{1}/;
/**
* Parsing the output of nmcli
* @param str output of the tool
* @param callback
*/
function parseOutput(str, callback) {
var err = null;
try {
var lines = str.split('\n');
var wifis = [];
for (var i = 1, l = lines.length; i < l; i++) {
var mac = lines[i].match(macRegex);
if (!mac) {
continue;
}
var macStart = lines[i].indexOf(mac[0]);
var elements = lines[i].substr(macStart).split(/[ ]+/);
wifis.push({
'ssid' : _.trim(lines[i].substr(0, macStart), ' \''),
'mac' : elements[0].trim(),
'channel' : parseInt(elements[2].trim(), 10),
'rssi' : parseInt(elements[1].trim())
});
}
}
catch (ex) {
err = ex;
}
callback(err, wifis);
}
module.exports = {
parseOutput: parseOutput,
cmdLine : cmdLine,
tool : tool
};

View File

@ -1,36 +1,46 @@
{
"name": "node-wifi-scanner",
"version": "0.0.2",
"version": "1.1.0",
"description": "node.js module for WiFi network detection",
"main": "index.js",
"keywords": [
"WiFi",
"Node.js",
"scanner"
"scanner",
"airport",
"netsh",
"iwlist",
"nmcli"
],
"author": {
"name": "Christian Kuster, CH-8342 Wernetshausen",
"email": "info@kusti.ch",
"url": "http://www.kusti.ch/"
},
"homepage": "http://www.ferropoly.ch/",
"homepage": "https://github.com/ancasicolica/node-wifi-scanner",
"bugs": {
"url": "https://github.com/ancasicolica/node-wifi-scanner/issues",
"email": "info@ancasicolica.ch"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/ancasicolica/node-wifi-scanner.git"
},
"engines": {
"node": ">= 4.4.0",
"npm": ">= 2.14.0"
"node": ">= 4.0.0",
"npm": ">= 2.0.0"
},
"scripts": {
"test": "mocha test"
},
"dependencies": {
"lodash": "4.8.1"
"async": "2.1.4",
"lodash": "4.17.2"
},
"devDependencies": {
"grunt": "0.4.5",
"grunt-bump": "0.7.0"
"grunt-bump": "0.7.0",
"mocha": "2.2.5"
}
}

View File

@ -1,20 +0,0 @@
SSID BSSID SIGNAL FREQUENZ
'PDANet1' 00:35:1A:90:56:06 100 2412 MHz
'ExoNet1' 00:35:1A:90:56:05 100 2412 MHz
'TEST-Wifi' 00:35:1A:90:56:00 96 2412 MHz
'OurTest' 00:35:1A:90:56:0C 96 2412 MHz
'OurDev' 00:35:1A:90:56:0B 76 2412 MHz
'PDANet1' 00:35:1A:6F:0F:46 48 2437 MHz
'TEST-Wifi' 00:35:1A:6F:0F:40 58 2437 MHz
'ExoNet1' 00:35:1A:6F:0F:45 58 2437 MHz
'OurDev' 00:35:1A:6F:0F:4B 58 2437 MHz
'OurTest' 00:35:1A:6F:0F:4C 60 2437 MHz
'TEST-Wifi' 00:F2:8B:8F:58:70 58 2462 MHz
'ExoNet1' 00:F2:8B:8F:58:75 72 2462 MHz
'PDANet1' 00:F2:8B:8F:58:76 58 2462 MHz
'PDANet1' 00:35:1A:5B:46:76 56 2412 MHz
'OurDev' 00:35:1A:5B:46:7B 48 2412 MHz
'OurDev' 00:F2:8B:8F:58:7B 58 2462 MHz
'OurTest' 00:F2:8B:8F:58:7C 72 2462 MHz
'TEST-Wifi' 00:35:1A:5B:46:70 56 2412 MHz
'OurTest' 00:35:1A:5B:46:7C 48 2412 MHz

View File

@ -93,7 +93,7 @@ describe('netsh', function () {
netsh.parseOutput(fs.readFileSync(path.join(__dirname, 'fixtures', 'netsh', 'netsh_sp.txt'), {encoding: 'utf8'}), (err, info) => {
assert.ok(info);
assert.equal(info.length, 8);
console.log(info);
var ap = info[0];
assert.equal(ap.mac, '98:fc:11:b6:88:9e');
assert.equal(ap.ssid, 'CARAMANZANAS_BAJA');

View File

@ -1,30 +0,0 @@
/**
* nmcli unit test
* Created by kc on 04.04.16.
*/
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const nmcli = require('../lib/nmcli');
describe.skip('nmcli', () => {
it('parses the output of file 1', function(done) {
nmcli.parseOutput(fs.readFileSync(path.join(__dirname, 'fixtures','nmcli','nmcli01.txt'), { encoding: 'utf8' }), (err, info) => {
console.log(info);
assert.ok(info);
assert.equal(info.length, 19);
var ap = info[0];
assert.equal(ap.mac, '00:35:1A:90:56:06');
assert.equal(ap.ssid, 'PDANet1');
//assert.equal(ap.rssi, -70);
assert.strictEqual(ap.channel, 112);
done(err);
});
});
});