From 7cd5ac87b0b9e917379065a03e9e6012a7202723 Mon Sep 17 00:00:00 2001 From: johnnyman727 Date: Mon, 4 Jan 2016 22:34:33 -0800 Subject: [PATCH] Uses an alternative wifi scan to produce consistent results --- .jshintrc | 1 + lib/controller.js | 2 +- lib/tessel/commands.js | 2 +- lib/tessel/wifi.js | 47 ++++++++++++++------------ test/unit/wifi.js | 76 ++++++++++++++++++++---------------------- 5 files changed, 66 insertions(+), 62 deletions(-) diff --git a/.jshintrc b/.jshintrc index bc6ee67d..782415ad 100644 --- a/.jshintrc +++ b/.jshintrc @@ -15,6 +15,7 @@ "strict": false, "esnext": true, "unused": true, + "evil" : true, "globals": { "exports": true, "document": true, diff --git a/lib/controller.js b/lib/controller.js index 3e57ad12..01c7e253 100644 --- a/lib/controller.js +++ b/lib/controller.js @@ -607,7 +607,7 @@ controller.printAvailableNetworks = function(opts) { // Print out networks networks.forEach(function(network) { - logs.info('\t', network.ssid, '(' + network.quality + '/' + network.quality_max + ')'); + logs.info('\t', network.ssid, '(' + network.quality + ')'); }); }); }); diff --git a/lib/tessel/commands.js b/lib/tessel/commands.js index c6c872b6..91d83d16 100644 --- a/lib/tessel/commands.js +++ b/lib/tessel/commands.js @@ -2,7 +2,7 @@ module.exports.readFile = function(filepath) { return ['cat', filepath]; }; module.exports.scanWiFi = function() { - return ['ubus', 'call', 'iwinfo', 'scan', '{"device":"wlan0"}']; + return ['iwinfo', 'wlan0', 'scan']; }; module.exports.getWifiInfo = function() { return ['ubus', 'call', 'iwinfo', 'info', '{"device":"wlan0"}']; diff --git a/lib/tessel/wifi.js b/lib/tessel/wifi.js index 0f436084..48845a8b 100644 --- a/lib/tessel/wifi.js +++ b/lib/tessel/wifi.js @@ -13,27 +13,31 @@ var Tessel = require('./tessel'); Tessel.prototype.findAvailableNetworks = function() { logs.info('Scanning for available networks...'); return this.simpleExec(commands.scanWiFi()) - .then(function wifiScanResults(resultsJSON) { - // Parse the response - var networks = ''; - try { - networks = JSON.parse(resultsJSON).results; - } catch (err) { - // Throw any unfortunate errors - return Promise.reject(err); - } - - // Sort by signal strength - networks.sort(compareBySignal); - - // Remove networks without SSIDs - networks.forEach(function(network, index) { - if (!network.ssid) { - networks.splice(index, 1); + .then(function wifiScanResults(resultsData) { + // For each string chunk + return resultsData.trim().split('\n\n').reduce((networks, entry) => { + try { + + var ssidRegex = /ESSID: "(.*)"/; + var qualityRegex = /Quality: (.*)/; + var encryptionRegex = /Encryption: (.*)/; + + var networkInfo = { + // Parse out the SSID + ssid: ssidRegex.exec(entry)[1], + // Parse out the quality of the connection + quality: qualityRegex.exec(entry)[1], + // Parse the security type - unused at the moment + security: encryptionRegex.exec(entry)[1], + }; + // Add this parsed network to our array + networks.push(networkInfo); + } catch (err) { + // Suppress errors created by entries that cannot be parsed. } - }); - return networks; + return networks; + }, []).sort(compareBySignal); }); }; @@ -60,9 +64,10 @@ Tessel.prototype.getWifiInfo = function() { }; function compareBySignal(a, b) { - if ((a.quality / a.quality_max) > (b.quality / b.quality_max)) { + // eval(quality) turns a string fraction like 21/70 into a decimal + if (eval(a.quality) > eval(b.quality)) { return -1; - } else if ((a.quality / a.quality_max) < (b.quality / b.quality_max)) { + } else if (eval(a.quality) < eval(b.quality)) { return 1; } else { return 0; diff --git a/test/unit/wifi.js b/test/unit/wifi.js index 502ec443..58ca1537 100644 --- a/test/unit/wifi.js +++ b/test/unit/wifi.js @@ -27,9 +27,7 @@ exports['Tessel.prototype.findAvailableNetworks'] = { test.done(); }); - var networks = JSON.stringify({ - results: [] - }); + var networks = ''; this.tessel._rps.stdout.push(networks); @@ -41,26 +39,28 @@ exports['Tessel.prototype.findAvailableNetworks'] = { someNetworks: function(test) { test.expect(2); - var networks = { - results: [{ - ssid: 'ssid1', - quality: 21, - max_quality: 73, - }, { - ssid: 'ssid2', - quality: 5, - max_quality: 73, - }, ] - }; + var networks = + `Cell 01 - Address: 14:35:8B:11:30:F0 + ESSID: "technicallyHome" + Mode: Master Channel: 11 + Signal: -55 dBm Quality: 55/70 + Encryption: mixed WPA/WPA2 PSK (TKIP, CCMP) + + Cell 02 - Address: 6C:70:9F:D9:7A:5C + ESSID: "Fried Chicken Sandwich" + Mode: Master Channel: 2 + Signal: -51 dBm Quality: 59/70 + Encryption: WPA2 PSK (CCMP) +`; this.tessel.findAvailableNetworks() .then((found) => { - test.equal(found.length, networks.results.length); + test.equal(found.length, 2); test.equal(this.findAvailableNetworks.callCount, 1); test.done(); }); - this.tessel._rps.stdout.push(JSON.stringify(networks)); + this.tessel._rps.stdout.push(networks); setImmediate(() => { this.tessel._rps.emit('close'); @@ -70,39 +70,37 @@ exports['Tessel.prototype.findAvailableNetworks'] = { compareSignalStrengths: function(test) { test.expect(5); - var bestNetwork = { - ssid: 'best', - quality: 60, - quality_max: 73, - }; - var worstNetwork = { - ssid: 'worst', - quality: 5, - quality_max: 73, - }; + var networks = `Cell 01 - Address: 14:35:8B:11:30:F0 + ESSID: "middle" + Mode: Master Channel: 11 + Signal: -55 dBm Quality: 30/70 + Encryption: mixed WPA/WPA2 PSK (TKIP, CCMP) - var middleNetwork = { - ssid: 'middle', - quality: 10, - quality_max: 73, - }; + Cell 02 - Address: 6C:70:9F:D9:7A:5C + ESSID: "worst" + Mode: Master Channel: 2 + Signal: -57 dBm Quality: 5/70 + Encryption: WPA2 PSK (CCMP) - var networks = { - results: [bestNetwork, worstNetwork, middleNetwork] - }; + Cell 03 - Address: 6C:70:9F:D9:7A:5C + ESSID: "best" + Mode: Master Channel: 2 + Signal: -57 dBm Quality: 60/70 + Encryption: WPA2 PSK (CCMP) +`; this.tessel.findAvailableNetworks() .then((found) => { - test.equal(found.length, networks.results.length); + test.equal(found.length, 3); test.equal(this.findAvailableNetworks.callCount, 1); - test.equal(found[0].ssid, bestNetwork.ssid); - test.equal(found[1].ssid, middleNetwork.ssid); - test.equal(found[2].ssid, worstNetwork.ssid); + test.equal(found[0].ssid, 'best'); + test.equal(found[1].ssid, 'middle'); + test.equal(found[2].ssid, 'worst'); test.done(); }); - this.tessel._rps.stdout.push(JSON.stringify(networks)); + this.tessel._rps.stdout.push(networks); setImmediate(() => { this.tessel._rps.emit('close');