Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wifi.connection(): Fetch network settings, normalize values #195

Merged
merged 9 commits into from
Sep 2, 2016
6 changes: 3 additions & 3 deletions node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
"version": "0.0.9",
"description": "",
"main": "tessel.js",
"dependencies": {
},
"dependencies": {},
"devDependencies": {
"grunt": "^0.4.5",
"grunt-cli": "^0.1.13",
Expand All @@ -13,10 +12,11 @@
"grunt-contrib-watch": "^0.6.1",
"grunt-jsbeautifier": "^0.2.10",
"grunt-jscs": "^2.6.0",
"npm": "^3.10.5",
"sinon": "^1.14.1"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "grunt"
},
"author": "Technical Machine <team@technical.io>",
"license": "MIT"
Expand Down
151 changes: 101 additions & 50 deletions node/tessel-export.js
Original file line number Diff line number Diff line change
Expand Up @@ -1142,19 +1142,10 @@ Tessel.LED.prototype.read = function(callback) {

Tessel.Wifi = function() {
var state = {
settings: {},
connected: false
settings: {}
};

Object.defineProperties(this, {
isConnected: {
get: () => state.connected
},
connected: {
set: (value) => {
state.connected = value;
}
},
settings: {
get: () => state.settings,
set: (settings) => {
Expand All @@ -1174,9 +1165,10 @@ Tessel.Wifi.prototype.enable = function(callback) {
turnOnWifi()
.then(commitWireless)
.then(restartWifi)
.then(() => {
.then(getWifiInfo)
.then((network) => {
Object.assign(this.settings, network);
this.emit('connect', this.settings);
this.connected = true;
callback();
})
.catch((error) => {
Expand All @@ -1195,7 +1187,6 @@ Tessel.Wifi.prototype.disable = function(callback) {
.then(commitWireless)
.then(restartWifi)
.then(() => {
this.connected = false;
this.emit('disconnect');
callback();
})
Expand All @@ -1210,11 +1201,11 @@ Tessel.Wifi.prototype.reset = function(callback) {
callback = function() {};
}

this.connected = false;
this.emit('disconnect', 'Resetting connection');
restartWifi()
.then(() => {
this.connected = true;
.then(getWifiInfo)
.then((network) => {
Object.assign(this.settings, network);
this.emit('connect', this.settings);
callback();
})
Expand All @@ -1224,12 +1215,34 @@ Tessel.Wifi.prototype.reset = function(callback) {
});
};

Tessel.Wifi.prototype.connection = function() {
if (this.isConnected) {
return this.settings;
} else {
return null;
Tessel.Wifi.prototype.connection = function(callback) {
if (typeof callback !== 'function') {
callback = function() {};
}

isEnabled()
.then((enabled) => {
if (enabled) {
getWifiInfo()
.then((network) => {
delete network.password;

this.settings = network;

callback(null, network);
})
.catch((error) => {
this.emit('error', error);
callback(error);
});
} else {
callback(null, null);
}
})
.catch((error) => {
this.emit('error', error);
callback(error);
});
};

Tessel.Wifi.prototype.connect = function(settings, callback) {
Expand Down Expand Up @@ -1259,7 +1272,6 @@ Tessel.Wifi.prototype.connect = function(settings, callback) {
delete settings.password;

this.settings = Object.assign(network, settings);
this.connected = true;
this.emit('connect', this.settings);

callback(null, this.settings);
Expand Down Expand Up @@ -1375,40 +1387,69 @@ function isEnabled() {
function getWifiInfo() {
return new Promise((resolve, reject) => {
var checkCount = 0;
var rbcast = /(Bcast):([\w\.]+)/;

function recursiveWifi() {
setImmediate(() => {
childProcess.exec(`ubus call iwinfo info '{"device":"wlan0"}'`, (error, results) => {
if (error) {
recursiveWifi();
} else {
try {
var network = JSON.parse(results);

if (network.ssid === undefined) {
// using 6 because it's the lowest count with accurate results after testing
if (checkCount < 6) {
checkCount++;
recursiveWifi();
} else {
var msg = 'Tessel is unable to connect, please check your credentials or list of available networks (using tessel.network.wifi.findAvailableNetworks()) and try again.';
throw msg;
}
childProcess.exec(`ubus call iwinfo info '{"device":"wlan0"}'`, (error, results) => {
if (error) {
recursiveWifi();
} else {
try {
var network = JSON.parse(results);

if (network.ssid === undefined) {
// using 6 because it's the lowest count with accurate results after testing
if (checkCount < 6) {
checkCount++;
recursiveWifi();
} else {
childProcess.exec('ifconfig wlan0', (error, ipResults) => {
if (error) {
reject(error);
} else {
network.ips = ipResults.split('\n');
resolve(network);
}
});
var msg = 'Tessel is unable to connect, please check your credentials or list of available networks (using tessel.network.wifi.findAvailableNetworks()) and try again.';
throw msg;
}
} catch (error) {
reject(error);
} else {
recursiveIP(network);
}
} catch (error) {
reject(error);
}
});
}
});
}

// when immediately connecting and restarting the wifi chip, it takes a few moments before an IP address is broadcast to Tessel.
// This function keeps checking for that IP until it's available.
function recursiveIP(network) {
childProcess.exec('ifconfig wlan0', (error, ipResults) => {
if (error) {
reject(error);
} else {
var bcastMatches = ipResults.match(rbcast);

if (bcastMatches === null) {
recursiveWifi(network);
} else {
// Successful matches will have a result that looks like:
// ["Bcast:0.0.0.0", "Bcast", "0.0.0.0"]
if (bcastMatches.length === 3) {
network.ip = bcastMatches[2];
} else {
recursiveWifi(network);
}
}

// attempt to parse out the security configuration from the returned network object
if (network.encryption.enabled) {
if (network.encryption.wep) {
network.security = 'wep';
} else if (network.encryption.authentication && network.encryption.wpa) {
// sets "security" to either psk or psk2
network.security = `${network.encryption.authentication[0]}${network.encryption.wpa[0] === 2 ? 2 : null}`;
}
} else {
network.security = 'none';
}
resolve(network);
}
});
}

Expand Down Expand Up @@ -1441,6 +1482,16 @@ function scanWifi() {
// Parse the security type - unused at the moment
security: encryptionRegex.exec(entry)[1],
};

// normalize security info to match configuration settings, i.e. none, wep, psk, psk2. "none" is already set correctly
if (networkInfo.security.includes('WEP')) {
networkInfo.security = 'wep';
} else if (networkInfo.security.includes('WPA2')) {
networkInfo.security = 'psk2';
} else if (networkInfo.security.includes('WPA')) {
networkInfo.security = 'psk';
}

// Add this parsed network to our array
networks.push(networkInfo);
} catch (error) {
Expand Down
Loading