Commit a54c3d25 authored by David Mondou's avatar David Mondou
Browse files

Initial commit

parents
This diff is collapsed.
{
"name": "IOT-Gateway-Setup",
"version": "1.0.0",
"description": "Web-based administration portal for configuring the WiFi on the gateway",
"main": "server.js",
"dependencies": {
"multiparty": "*",
"shelljs": "*"
},
"author": "Intel Corporation",
"license": "MIT"
}
<!DOCTYPE html>
<html>
<head>
<title>IoT Gateway | Page Not Found</title>
<link rel="stylesheet" type="text/css" href="main.css" media="screen"/>
</head>
<body>
<h1>IoT Gateway</h1>
<div id="name_section" class="section">
<div class="header">404</div>
<table class="content">
<tr>
<td class="left">
Oops, something went wrong. This page does not exist.
</td>
</tr>
</table>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Leaving Setup</title>
<link rel="stylesheet" type="text/css" href="main.css" media="screen"/>
<script src="feedbacklib.js"></script>
<script type="text/javascript">
window.onload = function () {
document.cookie = '{}';
var config = {};
config.currenthost = 'params_curr_hostname';
config.currentssid = 'params_curr_ssid';
config.host = 'params_hostname'; // uncomment
config.ssid = 'params_ssid';
config.newwifi = 'params_new_wifi';
initFeedbackLib(config);
queryForCommandOutput();
}
</script>
<noscript>
Please enable Javascript. It is needed for this page to work correctly. Thank you.
</noscript>
</head>
<body>
<h1>Leaving Setup</h1>
<div class='section'>
<div class="content" style="padding: 30px; padding-bottom: 0px">
Please wait while we setup your device. Note that if WiFi is being setup, <b>the device will disconnect
momentarily. When that happens, please reconnect by joining <i>this</i> machine to the 'params_new_wifi'
network</b> and wait while we try to reach your device at
<a href="http://params_hostname">http://params_hostname</a>.
<br><br>
<hr class="progressbar" id="progressbar" align="left">
<textarea class="progresstext" id="progresstext" readonly rows="1" cols="200"></textarea><br><br>
<textarea class="cmdout" id="cmdout" readonly rows="10"></textarea>
</div>
</div>
<div class='section'>
<div class="content" id="errbox" style="padding: 30px; padding-bottom: 0px; padding-top: 0px; display: none">
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Leaving Setup</title>
<link rel="stylesheet" type="text/css" href="main.css" media="screen"/>
<script src="feedbacklib.js"></script>
<script type="text/javascript">
window.onload = function () {
document.cookie = '{}';
var config = {};
config.currenthost = 'params_curr_hostname';
config.currentssid = 'params_curr_ssid';
config.host = 'params_hostname';
config.ssid = 'params_ssid';
config.newwifi = 'params_new_wifi';
initFeedbackLib(config);
document.getElementById("errbox").innerHTML += "<br><br>" + getRerunSetupMessage(config.host, config.ssid);
document.getElementById("errbox").style.display = "inherit";
queryForCommandOutput();
}
</script>
<noscript>
Please enable Javascript. It is needed for this page to work correctly. Thank you.
</noscript>
</head>
<body>
<h1>Leaving Setup</h1>
<div class='section'>
<div class="content" style="padding: 30px; padding-bottom: 0px">
Please wait while we setup your device. <i>Note that you have left the one-time setup process without
configuring WiFi network access</i>.
<br><br>
<hr class="progressbar" id="progressbar" align="left">
<textarea class="progresstext" id="progresstext" readonly rows="1" cols="200"></textarea><br><br>
<textarea class="cmdout" id="cmdout" readonly rows="10"></textarea>
</div>
</div>
<div class='section'>
<div class="content" id="errbox" style="padding: 30px; padding-bottom: 0px; padding-top: 0px; display: none">
To configure WiFi later, rerun this setup using the steps below or connect to the device via its serial
port and run <code>configure_gateway --wifi</code> on the command line.
</div>
</div>
</body>
</html>
\ No newline at end of file
/*
* Copyright (c) 2015, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU Lesser General Public License,
* version 2.1, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
* more details.
*/
var OUTPUT_CMD = "commandOutput",
PROTO = "http://",
CURRENT_HOSTNAME = "",
CURRENT_SSID = "",
NEW_HOSTNAME = "",
NEW_SSID = "",
NEW_WIFI = "",
REQUEST_INTERVAL = 10, // secs
PROGRESS_BAR_INITIAL_WIDTH = 10, // px
MAX_PROGRESS_BAR_LEN = 935, // px
MAX_RETRY_TIME = 3, // min
PROGRESS_BAR_INCREMENT = 0, // should be set in init
PROGRESS_TEXT_HEADER_DISCONNECT = "Disconnected. Please connect to network '",
PROGRESS_TEXT_HEADER_CONFIGURE = "Configuring your device",
PROGRESS_TEXT_HEADER = PROGRESS_TEXT_HEADER_CONFIGURE,
PROGRESS_TEXT_PREFIX = " (",
PROGRESS_TEXT_SUFFIX = " mins remaining).",
COMMAND_OUTPUT_BOX_ID = "cmdout",
ERROR_BOX_ID = "errbox",
PROGRESS = 0,
DISCONNECT_ERROR_MESSAGE = "",
CONFIGURE_ERROR_MESSAGE = "",
CONFIGURE_FAIL_PROGRESS_TEXT = "Sorry, could not configure your device.",
CONFIGURE_SUCCESS_PROGRESS_TEXT = "Configuration is complete.",
MAX_RETRIES_ON_NAME_CHANGE_ONLY = 2,
RETRIES_ON_NAME_CHANGE_ONLY = 0;
// maxtime: in minutes
// interval: in secs
// headertext: string that shows below progress bar (e.g. attempting to reach your device)
function initFeedbackLib(config) {
PROGRESS = 0;
if (config) {
if (config.proto || config.proto === "")
PROTO = config.proto;
if (config.host)
NEW_HOSTNAME = config.host;
if (config.newwifi)
NEW_WIFI = config.newwifi;
if (config.maxtime)
MAX_RETRY_TIME = config.maxtime;
if (config.interval)
REQUEST_INTERVAL = config.interval;
if (config.headertext)
PROGRESS_TEXT_HEADER = config.headertext;
if (config.headertextDisconnect)
PROGRESS_TEXT_HEADER_DISCONNECT = config.headertextDisconnect;
if (config.cmdoutid)
COMMAND_OUTPUT_BOX_ID = config.cmdoutid;
if (config.errboxid)
ERROR_BOX_ID = config.errboxid;
if (config.currenthost)
CURRENT_HOSTNAME = config.currenthost;
if (config.currentssid)
CURRENT_SSID = config.currentssid;
if (config.ssid)
NEW_SSID = config.ssid;
if (config.configFailProgressText)
CONFIGURE_FAIL_PROGRESS_TEXT = config.configFailProgressText;
if (config.configSuccessProgressText)
CONFIGURE_SUCCESS_PROGRESS_TEXT = config.configSuccessProgressText
}
resetProgressBarIncrement();
if (config && config.errdisconnect)
DISCONNECT_ERROR_MESSAGE = config.errdisconnect + getRerunSetupMessage(NEW_HOSTNAME, NEW_SSID);
else
DISCONNECT_ERROR_MESSAGE =
"<b style='color: red'>Sorry, we were unable to reach your device.</b> Please try again by " +
"reconnecting this machine to the '" + NEW_WIFI + "' network and clicking " +
"<a href='http://" + NEW_HOSTNAME + "'>http://" + NEW_HOSTNAME + "</a>. You can also rerun this setup " +
"by following the steps below. " +
"If that fails, please connect to the device via its serial port and run <code>configure_gateway " +
"--wifi</code> on the command line. To learn about other configuration options, run <code>configure_gateway " +
"--help</code>." + "<br><br>" + getRerunSetupMessage(NEW_HOSTNAME, NEW_SSID);
if (config && config.errsetup)
CONFIGURE_ERROR_MESSAGE = config.errsetup + getRerunSetupMessage(CURRENT_HOSTNAME, CURRENT_SSID);
else
CONFIGURE_ERROR_MESSAGE =
"<b style='color: red'>Sorry, we encountered an error while configuring your device.</b> " +
"Please see messsages in the status area above for details. At this time, we recommend rerunning this setup " +
"by following the steps below. If that fails, please connect to the device via its serial port " +
"and run <code>configure_gateway --setup</code> on the command line. " +
"To learn about other configuration options, run <code>configure_gateway --help</code>." + "<br><br>" +
getRerunSetupMessage(CURRENT_HOSTNAME, CURRENT_SSID);
updateProgressText();
}
function resetProgressBarIncrement() {
PROGRESS_BAR_INCREMENT = (MAX_PROGRESS_BAR_LEN - PROGRESS_BAR_INITIAL_WIDTH)/(MAX_RETRY_TIME * 60) * REQUEST_INTERVAL;
}
function getRerunSetupMessage(hostname, ssid) {
return "To rerun this setup, do the following: " +
"<ol>" +
"<li>Press the 'PWR' button for more than 2 seconds (NOTE: Pressing 'PWR' for more than 7 seconds will " +
"switch off power to the board)</li> " +
"<li>Wait approximately 15 seconds for the device's access point to start</li> " +
"<li>Reconnect this machine to the '" + ssid + "' network</li> " +
"<li>Visit '<a href='http://" + hostname + "'>http://" + hostname + "</a>' in your browser</li> " +
"</ol> ";
}
function updateProgressBar(allok) {
if ((PROGRESS * REQUEST_INTERVAL)/60 < MAX_RETRY_TIME) {
document.getElementById("progressbar").style.width = "" + (PROGRESS_BAR_INITIAL_WIDTH +
PROGRESS_BAR_INCREMENT * PROGRESS) + "px";
} else {
document.getElementById("progressbar").style.width = "" + MAX_PROGRESS_BAR_LEN + "px";
if (!allok)
document.getElementById("progressbar").style.backgroundColor = "red";
}
}
function updateProgressText() {
var minpassed = (PROGRESS * REQUEST_INTERVAL)/60;
if (minpassed >= MAX_RETRY_TIME) {
if (PROGRESS_TEXT_HEADER_DISCONNECT === PROGRESS_TEXT_HEADER) {
document.getElementById("progresstext").value =
"Sorry, could not reach your device.";
document.getElementById(ERROR_BOX_ID).innerHTML = DISCONNECT_ERROR_MESSAGE;
} else {
document.getElementById("progresstext").value = CONFIGURE_FAIL_PROGRESS_TEXT;
document.getElementById(ERROR_BOX_ID).innerHTML = CONFIGURE_ERROR_MESSAGE;
}
document.getElementById(ERROR_BOX_ID).style.display = "inherit";
} else {
document.getElementById("progresstext").innerHTML = PROGRESS_TEXT_HEADER + PROGRESS_TEXT_PREFIX +
(MAX_RETRY_TIME - minpassed).toFixed(1) + PROGRESS_TEXT_SUFFIX;
}
}
function maxOutProgressBar(progressText, allOK) {
PROGRESS = (MAX_RETRY_TIME * 60)/REQUEST_INTERVAL;
updateProgressBar(allOK);
document.getElementById("progresstext").value = progressText;
}
function queryForDevice() {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
} else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
document.getElementById(COMMAND_OUTPUT_BOX_ID).value = xmlhttp.responseText;
maxOutProgressBar("Found device. Connecting in 5 seconds...", true);
setTimeout(function () { location.replace(PROTO + NEW_HOSTNAME); }, 5000);
} else if (xmlhttp.readyState === 4 && xmlhttp.status === 404) {
console.log("Unexpected request sent to server. Command: /");
}
};
// if wifi is not changing, then we are waiting for name change (otherwise we would have
// ended in queryForCommandOutput()). In this case, query device only once more and then give up.
function handleServerNonResponse() {
PROGRESS++;
updateProgressBar();
updateProgressText();
if ((PROGRESS * REQUEST_INTERVAL)/60 < MAX_RETRY_TIME) {
// assuming setTimeout better than recursive call in terms of stack memory usage
// if wifi is not changing, then increment RETRIES_ON_NAME_CHANGE_ONLY
// if RETRIES_ON_NAME_CHANGE_ONLY equals 1 (or some max) give up. Give up means end by saying
// configuration was a success.
if (!NEW_WIFI) {
if (RETRIES_ON_NAME_CHANGE_ONLY === MAX_RETRIES_ON_NAME_CHANGE_ONLY) {
maxOutProgressBar(CONFIGURE_SUCCESS_PROGRESS_TEXT, true);
return;
} else {
RETRIES_ON_NAME_CHANGE_ONLY++;
}
}
setTimeout(queryForDevice, REQUEST_INTERVAL * 1000);
}
}
xmlhttp.timeout = REQUEST_INTERVAL * 1000;
xmlhttp.ontimeout = handleServerNonResponse;
xmlhttp.onerror = handleServerNonResponse;
xmlhttp.open("GET", PROTO + NEW_HOSTNAME + "/" + OUTPUT_CMD, true); // change to gateway address
xmlhttp.send();
}
function queryForCommandOutput() {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
} else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
document.getElementById(COMMAND_OUTPUT_BOX_ID).value = xmlhttp.responseText;
PROGRESS++;
updateProgressBar();
updateProgressText();
if ((PROGRESS * REQUEST_INTERVAL)/60 < MAX_RETRY_TIME) {
setTimeout(queryForCommandOutput, REQUEST_INTERVAL * 1000);
}
} else if (xmlhttp.readyState === 4 && xmlhttp.status === 404) {
console.log("Sent unexpected request to server. Command: " + OUTPUT_CMD);
}
};
function handleServerNonResponse() {
PROGRESS++;
updateProgressBar();
// if name change is happening then check if wifi is changing as well
// if wifi is changing, continue as normal. otherwise, don't change progress
// text and call queryForDevice.
// if name is not changing and wifi is not changing, then end now, by saying
// config complete.
if (CURRENT_HOSTNAME === NEW_HOSTNAME && !NEW_WIFI) { // wifi and hostname are not changing
// todo: this assumption is not good. some day know if each command succeeded or failed (very hard to do)
// todo: (contd...) knowing commands are successful or not is hard because device gets disconnected in both
// todo: (contd...) success and failure cases.
maxOutProgressBar(CONFIGURE_SUCCESS_PROGRESS_TEXT, true);
return;
}
if (NEW_WIFI) { // wifi is changing
PROGRESS_TEXT_HEADER = PROGRESS_TEXT_HEADER_DISCONNECT;
PROGRESS_TEXT_PREFIX = NEW_WIFI + "' and wait while we attempt to reach your device" + PROGRESS_TEXT_PREFIX;
updateProgressText();
}
if ((PROGRESS * REQUEST_INTERVAL)/60 < MAX_RETRY_TIME) {
setTimeout(queryForDevice, 0);
}
}
xmlhttp.timeout = REQUEST_INTERVAL * 1000;
xmlhttp.ontimeout = handleServerNonResponse;
xmlhttp.onerror = handleServerNonResponse;
xmlhttp.open("GET", OUTPUT_CMD, true);
xmlhttp.send();
}
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>IoT Gateway Setup</title>
<link rel="stylesheet" type="text/css" href="main.css" media="screen"/>
<script type="text/javascript">
var MANUAL_SETUP_TEXT = "Not listed? Switch to manual setup";
var SKIP_SETUP_TEXT = "Not applicable. Skip WiFi setup.";
var SCANNING_TEXT = "Scanning...";
var LIST_SEPARATOR = "-------------------------";
var COOKIE = {};
function selectProtocolForSsid(ssid) {
var networks = JSON.parse(document.getElementById("_networks").value);
var protocol = networks[ssid];
var protocolSelector = document.getElementById("protocol");
for (var i = 0; i < protocolSelector.length; i++) {
if (protocolSelector[i].value === protocol) {
protocolSelector.selectedIndex = i;
displayWiFiInputs(protocol);
break;
}
}
}
function switchToManualSetup() {
document.getElementById("newwifis").style.display = "none";
resetSsidRelatedFields();
document.getElementById("newwifi").style.display = "inline";
document.getElementById("protocollabel").style.display = "inline";
document.getElementById("protocol").style.display = "inline";
}
function switchToAutomaticSetup() {
document.getElementById("newwifi").style.display = "none";
resetSsidRelatedFields();
document.getElementById("newwifis").style.display = "inline";
document.getElementById("protocollabel").style.display = "none";
document.getElementById("protocol").style.display = "none";
document.getElementById("backToAutomatic").style.visibility = "hidden";
}
function resetSsidRelatedFields() {
if (COOKIE.newwifi) {
document.getElementById("newwifi").value = COOKIE.newwifi;
if (COOKIE.newwifi !== COOKIE.ssidsValue) {
document.getElementById("newwifis").value = COOKIE.ssidsValue;
document.getElementById("protocol").value = COOKIE.protocol;
displayWiFiInputs(COOKIE.protocol);
} else {
document.getElementById("newwifis").value = COOKIE.newwifi;
selectProtocolForSsid(COOKIE.newwifi);
}
} else {
if (COOKIE.ssidsValue) {
document.getElementById("newwifis").value = COOKIE.ssidsValue;
} else {
document.getElementById("newwifis").selectedIndex = 0;
}
document.getElementById("newwifi").value = document.getElementById("newwifis").value;
selectProtocolForSsid(document.getElementById("newwifi").value)
}
}
function setSsidsRelatedFields() {
var ssidSelector = document.getElementById("newwifis");
var selectedValue = ssidSelector[ssidSelector.selectedIndex].value;
// These text strings come from default values set in functions below. Search to find out where.
if (selectedValue !== SCANNING_TEXT && selectedValue !== MANUAL_SETUP_TEXT &&
selectedValue != SKIP_SETUP_TEXT) {
document.getElementById("newwifi").value = selectedValue;
selectProtocolForSsid(selectedValue);
} else if (selectedValue === MANUAL_SETUP_TEXT) {
document.getElementById("backToAutomatic").style.visibility = "visible";
switchToManualSetup();
} else { // skip wifi setup
document.getElementById("newwifi").value = "";
document.getElementById("netpasslabel").style.display="none";
document.getElementById("netpass").style.display="none";
document.getElementById("netuserlabel").style.display="none";
document.getElementById("netuser").style.display="none";
document.getElementById("protocol").style.display="none";
}
}
function displayWiFiInputs(protocol) {
if (protocol === 'WEP' || protocol === 'WPA-PSK') {
document.getElementById("netpasslabel").style.display="inline";
document.getElementById("netpass").style.display="inline";
document.getElementById("netuserlabel").style.display="none";
document.getElementById("netuser").style.display="none";
} else if (protocol === 'WPA-EAP') {
document.getElementById("netpasslabel").style.display="inline";
document.getElementById("netpass").style.display="inline";
document.getElementById("netuserlabel").style.display="inline";
document.getElementById("netuser").style.display="inline";
} else {
document.getElementById("netpasslabel").style.display="none";
document.getElementById("netpass").style.display="none";
document.getElementById("netuserlabel").style.display="none";
document.getElementById("netuser").style.display="none";
}
}
function saveFields() {
document.cookie =
'{' +
'"name": "' + document.getElementById("name").value + '",' +
'"newwifi": "' + document.getElementById("newwifi").value + '",' +
'"protocol": "' + document.getElementById("protocol").value + '",' +
'"netuser": "' + document.getElementById("netuser").value + '",' +
'"ssidsValue": "' + document.getElementById("newwifis").value + '"' +
'}';
}
function initWiFiNetworkFields() {
var networks = JSON.parse(document.getElementById("_networks").value);
console.log("WiFi networks:");
console.log(networks);
var ssidSelector = document.getElementById("newwifis");
ssidSelector.remove(0);
for (var ssid in networks) {
if (networks.hasOwnProperty(ssid)) {
var opt = document.createElement("option");
opt.value = ssid;
opt.textContent = ssid;
ssidSelector.add(opt);
}
}
if (ssidSelector.length === 0) {
console.log("No WiFi networks found. Switching to manual setup.");
switchToManualSetup();
} else {
// add the switch to manual setup option
var opt = document.createElement("option");
opt.value = LIST_SEPARATOR;
opt.textContent = opt.value;
opt.disabled = "disabled";
ssidSelector.add(opt);
opt = document.createElement("option");
opt.value = MANUAL_SETUP_TEXT;
opt.textContent = opt.value;
ssidSelector.add(opt);
opt = document.createElement("option");
opt.value = SKIP_SETUP_TEXT;
opt.textContent = opt.value;
ssidSelector.add(opt);
resetSsidRelatedFields();
}
}
function getWiFiNetworks() {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
} else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
document.getElementById("_networks").value = xmlhttp.responseText;
initWiFiNetworkFields();
} else if (xmlhttp.readyState === 4 && xmlhttp.status === 404) {
if (getWiFiNetworks.called) {
getWiFiNetworks.called++;
} else {
getWiFiNetworks.called = 1;
}
if (getWiFiNetworks.called < 5) {
console.log("Retrying getWiFiNetworks: " + getWiFiNetworks.called);
setTimeout(getWiFiNetworks, 2000);
} else { // switch to manual entry
console.log("Giving up on getWiFiNetworks. Switching to manual WiFi Setup.");
switchToManualSetup();
}
}
};
xmlhttp.open("GET", "wifiNetworks", true);
xmlhttp.send();
}
window.onload = function () {
if (document.cookie)
COOKIE = JSON.parse(document.cookie);
getWiFiNetworks();
// restore subset of saved fields
// wifi related fields will be restored in getWiFiNetworks()
if (COOKIE.name)
document.getElementById("name").value = COOKIE.name;
if (COOKIE.netuser)
document.getElementById("netuser").value = COOKIE.netuser;
};
</script>
<noscript>
Please enable Javascript. It is needed for this page to work correctly. Thank you.
</noscript>
</head>
<body>
<a href="/" style="text-decoration: none"><h1>IoT Gateway Setup</h1></a>