WiFi sections hiding, STA auto enable on scan click, Terminal colors preview, better explanations, CONFIGURABLE UART

pull/111/merge
Ondřej Hruška 7 years ago
parent e42407ad62
commit 76167b8014
  1. 13
      CMakeLists.txt
  2. 10
      html_orig/_debug_replacements.php
  3. 14
      html_orig/_pages.php
  4. 41
      html_orig/css/app.css
  5. 1
      html_orig/dump_js_lang.php
  6. BIN
      html_orig/fontello/fontello.zip
  7. 50
      html_orig/js/app.js
  8. 6
      html_orig/jssrc/appcommon.js
  9. 2
      html_orig/jssrc/chibi.js
  10. 3
      html_orig/jssrc/lang.js
  11. 39
      html_orig/jssrc/wifi.js
  12. 97
      html_orig/lang/en.php
  13. 34
      html_orig/pages/cfg_admin.php
  14. 29
      html_orig/pages/cfg_network.php
  15. 90
      html_orig/pages/cfg_system.php
  16. 59
      html_orig/pages/cfg_term.php
  17. 63
      html_orig/pages/cfg_wifi.php
  18. 6
      html_orig/sass/_fontello.scss
  19. 8
      html_orig/sass/form/_form_elements.scss
  20. 11
      html_orig/sass/form/_form_layout.scss
  21. 15
      html_orig/sass/layout/_box.scss
  22. 10
      html_orig/sass/layout/_content.scss
  23. 1
      html_orig/sass/pages/_wifi.scss
  24. 0
      include/uart_hw.h-
  25. 9
      user/cgi_appcfg.h
  26. 20
      user/cgi_ping.c
  27. 11
      user/cgi_ping.h
  28. 31
      user/cgi_reset.c
  29. 9
      user/cgi_reset.h
  30. 164
      user/cgi_system.c
  31. 12
      user/cgi_system.h
  32. 10
      user/cgi_term_cfg.c
  33. 9
      user/cgi_term_cfg.h
  34. 11
      user/cgi_wifi.c
  35. 18
      user/persist.c
  36. 18
      user/persist.h
  37. 18
      user/routes.c
  38. 30
      user/screen.h
  39. 29
      user/serial.c
  40. 3
      user/serial.h
  41. 24
      user/syscfg.c
  42. 33
      user/syscfg.h
  43. 22
      user/uart_handler.c
  44. 4
      user/uart_handler.h
  45. 20
      user/user_main.c
  46. 2
      user/wifimgr.c
  47. 26
      user/wifimgr.h

@ -86,7 +86,6 @@ set(SOURCE_FILES
esp_iot_sdk_v1.5.2/include/json/jsonparse.h
esp_iot_sdk_v1.5.2/include/json/json.h
include/uart_hw.h
include/user_config.h
include/ets_sys_extra.h
user/io.c
@ -97,10 +96,9 @@ set(SOURCE_FILES
user/cgi_persist.h
user/cgi_network.c
user/cgi_network.h
user/cgi_appcfg.c
user/cgi_appcfg.h
user/cgi_ping.c
user/cgi_reset.c
user/cgi_term_cfg.c
user/cgi_term_cfg.h
user/cgi_system.c
user/uart_driver.c
user/uart_handler.c
user/ansi_parser.c
@ -123,7 +121,10 @@ set(SOURCE_FILES
user/wifimgr.c
user/wifimgr.h
user/persist.c
user/persist.h include/helpers.h)
user/persist.h
include/helpers.h
user/syscfg.c
user/syscfg.h)
include_directories(include)
include_directories(user)

@ -21,19 +21,21 @@ return [
"screen": "70 t259"
}',
'%opmode%' => '2',
'%sta_enable%' => '0',
'%ap_enable%' => '1',
'%tpw%' => '60',
'%ap_channel%' => '7',
'%ap_ssid%' => 'ESP-123456',
'%ap_password%' => 'Passw0rd!',
'%ap_hidden%' => '0',
'%sta_ssid%' => 'Chlivek',
'%sta_password%' => 'windows XP is The Best',
'%sta_active_ip%' => '1.2.3.4',
'%sta_active_ssid%' => 'Chlivek',
'%sta_enable%' => '1',
'%opmode%' => '3',
'%vers_fw%' => '1.2.3',
'%date%' => date('Y-m-d'),
'%time%' => date('G:i'),
@ -59,4 +61,8 @@ return [
'%term_height%' => '10',
'%default_bg%' => '0',
'%default_fg%' => '7',
'%uart_baud%' => 115200,
'%uart_stopbits%' => 1,
'%uart_parity%' => 2,
];

@ -27,13 +27,15 @@ pg('wifi_scan', 'api', '', '/cfg/wifi/scan');
pg('cfg_network', 'cfg', 'network', '/cfg/network');
pg('network_set', 'api', '', '/cfg/network/set');
pg('cfg_app', 'cfg', 'terminal', '/cfg/app');
pg('app_set', 'api', '', '/cfg/app/set');
pg('cfg_term', 'cfg', 'terminal', '/cfg/term');
pg('term_set', 'api', '', '/cfg/term/set');
pg('cfg_admin', 'cfg', 'persist', '/cfg/admin');
pg('write_defaults', 'api', '', '/cfg/admin/write_defaults');
pg('restore_defaults', 'api', '', '/cfg/admin/restore_defaults');
pg('restore_hard', 'api', '', '/cfg/admin/restore_hard');
pg('cfg_system', 'cfg', 'configure', '/cfg/system');
pg('system_set', 'api', '', '/cfg/system/set');
pg('write_defaults', 'api', '', '/cfg/system/write_defaults');
pg('restore_defaults', 'api', '', '/cfg/system/restore_defaults');
pg('restore_hard', 'api', '', '/cfg/system/restore_hard');
pg('help', 'cfg page-help', 'help', '/help');
pg('about', 'cfg page-about', 'about', '/about');

File diff suppressed because one or more lines are too long

@ -7,6 +7,7 @@ require_once __DIR__ . '/base.php';
$selected = [
'wifi.connected_ip_is',
'wifi.not_conn',
'wifi.enter_passwd',
];
$out = [];

Binary file not shown.

@ -488,7 +488,7 @@
// Multiple select
for (j = 0; j < value.length; j += 1) {
elm[i].selected = '';
if (elm[i].value === value[j]) {
if (elm[i].value === ""+value[j]) {
elm[i].selected = 'selected';
break;
}
@ -1007,10 +1007,17 @@ $.ready(function () {
$._loader = function(vis) {
$('#loader').toggleClass('show', vis);
};
$.ready(function() {
setTimeout(function() {
$('#content').addClass('load');
}, 1);
});
// Generated from PHP locale file
var _tr = {
"wifi.connected_ip_is": "Connected, IP is ",
"wifi.not_conn": "Not connected."
"wifi.not_conn": "Not connected.",
"wifi.enter_passwd": "Enter password for \":ssid:\""
};
function tr(key) { return _tr[key] || '?'+key+'?'; }
@ -1039,21 +1046,6 @@ function tr(key) { return _tr[key] || '?'+key+'?'; }
$('#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 = {
@ -1123,19 +1115,18 @@ function tr(key) { return _tr[key] || '?'+key+'?'; }
$item.on('click', function () {
var $th = $(this);
var ssid = $th.data('ssid');
$('#conn-ssid').val(ssid);
$('#conn-passwd').val('');
var conn_ssid = $th.data('ssid');
var conn_pass = '';
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);
conn_pass = prompt(tr("wifi.enter_passwd").replace(":ssid:", conn_ssid));
if (!conn_pass) return;
}
$('#sta_password').val(conn_pass);
$('#sta_ssid').val(conn_ssid);
selectSta(conn_ssid, conn_pass, '');
});
@ -1148,6 +1139,7 @@ function tr(key) { return _tr[key] || '?'+key+'?'; }
$('#ap-loader').removeClass('hidden');
$('#ap-scan').addClass('hidden');
$('#ap-loader .anim-dots').html('.');
scanAPs();
}
@ -1162,12 +1154,6 @@ function tr(key) { return _tr[key] || '?'+key+'?'; }
/** 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');

@ -108,3 +108,9 @@ $.ready(function () {
$._loader = function(vis) {
$('#loader').toggleClass('show', vis);
};
$.ready(function() {
setTimeout(function() {
$('#content').addClass('load');
}, 1);
});

@ -488,7 +488,7 @@
// Multiple select
for (j = 0; j < value.length; j += 1) {
elm[i].selected = '';
if (elm[i].value === value[j]) {
if (elm[i].value === ""+value[j]) {
elm[i].selected = 'selected';
break;
}

@ -1,7 +1,8 @@
// Generated from PHP locale file
var _tr = {
"wifi.connected_ip_is": "Connected, IP is ",
"wifi.not_conn": "Not connected."
"wifi.not_conn": "Not connected.",
"wifi.enter_passwd": "Enter password for \":ssid:\""
};
function tr(key) { return _tr[key] || '?'+key+'?'; }

@ -23,21 +23,6 @@
$('#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 = {
@ -107,19 +92,18 @@
$item.on('click', function () {
var $th = $(this);
var ssid = $th.data('ssid');
$('#conn-ssid').val(ssid);
$('#conn-passwd').val('');
var conn_ssid = $th.data('ssid');
var conn_pass = '';
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);
conn_pass = prompt(tr("wifi.enter_passwd").replace(":ssid:", conn_ssid));
if (!conn_pass) return;
}
$('#sta_password').val(conn_pass);
$('#sta_ssid').val(conn_ssid);
selectSta(conn_ssid, conn_pass, '');
});
@ -132,6 +116,7 @@
$('#ap-loader').removeClass('hidden');
$('#ap-scan').addClass('hidden');
$('#ap-loader .anim-dots').html('.');
scanAPs();
}
@ -146,12 +131,6 @@
/** 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');

@ -4,13 +4,13 @@ return [
'appname' => 'ESPTerm',
'menu.cfg_wifi' => 'WiFi Settings',
'menu.cfg_network' => 'Network Configuration',
'menu.cfg_app' => 'Terminal Settings',
'menu.cfg_network' => 'Network Settings',
'menu.cfg_term' => 'Terminal Settings',
'menu.about' => 'About ESPTerm',
'menu.help' => 'Quick Reference',
'menu.term' => 'Back to Terminal',
'menu.cfg_admin' => 'Reset & Restore',
'menu.cfg_wifi_conn' => 'Connecting to External Network',
'menu.cfg_system' => 'System Settings',
'menu.cfg_wifi_conn' => 'Connecting to Network',
'menu.settings' => 'Settings',
@ -22,30 +22,31 @@ return [
'net.ap_mac' => 'AP MAC',
'net.details' => 'MAC addresses',
'app.defaults' => 'Initial settings',
'app.explain_initials' => '
Those are the initial settings used after ESPTerm restarts, and they
will also be applied immediately after you submit this form.
They can be subsequently changed by ESC commands, but those changes
aren\'t persistent and will be lost when the device powers off.',
'app.term_title' => 'Header text',
'app.term_width' => 'Screen width',
'app.term_height' => 'Screen height',
'app.default_fg' => 'Base text color',
'app.default_bg' => 'Base background',
'app.btn1' => 'Button 1 text',
'app.btn2' => 'Button 2 text',
'app.btn3' => 'Button 3 text',
'app.btn4' => 'Button 4 text',
'app.btn5' => 'Button 5 text',
'term.defaults' => 'Initial Settings',
'term.explain_initials' => '
Those are the initial settings used after ESPTerm powers on. They
will also be applied immediately after you submit this form.',
'term.example' => 'Color settings example',
'term.term_title' => 'Header text',
'term.term_width' => 'Screen width',
'term.term_height' => 'Screen height',
'term.default_fg' => 'Text color',
'term.default_bg' => 'Background',
'term.btn1' => 'Button 1 text',
'term.btn2' => 'Button 2 text',
'term.btn3' => 'Button 3 text',
'term.btn4' => 'Button 4 text',
'term.btn5' => 'Button 5 text',
// terminal color labels
'color.0' => 'Black',
'color.1' => 'Dark Red',
'color.2' => 'Dark Green',
'color.3' => 'Dim Yellow',
'color.4' => 'Deep Blue',
'color.5' => 'Dark Violet',
'color.5' => 'Deep Purple',
'color.6' => 'Dark Cyan',
'color.7' => 'Silver',
'color.8' => 'Gray',
@ -53,21 +54,15 @@ return [
'color.10' => 'Light Green',
'color.11' => 'Light Yellow',
'color.12' => 'Light Blue',
'color.13' => 'Light Violet',
'color.13' => 'Light Purple',
'color.14' => 'Light Cyan',
'color.15' => 'White',
'net.explain_sta' => '
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
those settings before submitting, setting them incorrectly may
make it hard to access ESPTerm via the external network.',
Switch off Dynamic IP to configure the static IP address.',
'net.explain_ap' => '
Those settings affect the built-in DHCP server in AP mode.
Please double-check those settings before submitting, setting them
incorrectly may render ESPTerm inaccessible via the AP.',
Those settings affect the built-in DHCP server in AP mode.',
'net.ap_dhcp_time' => 'Lease time',
'net.ap_dhcp_start' => 'Pool start IP',
@ -81,7 +76,7 @@ return [
'net.sta_addr_gw' => 'Gateway IP',
'wifi.ap' => 'Built-in Access Point',
'wifi.sta' => 'Connect to External Network',
'wifi.sta' => 'Join Existing Network',
'wifi.enable' => 'Enabled',
'wifi.tpw' => 'Transmit power',
@ -99,9 +94,11 @@ return [
'wifi.sta_password' => 'Password:',
'wifi.scanning' => 'Scanning',
'wifi.scan_now' => 'Start scanning!',
'wifi.cant_scan_no_sta' => 'Can\'t scan with Client mode disabled.',
'wifi.scan_now' => 'Click here to start scanning!',
'wifi.cant_scan_no_sta' => 'Click here to enable client mode and start scanning!',
'wifi.select_ssid' => 'Available networks:',
'wifi.enter_passwd' => 'Enter password for ":ssid:"',
'wifi.sta_explain' => 'After selecting a network, press Apply to connect.',
'wifi.conn.status' => 'Status:',
'wifi.conn.back_to_config' => 'Back to WiFi config',
@ -113,22 +110,36 @@ return [
'wifi.conn.working' => "Connecting to selected AP",
'wifi.conn.fail' => "Connection failed, check settings & try again. Cause: ",
'admin.confirm_restore' => 'Restore all settings to their default values?',
'admin.confirm_restore_hard' =>
'system.save_restore' => 'Save & Restore',
'system.confirm_restore' => 'Restore all settings to their default values?',
'system.confirm_restore_hard' =>
'Restore to firmware default settings? This will reset ' .
'all active settings and switch to AP mode with the default SSID.',
'admin.confirm_store_defaults' =>
'system.confirm_store_defaults' =>
'Enter admin password to confirm you want to store the current settings as defaults.',
'admin.password' => 'Admin password:',
'admin.restore_defaults' => 'Reset to default settings',
'admin.write_defaults' => 'Save current settings as default',
'admin.restore_hard' => 'Reset to firmware default settings',
'admin.explain' => '
'system.password' => 'Admin password:',
'system.restore_defaults' => 'Reset to default settings',
'system.write_defaults' => 'Save current settings as default',
'system.restore_hard' => 'Reset to firmware default settings',
'system.explain_persist' => '
ESPTerm contains two persistent memory banks, one for default and
one for active settings. Active settings can be stored as defaults
by the administrator. Use the following button to revert all
active settings to their stored default values.
',
'system.uart' => 'Serial Port',
'system.explain_uart' => '
This form controls the primary UART. The debug port is fixed at 115200 baud, one stop-bit and no parity.
',
'uart.baud' => 'Baud rate',
'uart.parity' => 'Parity',
'uart.parity.none' => 'None',
'uart.parity.odd' => 'Odd',
'uart.parity.even' => 'Even',
'uart.stop_bits' => 'Stop-bits',
'uart.stop_bits.one' => 'One',
'uart.stop_bits.one_and_half' => 'One and half',
'uart.stop_bits.two' => 'Two',
'apply' => 'Apply!',
'enabled' => 'Enabled',

@ -1,34 +0,0 @@
<div class="Box">
<div class="Row explain">
<?= tr('admin.explain') ?>
</div>
<div class="Row buttons">
<a class="button icn-restore"
onclick="return confirm('<?= tr('admin.confirm_restore') ?>');"
href="<?= e(url('restore_defaults')) ?>"
>
<?= tr('admin.restore_defaults') ?>
</a>
</div>
<div class="Row buttons">
<a onclick="writeDefaults(); return false;" href="#"><?= tr('admin.write_defaults') ?></a>
</div>
<div class="Row buttons">
<a onclick="return confirm('<?= tr('admin.confirm_restore_hard') ?>');"
href="<?= e(url('restore_hard')) ?>"
>
<?= tr('admin.restore_hard') ?>
</a>
</div>
</div>
<script>
function writeDefaults() {
var pw = prompt('<?= tr('admin.confirm_store_defaults') ?>');
if (!pw) return;
location.href = <?=json_encode(url('write_defaults')) ?> + '?pw=' + pw;
}
</script>

@ -12,7 +12,7 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
<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%">
<input type="hidden" id="sta_dhcp_enable" name="sta_dhcp_enable" value="%sta_dhcp_enable%">
</div>
<div class="Row x-static">
@ -43,9 +43,13 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
</div>
<div class="Row">
<label for="ap_dhcp_time"><?= tr('net.ap_dhcp_time') ?><span class="mq-phone">&nbsp;(min)</span></label>
<input type="number" step=1 min=1 max=2880 name="ap_dhcp_time" id="ap_dhcp_time" value="%ap_dhcp_time%" required>
<span class="mq-no-phone">&nbsp;(min)</span>
<label for="ap_addr_mask"><?= tr('net.ap_addr_mask') ?></label>
<input type="text" name="ap_addr_mask" id="ap_addr_mask" value="%ap_addr_mask%" <?=$ipmask?> required>
</div>
<div class="Row">
<label for="ap_addr_ip"><?= tr('net.ap_addr_ip') ?></label>
<input type="text" name="ap_addr_ip" id="ap_addr_ip" value="%ap_addr_ip%" <?=$ipmask?> required>
</div>
<div class="Row">
@ -59,13 +63,9 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
</div>
<div class="Row">
<label for="ap_addr_ip"><?= tr('net.ap_addr_ip') ?></label>
<input type="text" name="ap_addr_ip" id="ap_addr_ip" value="%ap_addr_ip%" <?=$ipmask?> required>
</div>
<div class="Row">
<label for="ap_addr_mask"><?= tr('net.ap_addr_mask') ?></label>
<input type="text" name="ap_addr_mask" id="ap_addr_mask" value="%ap_addr_mask%" <?=$ipmask?> required>
<label for="ap_dhcp_time"><?= tr('net.ap_dhcp_time') ?><span class="mq-phone">&nbsp;(min)</span></label>
<input type="number" step=1 min=1 max=2880 name="ap_dhcp_time" id="ap_dhcp_time" value="%ap_dhcp_time%" required>
<span class="mq-no-phone">&nbsp;min</span>
</div>
<div class="Row buttons">
@ -86,10 +86,13 @@ $ipmask='pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"';
<script>
function updateStaticDisp() {
$('.x-static').toggleClass('hidden', $('#sta_dhcp_enable').val());
var sttc = !parseInt($('#sta_dhcp_enable').val());
$('.x-static').toggleClass('hidden', !sttc);
}
$('.x-static-toggle').on('click', function() {
updateStaticDisp();
setTimeout(function() {
updateStaticDisp();
}, 0)
});
updateStaticDisp();
</script>

@ -0,0 +1,90 @@
<div class="Box str mobcol">
<h2 tabindex=0><?= tr('system.save_restore') ?></h2>
<div class="Row explain nomargintop">
<?= tr('system.explain_persist') ?>
</div>
<div class="Row buttons2">
<a class="button icn-restore"
onclick="return confirm('<?= tr('system.confirm_restore') ?>');"
href="<?= e(url('restore_defaults')) ?>">
<?= tr('system.restore_defaults') ?>
</a>
</div>
<div class="Row buttons2">
<a onclick="writeDefaults(); return false;" href="#"><?= tr('system.write_defaults') ?></a>
</div>
<div class="Row buttons2">
<a onclick="return confirm('<?= tr('system.confirm_restore_hard') ?>');"
href="<?= e(url('restore_hard')) ?>">
<?= tr('system.restore_hard') ?>
</a>
</div>
</div>
<form class="Box str mobcol" action="<?= e(url('system_set')) ?>" method="GET" id="form-1">
<h2 tabindex=0><?= tr('system.uart') ?></h2>
<div class="Row explain">
<?= tr('system.explain_uart') ?>
</div>
<div class="Row">
<label for="uart_baud"><?= tr('uart.baud') ?><span class="mq-phone">&nbsp;(bps)</span></label>
<select name="uart_baud" id="uart_baud" class="short">
<?php foreach([
300, 600, 1200, 2400, 4800, 9600, 19200, 38400,
57600, 74880, 115200, 230400, 460800, 921600, 1843200, 3686400,
] as $b):
?><option value="<?=$b?>"><?= number_format($b, 0, ',', '.') ?></option>
<?php endforeach; ?>
</select>
<span class="mq-no-phone">&nbsp;bps</span>
</div>
<div class="Row">
<label for="uart_parity"><?= tr('uart.parity') ?></label>
<select name="uart_parity" id="uart_parity" class="short">
<?php foreach([
2 => tr('uart.parity.none'),
1 => tr('uart.parity.odd'),
0 => tr('uart.parity.even'),
] as $k => $label):
?><option value="<?=$k?>"><?=$label?></option>
<?php endforeach; ?>
</select>
</div>
<div class="Row">
<label for="uart_stopbits"><?= tr('uart.stop_bits') ?></label>
<select name="uart_stopbits" id="uart_stopbits" class="short">
<?php foreach([
1 => tr('uart.stop_bits.one'),
2 => tr('uart.stop_bits.one_and_half'),
3 => tr('uart.stop_bits.two'),
] as $k => $label):
?><option value="<?=$k?>"><?=$label?></option>
<?php endforeach; ?>
</select>
</div>
<div class="Row buttons">
<a class="button icn-ok" href="#" onclick="qs('#form-1').submit()"><?= tr('apply') ?></a>
</div>
</form>
<script>
function writeDefaults() {
var pw = prompt('<?= tr('system.confirm_store_defaults') ?>');
if (!pw) return;
location.href = <?=json_encode(url('write_defaults')) ?> + '?pw=' + pw;
}
$('#uart_baud').val(%uart_baud%);
$('#uart_parity').val(%uart_parity%);
$('#uart_stopbits').val(%uart_stopbits%);
</script>

@ -1,67 +1,69 @@
<form class="Box mobopen str" action="<?= e(url('app_set')) ?>" method="GET" id='form-1'>
<h2><?= tr('app.defaults') ?></h2>
<form class="Box mobopen str" action="<?= e(url('term_set')) ?>" method="GET" id='form-1'>
<h2><?= tr('term.defaults') ?></h2>
<div class="Row explain">
<?= tr('app.explain_initials') ?>
<?= tr('term.explain_initials') ?>
</div>
<div class="Row">
<label for="term_width"><?= tr('app.term_width') ?></label>
<input type="number" step=1 min=1 max=255 name="term_width" id="term_width" value="%term_width%" required>
</div>
<div class="Row">
<label for="term_height"><?= tr('app.term_height') ?></label>
<input type="number" step=1 min=1 max=255 name="term_height" id="term_height" value="%term_height%" required>
<div style="font-family:monospace; font-size: 16pt; padding: 5px;" id="color-example"><?= tr("term.example") ?></div>
</div>
<div class="Row">
<label for="default_fg"><?= tr("app.default_fg") ?></label>
<select name="default_fg" id="default_fg">
<label for="default_fg"><?= tr("term.default_fg") ?></label>
<select name="default_fg" id="default_fg" class="short" onchange="showColor()">
<?php for($i=0; $i<16; $i++): ?>
<option value="<?=$i?>"><?= tr("color.$i") ?></option>
<?php endfor; ?>
</select>
<script>qs('#default_fg').selectedIndex = %default_fg%;</script>
</div>
<div class="Row">
<label for="default_bg"><?= tr("app.default_bg") ?></label>
<select name="default_bg" id="default_bg">
<label for="default_bg"><?= tr("term.default_bg") ?></label>
<select name="default_bg" id="default_bg" class="short" onchange="showColor()">
<?php for($i=0; $i<16; $i++): ?>
<option value="<?=$i?>"><?= tr("color.$i") ?></option>
<?php endfor; ?>
</select>
<script>qs('#default_bg').selectedIndex = %default_bg%;</script>
</div>
<div class="Row">
<label for="term_title"><?= tr('app.term_title') ?></label>
<label for="term_width"><?= tr('term.term_width') ?></label>
<input type="number" step=1 min=1 max=255 name="term_width" id="term_width" value="%term_width%" required>
</div>
<div class="Row">
<label for="term_height"><?= tr('term.term_height') ?></label>
<input type="number" step=1 min=1 max=255 name="term_height" id="term_height" value="%term_height%" required>
</div>
<div class="Row">
<label for="term_title"><?= tr('term.term_title') ?></label>
<input type="text" name="term_title" id="term_title" value="%term_title%" required>
</div>
<div class="Row">
<label for="btn1"><?= tr("app.btn1") ?></label>
<label for="btn1"><?= tr("term.btn1") ?></label>
<input class="short" type="text" name="btn1" id="btn1" value="%btn1%">
</div>
<div class="Row">
<label for="btn2"><?= tr("app.btn2") ?></label>
<label for="btn2"><?= tr("term.btn2") ?></label>
<input class="short" type="text" name="btn2" id="btn2" value="%btn2%">
</div>
<div class="Row">
<label for="btn3"><?= tr("app.btn3") ?></label>
<label for="btn3"><?= tr("term.btn3") ?></label>
<input class="short" type="text" name="btn3" id="btn3" value="%btn3%">
</div>
<div class="Row">
<label for="btn4"><?= tr("app.btn4") ?></label>
<label for="btn4"><?= tr("term.btn4") ?></label>
<input class="short" type="text" name="btn4" id="btn4" value="%btn4%">
</div>
<div class="Row">
<label for="btn5"><?= tr("app.btn5") ?></label>
<label for="btn5"><?= tr("term.btn5") ?></label>
<input class="short" type="text" name="btn5" id="btn5" value="%btn5%">
</div>
@ -69,3 +71,16 @@
<a class="button icn-ok" href="#" onclick="qs('#form-1').submit()"><?= tr('apply') ?></a>
</div>
</form>
<script>
$('#default_fg').val(%default_fg%);
$('#default_bg').val(%default_bg%);
function showColor() {
var ex = qs('#color-example');
ex.className = '';
ex.classList.add('fg'+$('#default_fg').val());
ex.classList.add('bg'+$('#default_bg').val());
}
showColor();
</script>

@ -1,28 +1,28 @@
<form class="Box str mobcol" action="<?= e(url('wifi_set')) ?>" method="GET" id="form-1">
<h2 tabindex=0><?= tr('wifi.ap') ?></h2>
<div class="Row checkbox">
<div class="Row checkbox x-ap-toggle">
<label><?= tr('wifi.enable') ?></label><!--
--><span class="box" tabindex=0></span>
<input type="hidden" name="ap_enable" value="%ap_enable%">
<input type="hidden" id="ap_enabled" name="ap_enable" value="%ap_enable%">
</div>
<div class="Row">
<div class="Row x-ap-on">
<label for="ap_ssid"><?= tr('wifi.ap_ssid') ?></label>
<input type="text" name="ap_ssid" id="ap_ssid" value="%ap_ssid%" required>
</div>
<div class="Row">
<div class="Row x-ap-on">
<label for="ap_password"><?= tr('wifi.ap_password') ?></label>
<input type="text" name="ap_password" id="ap_password" value="%ap_password%">
</div>
<div class="Row">
<div class="Row x-ap-on">
<label for="ap_channel"><?= tr('wifi.ap_channel') ?></label>
<input type="number" name="ap_channel" id="ap_channel" min=1 max=14 value="%ap_channel%" required>
</div>
<div class="Row range">
<div class="Row range x-ap-on">
<label for="tpw">
<?= tr('wifi.tpw') ?>
<span class="display x-disp1 mq-phone"></span>
@ -31,7 +31,7 @@
<span class="display x-disp2 mq-no-phone"></span>
</div>
<div class="Row checkbox">
<div class="Row checkbox x-ap-on">
<label><?= tr('wifi.ap_hidden') ?></label><!--
--><span class="box" tabindex=0></span>
<input type="hidden" name="ap_hidden" value="%ap_hidden%">
@ -45,16 +45,21 @@
<form class="Box str mobcol" action="<?= e(url('wifi_set')) ?>" method="GET" id="form-2">
<h2 tabindex=0><?= tr('wifi.sta') ?></h2>
<div class="Row checkbox">
<div class="Row checkbox x-sta-toggle">
<label><?= tr('wifi.enable') ?></label><!--
--><span class="box" tabindex=0></span>
<input type="hidden" name="sta_enable" value="%sta_enable%">
<input type="hidden" id="sta_enabled" name="sta_enable" value="%sta_enable%">
</div>
<div class="Row explain nomargintop x-sta-on">
<span class="spacer"></span>
<?= tr("wifi.sta_explain") ?>
</div>
<input type="hidden" name="sta_ssid" id="sta_ssid" value="">
<input type="hidden" name="sta_password" id="sta_password" value="">
<div class="Row sta-info">
<div class="Row sta-info x-sta-on">
<label><?= tr('wifi.sta_info') ?></label>
<div class="AP-preview hidden" id="sta-nw">
<div class="wrap">
@ -72,11 +77,10 @@
</div>
</div>
<div id="ap-box">
<div id="ap-box" class="x-sta-on">
<label><?= tr('wifi.select_ssid') ?></label>
<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-noscan" class="hidden"><?= tr('wifi.cant_scan_no_sta') ?></div>
<div id="ap-list" class="hidden"></div>
</div>
@ -85,24 +89,35 @@
</div>
</form>
<div class="Modal hidden" id="psk-modal">
<div class="Dialog">
<form id="conn-form" onsubmit="submitPskModal(); return false;">
<input type="hidden" id="conn-ssid"><!--
--><label for="conn-passwd"><?= tr('wifi.sta_password') ?></label><!--
--><input type="text" id="conn-passwd"><!--
--><input type="submit" value="<?= tr('confirm') ?>">
</form>
</div>
</div>
<script>
WiFi.scan_url = '<?= url('wifi_scan', true) ?>';
WiFi.init({
mode: '%opmode%',
sta_ssid: '%sta_ssid%',
sta_password: '%sta_password%',
sta_active_ip: '%sta_active_ip%',
sta_active_ssid: '%sta_active_ssid%',
});
function updateApDisp() {
var a = !!parseInt($('#ap_enabled').val());
$('.x-ap-on').toggleClass('hidden', !a);
}
$('.x-ap-toggle').on('click', function() {
setTimeout(function() {
updateApDisp();
}, 0)
});
function updateStaDisp() {
var a = !!parseInt($('#sta_enabled').val());
$('.x-sta-on').toggleClass('hidden', !a);
}
$('.x-sta-toggle').on('click', function() {
setTimeout(function() {
updateStaDisp();
}, 0)
});
updateApDisp();
updateStaDisp();
</script>

File diff suppressed because one or more lines are too long

@ -1,5 +1,13 @@
@import "buttons";
#{$all-text-inputs}, select, label.select-wrap {
width: $form-field-w;
}
input[type="number"], input.short, select.short {
width: $form-field-w/2;
}
#{$all-text-inputs}, select {
border: 0 none;
border-bottom: 2px solid $c-form-highlight;

@ -1,14 +1,6 @@
// Unified Form wrapper
form { @include naked(); }
#{$all-text-inputs}, select, label.select-wrap {
width: $form-field-w;
}
input[type="number"], input.short {
width: $form-field-w/2;
}
.Box.errors {
.list {
color: crimson;
@ -45,7 +37,8 @@ input[type="number"], input.short {
}
}
&.buttons {
// buttons2 is the same style, but different selector for use in the admin page
&.buttons, &.buttons2 {
margin: 16px auto;
input, .button {
margin-right: dist(-1);

@ -79,9 +79,19 @@
.Row.explain {
max-width: 600px; margin-left: 0;
line-height: 1.2;
@include media($phone) {
margin-top: 60px;
}
&.nomargintop {
margin-top: 12px !important;
}
&.padleft {
}
}
&.mobopen .Row.explain {
margin-top: 12px; // default from .Row
@ -97,11 +107,12 @@
h2 {
position: relative;
cursor: pointer;
padding-right: 1.3rem;
padding: 2px 1.3rem 2px 5px;
margin: 0 -5px 0 -5px;
&::after {
position: absolute;
right: 0;
right: 4px;
content: '';
top:50%;

@ -48,3 +48,13 @@
color: $c-form-label-fg;
}
}
#content {
// fade in effect
opacity: 0;
transition: opacity 0.15s ease-in;
}
#content.load {
opacity: 1;
}

@ -19,6 +19,7 @@
padding: dist(-2);
margin-bottom: dist(-2);
margin-top: dist(-2);
font-size: 110%;
}
#ap-noscan {

@ -1,9 +0,0 @@
#ifndef CGIAPPCFG_H
#define CGIAPPCFG_H
#include "httpd.h"
httpd_cgi_state cgiAppCfgSetParams(HttpdConnData *connData);
httpd_cgi_state tplAppCfg(HttpdConnData *connData, char *token, void **arg);
#endif

@ -1,20 +0,0 @@
#include <esp8266.h>
#include <httpd.h>
#include "cgi_ping.h"
httpd_cgi_state ICACHE_FLASH_ATTR cgiPing(HttpdConnData *connData)
{
if (connData->conn==NULL) {
//Connection aborted. Clean up.
return HTTPD_CGI_DONE;
}
httpdStartResponse(connData, 200);
httpdHeader(connData, "Content-Type", "text/plain");
httpdEndHeaders(connData);
httpdSend(connData, "pong\n", -1);
return HTTPD_CGI_DONE;
}

@ -1,11 +0,0 @@
#ifndef CGI_PING_H
#define CGI_PING_H
#include <esp8266.h>
#include <httpd.h>
// this is used by the UI to check if server is already restarted and working again.
httpd_cgi_state cgiPing(HttpdConnData *connData);
#endif // CGI_PING_H

@ -1,31 +0,0 @@
#include <esp8266.h>
#include <httpd.h>
#include "cgi_reset.h"
static ETSTimer tmr;
static void ICACHE_FLASH_ATTR tmrCb(void *arg)
{
system_restart();
}
httpd_cgi_state ICACHE_FLASH_ATTR cgiResetDevice(HttpdConnData *connData)
{
if (connData->conn==NULL) {
//Connection aborted. Clean up.
return HTTPD_CGI_DONE;
}
httpdStartResponse(connData, 200);
httpdHeader(connData, "Content-Type", "text/plain");
httpdEndHeaders(connData);
os_timer_disarm(&tmr);
os_timer_setfn(&tmr, tmrCb, NULL);
os_timer_arm(&tmr, 100, false);
httpdSend(connData, "system reset\n", -1);
return HTTPD_CGI_DONE;
}

@ -1,9 +0,0 @@
#ifndef CGI_RESET_H
#define CGI_RESET_H
#include <esp8266.h>
#include <httpd.h>
httpd_cgi_state cgiResetDevice(HttpdConnData *connData);
#endif // CGI_RESET_H

@ -0,0 +1,164 @@
#include <esp8266.h>
#include <httpd.h>
#include <helpers.h>
#include "cgi_system.h"
#include "persist.h"
#include "syscfg.h"
#include "uart_driver.h"
#define SET_REDIR_SUC "/cfg/system"
#define SET_REDIR_ERR SET_REDIR_SUC"?err="
static ETSTimer tmr;
static void ICACHE_FLASH_ATTR tmrCb(void *arg)
{
system_restart();
}
httpd_cgi_state ICACHE_FLASH_ATTR cgiResetDevice(HttpdConnData *connData)
{
if (connData->conn==NULL) {
//Connection aborted. Clean up.
return HTTPD_CGI_DONE;
}
httpdStartResponse(connData, 200);
httpdHeader(connData, "Content-Type", "text/plain");
httpdEndHeaders(connData);
os_timer_disarm(&tmr);
os_timer_setfn(&tmr, tmrCb, NULL);
os_timer_arm(&tmr, 100, false);
httpdSend(connData, "system reset\n", -1);
return HTTPD_CGI_DONE;
}
httpd_cgi_state ICACHE_FLASH_ATTR cgiPing(HttpdConnData *connData)
{
if (connData->conn==NULL) {
//Connection aborted. Clean up.
return HTTPD_CGI_DONE;
}
httpdStartResponse(connData, 200);
httpdHeader(connData, "Content-Type", "text/plain");
httpdEndHeaders(connData);
httpdSend(connData, "pong\n", -1);
return HTTPD_CGI_DONE;
}
/**
* Universal CGI endpoint to set Terminal params.
*/
httpd_cgi_state ICACHE_FLASH_ATTR
cgiSystemCfgSetParams(HttpdConnData *connData)
{
char buff[50];
char redir_url_buf[300];
char *redir_url = redir_url_buf;
redir_url += sprintf(redir_url, SET_REDIR_ERR);
// 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;
}
if (GET_ARG("uart_baud")) {
dbg("Baud rate: %s", buff);
int baud = atoi(buff);
if (baud == BIT_RATE_300 ||
baud == BIT_RATE_600 ||
baud == BIT_RATE_1200 ||
baud == BIT_RATE_2400 ||
baud == BIT_RATE_4800 ||
baud == BIT_RATE_9600 ||
baud == BIT_RATE_19200 ||
baud == BIT_RATE_38400 ||
baud == BIT_RATE_57600 ||
baud == BIT_RATE_74880 ||
baud == BIT_RATE_115200 ||
baud == BIT_RATE_230400 ||
baud == BIT_RATE_460800 ||
baud == BIT_RATE_921600 ||
baud == BIT_RATE_1843200 ||
baud == BIT_RATE_3686400) {
sysconf->uart_baudrate = (u32) baud;
} else {
warn("Bad baud rate %s", buff);
redir_url += sprintf(redir_url, "uart_baud,");
}
}
if (GET_ARG("uart_parity")) {
dbg("Parity: %s", buff);
int parity = atoi(buff);
if (parity >= 0 && parity <= 2) {
sysconf->uart_parity = (UartParityMode) parity;
} else {
warn("Bad parity %s", buff);
redir_url += sprintf(redir_url, "uart_parity,");
}
}
if (GET_ARG("uart_stopbits")) {
dbg("Stop bits: %s", buff);
int stopbits = atoi(buff);
if (stopbits >= 1 && stopbits <= 3) {
sysconf->uart_stopbits = (UartStopBitsNum) stopbits;
} else {
warn("Bad stopbits %s", buff);
redir_url += sprintf(redir_url, "uart_stopbits,");
}
}
if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) {
// All was OK
info("Set system params - success, saving...");
sysconf_apply_settings();
persist_store();
httpdRedirect(connData, SET_REDIR_SUC);
} else {
warn("Some settings did not validate, asking for correction");
// Some errors, appended to the URL as ?err=
httpdRedirect(connData, redir_url_buf);
}
return HTTPD_CGI_DONE;
}
httpd_cgi_state ICACHE_FLASH_ATTR
tplSystemCfg(HttpdConnData *connData, char *token, void **arg)
{
#define BUFLEN 100
char buff[BUFLEN];
if (token == NULL) {
// We're done
return HTTPD_CGI_DONE;
}
strcpy(buff, ""); // fallback
if (streq(token, "uart_baud")) {
sprintf(buff, "%d", sysconf->uart_baudrate);
}
else if (streq(token, "uart_parity")) {
sprintf(buff, "%d", sysconf->uart_parity);
}
else if (streq(token, "uart_stopbits")) {
sprintf(buff, "%d", sysconf->uart_stopbits);
}
httpdSend(connData, buff, -1);
return HTTPD_CGI_DONE;
}

@ -0,0 +1,12 @@
#ifndef CGI_PING_H
#define CGI_PING_H
#include <esp8266.h>
#include <httpd.h>
httpd_cgi_state cgiPing(HttpdConnData *connData);
httpd_cgi_state cgiResetDevice(HttpdConnData *connData);
httpd_cgi_state cgiSystemCfgSetParams(HttpdConnData *connData);
httpd_cgi_state tplSystemCfg(HttpdConnData *connData, char *token, void **arg);
#endif // CGI_PING_H

@ -3,19 +3,19 @@ Cgi/template routines for configuring non-wifi settings
*/
#include <esp8266.h>
#include "cgi_appcfg.h"
#include "cgi_term_cfg.h"
#include "persist.h"
#include "screen.h"
#include "helpers.h"
#define SET_REDIR_SUC "/cfg/app"
#define SET_REDIR_SUC "/cfg/term"
#define SET_REDIR_ERR SET_REDIR_SUC"?err="
/**
* Universal CGI endpoint to set Terminal params.
*/
httpd_cgi_state ICACHE_FLASH_ATTR
cgiAppCfgSetParams(HttpdConnData *connData)
cgiTermCfgSetParams(HttpdConnData *connData)
{
char buff[50];
@ -114,7 +114,7 @@ cgiAppCfgSetParams(HttpdConnData *connData)
if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) {
// All was OK
info("Set app params - success, saving...");
info("Set term params - success, saving...");
terminal_apply_settings();
persist_store();
@ -130,7 +130,7 @@ cgiAppCfgSetParams(HttpdConnData *connData)
httpd_cgi_state ICACHE_FLASH_ATTR
tplAppCfg(HttpdConnData *connData, char *token, void **arg)
tplTermCfg(HttpdConnData *connData, char *token, void **arg)
{
#define BUFLEN 100
char buff[BUFLEN];

@ -0,0 +1,9 @@
#ifndef CGIAPPCFG_H
#define CGIAPPCFG_H
#include "httpd.h"
httpd_cgi_state cgiTermCfgSetParams(HttpdConnData *connData);
httpd_cgi_state tplTermCfg(HttpdConnData *connData, char *token, void **arg);
#endif

@ -183,9 +183,8 @@ static void ICACHE_FLASH_ATTR wifiStartScan(void)
}
/**
* This CGI is called from the bit of AJAX-code in wifi.tpl. It will initiate a
* scan for access points and if available will return the result of an earlier scan.
* The result is embedded in a bit of JSON parsed by the javascript in wifi.tpl.
* Start a scan and return a result of an earlier scan, if available.
* The STA is switched ON if disabled.
*/
httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData)
{
@ -193,6 +192,12 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData)
int len;
char buff[256];
// auto-turn on STA
if ((wificonf->opmode & STATION_MODE) == 0) {
wificonf->opmode |= STATION_MODE;
wifimgr_apply_settings();
}
// 2nd and following runs of the function via MORE:
if (!cgiWifiAps.scanInProgress && pos != 0) {
// Fill in json code for an access point

@ -19,6 +19,7 @@ apply_live_settings(void)
dbg("[Persist] Applying live settings...");
terminal_apply_settings();
wifimgr_apply_settings();
sysconf_apply_settings();
// ...
}
@ -27,6 +28,7 @@ restore_live_settings_to_hard_defaults(void)
{
wifimgr_restore_defaults();
terminal_restore_defaults();
sysconf_restore_defaults();
// ...
}
@ -41,7 +43,7 @@ restore_live_settings_to_hard_defaults(void)
static uint32_t ICACHE_FLASH_ATTR
calculateCRC32(const uint8_t *data, size_t length)
{
uint32_t crc = 0xffffffff;
uint32_t crc = 0xffffffff + CHECKSUM_SALT;
while (length--) {
uint8_t c = *data++;
for (uint32_t i = 0x80; i > 0; i >>= 1) {
@ -67,7 +69,8 @@ calculateCRC32(const uint8_t *data, size_t length)
static uint32_t ICACHE_FLASH_ATTR
compute_checksum(AppConfigBundle *bundle)
{
return calculateCRC32((uint8_t *) bundle, sizeof(AppConfigBundle) - 4) ^ CHECKSUM_SALT;
// this should be the bundle without the checksum
return calculateCRC32((uint8_t *) bundle, sizeof(AppConfigBundle) - 4);
}
/**
@ -78,10 +81,13 @@ persist_load(void)
{
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));
dbg("sizeof(AppConfigBundle) = %d bytes", sizeof(AppConfigBundle));
dbg("> sizeof(WiFiConfigBundle) = %d bytes", sizeof(WiFiConfigBundle));
dbg("> sizeof(TerminalConfigBundle) = %d bytes", sizeof(TerminalConfigBundle));
dbg("> sizeof(SystemConfigBundle) = %d bytes", sizeof(SystemConfigBundle));
dbg("> sizeof(checksum) = %d bytes", sizeof(uint32_t));
dbg("> filler = %d bytes",
sizeof(AppConfigBundle) - (sizeof(WiFiConfigBundle) + sizeof(TerminalConfigBundle) + sizeof(SystemConfigBundle)));
bool hard_reset = false;

@ -12,19 +12,21 @@
#include "wifimgr.h"
#include "screen.h"
#include "syscfg.h"
// Changing this could be used to force-erase the config area
// after a firmware upgrade
#define CHECKSUM_SALT 0x5F5F5F5F
#define CHECKSUM_SALT 1
#define APPCONF_SIZE 2048
/** Struct for current or default settings */
typedef struct {
typedef struct { // the entire block should be 1024 bytes long (for compatibility across upgrades)
WiFiConfigBundle wificonf;
TerminalConfigBundle termconf;
SystemConfigBundle sysconf;
// --- 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.
@ -32,7 +34,13 @@ typedef struct {
// 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];
uint8_t filler[
APPCONF_SIZE
- sizeof(uint32_t) // checksum
- sizeof(WiFiConfigBundle)
- sizeof(TerminalConfigBundle)
- sizeof(SystemConfigBundle)
];
uint32_t checksum; // computed before write and tested on load. If it doesn't match, values are reset to hard defaults.
} AppConfigBundle;

@ -6,12 +6,11 @@
#include "routes.h"
#include "cgi_wifi.h"
#include "cgi_reset.h"
#include "cgi_ping.h"
#include "cgi_system.h"
#include "cgi_main.h"
#include "cgi_sockets.h"
#include "cgi_network.h"
#include "cgi_appcfg.h"
#include "cgi_term_cfg.h"
#include "cgi_persist.h"
#define WIFI_PROTECT 0
@ -54,13 +53,14 @@ HttpdBuiltInUrl routes[] = {
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_TPL_FILE("/cfg/term/?", tplTermCfg, "/cfg_term.tpl"),
ROUTE_CGI("/cfg/term/set", cgiTermCfgSetParams),
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_TPL_FILE("/cfg/system/?", tplSystemCfg, "/cfg_system.tpl"),
ROUTE_CGI("/cfg/system/set", cgiSystemCfgSetParams),
ROUTE_CGI("/cfg/system/write_defaults", cgiPersistWriteDefaults),
ROUTE_CGI("/cfg/system/restore_defaults", cgiPersistRestoreDefaults),
ROUTE_CGI("/cfg/system/restore_hard", cgiPersistRestoreHard),
ROUTE_FILESYSTEM(),
ROUTE_END(),

@ -34,17 +34,35 @@
*
*/
// Size designed for the wifi config structure
// Must be constant to avoid corrupting user config after upgrade
#define TERMCONF_SIZE 200
#define TERM_BTN_LEN 10
#define TERM_TITLE_LEN 64
typedef struct {
u32 width;
u32 height;
u8 default_bg;
u8 default_fg;
char title[64];
char btn1[10];
char btn2[10];
char btn3[10];
char btn4[10];
char btn5[10];
char title[TERM_TITLE_LEN];
char btn1[TERM_BTN_LEN];
char btn2[TERM_BTN_LEN];
char btn3[TERM_BTN_LEN];
char btn4[TERM_BTN_LEN];
char btn5[TERM_BTN_LEN];
u8 _filler[
TERMCONF_SIZE
- 4
- 4
- 1
- 1
- TERM_TITLE_LEN
- TERM_BTN_LEN * 5
];
} TerminalConfigBundle;
// Live config

@ -2,21 +2,38 @@
#include "uart_driver.h"
#include "uart_handler.h"
#include "ansi_parser.h"
// Here the bitrates are defined
#define UART0_BAUD BIT_RATE_115200
#define UART1_BAUD BIT_RATE_115200
#include "syscfg.h"
/**
* Init the serial ports
*/
void ICACHE_FLASH_ATTR serialInit(void)
void ICACHE_FLASH_ATTR serialInitBase(void)
{
UART_Init(UART0_BAUD, UART1_BAUD);
UART_Init();
// debug port
UART_SetParity(UART1, PARITY_NONE);
UART_SetStopBits(UART1, ONE_STOP_BIT);
UART_SetBaudrate(UART1, BIT_RATE_115200);
UART_SetPrintPort(UART1);
UART_SetupAsyncReceiver();
}
/**
* Init the serial ports
*/
void ICACHE_FLASH_ATTR serialInit(void)
{
UART_SetParity(UART0, (UartParityMode) sysconf->uart_parity);
UART_SetStopBits(UART0, (UartStopBitsNum) sysconf->uart_stopbits);
UART_SetBaudrate(UART0, sysconf->uart_baudrate);
info("COM SERIAL: %d baud, %s parity, %s stopbit(s)",
sysconf->uart_baudrate,
(sysconf->uart_parity == PARITY_NONE ? "NONE" : (sysconf->uart_parity == PARITY_ODD ? "ODD" : "EVEN")),
(sysconf->uart_stopbits == ONE_STOP_BIT ? "1" : (sysconf->uart_stopbits == ONE_HALF_STOP_BIT ? "1.5" : "2"))
);
}
/**
* Handle a byte received from UART.
* Might do some buffering here maybe

@ -1,6 +1,9 @@
#ifndef SERIAL_H
#define SERIAL_H
/** Initial uart init (before sysconf is loaded) */
void serialInitBase(void);
/** Init the uarts */
void serialInit(void);

@ -0,0 +1,24 @@
//
// Created by MightyPork on 2017/07/29.
//
#include "syscfg.h"
#include "persist.h"
#include "uart_driver.h"
#include "serial.h"
SystemConfigBundle * const sysconf = &persist.current.sysconf;
void ICACHE_FLASH_ATTR
sysconf_apply_settings(void)
{
serialInit();
}
void ICACHE_FLASH_ATTR
sysconf_restore_defaults(void)
{
sysconf->uart_parity = PARITY_NONE;
sysconf->uart_baudrate = BIT_RATE_115200;
sysconf->uart_stopbits = ONE_STOP_BIT;
}

@ -0,0 +1,33 @@
//
// Created by MightyPork on 2017/07/29.
//
#ifndef ESP_VT100_FIRMWARE_SYSCFG_H
#define ESP_VT100_FIRMWARE_SYSCFG_H
#include <esp8266.h>
// Size designed for the wifi config structure
// Must be constant to avoid corrupting user config after upgrade
#define SYSCONF_SIZE 200
typedef struct {
u32 uart_baudrate;
u8 uart_parity;
u8 uart_stopbits;
u8 _filler[
SYSCONF_SIZE
- 4
- 1
- 1
];
} SystemConfigBundle;
extern SystemConfigBundle * const sysconf;
void sysconf_apply_settings(void);
void sysconf_restore_defaults(void);
#endif //ESP_VT100_FIRMWARE_SYSCFG_H

@ -32,22 +32,8 @@ void ICACHE_FLASH_ATTR clear_rxtx(int uart_no)
}
/**
* @brief Configure UART 115200-8-N-1
* @param uart_no
*/
static void ICACHE_FLASH_ATTR my_uart_init(UARTn uart_no, uint32 baud)
{
UART_SetParity(uart_no, PARITY_NONE);
UART_SetStopBits(uart_no, ONE_STOP_BIT);
UART_SetWordLength(uart_no, EIGHT_BITS);
UART_SetBaudrate(uart_no, baud);
UART_ResetFifo(uart_no);
}
/** Configure basic UART func and pins */
void ICACHE_FLASH_ATTR UART_Init(uint32_t baud0, uint32_t baud1)
void ICACHE_FLASH_ATTR UART_Init(void)
{
// U0TXD
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
@ -60,8 +46,10 @@ void ICACHE_FLASH_ATTR UART_Init(uint32_t baud0, uint32_t baud1)
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
// Configure the UART peripherals
my_uart_init(UART0, baud0); // main
my_uart_init(UART1, baud1); // debug (output only)
UART_SetWordLength(UART0, EIGHT_BITS); // main
UART_ResetFifo(UART0);
UART_SetWordLength(UART1, EIGHT_BITS); // debug (output only)
UART_ResetFifo(UART1);
}
/** Configure Rx on UART0 */

@ -12,8 +12,8 @@
#include <esp8266.h>
/** Configure UART periphs and enable pins */
void UART_Init(uint32_t baud0, uint32_t baud1);
/** Configure UART periphs and enable pins - does not set baud rate, parity and stopbits */
void UART_Init(void);
/** Configure async Rx on UART0 */
void UART_SetupAsyncReceiver(void);

@ -86,12 +86,12 @@ void ICACHE_FLASH_ATTR user_init(void)
static ETSTimer userStartTimer;
static ETSTimer prHeapTimer;
serialInit();
serialInitBase();
// Prevent WiFi starting and connecting by default
// let wifi manager handle it
wifi_station_set_auto_connect(false);
wifi_set_opmode(NULL_MODE); // save to flash if changed - this might avoid the current spike on startup?
wifi_set_opmode(NULL_MODE); // saves to flash if changed - this might avoid the current spike on startup?
printf("\r\n");
banner("====== ESP8266 Remote Terminal ======");
@ -126,30 +126,16 @@ void ICACHE_FLASH_ATTR user_init(void)
static void user_start(void *unused)
{
// Change AP name if AI-THINKER found (means un-initialized device)
// struct softap_config apconf;
// wifi_softap_get_config(&apconf);
// if (strstarts((char *) apconf.ssid, "AI-THINKER")) {
// warn("Un-initialized device, performing factory reset.");
// apars_handle_OSC_FactoryReset();
// return;
// }
// Load and apply stored settings, or defaults if stored settings are invalid
persist_load();
// Captive portal (DNS redirector)
captdnsInit();
// Server
httpdInit(routes, 80);
// The terminal screen
screen_init();
// Print the CANCEL character to indicate the module has restarted
// Critically important for client application if any kind of screen persistence / content re-use is needed
UART_WriteChar(UART0, 24, UART_TIMEOUT_US); // 0x18 - 24 - CAN
info("Listening on UART0, 115200-8-N-1!");
}
// ---- unused funcs removed from sdk to save space ---

@ -19,7 +19,7 @@ wifimgr_restore_defaults(void)
u8 mac[6];
wifi_get_macaddr(SOFTAP_IF, mac);
wificonf->opmode = SOFTAP_MODE;
wificonf->opmode = STATIONAP_MODE; // Client+AP, so we can scan without having to enable Station
wificonf->tpw = 20;
wificonf->ap_channel = 1;
sprintf((char *) wificonf->ap_ssid, "TERM-%02X%02X%02X", mac[3], mac[4], mac[5]);

@ -13,6 +13,10 @@
#define SSID_LEN 32
#define PASSWORD_LEN 64
// Size designed for the wifi config structure
// Must be constant to avoid corrupting user config after upgrade
#define WIFICONF_SIZE 340
/**
* A structure holding all configured WiFi parameters
* and the active state.
@ -37,8 +41,28 @@ typedef struct {
u8 sta_ssid[SSID_LEN];
u8 sta_password[PASSWORD_LEN];
bool sta_dhcp_enable;
struct ip_info sta_addr;
u8 _filler[
WIFICONF_SIZE
- 1
- 1
- 1
- SSID_LEN
- PASSWORD_LEN
- 1
- 2
- sizeof(struct dhcps_lease)
- sizeof(struct ip_info)
- SSID_LEN
- PASSWORD_LEN
- 1
- sizeof(struct ip_info)
- 8 // padding?
];
} WiFiConfigBundle;
typedef struct {

Loading…
Cancel
Save