error indication via GET arg err=...

This commit is contained in:
2017-07-23 01:47:18 +02:00
parent b238390ca8
commit 3c202a1f50
13 changed files with 235 additions and 24 deletions
+7 -1
View File
@@ -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_appcfg.c
user/cgi_appcfg.h
user/cgi_ping.c user/cgi_ping.c
user/cgi_reset.c user/cgi_reset.c
user/uart_driver.c user/uart_driver.c
@@ -113,7 +115,11 @@ set(SOURCE_FILES
user/cgi_sockets.h user/cgi_sockets.h
user/ansi_parser_callbacks.c user/ansi_parser_callbacks.c
user/ansi_parser_callbacks.h user/ansi_parser_callbacks.h
user/user_main.h user/wifimgr.c user/wifimgr.h user/persist.c user/persist.h) user/user_main.h
user/wifimgr.c
user/wifimgr.h
user/persist.c
user/persist.h)
include_directories(include) include_directories(include)
include_directories(user) include_directories(user)
+11 -8
View File
@@ -579,17 +579,12 @@ ul > * {
.NotifyMsg { .NotifyMsg {
position: fixed; position: fixed;
bottom: 2.61792rem; top: 1.618rem;
right: 2.61792rem;
padding: 0.61805rem 1rem; padding: 0.61805rem 1rem;
left: 50%;
-webkit-transform: translate(-50%, 0);
-moz-transform: translate(-50%, 0);
-ms-transform: translate(-50%, 0);
-o-transform: translate(-50%, 0);
transform: translate(-50%, 0);
-webkit-font-smoothing: subpixel-antialiased; -webkit-font-smoothing: subpixel-antialiased;
-webkit-transform: translateZ(0) scale(1, 1); -webkit-transform: translateZ(0) scale(1, 1);
background: #37a349; background: #3887d0;
color: white; color: white;
text-shadow: 0 0 2px black; text-shadow: 0 0 2px black;
box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.6); box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.6);
@@ -740,6 +735,12 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele
input[type="number"] { input[type="number"] {
width: 125px; } width: 125px; }
.Box.errors .list {
color: crimson;
font-weight: bold; }
.Box.errors .lead {
color: white; }
form .Row { form .Row {
vertical-align: middle; vertical-align: middle;
margin: 12px auto; margin: 12px auto;
@@ -794,6 +795,8 @@ form .Row {
user-select: none; user-select: none;
white-space: nowrap; white-space: nowrap;
word-wrap: normal; } word-wrap: normal; }
form .Row label.error {
color: crimson; }
form .Row input[type="range"] { form .Row input[type="range"] {
width: 200px; } width: 200px; }
@media screen and (max-width: 544px) { @media screen and (max-width: 544px) {
+51
View File
@@ -852,6 +852,38 @@ function jsp() {
window.Modal = modal; window.Modal = modal;
})(); })();
(function (nt) {
var sel = '#notif';
var hideTmeo1; // timeout to start hiding (transition)
var hideTmeo2; // timeout to add the hidden class
nt.show = function (message, timeout) {
$(sel).html(message);
Modal.show(sel);
clearTimeout(hideTmeo1);
clearTimeout(hideTmeo2);
if (undef(timeout)) timeout = 2500;
hideTmeo1 = setTimeout(nt.hide, timeout);
};
nt.hide = function () {
var $m = $(sel);
$m.removeClass('visible');
hideTmeo2 = setTimeout(function () {
$m.addClass('hidden');
}, 250); // transition time
};
nt.init = function() {
$(sel).on('click', function() {
nt.hide(this);
});
};
})(window.Notify = {});
/** Global generic init */ /** Global generic init */
$.ready(function () { $.ready(function () {
// Checkbox UI (checkbox CSS and hidden input with int value) // Checkbox UI (checkbox CSS and hidden input with int value)
@@ -915,7 +947,26 @@ $.ready(function () {
e.preventDefault(); e.preventDefault();
}); });
var errAt = location.search.indexOf('err=');
if (errAt !== -1 && qs('.Box.errors')) {
var errs = location.search.substr(errAt+4).split(',');
var hres = [];
errs.forEach(function(er) {
var lbl = qs('label[for="'+er+'"]');
if (lbl) {
lbl.classList.add('error');
hres.push(lbl.childNodes[0].textContent.trim().replace(/: ?$/, ''));
} else {
hres.push(er);
}
});
qs('.Box.errors .list').innerHTML = hres.join(', ');
qs('.Box.errors').classList.remove('hidden');
}
Modal.init(); Modal.init();
Notify.init();
}); });
$._loader = function(vis) { $._loader = function(vis) {
+19
View File
@@ -61,7 +61,26 @@ $.ready(function () {
e.preventDefault(); e.preventDefault();
}); });
var errAt = location.search.indexOf('err=');
if (errAt !== -1 && qs('.Box.errors')) {
var errs = location.search.substr(errAt+4).split(',');
var hres = [];
errs.forEach(function(er) {
var lbl = qs('label[for="'+er+'"]');
if (lbl) {
lbl.classList.add('error');
hres.push(lbl.childNodes[0].textContent.trim().replace(/: ?$/, ''));
} else {
hres.push(er);
}
});
qs('.Box.errors .list').innerHTML = hres.join(', ');
qs('.Box.errors').classList.remove('hidden');
}
Modal.init(); Modal.init();
Notify.init();
}); });
$._loader = function(vis) { $._loader = function(vis) {
+6 -4
View File
@@ -13,11 +13,12 @@ return [
'title.term' => 'Terminal', 'title.term' => 'Terminal',
'net.ap' => 'Access Point DHCP Config', 'net.ap' => 'DHCP Server',
'net.sta' => 'Client IP Config', 'net.sta' => 'DHCP Client',
'net.explain_sta' => ' 'net.explain_sta' => '
Those settings affect the built-in DHCP client. Switching it off Those settings affect the built-in DHCP client used for
connecting to an external network. Switching DHCP (dynamic IP) off
makes ESPTerm use the configured static IP. Please double-check makes ESPTerm use the configured static IP. Please double-check
those settings before submitting, setting them incorrectly may those settings before submitting, setting them incorrectly may
make it hard to access ESPTerm via the external network.', make it hard to access ESPTerm via the external network.',
@@ -33,7 +34,7 @@ return [
'net.ap_addr_ip' => 'Own IP address', 'net.ap_addr_ip' => 'Own IP address',
'net.ap_addr_mask' => 'Subnet mask', 'net.ap_addr_mask' => 'Subnet mask',
'net.sta_dhcp_enable' => 'Enable DHCP', 'net.sta_dhcp_enable' => 'Use dynamic IP',
'net.sta_addr_ip' => 'ESPTerm static IP', 'net.sta_addr_ip' => 'ESPTerm static IP',
'net.sta_addr_mask' => 'Subnet mask', 'net.sta_addr_mask' => 'Subnet mask',
'net.sta_addr_gw' => 'Gateway IP', 'net.sta_addr_gw' => 'Gateway IP',
@@ -77,4 +78,5 @@ return [
'yes' => 'Yes', 'yes' => 'Yes',
'no' => 'No', 'no' => 'No',
'confirm' => 'OK', 'confirm' => 'OK',
'form_errors' => 'Validation errors for:',
]; ];
+1
View File
@@ -5,5 +5,6 @@ echo "Packing js..."
cat jssrc/chibi.js \ cat jssrc/chibi.js \
jssrc/utils.js \ jssrc/utils.js \
jssrc/modal.js \ jssrc/modal.js \
jssrc/notif.js \
jssrc/appcommon.js \ jssrc/appcommon.js \
jssrc/term.js > js/app.js jssrc/term.js > js/app.js
+5
View File
@@ -23,4 +23,9 @@ if (strpos($_GET['BODYCLASS'], 'cfg') !== false) {
<img src="/img/loader.gif" alt="Loading…" id="loader"> <img src="/img/loader.gif" alt="Loading…" id="loader">
<?php if ($cfg): ?> <?php if ($cfg): ?>
<h1><?= tr('menu.' . $_GET['page']) ?></h1> <h1><?= tr('menu.' . $_GET['page']) ?></h1>
<div class="Box errors hidden">
<span class="lead"><?= tr('form_errors') ?></span>&nbsp;<span class="list"></span>
</div>
<?php endif; ?> <?php endif; ?>
+4
View File
@@ -1,5 +1,9 @@
<div class="NotifyMsg hidden" id="notif"></div>
</div> </div>
</div> </div>
</body> </body>
</html> </html>
+15
View File
@@ -9,6 +9,17 @@ input[type="number"] {
width: $form-field-w/2; width: $form-field-w/2;
} }
.Box.errors {
.list {
color: crimson;
font-weight: bold;
}
.lead {
color: white;
}
}
form .Row { form .Row {
vertical-align: middle; vertical-align: middle;
margin: 12px auto; margin: 12px auto;
@@ -89,6 +100,10 @@ form .Row {
@include nowrap; @include nowrap;
} }
label.error {
color: crimson;
}
//.checkbox-wrap { //.checkbox-wrap {
// display: inline-block; // display: inline-block;
// width: $form-label-w; // width: $form-label-w;
+5 -4
View File
@@ -43,17 +43,18 @@
// "toast" // "toast"
.NotifyMsg { .NotifyMsg {
position: fixed; position: fixed;
bottom: dist(2); top: dist(1);
right: dist(2);
padding: dist(-1) dist(0); padding: dist(-1) dist(0);
// center horizontally // center horizontally
left: 50%; //left: 50%;
@include translate(-50%,0); //@include translate(-50%,0);
// hack to remove blur in chrome // hack to remove blur in chrome
-webkit-font-smoothing: subpixel-antialiased; -webkit-font-smoothing: subpixel-antialiased;
-webkit-transform: translateZ(0) scale(1.0, 1.0); -webkit-transform: translateZ(0) scale(1.0, 1.0);
background: #37a349; background: #3887d0;
&.error { &.error {
background: #d03e42; background: #d03e42;
} }
+97
View File
@@ -0,0 +1,97 @@
/*
Cgi/template routines for configuring non-wifi settings
*/
#include <esp8266.h>
#include "cgi_wifi.h"
#include "wifimgr.h"
#include "persist.h"
// strcpy that adds 0 at the end of the buffer. Returns void.
#define strncpy_safe(dst, src, n) do { strncpy((char *)(dst), (char *)(src), (n)); (dst)[(n)-1]=0; } while (0)
/**
* Universal CGI endpoint to set WiFi params.
* Note that some may cause a (delayed) restart.
*/
httpd_cgi_state ICACHE_FLASH_ATTR cgiAppCfgSet(HttpdConnData *connData)
{
static ETSTimer timer;
char buff[50];
#define REDIR_BASE_URL "/wifi?err="
char redir_url_buf[300];
char *redir_url = redir_url_buf;
redir_url += sprintf(redir_url, REDIR_BASE_URL);
// we'll test if anything was printed by looking for \0 in failed_keys_buf
if (connData->conn == NULL) {
//Connection aborted. Clean up.
return HTTPD_CGI_DONE;
}
#define GET_ARG(key) (httpdFindArg(connData->getArgs, key, buff, sizeof(buff)) > 0)
// TODO
if (GET_ARG("opmode")) {
dbg("Setting WiFi opmode to: %s", buff);
int mode = atoi(buff);
if (mode > NULL_MODE && mode < MAX_MODE) {
wificonf->opmode = (WIFI_MODE) mode;
} else {
warn("Bad opmode value \"%s\"", buff);
redir_url += sprintf(redir_url, "opmode,");
}
}
if (redir_url_buf[strlen(REDIR_BASE_URL)] == 0) {
// All was OK
info("Set WiFi params - success, applying in 1000 ms");
// Settings are applied only if all was OK
//
// This is so that options that consist of multiple keys sent together are not applied
// only partially if set wrong, which could lead to eg. user losing access and having
// to reset to defaults.
persist_store();
// Delayed settings apply, so the response page has a chance to load.
// If user connects via the Station IF, they may not even notice the connection reset.
os_timer_disarm(&timer);
os_timer_setfn(&timer, applyWifiSettingsLaterCb, NULL);
os_timer_arm(&timer, 1000, false);
httpdRedirect(connData, "/wifi");
} else {
warn("Some WiFi settings did not validate, asking for correction");
// Some errors, appended to the URL as ?err=
httpdRedirect(connData, redir_url_buf);
}
return HTTPD_CGI_DONE;
}
//Template code for the WLAN page.
httpd_cgi_state ICACHE_FLASH_ATTR tplAppCfg(HttpdConnData *connData, char *token, void **arg)
{
char buff[100];
int x;
int connectStatus;
if (token == NULL) {
// We're done
return HTTPD_CGI_DONE;
}
strcpy(buff, ""); // fallback
// TODO
if (streq(token, "opmode_name")) {
strcpy(buff, opmode2str(wificonf->opmode));
}
httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE;
}
+9
View File
@@ -0,0 +1,9 @@
#ifndef CGIAPPCFG_H
#define CGIAPPCFG_H
#include "httpd.h"
httpd_cgi_state cgiAppCfgSet(HttpdConnData *connData);
httpd_cgi_state tplAppCfg(HttpdConnData *connData, char *token, void **arg);
#endif
+5 -7
View File
@@ -13,17 +13,13 @@ Cgi/template routines for the /wifi url.
* File adapted and improved by Ondřej Hruška <ondra@ondrovo.com> * File adapted and improved by Ondřej Hruška <ondra@ondrovo.com>
*/ */
// TODO convert to work with WiFi Manager
// TODO make changes write to wificonf and apply when a different CGI is run (/wifi/apply or something)
// TODO (connection will trigger this immediately, with some delayto show the connecting page. Then polling cna proceed as usual)
#include <esp8266.h> #include <esp8266.h>
#include "cgi_wifi.h" #include "cgi_wifi.h"
#include "wifimgr.h" #include "wifimgr.h"
#include "persist.h" #include "persist.h"
// strcpy that adds 0 at the end of the buffer. Returns void. // strcpy that adds 0 at the end of the buffer. Returns void.
#define strncpy_safe(dst, src, n) do { strncpy((char *)(dst), (char *)(src), (n)); dst[(n)-1]=0; } while (0) #define strncpy_safe(dst, src, n) do { strncpy((char *)(dst), (char *)(src), (n)); (dst)[(n)-1]=0; } while (0)
/** WiFi access point data */ /** WiFi access point data */
typedef struct { typedef struct {
@@ -419,9 +415,11 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
char buff[50]; char buff[50];
#define REDIR_BASE_URL "/wifi?err="
char redir_url_buf[300]; char redir_url_buf[300];
char *redir_url = redir_url_buf; char *redir_url = redir_url_buf;
redir_url += sprintf(redir_url, "/wifi?err="); redir_url += sprintf(redir_url, REDIR_BASE_URL);
// we'll test if anything was printed by looking for \0 in failed_keys_buf // we'll test if anything was printed by looking for \0 in failed_keys_buf
if (connData->conn == NULL) { if (connData->conn == NULL) {
@@ -707,7 +705,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
} }
} }
if (redir_url_buf[10] == 0) { if (redir_url_buf[strlen(REDIR_BASE_URL)] == 0) {
// All was OK // All was OK
info("Set WiFi params - success, applying in 1000 ms"); info("Set WiFi params - success, applying in 1000 ms");