Fixed a ton of bugs and made almost everything work
This commit is contained in:
@@ -93,6 +93,8 @@ set(SOURCE_FILES
|
|||||||
user/io.h
|
user/io.h
|
||||||
user/cgi_wifi.c
|
user/cgi_wifi.c
|
||||||
user/cgi_wifi.h
|
user/cgi_wifi.h
|
||||||
|
user/cgi_persist.c
|
||||||
|
user/cgi_persist.h
|
||||||
user/cgi_network.c
|
user/cgi_network.c
|
||||||
user/cgi_network.h
|
user/cgi_network.h
|
||||||
user/cgi_appcfg.c
|
user/cgi_appcfg.c
|
||||||
@@ -140,6 +142,7 @@ add_definitions(
|
|||||||
-DICACHE_FLASH_ATTR=
|
-DICACHE_FLASH_ATTR=
|
||||||
-DICACHE_RODATA_ATTR=
|
-DICACHE_RODATA_ATTR=
|
||||||
-DFLAG_GZIP=2
|
-DFLAG_GZIP=2
|
||||||
|
-DADMIN_PASSWORD="asdf"
|
||||||
-DESPFS_HEATSHRINK)
|
-DESPFS_HEATSHRINK)
|
||||||
|
|
||||||
add_executable(esp_vt100_firmware ${SOURCE_FILES})
|
add_executable(esp_vt100_firmware ${SOURCE_FILES})
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ LIBS += esphttpd
|
|||||||
# compiler flags using during compilation of source files
|
# compiler flags using during compilation of source files
|
||||||
CFLAGS = -Os -ggdb -std=gnu99 -Werror -Wpointer-arith -Wundef -Wall -Wl,-EL -fno-inline-functions \
|
CFLAGS = -Os -ggdb -std=gnu99 -Werror -Wpointer-arith -Wundef -Wall -Wl,-EL -fno-inline-functions \
|
||||||
-nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH \
|
-nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH \
|
||||||
-Wno-address -Wno-unused -DHTTPD_MAX_BACKLOG_SIZE=8192
|
-Wno-address -Wno-unused -DHTTPD_MAX_BACKLOG_SIZE=8192 -DADMIN_PASSWORD=$(ADMIN_PASSWORD)
|
||||||
|
|
||||||
# linker flags used to generate the main object file
|
# linker flags used to generate the main object file
|
||||||
LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static
|
LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static
|
||||||
|
|||||||
+3
-2
@@ -14,7 +14,8 @@ cd ..
|
|||||||
|
|
||||||
cp html_orig/js/app.js html/js/
|
cp html_orig/js/app.js html/js/
|
||||||
|
|
||||||
sass --sourcemap=none html_orig/sass/app.scss html/css/app.css
|
sass html_orig/sass/app.scss html/css/app.css
|
||||||
|
rm html/css/app.css.map
|
||||||
|
|
||||||
cp html_orig/img/* html/img/
|
cp html_orig/img/* html/img/
|
||||||
|
cp html_orig/favicon.ico html/favicon.ico
|
||||||
|
|||||||
@@ -37,3 +37,6 @@ OUTPUT_TYPE = combined
|
|||||||
|
|
||||||
# SPI flash size, in K
|
# SPI flash size, in K
|
||||||
ESP_SPI_FLASH_SIZE_K = 1024
|
ESP_SPI_FLASH_SIZE_K = 1024
|
||||||
|
|
||||||
|
# Admin password, used to store settings to flash as defaults
|
||||||
|
ADMIN_PASSWORD = "19738426"
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ require_once __DIR__ . '/_env.php';
|
|||||||
|
|
||||||
$prod = defined('STDIN');
|
$prod = defined('STDIN');
|
||||||
define('DEBUG', !$prod);
|
define('DEBUG', !$prod);
|
||||||
$root = DEBUG ? json_encode(ESP_IP) : 'window.location.href';
|
$root = DEBUG ? json_encode(ESP_IP) : 'location.host';
|
||||||
define('JS_WEB_ROOT', $root);
|
define('JS_WEB_ROOT', $root);
|
||||||
|
|
||||||
define('LOCALE', isset($_GET['locale']) ? $_GET['locale'] : 'en');
|
define('LOCALE', isset($_GET['locale']) ? $_GET['locale'] : 'en');
|
||||||
|
|||||||
Regular → Executable
+18
@@ -2,6 +2,18 @@
|
|||||||
|
|
||||||
require_once __DIR__ . '/base.php';
|
require_once __DIR__ . '/base.php';
|
||||||
|
|
||||||
|
function process_html($s) {
|
||||||
|
$pattern = '/<!--(.*)-->/Uis';
|
||||||
|
$s = preg_replace($pattern, '', $s);
|
||||||
|
|
||||||
|
$pattern = '/(?:(?:\/\*(?:[^*]|(?:\*+[^*\/]))*\*+\/)|(?:(?<!\:|\\\|\'|\")\/\/.*))/';
|
||||||
|
$s = preg_replace($pattern, '', $s);
|
||||||
|
|
||||||
|
$pattern = '/\s+/s';
|
||||||
|
$s = preg_replace($pattern, ' ', $s);
|
||||||
|
return $s;
|
||||||
|
}
|
||||||
|
|
||||||
ob_start();
|
ob_start();
|
||||||
foreach($_pages as $_k => $p) {
|
foreach($_pages as $_k => $p) {
|
||||||
if ($p->bodyclass == 'api') continue;
|
if ($p->bodyclass == 'api') continue;
|
||||||
@@ -11,6 +23,12 @@ foreach($_pages as $_k => $p) {
|
|||||||
ob_clean(); // clean up
|
ob_clean(); // clean up
|
||||||
include(__DIR__ . '/index.php');
|
include(__DIR__ . '/index.php');
|
||||||
$s = ob_get_contents(); // grab the output
|
$s = ob_get_contents(); // grab the output
|
||||||
|
|
||||||
|
// remove newlines and comments
|
||||||
|
// as tests have shown, it saves just a couple kilobytes,
|
||||||
|
// making it not a very big improvement at the expense of ugly html.
|
||||||
|
// $s = process_html($s);
|
||||||
|
|
||||||
ob_clean(); // clean up
|
ob_clean(); // clean up
|
||||||
$of = __DIR__ . '/../html/' . $_k . '.tpl';
|
$of = __DIR__ . '/../html/' . $_k . '.tpl';
|
||||||
file_put_contents($of, $s); // write to a file
|
file_put_contents($of, $s); // write to a file
|
||||||
|
|||||||
+14
-6
@@ -576,6 +576,10 @@ ul > * {
|
|||||||
background-color: rgba(255, 255, 255, 0.07);
|
background-color: rgba(255, 255, 255, 0.07);
|
||||||
box-shadow: 0 0 4px black;
|
box-shadow: 0 0 4px black;
|
||||||
border: 1px solid #4f4f4f; }
|
border: 1px solid #4f4f4f; }
|
||||||
|
.Box::after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
clear: both; }
|
||||||
@media screen and (max-width: 544px) {
|
@media screen and (max-width: 544px) {
|
||||||
.Box {
|
.Box {
|
||||||
margin-top: 0.61805rem; } }
|
margin-top: 0.61805rem; } }
|
||||||
@@ -586,6 +590,8 @@ ul > * {
|
|||||||
.Box h2 {
|
.Box h2 {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 0 !important; }
|
margin-bottom: 0 !important; }
|
||||||
|
.Box p:last-child {
|
||||||
|
margin-bottom: 0.5em; }
|
||||||
.Box.wide {
|
.Box.wide {
|
||||||
width: initial;
|
width: initial;
|
||||||
max-width: initial; }
|
max-width: initial; }
|
||||||
@@ -967,7 +973,8 @@ form span.required {
|
|||||||
background: rgba(255, 255, 255, 0.1);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 0.38198rem;
|
padding: 0.38198rem;
|
||||||
margin-bottom: 0.38198rem; }
|
margin-bottom: 0.38198rem;
|
||||||
|
margin-top: 0.38198rem; }
|
||||||
|
|
||||||
#ap-noscan {
|
#ap-noscan {
|
||||||
font-weight: bold; }
|
font-weight: bold; }
|
||||||
@@ -1109,10 +1116,8 @@ body.term #buttons {
|
|||||||
white-space: nowrap; }
|
white-space: nowrap; }
|
||||||
body.term #buttons button {
|
body.term #buttons button {
|
||||||
margin: 0 3px;
|
margin: 0 3px;
|
||||||
padding: 10px 0;
|
padding: 8px 5px;
|
||||||
width: 18%;
|
min-width: 65px;
|
||||||
max-width: 65px;
|
|
||||||
min-width: initial;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: bold; }
|
font-weight: bold; }
|
||||||
body.term #botnav {
|
body.term #botnav {
|
||||||
@@ -1138,7 +1143,8 @@ body.term #botnav {
|
|||||||
float: right;
|
float: right;
|
||||||
height: 130px; }
|
height: 130px; }
|
||||||
.page-about #logo2 {
|
.page-about #logo2 {
|
||||||
max-width: 100%; }
|
max-width: 100%;
|
||||||
|
margin: 1rem; }
|
||||||
.page-about td {
|
.page-about td {
|
||||||
white-space: normal; }
|
white-space: normal; }
|
||||||
|
|
||||||
@@ -1280,3 +1286,5 @@ body.term #botnav {
|
|||||||
@media screen and (max-width: 1000px) {
|
@media screen and (max-width: 1000px) {
|
||||||
.mq-normal-min {
|
.mq-normal-min {
|
||||||
display: none !important; } }
|
display: none !important; } }
|
||||||
|
|
||||||
|
/*# sourceMappingURL=app.css.map */
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Executable
+21
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/* This script is run on demand to generate JS version of tr() */
|
||||||
|
|
||||||
|
require_once __DIR__ . '/base.php';
|
||||||
|
|
||||||
|
$selected = [
|
||||||
|
'wifi.connected_ip_is',
|
||||||
|
'wifi.not_conn',
|
||||||
|
];
|
||||||
|
|
||||||
|
$out = [];
|
||||||
|
foreach ($selected as $key) {
|
||||||
|
$out[$key] = $_messages[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
file_put_contents(__DIR__. '/jssrc/lang.js',
|
||||||
|
"// Generated from PHP locale file\n" .
|
||||||
|
'var _tr = ' . json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE) . ";\n\n" .
|
||||||
|
"function tr(key) { return _tr[key] || '?'+key+'?'; }\n"
|
||||||
|
);
|
||||||
+192
-2
@@ -999,13 +999,203 @@ $.ready(function () {
|
|||||||
x.removeAttribute('tabindex');
|
x.removeAttribute('tabindex');
|
||||||
});
|
});
|
||||||
|
|
||||||
qs('#brand').removeAttribute('tabindex');
|
var br = qs('#brand');
|
||||||
|
br && br.removeAttribute('tabindex');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$._loader = function(vis) {
|
$._loader = function(vis) {
|
||||||
$('#loader').toggleClass('show', vis);
|
$('#loader').toggleClass('show', vis);
|
||||||
};
|
};
|
||||||
|
// Generated from PHP locale file
|
||||||
|
var _tr = {
|
||||||
|
"wifi.connected_ip_is": "Connected, IP is ",
|
||||||
|
"wifi.not_conn": "Not connected."
|
||||||
|
};
|
||||||
|
|
||||||
|
function tr(key) { return _tr[key] || '?'+key+'?'; }
|
||||||
|
(function(w) {
|
||||||
|
var authStr = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2'];
|
||||||
|
var curSSID;
|
||||||
|
|
||||||
|
// Get XX % for a slider input
|
||||||
|
function rangePt(inp) {
|
||||||
|
return Math.round(((inp.value / inp.max)*100)) + '%';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display selected STA SSID etc
|
||||||
|
function selectSta(name, password, ip) {
|
||||||
|
$('#sta_ssid').val(name);
|
||||||
|
$('#sta_password').val(password);
|
||||||
|
|
||||||
|
$('#sta-nw').toggleClass('hidden', name.length == 0);
|
||||||
|
$('#sta-nw-nil').toggleClass('hidden', name.length > 0);
|
||||||
|
|
||||||
|
$('#sta-nw .essid').html(e(name));
|
||||||
|
var nopw = undef(password) || password.length == 0;
|
||||||
|
$('#sta-nw .x-passwd').html(e(password));
|
||||||
|
$('#sta-nw .passwd').toggleClass('hidden', nopw);
|
||||||
|
$('#sta-nw .nopasswd').toggleClass('hidden', !nopw);
|
||||||
|
$('#sta-nw .ip').html(ip.length>0 ? tr('wifi.connected_ip_is')+ip : tr('wifi.not_conn'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitPskModal(e, open) {
|
||||||
|
var passwd = $('#conn-passwd').val();
|
||||||
|
var ssid = $('#conn-ssid').val();
|
||||||
|
|
||||||
|
if (open || passwd.length) {
|
||||||
|
$('#sta_password').val(passwd);
|
||||||
|
$('#sta_ssid').val(ssid);
|
||||||
|
selectSta(ssid, passwd, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e) e.preventDefault();
|
||||||
|
Modal.hide('#psk-modal');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update display for received response */
|
||||||
|
function onScan(resp, status) {
|
||||||
|
//var ap_json = {
|
||||||
|
// "result": {
|
||||||
|
// "inProgress": "0",
|
||||||
|
// "APs": [
|
||||||
|
// {"essid": "Chlivek", "bssid": "88:f7:c7:52:b3:99", "rssi": "204", "enc": "4", "channel": "1"},
|
||||||
|
// {"essid": "TyNikdy", "bssid": "5c:f4:ab:0d:f1:1b", "rssi": "164", "enc": "3", "channel": "1"},
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
//};
|
||||||
|
|
||||||
|
if (status != 200) {
|
||||||
|
// bad response
|
||||||
|
rescan(5000); // wait 5sm then retry
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
resp = JSON.parse(resp);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
rescan(5000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0);
|
||||||
|
rescan(done ? 15000 : 1000);
|
||||||
|
if (!done) return; // no redraw yet
|
||||||
|
|
||||||
|
// clear the AP list
|
||||||
|
var $list = $('#ap-list');
|
||||||
|
// remove old APs
|
||||||
|
$('#ap-list .AP').remove();
|
||||||
|
|
||||||
|
$list.toggleClass('hidden', !done);
|
||||||
|
$('#ap-loader').toggleClass('hidden', done);
|
||||||
|
|
||||||
|
// scan done
|
||||||
|
resp.result.APs.sort(function (a, b) {
|
||||||
|
return b.rssi - a.rssi;
|
||||||
|
}).forEach(function (ap) {
|
||||||
|
ap.enc = parseInt(ap.enc);
|
||||||
|
|
||||||
|
if (ap.enc > 4) return; // hide unsupported auths
|
||||||
|
WiFi.scan_url = '/cfg/wifi/scan';
|
||||||
|
|
||||||
|
var item = mk('div');
|
||||||
|
|
||||||
|
var $item = $(item)
|
||||||
|
.data('ssid', ap.essid)
|
||||||
|
.data('pwd', ap.enc)
|
||||||
|
.attr('tabindex', 0)
|
||||||
|
.addClass('AP');
|
||||||
|
|
||||||
|
// mark current SSID
|
||||||
|
if (ap.essid == curSSID) {
|
||||||
|
$item.addClass('selected');
|
||||||
|
}
|
||||||
|
|
||||||
|
var inner = mk('div');
|
||||||
|
$(inner).addClass('inner')
|
||||||
|
.htmlAppend('<div class="rssi">{0}</div>'.format(ap.rssi_perc))
|
||||||
|
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format($.htmlEscape(ap.essid)))
|
||||||
|
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc]));
|
||||||
|
|
||||||
|
$item.on('click', function () {
|
||||||
|
var $th = $(this);
|
||||||
|
|
||||||
|
var ssid = $th.data('ssid');
|
||||||
|
|
||||||
|
$('#conn-ssid').val(ssid);
|
||||||
|
$('#conn-passwd').val('');
|
||||||
|
|
||||||
|
if (+$th.data('pwd')) {
|
||||||
|
// this AP needs a password
|
||||||
|
Modal.show('#psk-modal');
|
||||||
|
$('#conn-passwd')[0].focus();
|
||||||
|
} else {
|
||||||
|
//Modal.show('#reset-modal');
|
||||||
|
submitPskModal(null, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
item.appendChild(inner);
|
||||||
|
$list[0].appendChild(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function startScanning() {
|
||||||
|
$('#ap-loader').removeClass('hidden');
|
||||||
|
$('#ap-scan').addClass('hidden');
|
||||||
|
$('#ap-loader .anim-dots').html('.');
|
||||||
|
scanAPs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Ask the CGI what APs are visible (async) */
|
||||||
|
function scanAPs() {
|
||||||
|
$.get('http://'+_root+w.scan_url, onScan);
|
||||||
|
}
|
||||||
|
|
||||||
|
function rescan(time) {
|
||||||
|
setTimeout(scanAPs, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set up the WiFi page */
|
||||||
|
function wifiInit(cfg) {
|
||||||
|
// Hide what should be hidden in this mode
|
||||||
|
cfg.mode = +cfg.mode;
|
||||||
|
|
||||||
|
$('#ap-noscan').toggleClass('hidden', cfg.mode != 2);
|
||||||
|
$('#ap-scan').toggleClass('hidden', cfg.mode == 2);
|
||||||
|
|
||||||
|
// Update slider value displays
|
||||||
|
$('.Row.range').forEach(function(x) {
|
||||||
|
var inp = x.querySelector('input');
|
||||||
|
var disp1 = x.querySelector('.x-disp1');
|
||||||
|
var disp2 = x.querySelector('.x-disp2');
|
||||||
|
var t = rangePt(inp);
|
||||||
|
$(disp1).html(t);
|
||||||
|
$(disp2).html(t);
|
||||||
|
$(inp).on('input', function() {
|
||||||
|
t = rangePt(inp);
|
||||||
|
$(disp1).html(t);
|
||||||
|
$(disp2).html(t);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Forget STA credentials
|
||||||
|
$('#forget-sta').on('click', function() {
|
||||||
|
selectSta('', '', '');
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
selectSta(cfg.sta_ssid, cfg.sta_password, cfg.sta_active_ip);
|
||||||
|
curSSID = cfg.sta_active_ssid;
|
||||||
|
}
|
||||||
|
|
||||||
|
w.init = wifiInit;
|
||||||
|
w.startScanning = startScanning;
|
||||||
|
})(window.WiFi = {});
|
||||||
(function() {
|
(function() {
|
||||||
/**
|
/**
|
||||||
* Terminal module
|
* Terminal module
|
||||||
@@ -1307,5 +1497,5 @@ $._loader = function(vis) {
|
|||||||
Term.init(obj);
|
Term.init(obj);
|
||||||
Conn.init();
|
Conn.init();
|
||||||
Input.init();
|
Input.init();
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -100,7 +100,8 @@ $.ready(function () {
|
|||||||
x.removeAttribute('tabindex');
|
x.removeAttribute('tabindex');
|
||||||
});
|
});
|
||||||
|
|
||||||
qs('#brand').removeAttribute('tabindex');
|
var br = qs('#brand');
|
||||||
|
br && br.removeAttribute('tabindex');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// Generated from PHP locale file
|
||||||
|
var _tr = {
|
||||||
|
"wifi.connected_ip_is": "Connected, IP is ",
|
||||||
|
"wifi.not_conn": "Not connected."
|
||||||
|
};
|
||||||
|
|
||||||
|
function tr(key) { return _tr[key] || '?'+key+'?'; }
|
||||||
@@ -299,5 +299,5 @@
|
|||||||
Term.init(obj);
|
Term.init(obj);
|
||||||
Conn.init();
|
Conn.init();
|
||||||
Input.init();
|
Input.init();
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
+159
-105
@@ -1,89 +1,45 @@
|
|||||||
/** Wifi page */
|
(function(w) {
|
||||||
(function () {
|
|
||||||
var authStr = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2'];
|
var authStr = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2'];
|
||||||
var curSSID;
|
var curSSID;
|
||||||
|
|
||||||
/** Update display for received response */
|
// Get XX % for a slider input
|
||||||
function onScan(resp, status) {
|
function rangePt(inp) {
|
||||||
if (status != 200) {
|
return Math.round(((inp.value / inp.max)*100)) + '%';
|
||||||
// bad response
|
}
|
||||||
rescan(5000); // wait 5sm then retry
|
|
||||||
return;
|
// Display selected STA SSID etc
|
||||||
|
function selectSta(name, password, ip) {
|
||||||
|
$('#sta_ssid').val(name);
|
||||||
|
$('#sta_password').val(password);
|
||||||
|
|
||||||
|
$('#sta-nw').toggleClass('hidden', name.length == 0);
|
||||||
|
$('#sta-nw-nil').toggleClass('hidden', name.length > 0);
|
||||||
|
|
||||||
|
$('#sta-nw .essid').html(e(name));
|
||||||
|
var nopw = undef(password) || password.length == 0;
|
||||||
|
$('#sta-nw .x-passwd').html(e(password));
|
||||||
|
$('#sta-nw .passwd').toggleClass('hidden', nopw);
|
||||||
|
$('#sta-nw .nopasswd').toggleClass('hidden', !nopw);
|
||||||
|
$('#sta-nw .ip').html(ip.length>0 ? tr('wifi.connected_ip_is')+ip : tr('wifi.not_conn'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitPskModal(e, open) {
|
||||||
|
var passwd = $('#conn-passwd').val();
|
||||||
|
var ssid = $('#conn-ssid').val();
|
||||||
|
|
||||||
|
if (open || passwd.length) {
|
||||||
|
$('#sta_password').val(passwd);
|
||||||
|
$('#sta_ssid').val(ssid);
|
||||||
|
selectSta(ssid, passwd, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = jsp(resp);
|
if (e) e.preventDefault();
|
||||||
|
Modal.hide('#psk-modal');
|
||||||
var done = resp && !bool(resp.result.inProgress) && (resp.result.APs.length > 0);
|
return false;
|
||||||
rescan(done ? 15000 : 1000);
|
|
||||||
if (!done) return; // no redraw yet
|
|
||||||
|
|
||||||
// clear the AP list
|
|
||||||
var $list = $('#ap-list');
|
|
||||||
// remove old APs
|
|
||||||
$('#ap-list .AP').remove();
|
|
||||||
|
|
||||||
$list.toggle(done);
|
|
||||||
$('#ap-loader').toggle(!done);
|
|
||||||
|
|
||||||
// scan done
|
|
||||||
resp.result.APs.sort(function (a, b) {
|
|
||||||
return b.rssi - a.rssi;
|
|
||||||
}).forEach(function (ap) {
|
|
||||||
ap.enc = parseInt(ap.enc);
|
|
||||||
|
|
||||||
if (ap.enc > 4) return; // hide unsupported auths
|
|
||||||
|
|
||||||
var item = document.createElement('div');
|
|
||||||
|
|
||||||
var $item = $(item)
|
|
||||||
.data('ssid', ap.essid)
|
|
||||||
.data('pwd', ap.enc != 0)
|
|
||||||
.addClass('AP');
|
|
||||||
|
|
||||||
// mark current SSID
|
|
||||||
if (ap.essid == curSSID) {
|
|
||||||
$item.addClass('selected');
|
|
||||||
}
|
|
||||||
|
|
||||||
var inner = document.createElement('div');
|
|
||||||
$(inner).addClass('inner')
|
|
||||||
.htmlAppend('<div class="rssi">{0}</div>'.format(ap.rssi_perc))
|
|
||||||
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format($.htmlEscape(ap.essid)))
|
|
||||||
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc]));
|
|
||||||
|
|
||||||
$item.on('click', function () {
|
|
||||||
var $th = $(this);
|
|
||||||
|
|
||||||
// populate the form
|
|
||||||
$('#conn-essid').val($th.data('ssid'));
|
|
||||||
$('#conn-passwd').val(''); // clear
|
|
||||||
|
|
||||||
if ($th.data('pwd')) {
|
|
||||||
// this AP needs a password
|
|
||||||
Modal.show('#psk-modal');
|
|
||||||
} else {
|
|
||||||
Modal.show('#reset-modal');
|
|
||||||
$('#conn-form').submit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
item.appendChild(inner);
|
|
||||||
$list[0].appendChild(item);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Ask the CGI what APs are visible (async) */
|
/** Update display for received response */
|
||||||
function scanAPs() {
|
function onScan(resp, status) {
|
||||||
$.get('http://'+_root+'/wifi/scan', onScan);
|
|
||||||
}
|
|
||||||
|
|
||||||
function rescan(time) {
|
|
||||||
setTimeout(scanAPs, time);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set up the WiFi page */
|
|
||||||
window.wifiInit = function (obj) {
|
|
||||||
//var ap_json = {
|
//var ap_json = {
|
||||||
// "result": {
|
// "result": {
|
||||||
// "inProgress": "0",
|
// "inProgress": "0",
|
||||||
@@ -94,35 +50,133 @@
|
|||||||
// }
|
// }
|
||||||
//};
|
//};
|
||||||
|
|
||||||
|
if (status != 200) {
|
||||||
|
// bad response
|
||||||
|
rescan(5000); // wait 5sm then retry
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
resp = JSON.parse(resp);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
rescan(5000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0);
|
||||||
|
rescan(done ? 15000 : 1000);
|
||||||
|
if (!done) return; // no redraw yet
|
||||||
|
|
||||||
|
// clear the AP list
|
||||||
|
var $list = $('#ap-list');
|
||||||
|
// remove old APs
|
||||||
|
$('#ap-list .AP').remove();
|
||||||
|
|
||||||
|
$list.toggleClass('hidden', !done);
|
||||||
|
$('#ap-loader').toggleClass('hidden', done);
|
||||||
|
|
||||||
|
// scan done
|
||||||
|
resp.result.APs.sort(function (a, b) {
|
||||||
|
return b.rssi - a.rssi;
|
||||||
|
}).forEach(function (ap) {
|
||||||
|
ap.enc = parseInt(ap.enc);
|
||||||
|
|
||||||
|
if (ap.enc > 4) return; // hide unsupported auths
|
||||||
|
WiFi.scan_url = '/cfg/wifi/scan';
|
||||||
|
|
||||||
|
var item = mk('div');
|
||||||
|
|
||||||
|
var $item = $(item)
|
||||||
|
.data('ssid', ap.essid)
|
||||||
|
.data('pwd', ap.enc)
|
||||||
|
.attr('tabindex', 0)
|
||||||
|
.addClass('AP');
|
||||||
|
|
||||||
|
// mark current SSID
|
||||||
|
if (ap.essid == curSSID) {
|
||||||
|
$item.addClass('selected');
|
||||||
|
}
|
||||||
|
|
||||||
|
var inner = mk('div');
|
||||||
|
$(inner).addClass('inner')
|
||||||
|
.htmlAppend('<div class="rssi">{0}</div>'.format(ap.rssi_perc))
|
||||||
|
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format($.htmlEscape(ap.essid)))
|
||||||
|
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc]));
|
||||||
|
|
||||||
|
$item.on('click', function () {
|
||||||
|
var $th = $(this);
|
||||||
|
|
||||||
|
var ssid = $th.data('ssid');
|
||||||
|
|
||||||
|
$('#conn-ssid').val(ssid);
|
||||||
|
$('#conn-passwd').val('');
|
||||||
|
|
||||||
|
if (+$th.data('pwd')) {
|
||||||
|
// this AP needs a password
|
||||||
|
Modal.show('#psk-modal');
|
||||||
|
$('#conn-passwd')[0].focus();
|
||||||
|
} else {
|
||||||
|
//Modal.show('#reset-modal');
|
||||||
|
submitPskModal(null, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
item.appendChild(inner);
|
||||||
|
$list[0].appendChild(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function startScanning() {
|
||||||
|
$('#ap-loader').removeClass('hidden');
|
||||||
|
$('#ap-scan').addClass('hidden');
|
||||||
|
$('#ap-loader .anim-dots').html('.');
|
||||||
|
scanAPs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Ask the CGI what APs are visible (async) */
|
||||||
|
function scanAPs() {
|
||||||
|
$.get('http://'+_root+w.scan_url, onScan);
|
||||||
|
}
|
||||||
|
|
||||||
|
function rescan(time) {
|
||||||
|
setTimeout(scanAPs, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set up the WiFi page */
|
||||||
|
function wifiInit(cfg) {
|
||||||
// Hide what should be hidden in this mode
|
// Hide what should be hidden in this mode
|
||||||
$('.x-hide-'+obj.mode).addClass('hidden');
|
cfg.mode = +cfg.mode;
|
||||||
obj.mode = +obj.mode;
|
|
||||||
|
|
||||||
// Channel writable only in AP mode
|
$('#ap-noscan').toggleClass('hidden', cfg.mode != 2);
|
||||||
if (obj.mode != 2) $('#channel').attr('readonly', 1);
|
$('#ap-scan').toggleClass('hidden', cfg.mode == 2);
|
||||||
|
|
||||||
curSSID = obj.staSSID;
|
// Update slider value displays
|
||||||
|
$('.Row.range').forEach(function(x) {
|
||||||
|
var inp = x.querySelector('input');
|
||||||
|
var disp1 = x.querySelector('.x-disp1');
|
||||||
|
var disp2 = x.querySelector('.x-disp2');
|
||||||
|
var t = rangePt(inp);
|
||||||
|
$(disp1).html(t);
|
||||||
|
$(disp2).html(t);
|
||||||
|
$(inp).on('input', function() {
|
||||||
|
t = rangePt(inp);
|
||||||
|
$(disp1).html(t);
|
||||||
|
$(disp2).html(t);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// add SSID to the opmode field
|
// Forget STA credentials
|
||||||
if (curSSID) {
|
$('#forget-sta').on('click', function() {
|
||||||
var box = $('#opmodebox');
|
selectSta('', '', '');
|
||||||
box.html(box.html() + ' (' + curSSID + ')');
|
return false;
|
||||||
}
|
});
|
||||||
|
|
||||||
// hide IP if IP not received
|
selectSta(cfg.sta_ssid, cfg.sta_password, cfg.sta_active_ip);
|
||||||
if (!obj.staIP) $('.x-hide-noip').addClass('hidden');
|
curSSID = cfg.sta_active_ssid;
|
||||||
|
}
|
||||||
|
|
||||||
// scan if not AP
|
w.init = wifiInit;
|
||||||
if (obj.mode != 2) {
|
w.startScanning = startScanning;
|
||||||
scanAPs();
|
})(window.WiFi = {});
|
||||||
}
|
|
||||||
|
|
||||||
$('#modeswitch').html([
|
|
||||||
'<a class="button" href="/wifi/set?opmode=3">Client+AP</a> <a class="button" href="/wifi/set?opmode=2">AP only</a>',
|
|
||||||
'<a class="button" href="/wifi/set?opmode=3">Client+AP</a>',
|
|
||||||
'<a class="button" href="/wifi/set?opmode=1">Client only</a> <a class="button" href="/wifi/set?opmode=2">AP only</a>'
|
|
||||||
][obj.mode-1]);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ return [
|
|||||||
'menu.cfg_admin' => 'Reset & Restore',
|
'menu.cfg_admin' => 'Reset & Restore',
|
||||||
'menu.cfg_wifi_conn' => 'Connecting to External Network',
|
'menu.cfg_wifi_conn' => 'Connecting to External Network',
|
||||||
|
|
||||||
|
'menu.settings' => 'Settings',
|
||||||
|
|
||||||
'title.term' => 'Terminal',
|
'title.term' => 'Terminal',
|
||||||
|
|
||||||
'net.ap' => 'DHCP Server (AP)',
|
'net.ap' => 'DHCP Server (AP)',
|
||||||
|
|||||||
@@ -7,4 +7,6 @@ cat jssrc/chibi.js \
|
|||||||
jssrc/modal.js \
|
jssrc/modal.js \
|
||||||
jssrc/notif.js \
|
jssrc/notif.js \
|
||||||
jssrc/appcommon.js \
|
jssrc/appcommon.js \
|
||||||
|
jssrc/lang.js \
|
||||||
|
jssrc/wifi.js \
|
||||||
jssrc/term.js > js/app.js
|
jssrc/term.js > js/app.js
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<nav id="menu">
|
<nav id="menu">
|
||||||
<div id="brand" tabindex=0><?= tr('appname') ?></div>
|
<div id="brand" tabindex=0><?= tr('appname') ?></div>
|
||||||
|
<a href="<?= e(url('term')) ?>" class="icn-back"><?= tr('menu.term') ?></a>
|
||||||
<?php
|
<?php
|
||||||
// generate the menu
|
// generate the menu
|
||||||
foreach ($_pages as $k => $page) {
|
foreach ($_pages as $k => $page) {
|
||||||
@@ -10,7 +11,7 @@
|
|||||||
$url = e(url($k));
|
$url = e(url($k));
|
||||||
echo "<a href=\"$url\" class=\"$page->icon $sel\">$text</a>";
|
echo "<a href=\"$url\" class=\"$page->icon $sel\">$text</a>";
|
||||||
}
|
}
|
||||||
?><a href="<?= e(url('term')) ?>" class="icn-back"><?= tr('menu.term') ?></a>
|
?>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -36,30 +36,28 @@
|
|||||||
<div class="Box">
|
<div class="Box">
|
||||||
<h2>Issues</h2>
|
<h2>Issues</h2>
|
||||||
<p>
|
<p>
|
||||||
Please report any issues to the <a href="%githubrepo%/issues">bugtracker</a> or send them by e-mail.
|
Please report any issues to the <a href="%githubrepo%/issues">bugtracker</a> or send them by e-mail (see above).
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Firmware updates can be downloaded from the <a href="%githubrepo%/releases">releases page</a>.
|
Firmware updates can be downloaded from the <a href="%githubrepo%/releases">releases page</a> and flashed
|
||||||
Flash the images using <a href="https://github.com/espressif/esptool">esptool</a>.
|
with <a href="https://github.com/espressif/esptool">esptool.py</a>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="Box">
|
<div class="Box">
|
||||||
<h2>Contributing</h2>
|
<h2>Contributing</h2>
|
||||||
<p>
|
<p>
|
||||||
Submit your improvements and ideas to the project on
|
<i class="icn-github"></i> You're welcome to submit your improvements and ideas to our <a href="%githubrepo%">GitHub repository</a>!
|
||||||
<a href="%githubrepo%">GitHub</a>.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
You can donate on <a href="https://paypal.me/mightypork">PayPal</a> or
|
<i class="icn-donate"></i> If you'd like to donate, please try <a href="https://paypal.me/mightypork">PayPal</a> or
|
||||||
<a href="https://liberapay.com/MightyPork/">LiberaPay</a> to help keep
|
<a href="https://liberapay.com/MightyPork/">LiberaPay</a>.
|
||||||
the project going.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="Box">
|
<div class="Box">
|
||||||
<h2>Acknowledgements</h2>
|
<h2>Thanks</h2>
|
||||||
<p>
|
<p>
|
||||||
The webserver is based on a <a href="https://github.com/MightyPork/libesphttpd">fork</a> of the
|
The webserver is based on a <a href="https://github.com/MightyPork/libesphttpd">fork</a> of the
|
||||||
<a href="https://github.com/Spritetm/esphttpd">esphttpd</a> library by Jeroen Domburg (Sprite_tm).
|
<a href="https://github.com/Spritetm/esphttpd">esphttpd</a> library by Jeroen Domburg (Sprite_tm).
|
||||||
|
|||||||
@@ -2,6 +2,39 @@
|
|||||||
$ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
|
$ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
<form class="Box str mobcol" action="<?= e(url('network_set')) ?>" method="GET" id="form-2">
|
||||||
|
<h2 tabindex=0><?= tr('net.sta') ?></h2>
|
||||||
|
|
||||||
|
<div class="Row explain">
|
||||||
|
<?= tr('net.explain_sta') ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Row checkbox x-static-toggle" >
|
||||||
|
<label><?= tr('net.sta_dhcp_enable') ?></label><!--
|
||||||
|
--><span class="box" tabindex=0 role=checkbox></span>
|
||||||
|
<input type="hidden" name="sta_dhcp_enable" value="%sta_dhcp_enable%">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Row x-static">
|
||||||
|
<label for="sta_addr_ip"><?= tr('net.sta_addr_ip') ?></label>
|
||||||
|
<input type="text" name="sta_addr_ip" id="sta_addr_ip" value="%sta_addr_ip%" <?=$ipmask?> required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Row x-static">
|
||||||
|
<label for="sta_addr_mask"><?= tr('net.sta_addr_mask') ?></label>
|
||||||
|
<input type="text" name="sta_addr_mask" id="sta_addr_mask" value="%sta_addr_mask%" <?=$ipmask?> required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Row x-static">
|
||||||
|
<label for="sta_addr_gw"><?= tr('net.sta_addr_gw') ?></label>
|
||||||
|
<input type="text" name="sta_addr_gw" id="sta_addr_gw" value="%sta_addr_gw%" <?=$ipmask?> required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Row buttons">
|
||||||
|
<a class="button icn-ok" href="#" onclick="qs('#form-2').submit()"><?= tr('apply') ?></a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
<form class="Box str mobcol" action="<?= e(url('network_set')) ?>" method="GET" id="form-1">
|
<form class="Box str mobcol" action="<?= e(url('network_set')) ?>" method="GET" id="form-1">
|
||||||
<h2 tabindex=0><?= tr('net.ap') ?></h2>
|
<h2 tabindex=0><?= tr('net.ap') ?></h2>
|
||||||
|
|
||||||
@@ -40,39 +73,6 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form class="Box str mobcol" action="<?= e(url('network_set')) ?>" method="GET" id="form-2">
|
|
||||||
<h2 tabindex=0><?= tr('net.sta') ?></h2>
|
|
||||||
|
|
||||||
<div class="Row explain">
|
|
||||||
<?= tr('net.explain_sta') ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="Row checkbox">
|
|
||||||
<label><?= tr('net.sta_dhcp_enable') ?></label><!--
|
|
||||||
--><span class="box" tabindex=0 role=checkbox></span>
|
|
||||||
<input type="hidden" name="sta_dhcp_enable" value="%sta_dhcp_enable%">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="Row">
|
|
||||||
<label for="sta_addr_ip"><?= tr('net.sta_addr_ip') ?></label>
|
|
||||||
<input type="text" name="sta_addr_ip" id="sta_addr_ip" value="%sta_addr_ip%" <?=$ipmask?> required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="Row">
|
|
||||||
<label for="sta_addr_mask"><?= tr('net.sta_addr_mask') ?></label>
|
|
||||||
<input type="text" name="sta_addr_mask" id="sta_addr_mask" value="%sta_addr_mask%" <?=$ipmask?> required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="Row">
|
|
||||||
<label for="sta_addr_gw"><?= tr('net.sta_addr_gw') ?></label>
|
|
||||||
<input type="text" name="sta_addr_gw" id="sta_addr_gw" value="%sta_addr_gw%" <?=$ipmask?> required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="Row buttons">
|
|
||||||
<a class="button icn-ok" href="#" onclick="qs('#form-2').submit()"><?= tr('apply') ?></a>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div class="Box mobcol">
|
<div class="Box mobcol">
|
||||||
<h2><?= tr('net.details') ?></h2>
|
<h2><?= tr('net.details') ?></h2>
|
||||||
|
|
||||||
@@ -83,3 +83,13 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
|
|||||||
<label><?= tr('net.ap_mac') ?></label><input type="text" readonly value="%ap_mac%">
|
<label><?= tr('net.ap_mac') ?></label><input type="text" readonly value="%ap_mac%">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function updateStaticDisp() {
|
||||||
|
$('.x-static').toggleClass('hidden', $('#sta_dhcp_enable').val());
|
||||||
|
}
|
||||||
|
$('.x-static-toggle').on('click', function() {
|
||||||
|
updateStaticDisp();
|
||||||
|
});
|
||||||
|
updateStaticDisp();
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
|
|
||||||
<div id="ap-box">
|
<div id="ap-box">
|
||||||
<label><?= tr('wifi.select_ssid') ?></label>
|
<label><?= tr('wifi.select_ssid') ?></label>
|
||||||
<div id="ap-scan"><a href="#" onclick="startScanning(); return false"><?= tr('wifi.scan_now') ?></a></div>
|
<div id="ap-scan"><a href="#" onclick="WiFi.startScanning(); return false"><?= tr('wifi.scan_now') ?></a></div>
|
||||||
<div id="ap-loader" class="hidden"><?= tr('wifi.scanning') ?><span class="anim-dots">.</span></div>
|
<div id="ap-loader" class="hidden"><?= tr('wifi.scanning') ?><span class="anim-dots">.</span></div>
|
||||||
<div id="ap-noscan" class="hidden"><?= tr('wifi.cant_scan_no_sta') ?></div>
|
<div id="ap-noscan" class="hidden"><?= tr('wifi.cant_scan_no_sta') ?></div>
|
||||||
<div id="ap-list" class="hidden"></div>
|
<div id="ap-list" class="hidden"></div>
|
||||||
@@ -97,186 +97,12 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Get XX % for a slider input
|
WiFi.scan_url = '<?= url('wifi_scan', true) ?>';
|
||||||
function rangePt(inp) {
|
WiFi.init({
|
||||||
return Math.round(((inp.value / inp.max)*100)) + '%';
|
mode: '%opmode%',
|
||||||
}
|
sta_ssid: '%sta_ssid%',
|
||||||
|
sta_password: '%sta_password%',
|
||||||
// Update slider value displays
|
sta_active_ip: '%sta_active_ip%',
|
||||||
$('.Row.range').forEach(function(x) {
|
sta_active_ssid: '%sta_active_ssid%',
|
||||||
var inp = x.querySelector('input');
|
|
||||||
var disp1 = x.querySelector('.x-disp1');
|
|
||||||
var disp2 = x.querySelector('.x-disp2');
|
|
||||||
var t = rangePt(inp);
|
|
||||||
$(disp1).html(t);
|
|
||||||
$(disp2).html(t);
|
|
||||||
$(inp).on('input', function() {
|
|
||||||
t = rangePt(inp);
|
|
||||||
$(disp1).html(t);
|
|
||||||
$(disp2).html(t);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Forget STA credentials
|
|
||||||
$('#forget-sta').on('click', function() {
|
|
||||||
selectSta('', '', '');
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Display selected STA SSID etc
|
|
||||||
function selectSta(name, password, ip) {
|
|
||||||
$('#sta_ssid').val(name);
|
|
||||||
$('#sta_password').val(password);
|
|
||||||
|
|
||||||
$('#sta-nw').toggleClass('hidden', name.length == 0);
|
|
||||||
$('#sta-nw-nil').toggleClass('hidden', name.length > 0);
|
|
||||||
|
|
||||||
$('#sta-nw .essid').html(e(name));
|
|
||||||
var nopw = undef(password) || password.length == 0;
|
|
||||||
$('#sta-nw .x-passwd').html(e(password));
|
|
||||||
$('#sta-nw .passwd').toggleClass('hidden', nopw);
|
|
||||||
$('#sta-nw .nopasswd').toggleClass('hidden', !nopw);
|
|
||||||
$('#sta-nw .ip').html(ip.length>0 ? '<?=tr('wifi.connected_ip_is')?>'+ip : '<?=tr('wifi.not_conn')?>');
|
|
||||||
}
|
|
||||||
|
|
||||||
selectSta('%sta_ssid%', '%sta_password%', '%sta_active_ip%');
|
|
||||||
|
|
||||||
var authStr = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2'];
|
|
||||||
var curSSID = '%sta_active_ssid%';
|
|
||||||
|
|
||||||
function submitPskModal(e, open) {
|
|
||||||
var passwd = $('#conn-passwd').val();
|
|
||||||
var ssid = $('#conn-ssid').val();
|
|
||||||
|
|
||||||
if (open || passwd.length) {
|
|
||||||
$('#sta_password').val(passwd);
|
|
||||||
$('#sta_ssid').val(ssid);
|
|
||||||
selectSta(ssid, passwd, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e) e.preventDefault();
|
|
||||||
Modal.hide('#psk-modal');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Update display for received response */
|
|
||||||
function onScan(resp, status) {
|
|
||||||
if (status != 200) {
|
|
||||||
// bad response
|
|
||||||
rescan(5000); // wait 5sm then retry
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
resp = JSON.parse(resp);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
rescan(5000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0);
|
|
||||||
rescan(done ? 15000 : 1000);
|
|
||||||
if (!done) return; // no redraw yet
|
|
||||||
|
|
||||||
// clear the AP list
|
|
||||||
var $list = $('#ap-list');
|
|
||||||
// remove old APs
|
|
||||||
$('#ap-list .AP').remove();
|
|
||||||
|
|
||||||
$list.toggleClass('hidden', !done);
|
|
||||||
$('#ap-loader').toggleClass('hidden', done);
|
|
||||||
|
|
||||||
// scan done
|
|
||||||
resp.result.APs.sort(function (a, b) {
|
|
||||||
return b.rssi - a.rssi;
|
|
||||||
}).forEach(function (ap) {
|
|
||||||
ap.enc = parseInt(ap.enc);
|
|
||||||
|
|
||||||
if (ap.enc > 4) return; // hide unsupported auths
|
|
||||||
|
|
||||||
var item = mk('div');
|
|
||||||
|
|
||||||
var $item = $(item)
|
|
||||||
.data('ssid', ap.essid)
|
|
||||||
.data('pwd', ap.enc)
|
|
||||||
.attr('tabindex', 0)
|
|
||||||
.addClass('AP');
|
|
||||||
|
|
||||||
// mark current SSID
|
|
||||||
if (ap.essid == curSSID) {
|
|
||||||
$item.addClass('selected');
|
|
||||||
}
|
|
||||||
|
|
||||||
var inner = mk('div');
|
|
||||||
$(inner).addClass('inner')
|
|
||||||
.htmlAppend('<div class="rssi">{0}</div>'.format(ap.rssi_perc))
|
|
||||||
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format($.htmlEscape(ap.essid)))
|
|
||||||
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc]));
|
|
||||||
|
|
||||||
$item.on('click', function () {
|
|
||||||
var $th = $(this);
|
|
||||||
|
|
||||||
var ssid = $th.data('ssid');
|
|
||||||
|
|
||||||
$('#conn-ssid').val(ssid);
|
|
||||||
$('#conn-passwd').val('');
|
|
||||||
|
|
||||||
if (+$th.data('pwd')) {
|
|
||||||
// this AP needs a password
|
|
||||||
Modal.show('#psk-modal');
|
|
||||||
$('#conn-passwd')[0].focus();
|
|
||||||
} else {
|
|
||||||
//Modal.show('#reset-modal');
|
|
||||||
submitPskModal(null, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
item.appendChild(inner);
|
|
||||||
$list[0].appendChild(item);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function startScanning() {
|
|
||||||
$('#ap-loader').removeClass('hidden');
|
|
||||||
$('#ap-scan').addClass('hidden');
|
|
||||||
$('#ap-loader .anim-dots').html('.');
|
|
||||||
scanAPs();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Ask the CGI what APs are visible (async) */
|
|
||||||
function scanAPs() {
|
|
||||||
$.get('http://'+_root+'<?= url('wifi_scan', true) ?>', onScan);
|
|
||||||
}
|
|
||||||
|
|
||||||
function rescan(time) {
|
|
||||||
setTimeout(scanAPs, time);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set up the WiFi page */
|
|
||||||
function wifiInit(obj) {
|
|
||||||
//var ap_json = {
|
|
||||||
// "result": {
|
|
||||||
// "inProgress": "0",
|
|
||||||
// "APs": [
|
|
||||||
// {"essid": "Chlivek", "bssid": "88:f7:c7:52:b3:99", "rssi": "204", "enc": "4", "channel": "1"},
|
|
||||||
// {"essid": "TyNikdy", "bssid": "5c:f4:ab:0d:f1:1b", "rssi": "164", "enc": "3", "channel": "1"},
|
|
||||||
// ]
|
|
||||||
// }
|
|
||||||
//};
|
|
||||||
|
|
||||||
// Hide what should be hidden in this mode
|
|
||||||
obj.mode = +obj.mode;
|
|
||||||
|
|
||||||
$('#ap-noscan').toggleClass('hidden', obj.mode != 2);
|
|
||||||
$('#ap-scan').toggleClass('hidden', obj.mode == 2);
|
|
||||||
|
|
||||||
// // scan if not AP
|
|
||||||
// if (obj.mode != 2) {
|
|
||||||
// scanAPs();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
wifiInit({mode: '%opmode%'});
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
$("#status").html(msg);
|
$("#status").html(msg);
|
||||||
|
|
||||||
if (done) {
|
if (done) {
|
||||||
// $('#backbtn').removeClass('hidden');
|
// $('#backbtn').removeClass('hidden');
|
||||||
$('.anim-dots').addClass('hidden');
|
$('.anim-dots').addClass('hidden');
|
||||||
} else {
|
} else {
|
||||||
window.setTimeout(getStatus, 1000);
|
window.setTimeout(getStatus, 1000);
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
abortTmeo = setTimeout(function () {
|
abortTmeo = setTimeout(function () {
|
||||||
xhr.abort();
|
xhr.abort();
|
||||||
$("#status").html(<?= json_encode(tr('wifi.conn.telemetry_lost')) ?>);
|
$("#status").html(<?= json_encode(tr('wifi.conn.telemetry_lost')) ?>);
|
||||||
// $('#backbtn').removeClass('hidden');
|
// $('#backbtn').removeClass('hidden');
|
||||||
$('.anim-dots').addClass('hidden');
|
$('.anim-dots').addClass('hidden');
|
||||||
}, 4000);
|
}, 4000);
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav id="botnav">
|
<nav id="botnav">
|
||||||
<a href="<?= url('cfg_wifi') ?>"><?= tr('menu.cfg_wifi') ?></a><!--
|
<a href="<?= url('cfg_wifi') ?>"><?= tr('menu.settings') ?></a><!--
|
||||||
--><a href="<?= url('help') ?>">Help</a><!--
|
--><a href="<?= url('help') ?>">Help</a><!--
|
||||||
--><a href="<?= url('about') ?>">About</a>
|
--><a href="<?= url('about') ?>">About</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@@ -5,6 +5,13 @@
|
|||||||
margin-top: dist(0);
|
margin-top: dist(0);
|
||||||
padding: dist(-1) dist(0);
|
padding: dist(-1) dist(0);
|
||||||
|
|
||||||
|
// clear floats
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
clear: both
|
||||||
|
}
|
||||||
|
|
||||||
@include media($phone) {
|
@include media($phone) {
|
||||||
margin-top: dist(-1);
|
margin-top: dist(-1);
|
||||||
}
|
}
|
||||||
@@ -22,6 +29,10 @@
|
|||||||
margin-bottom: 0 !important;
|
margin-bottom: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p:last-child {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
background-color: rgba(white, .07);
|
background-color: rgba(white, .07);
|
||||||
box-shadow: 0 0 4px black;
|
box-shadow: 0 0 4px black;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
// mobile friendly
|
// mobile friendly
|
||||||
#logo2 {
|
#logo2 {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
margin: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
|
|||||||
@@ -34,10 +34,11 @@ body.term {
|
|||||||
|
|
||||||
button {
|
button {
|
||||||
margin: 0 3px;
|
margin: 0 3px;
|
||||||
padding: 10px 0;
|
padding: 8px 5px;
|
||||||
width: 18%;
|
//width: 18%;
|
||||||
max-width: 65px;
|
min-width: 65px;
|
||||||
min-width: initial;
|
//max-width: 65px;
|
||||||
|
//min-width: initial;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: dist(-2);
|
padding: dist(-2);
|
||||||
margin-bottom: dist(-2);
|
margin-bottom: dist(-2);
|
||||||
|
margin-top: dist(-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ap-noscan {
|
#ap-noscan {
|
||||||
|
|||||||
@@ -19,4 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
#define GET_ARG(key) (httpdFindArg(connData->getArgs, key, buff, sizeof(buff)) > 0)
|
#define GET_ARG(key) (httpdFindArg(connData->getArgs, key, buff, sizeof(buff)) > 0)
|
||||||
|
|
||||||
|
#define STR_HELPER(x) #x
|
||||||
|
#define STR(x) STR_HELPER(x)
|
||||||
|
|
||||||
#endif //ESP_VT100_FIRMWARE_HELPERS_H
|
#endif //ESP_VT100_FIRMWARE_HELPERS_H
|
||||||
|
|||||||
+8
-5
@@ -8,13 +8,14 @@ Cgi/template routines for configuring non-wifi settings
|
|||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|
||||||
#define SET_REDIR_SUC "/cfg/term"
|
#define SET_REDIR_SUC "/cfg/app"
|
||||||
#define SET_REDIR_ERR SET_REDIR_SUC"?err="
|
#define SET_REDIR_ERR SET_REDIR_SUC"?err="
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Universal CGI endpoint to set Terminal params.
|
* Universal CGI endpoint to set Terminal params.
|
||||||
*/
|
*/
|
||||||
httpd_cgi_state ICACHE_FLASH_ATTR cgiAppCfgSet(HttpdConnData *connData)
|
httpd_cgi_state ICACHE_FLASH_ATTR
|
||||||
|
cgiAppCfgSetParams(HttpdConnData *connData)
|
||||||
{
|
{
|
||||||
char buff[50];
|
char buff[50];
|
||||||
|
|
||||||
@@ -49,7 +50,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiAppCfgSet(HttpdConnData *connData)
|
|||||||
redir_url += sprintf(redir_url, "term_width,");
|
redir_url += sprintf(redir_url, "term_width,");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warn("Missing height arg", buff);
|
warn("Missing height arg!");
|
||||||
// this wont happen normally when the form is used
|
// this wont happen normally when the form is used
|
||||||
redir_url += sprintf(redir_url, "term_width,term_height,");
|
redir_url += sprintf(redir_url, "term_width,term_height,");
|
||||||
}
|
}
|
||||||
@@ -115,6 +116,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiAppCfgSet(HttpdConnData *connData)
|
|||||||
// All was OK
|
// All was OK
|
||||||
info("Set app params - success, saving...");
|
info("Set app params - success, saving...");
|
||||||
|
|
||||||
|
terminal_apply_settings();
|
||||||
persist_store();
|
persist_store();
|
||||||
|
|
||||||
httpdRedirect(connData, SET_REDIR_SUC);
|
httpdRedirect(connData, SET_REDIR_SUC);
|
||||||
@@ -127,7 +129,8 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiAppCfgSet(HttpdConnData *connData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
httpd_cgi_state ICACHE_FLASH_ATTR tplAppCfg(HttpdConnData *connData, char *token, void **arg)
|
httpd_cgi_state ICACHE_FLASH_ATTR
|
||||||
|
tplAppCfg(HttpdConnData *connData, char *token, void **arg)
|
||||||
{
|
{
|
||||||
#define BUFLEN 100
|
#define BUFLEN 100
|
||||||
char buff[BUFLEN];
|
char buff[BUFLEN];
|
||||||
@@ -149,7 +152,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR tplAppCfg(HttpdConnData *connData, char *token
|
|||||||
sprintf(buff, "%d", termconf->default_bg);
|
sprintf(buff, "%d", termconf->default_bg);
|
||||||
}
|
}
|
||||||
else if (streq(token, "default_fg")) {
|
else if (streq(token, "default_fg")) {
|
||||||
sprintf(buff, "%d", termconf->default_bg);
|
sprintf(buff, "%d", termconf->default_fg);
|
||||||
}
|
}
|
||||||
else if (streq(token, "term_title")) {
|
else if (streq(token, "term_title")) {
|
||||||
strncpy_safe(buff, termconf->title, BUFLEN);
|
strncpy_safe(buff, termconf->title, BUFLEN);
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "httpd.h"
|
#include "httpd.h"
|
||||||
|
|
||||||
httpd_cgi_state cgiAppCfgSet(HttpdConnData *connData);
|
httpd_cgi_state cgiAppCfgSetParams(HttpdConnData *connData);
|
||||||
httpd_cgi_state tplAppCfg(HttpdConnData *connData, char *token, void **arg);
|
httpd_cgi_state tplAppCfg(HttpdConnData *connData, char *token, void **arg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+28
-4
@@ -5,9 +5,7 @@
|
|||||||
#include "cgi_main.h"
|
#include "cgi_main.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "user_main.h"
|
#include "user_main.h"
|
||||||
|
#include "helpers.h"
|
||||||
#define STR_HELPER(x) #x
|
|
||||||
#define STR(x) STR_HELPER(x)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main page template substitution
|
* Main page template substitution
|
||||||
@@ -28,7 +26,33 @@ httpd_cgi_state ICACHE_FLASH_ATTR tplScreen(HttpdConnData *connData, char *token
|
|||||||
const int bufsiz = 512;
|
const int bufsiz = 512;
|
||||||
char buff[bufsiz];
|
char buff[bufsiz];
|
||||||
|
|
||||||
if (streq(token, "screenData")) {
|
if (streq(token, "term_title")) {
|
||||||
|
httpdSend(connData, termconf->title, -1);
|
||||||
|
}
|
||||||
|
else if (streq(token, "btn1")) {
|
||||||
|
httpdSend(connData, termconf->btn1, -1);
|
||||||
|
}
|
||||||
|
else if (streq(token, "btn2")) {
|
||||||
|
httpdSend(connData, termconf->btn2, -1);
|
||||||
|
}
|
||||||
|
else if (streq(token, "btn3")) {
|
||||||
|
httpdSend(connData, termconf->btn3, -1);
|
||||||
|
}
|
||||||
|
else if (streq(token, "btn4")) {
|
||||||
|
httpdSend(connData, termconf->btn4, -1);
|
||||||
|
}
|
||||||
|
else if (streq(token, "btn5")) {
|
||||||
|
httpdSend(connData, termconf->btn5, -1);
|
||||||
|
}
|
||||||
|
else if (streq(token, "default_bg")) {
|
||||||
|
sprintf(buff, "%d", termconf->default_bg);
|
||||||
|
httpdSend(connData, buff, -1);
|
||||||
|
}
|
||||||
|
else if (streq(token, "default_fg")) {
|
||||||
|
sprintf(buff, "%d", termconf->default_fg);
|
||||||
|
httpdSend(connData, buff, -1);
|
||||||
|
}
|
||||||
|
else if (streq(token, "screenData")) {
|
||||||
httpd_cgi_state cont = screenSerializeToBuffer(buff, bufsiz, arg);
|
httpd_cgi_state cont = screenSerializeToBuffer(buff, bufsiz, arg);
|
||||||
httpdSend(connData, buff, -1);
|
httpdSend(connData, buff, -1);
|
||||||
return cont;
|
return cont;
|
||||||
|
|||||||
+2
-2
@@ -231,10 +231,10 @@ httpd_cgi_state ICACHE_FLASH_ATTR tplNetwork(HttpdConnData *connData, char *toke
|
|||||||
else if (streq(token, "sta_addr_ip")) {
|
else if (streq(token, "sta_addr_ip")) {
|
||||||
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->sta_addr.ip.addr));
|
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->sta_addr.ip.addr));
|
||||||
}
|
}
|
||||||
else if (streq(token, "ap_addr_mask")) {
|
else if (streq(token, "sta_addr_mask")) {
|
||||||
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->sta_addr.netmask.addr));
|
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->sta_addr.netmask.addr));
|
||||||
}
|
}
|
||||||
else if (streq(token, "ap_addr_gw")) {
|
else if (streq(token, "sta_addr_gw")) {
|
||||||
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->sta_addr.gw.addr));
|
sprintf(buff, IPSTR, GOOD_IP2STR(wificonf->sta_addr.gw.addr));
|
||||||
}
|
}
|
||||||
else if (streq(token, "sta_mac")) {
|
else if (streq(token, "sta_mac")) {
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
Cgi/template routines for configuring non-wifi settings
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <esp8266.h>
|
||||||
|
#include "cgi_persist.h"
|
||||||
|
#include "persist.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
#define SET_REDIR_SUC "/cfg/admin"
|
||||||
|
|
||||||
|
static bool ICACHE_FLASH_ATTR
|
||||||
|
verify_admin_pw(const char *pw)
|
||||||
|
{
|
||||||
|
// This is not really for security, but to prevent someone who
|
||||||
|
// shouldn't touch those settings from fucking it up.
|
||||||
|
return streq(pw, STR(ADMIN_PASSWORD)); // the PW comes from the makefile
|
||||||
|
}
|
||||||
|
|
||||||
|
httpd_cgi_state ICACHE_FLASH_ATTR
|
||||||
|
cgiPersistWriteDefaults(HttpdConnData *connData)
|
||||||
|
{
|
||||||
|
char buff[50];
|
||||||
|
|
||||||
|
if (connData->conn == NULL) {
|
||||||
|
//Connection aborted. Clean up.
|
||||||
|
return HTTPD_CGI_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// width and height must always go together so we can do max size validation
|
||||||
|
if (GET_ARG("pw")) {
|
||||||
|
dbg("Entered password for admin: %s", buff);
|
||||||
|
if (verify_admin_pw(buff)) {
|
||||||
|
dbg("pw is OK");
|
||||||
|
|
||||||
|
persist_set_as_default();
|
||||||
|
|
||||||
|
httpdRedirect(connData, SET_REDIR_SUC);
|
||||||
|
return HTTPD_CGI_DONE;
|
||||||
|
}
|
||||||
|
// if pw failed, show the same error as if it's wrong
|
||||||
|
}
|
||||||
|
|
||||||
|
httpdRedirect(connData, SET_REDIR_SUC "?err=Password"); // this will show in the "validation errors" box
|
||||||
|
return HTTPD_CGI_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
httpd_cgi_state ICACHE_FLASH_ATTR
|
||||||
|
cgiPersistRestoreDefaults(HttpdConnData *connData)
|
||||||
|
{
|
||||||
|
if (connData->conn == NULL) {
|
||||||
|
//Connection aborted. Clean up.
|
||||||
|
return HTTPD_CGI_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
persist_restore_default();
|
||||||
|
httpdRedirect(connData, SET_REDIR_SUC);
|
||||||
|
return HTTPD_CGI_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
httpd_cgi_state ICACHE_FLASH_ATTR
|
||||||
|
cgiPersistRestoreHard(HttpdConnData *connData)
|
||||||
|
{
|
||||||
|
if (connData->conn == NULL) {
|
||||||
|
//Connection aborted. Clean up.
|
||||||
|
return HTTPD_CGI_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
persist_restore_hard_default();
|
||||||
|
|
||||||
|
httpdRedirect(connData, SET_REDIR_SUC);
|
||||||
|
return HTTPD_CGI_DONE;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef CGIPERSIST_H
|
||||||
|
#define CGIPERSIST_H
|
||||||
|
|
||||||
|
#include "httpd.h"
|
||||||
|
|
||||||
|
httpd_cgi_state cgiPersistWriteDefaults(HttpdConnData *connData);
|
||||||
|
httpd_cgi_state cgiPersistRestoreDefaults(HttpdConnData *connData);
|
||||||
|
httpd_cgi_state cgiPersistRestoreHard(HttpdConnData *connData);
|
||||||
|
|
||||||
|
#endif
|
||||||
+6
-4
@@ -571,10 +571,12 @@ httpd_cgi_state ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token,
|
|||||||
else {
|
else {
|
||||||
struct ip_info info;
|
struct ip_info info;
|
||||||
wifi_get_ip_info(STATION_IF, &info);
|
wifi_get_ip_info(STATION_IF, &info);
|
||||||
sprintf(buff, "ip: "IPSTR", mask: "IPSTR", gw: "IPSTR,
|
sprintf(buff, IPSTR, GOOD_IP2STR(info.ip.addr));
|
||||||
GOOD_IP2STR(info.ip.addr),
|
|
||||||
GOOD_IP2STR(info.netmask.addr),
|
// sprintf(buff, "ip: "IPSTR", mask: "IPSTR", gw: "IPSTR,
|
||||||
GOOD_IP2STR(info.gw.addr));
|
// GOOD_IP2STR(info.ip.addr),
|
||||||
|
// GOOD_IP2STR(info.netmask.addr),
|
||||||
|
// GOOD_IP2STR(info.gw.addr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-7
@@ -11,9 +11,6 @@ PersistBlock persist;
|
|||||||
|
|
||||||
#define PERSIST_SECTOR_ID 0x3D
|
#define PERSIST_SECTOR_ID 0x3D
|
||||||
|
|
||||||
// This is used to force-erase the config area (when it's changed)
|
|
||||||
#define CHECKSUM_SALT 0x02
|
|
||||||
|
|
||||||
//region Persist and restore individual modules
|
//region Persist and restore individual modules
|
||||||
|
|
||||||
static void ICACHE_FLASH_ATTR
|
static void ICACHE_FLASH_ATTR
|
||||||
@@ -81,6 +78,11 @@ persist_load(void)
|
|||||||
{
|
{
|
||||||
info("[Persist] Loading stored settings from FLASH...");
|
info("[Persist] Loading stored settings from FLASH...");
|
||||||
|
|
||||||
|
dbg("sizeof(AppConfigBundle) = %d bytes", sizeof(AppConfigBundle));
|
||||||
|
dbg("sizeof(PersistBlock) = %d bytes", sizeof(PersistBlock));
|
||||||
|
dbg("sizeof(WiFiConfigBundle) = %d bytes", sizeof(WiFiConfigBundle));
|
||||||
|
dbg("sizeof(TerminalConfigBundle) = %d bytes", sizeof(TerminalConfigBundle));
|
||||||
|
|
||||||
bool hard_reset = false;
|
bool hard_reset = false;
|
||||||
|
|
||||||
// Try to load
|
// Try to load
|
||||||
@@ -90,15 +92,15 @@ persist_load(void)
|
|||||||
if (hard_reset ||
|
if (hard_reset ||
|
||||||
(compute_checksum(&persist.defaults) != persist.defaults.checksum) ||
|
(compute_checksum(&persist.defaults) != persist.defaults.checksum) ||
|
||||||
(compute_checksum(&persist.current) != persist.current.checksum)) {
|
(compute_checksum(&persist.current) != persist.current.checksum)) {
|
||||||
dbg("[Persist] Checksum verification: FAILED");
|
error("[Persist] Checksum verification: FAILED");
|
||||||
hard_reset = true;
|
hard_reset = true;
|
||||||
} else {
|
} else {
|
||||||
dbg("[Persist] Checksum verification: PASSED");
|
info("[Persist] Checksum verification: PASSED");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hard_reset) {
|
if (hard_reset) {
|
||||||
persist_restore_hard_default();
|
persist_restore_hard_default();
|
||||||
// this also stores them to flash and applies to modues
|
// this also stores them to flash and applies to modules
|
||||||
} else {
|
} else {
|
||||||
apply_live_settings();
|
apply_live_settings();
|
||||||
}
|
}
|
||||||
@@ -161,8 +163,8 @@ persist_set_as_default(void)
|
|||||||
{
|
{
|
||||||
info("[Persist] Storing live settings as defaults..");
|
info("[Persist] Storing live settings as defaults..");
|
||||||
|
|
||||||
|
// current -> defaults
|
||||||
memcpy(&persist.defaults, &persist.current, sizeof(AppConfigBundle));
|
memcpy(&persist.defaults, &persist.current, sizeof(AppConfigBundle));
|
||||||
|
|
||||||
persist_store();
|
persist_store();
|
||||||
|
|
||||||
info("[Persist] Default settings updated.");
|
info("[Persist] Default settings updated.");
|
||||||
|
|||||||
+19
-3
@@ -13,15 +13,31 @@
|
|||||||
#include "wifimgr.h"
|
#include "wifimgr.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
|
// Changing this could be used to force-erase the config area
|
||||||
|
// after a firmware upgrade
|
||||||
|
#define CHECKSUM_SALT 0x5F5F5F5F
|
||||||
|
|
||||||
|
/** Struct for current or default settings */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
WiFiConfigBundle wificonf;
|
WiFiConfigBundle wificonf;
|
||||||
TerminalConfigBundle termconf;
|
TerminalConfigBundle termconf;
|
||||||
// ...
|
|
||||||
// other settings here
|
// --- Space for future settings ---
|
||||||
// ...
|
// Original size: 1024
|
||||||
|
//
|
||||||
|
// The size must be appropriately reduced each time something is added,
|
||||||
|
// and boolean flags defaulting to 0 should be used to detect unpopulated
|
||||||
|
// sections that must be restored to defaults on load.
|
||||||
|
//
|
||||||
|
// This ensures user settings are not lost each time they upgrade the firmware,
|
||||||
|
// which would lead to a checksum mismatch if the structure was changed and
|
||||||
|
// it grew to a different memory area.
|
||||||
|
uint8_t filler[1024];
|
||||||
|
|
||||||
uint32_t checksum; // computed before write and tested on load. If it doesn't match, values are reset to hard defaults.
|
uint32_t checksum; // computed before write and tested on load. If it doesn't match, values are reset to hard defaults.
|
||||||
} AppConfigBundle;
|
} AppConfigBundle;
|
||||||
|
|
||||||
|
/** This is the entire data block stored in FLASH */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
AppConfigBundle defaults; // defaults are stored here
|
AppConfigBundle defaults; // defaults are stored here
|
||||||
AppConfigBundle current; // active settings adjusted by the user
|
AppConfigBundle current; // active settings adjusted by the user
|
||||||
|
|||||||
+25
-12
@@ -10,6 +10,9 @@
|
|||||||
#include "cgi_ping.h"
|
#include "cgi_ping.h"
|
||||||
#include "cgi_main.h"
|
#include "cgi_main.h"
|
||||||
#include "cgi_sockets.h"
|
#include "cgi_sockets.h"
|
||||||
|
#include "cgi_network.h"
|
||||||
|
#include "cgi_appcfg.h"
|
||||||
|
#include "cgi_persist.h"
|
||||||
|
|
||||||
#define WIFI_PROTECT 0
|
#define WIFI_PROTECT 0
|
||||||
#define WIFI_AUTH_NAME "wifi"
|
#define WIFI_AUTH_NAME "wifi"
|
||||||
@@ -26,28 +29,38 @@ HttpdBuiltInUrl routes[] = {
|
|||||||
|
|
||||||
// --- Web pages ---
|
// --- Web pages ---
|
||||||
ROUTE_TPL_FILE("/", tplScreen, "/term.tpl"),
|
ROUTE_TPL_FILE("/", tplScreen, "/term.tpl"),
|
||||||
ROUTE_TPL_FILE("/about", tplAbout, "/about.tpl"),
|
ROUTE_TPL_FILE("/about/?", tplAbout, "/about.tpl"),
|
||||||
ROUTE_FILE("/help", "/help.tpl"),
|
ROUTE_FILE("/help/?", "/help.tpl"),
|
||||||
|
|
||||||
// --- Sockets ---
|
// --- Sockets ---
|
||||||
ROUTE_WS(URL_WS_UPDATE, updateSockConnect),
|
ROUTE_WS(URL_WS_UPDATE, updateSockConnect),
|
||||||
|
|
||||||
// --- System control ---
|
// --- System control ---
|
||||||
ROUTE_CGI("/system/reset", cgiResetDevice),
|
ROUTE_CGI("/system/reset/?", cgiResetDevice),
|
||||||
ROUTE_CGI("/system/ping", cgiPing),
|
ROUTE_CGI("/system/ping/?", cgiPing),
|
||||||
|
|
||||||
// --- WiFi config ---
|
// --- WiFi config --- (TODO make this conditional and configurable)
|
||||||
#if WIFI_PROTECT
|
#if WIFI_PROTECT
|
||||||
ROUTE_AUTH("/wifi*", wifiPassFn),
|
ROUTE_AUTH("/wifi*", wifiPassFn),
|
||||||
#endif
|
#endif
|
||||||
ROUTE_REDIRECT("/wifi/", "/wifi"),
|
ROUTE_REDIRECT("/cfg/?", "/cfg/wifi"),
|
||||||
ROUTE_TPL_FILE("/wifi", tplWlan, "/wifi.tpl"),
|
|
||||||
|
|
||||||
ROUTE_CGI("/wifi/scan", cgiWiFiScan),
|
ROUTE_TPL_FILE("/cfg/wifi/?", tplWlan, "/cfg_wifi.tpl"),
|
||||||
ROUTE_CGI("/wifi/connect", cgiWiFiConnect),
|
ROUTE_FILE("/cfg/wifi/connecting/?", "/cfg_wifi_conn.tpl"),
|
||||||
ROUTE_CGI("/wifi/connstatus", cgiWiFiConnStatus),
|
ROUTE_CGI("/cfg/wifi/scan", cgiWiFiScan),
|
||||||
ROUTE_FILE("/wifi/connecting", "/wifi_conn.tpl"),
|
ROUTE_CGI("/cfg/wifi/connstatus", cgiWiFiConnStatus),
|
||||||
ROUTE_CGI("/wifi/set", cgiWiFiSetParams),
|
ROUTE_CGI("/cfg/wifi/set", cgiWiFiSetParams),
|
||||||
|
|
||||||
|
ROUTE_TPL_FILE("/cfg/network/?", tplNetwork, "/cfg_network.tpl"),
|
||||||
|
ROUTE_CGI("/cfg/network/set", cgiNetworkSetParams),
|
||||||
|
|
||||||
|
ROUTE_TPL_FILE("/cfg/app/?", tplAppCfg, "/cfg_app.tpl"),
|
||||||
|
ROUTE_CGI("/cfg/app/set", cgiAppCfgSetParams),
|
||||||
|
|
||||||
|
ROUTE_FILE("/cfg/admin/?", "/cfg_admin.tpl"),
|
||||||
|
ROUTE_CGI("/cfg/admin/write_defaults", cgiPersistWriteDefaults),
|
||||||
|
ROUTE_CGI("/cfg/admin/restore_defaults", cgiPersistRestoreDefaults),
|
||||||
|
ROUTE_CGI("/cfg/admin/restore_hard", cgiPersistRestoreHard),
|
||||||
|
|
||||||
ROUTE_FILESYSTEM(),
|
ROUTE_FILESYSTEM(),
|
||||||
ROUTE_END(),
|
ROUTE_END(),
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ void terminal_restore_defaults(void)
|
|||||||
termconf->default_fg = 7;
|
termconf->default_fg = 7;
|
||||||
termconf->width = 26;
|
termconf->width = 26;
|
||||||
termconf->height = 10;
|
termconf->height = 10;
|
||||||
sprintf(termconf->title, "ESP8266 Wireless Terminal");
|
sprintf(termconf->title, "ESPTerm");
|
||||||
sprintf(termconf->btn1, "1");
|
sprintf(termconf->btn1, "1");
|
||||||
sprintf(termconf->btn2, "2");
|
sprintf(termconf->btn2, "2");
|
||||||
sprintf(termconf->btn3, "3");
|
sprintf(termconf->btn3, "3");
|
||||||
|
|||||||
@@ -43,6 +43,11 @@ wifimgr_restore_defaults(void)
|
|||||||
IP4_ADDR(&wificonf->sta_addr.ip, 192, 168, 0, (mac[5] == 1 ? 2 : mac[5])); // avoid being the same as "default gw"
|
IP4_ADDR(&wificonf->sta_addr.ip, 192, 168, 0, (mac[5] == 1 ? 2 : mac[5])); // avoid being the same as "default gw"
|
||||||
IP4_ADDR(&wificonf->sta_addr.netmask, 255, 255, 255, 0);
|
IP4_ADDR(&wificonf->sta_addr.netmask, 255, 255, 255, 0);
|
||||||
IP4_ADDR(&wificonf->sta_addr.gw, 192, 168, 0, 1);
|
IP4_ADDR(&wificonf->sta_addr.gw, 192, 168, 0, 1);
|
||||||
|
|
||||||
|
// DEBUG ONLY - TODO remove for release
|
||||||
|
wificonf->opmode = STATION_MODE;
|
||||||
|
sprintf((char*)wificonf->sta_ssid, "Chlivek");
|
||||||
|
sprintf((char*)wificonf->sta_password, "prase chrochta");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ICACHE_FLASH_ATTR
|
static void ICACHE_FLASH_ATTR
|
||||||
|
|||||||
Reference in New Issue
Block a user