Compare commits

..
Author SHA1 Message Date
MightyPork c5670c09bb update frontend ref 2017-10-08 12:57:36 +02:00
MightyPork 4e74d1cd79 updated front-end ref 2017-10-08 12:54:26 +02:00
MightyPork 4c8360dbb5 Merge remote-tracking branch 'origin/work' 2017-10-08 12:35:21 +02:00
MightyPork c0adc253b4 add cgi for setting background image 2017-10-08 12:34:50 +02:00
MightyPork be3e06aac1 version bump 2017-10-08 11:21:11 +02:00
MightyPork 992c927490 Merge remote-tracking branch 'origin/work' 2017-10-08 11:16:44 +02:00
MightyPork ef3b02e68c added new chars to cp 1 2017-10-07 00:46:19 +02:00
MightyPork 1c556457c7 Merge branch 'new-codepages' into work 2017-10-07 00:15:34 +02:00
MightyPork e49a8b0adf added codepages 2 and 3 2017-10-06 23:25:01 +02:00
MightyPork 81c3e426e7 added quarter blocks to codepage 1 2017-10-06 22:28:36 +02:00
MightyPorkandGitHub c90de79a34 Update README.md 2017-10-06 00:12:28 +02:00
MightyPork df404f5f63 2.1.1 - patched cslang 2017-10-04 21:47:32 +02:00
MightyPork 00153656f1 flip front-end back to "work" 2017-10-04 00:22:08 +02:00
MightyPork aa920aee27 Merge branch 'master' into work 2017-10-04 00:21:45 +02:00
MightyPork 7b8c936559 Version bump 2017-10-04 00:13:14 +02:00
MightyPork 17c18ed1c9 update front-end to latest master 2017-10-04 00:12:47 +02:00
MightyPork 274e3b359b Merge branch 'work' 2017-10-04 00:11:26 +02:00
MightyPork 73c98eb2d1 some logging adjustments 2017-10-04 00:10:54 +02:00
MightyPork 022e882001 added IP to answerback message 2017-10-03 22:16:07 +02:00
MightyPork dc08512397 one timezone is probably enough in the release readme 2017-10-03 20:58:00 +02:00
16 changed files with 502 additions and 196 deletions
+33 -20
View File
@@ -5,21 +5,24 @@
![Photo][photo-hw]<br>
*Fig 1: Breadboard adapter developed for ESPTerm*
As of release 1.0, ESPTerm **passes most of VTTEST test cases** (from the main menu and some Xterm specific), making it
functionally comparable to eg. gnome-terminal, terminator, konsole, GtkTerm or PuTTY.
ESPTerm **passes most of VTTEST test cases**, making it functionally comparable to eg.
gnome-terminal, terminator, konsole, GtkTerm or PuTTY.
ESPTerm is **capable of running Midnight Commander** through agetty, **including full
mouse support**, provided agetty is made to believe it's Xterm, which shows ESPTerm is sufficiently well
implemented to work with ncurses.
mouse support**, provided agetty is made to believe it's Xterm, which shows ESPTerm
is compatible with ncurses.
In addition to control sequences that manipulate the terminal or user input, there
is a set of simple **networking commands** for device-to-device message exchange and
interacting with remote servers.
To see what escape sequences are supported, check out this [annotated Xterm manual page][xterm-compare]
which was used for reference, or the built-in help page ([online demo][demo-help])
The terminal screen can be accessed using any web browser, even on a phone or tablet.
It works with ESP-01, ESP-01S, ESP-12 and likely many other modules (I use an ESP-12
on a LoLin NodeMCU board from eBay for development).
It works with ESP-01, ESP-01S, ESP-12 and likely many other modules.
With ESPTerm, you can add remote access via WiFi to any embeded project, all you need is
a serial port and some imagination!
UART and some imagination!
## Try it online
@@ -48,6 +51,8 @@ It **does not work with**:
- Internet Explorer (any version) - crashes, missing JS features
- Opera Mini - crashes, missing JS and CSS features
- Blackberry browser - not tested, but unlikely
- Safari on old iOS versions - missing features
- WebOS browser
- Old Android Browser (before 4.4?) - not tested, likely missing JS features
## Main features
@@ -58,6 +63,10 @@ It **does not work with**:
- Full UTF-8 support, alternate character sets
- Standard mouse tracking modes
- You can dynamically set screen title, button labels...
- **Networking commands**
- Command for sending a message to another ESPTerm
- API endpoint (`/api/v1/msg`) for receiving messages sent e.g. from a script on PC, web browser or CURL
- Command for requesting remote servers and getting back response headers and/or body
- **Web Terminal Interface**
- Real-time screen update via WebSocket
- Mouse and keyboard input, works also on mobile
@@ -67,6 +76,15 @@ It **does not work with**:
- **User-friendly comprehensive WiFi configuration** (Demo: [WiFi][demo-wifi], [network][demo-network] config)
- Static IP, DHCP, channel selection, power
- SSID search utility for finding your existing network
- **Basic security features**
- Possibility to password-lock parts of the web interface
- Admin password for some sensitive operations (can be changed!)
- Configurable AP password & Hidden attribute
- **Advanced settings storage**
- Stored in Flash
- Seamlesly updated and usually backwards compatible in minor releases
- Settings can be saved as defaults and later easily restored (ideal e.g. for classroom use, saving
good tested settings before giving the module to students)
## Bugs? Ideas?
@@ -108,36 +126,31 @@ It can happen that some changes to the WiFi or network config make the module in
- To reset all settings to defaults, hold the button a couple seconds until the LED flashes rapidly, then release it.
- You can cancel this wipe/reset operation (when triggered by accident) by pressing Reset or disconnecting the power supply.
### Config files
### Config banks
ESPTerm has two config "files", one for defaults and one for the currently used settings. In the case of the terminal
config, there is also a third, temporary file for changes done via ESC commands.
When you get your settings *just right*, you can store them as defaults, which can then be at any time restored
by holding the BOOT (GPIO0) button. You can do this on the System Settings page. This asks for an "admin password",
which you can define when building the firmware in the `esphttpdconfig.mk` file.
The default password is `19738426`. This password can't presently be changed without re-flashing the firmware.
which can (and should!) be changed. This password can't be easily recovered when forgotten.
You can also restore everything (except the saved defaults) to "factory defaults", there is a button for this
on the System Settings page. Those are the initial values in the config files.
on the System Settings page. Those are the initial values you would get after a clean install.
## Research resources
Developing ESPTerm wasn't an easy task, because the information is scattered across many places and the existing
terminal emulators I originally used for reference (terminator, Konsole) are not implemented correctly in some details.
Developing the terminal emulator was complicated by the information being scattered across many places and the existing
implementations I used for reference often got some details wrong or didn't implement certain features at all. Xterm proved to be by far the most complete implementation.
A great tool for checking my implementation has proven to be [VTTTEST][vttest] and Xterm as a reference
implementation that is probably the most complete emulator available, although it's cumbersome to use and its age
really shows in the looks.
A great tool for checking my code has proven to be [VTTTEST][vttest]. ESPTerm passes most of the tests on the main page and some additional Xterm specific ones, like Mouse Tracking.
I've comnpiled a list of those I found most helpful here: [VT100 emulation resources][resources]
Here is a list of useful [VT100 emulation resources][resources] I've collected for reference.
## Development
ESPTerm's firmware is written in C and is based on SpriteTM's `libesphttpd` http server library forked to
[MightyPork/libesphttpd][httpdlib]. This fork includes various improvements
and changes required by the project.
[MightyPork/libesphttpd][httpdlib]. This fork includes various improvements and changes required by the project.
### Installation for development
-1
View File
@@ -1 +0,0 @@
+1 -1
View File
@@ -45,7 +45,7 @@ function buildlang() {
cp ../rel-tpl/README.txt ${readmefil}
sed -i s/%VERS%/${vers}/ ${readmefil}
sed -i s/%LANG%/${lang}/ ${readmefil}
dt=$(LC_TIME=en_US.UTF-8 date '+%c %Z')
dt=$(LC_TIME=en_US.UTF-8 date '+%c')
sed -i "s#%DATETIME%#${dt}#" ${readmefil}
unix2dos ${readmefil}
+12 -1
View File
@@ -11,6 +11,7 @@
#include "version.h"
#include "uart_buffer.h"
#include "screen.h"
#include "wifimgr.h"
volatile bool enquiry_suppressed = false;
ETSTimer enqTimer;
@@ -51,7 +52,17 @@ apars_handle_enq(void)
wifi_get_macaddr(SOFTAP_IF, mac);
char buf100[100];
sprintf(buf100, "\x1bXESPTerm "VERSION_STRING" #"GIT_HASH_BACKEND"+"GIT_HASH_FRONTEND" id=%02X%02X%02X\x1b\\", mac[3], mac[4], mac[5]);
char *buf = buf100;
buf += sprintf(buf, "\x1bX");
buf += sprintf(buf, "ESPTerm "VERSION_STRING" ");
buf += sprintf(buf, "#"GIT_HASH_BACKEND"+"GIT_HASH_FRONTEND" ");
buf += sprintf(buf, "id=%02X%02X%02X ", mac[3], mac[4], mac[5]);
int x = getStaIpAsString(buf);
if (x) buf += x;
else buf--; // remove the trailing space
buf += sprintf(buf, "\x1b\\");
(void)buf;
// version encased in SOS and ST
apars_respond(buf100);
+4
View File
@@ -49,6 +49,10 @@ apars_handle_osc(char *buffer)
buffer[0] = 'G';
notify_growl(buffer);
}
else if (n == 70) {
// ESPTerm: backdrop
screen_set_backdrop(buffer);
}
else if (n >= 81 && n <= 85) {
// ESPTerm: action button label
screen_set_button_text(n - 80, buffer);
+6 -7
View File
@@ -63,8 +63,6 @@ requestCb(int http_status,
struct d2d_request_opts *opts = userArg;
d2d_dbg("Rx url response, code %d, nonce \"%s\"", http_status, opts->nonce?opts->nonce:"");
// ensure positive - would be hard to parse
if (http_status < 0) http_status = -http_status;
@@ -77,6 +75,8 @@ requestCb(int http_status,
if (opts->max_result_len > 0 && len > opts->max_result_len)
len = (int) opts->max_result_len;
d2d_info("Rx HTTP response, code %d, len %d, nonce \"%s\"", http_status, len, opts->nonce?opts->nonce:"");
char *bb = buff100;
bb += sprintf(bb, "\x1b^h;%d;", http_status);
const char *comma = "";
@@ -160,7 +160,7 @@ d2d_parse_command(char *msg)
FIND_NEXT(ip, ';');
const char *payload = msg;
d2d_dbg("D2D Tx,dest=%s,msg=%s", ip, payload);
d2d_info("D2D Tx,dest=%s,msg=%s", ip, payload);
sprintf(buff40, "http://%s" API_D2D_MSG, ip);
httpclient_args args;
@@ -203,9 +203,8 @@ d2d_parse_command(char *msg)
FIND_NEXT(params, ';');
d2d_info("HTTP request");
d2d_dbg("Method %s", method);
d2d_dbg("Params %s", params);
size_t max_buf_len = HTTPCLIENT_DEF_MAX_LEN;
size_t max_result_len = 0; // 0 = no truncate
uint timeout = HTTPCLIENT_DEF_TIMEOUT_MS;
@@ -274,7 +273,7 @@ d2d_parse_command(char *msg)
request_pending = true;
http_request(&args, no_resp ? requestNoopCb : requestCb);
d2d_dbg("Done");
d2d_dbg("Request sent.");
return true;
}
@@ -308,7 +307,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiD2DMessage(HttpdConnData *connData)
sendResponseToUART("\a");
d2d_dbg("D2D Rx src="IPSTR",len=%d", ip[0], ip[1], ip[2], ip[3],len);
d2d_info("D2D Rx src="IPSTR",len=%d", ip[0], ip[1], ip[2], ip[3],len);
// Received a msg
+11 -2
View File
@@ -256,10 +256,16 @@ cgiTermCfgSetParams(HttpdConnData *connData)
if (GET_ARG("term_title")) {
cgi_dbg("Terminal title default text: \"%s\"", buff);
strncpy_safe(termconf->title, buff, 64); // ATTN those must match the values in
strncpy_safe(termconf->title, buff, TERM_TITLE_LEN); // ATTN those must match the values in
topics |= TOPIC_CHANGE_TITLE;
}
if (GET_ARG("backdrop")) {
cgi_dbg("Terminal backdrop url: \"%s\"", buff);
strncpy_safe(termconf->backdrop, buff, TERM_BACKDROP_LEN); // ATTN those must match the values in
topics |= TOPIC_CHANGE_BACKDROP;
}
for (int btn_i = 1; btn_i <= TERM_BTN_COUNT; btn_i++) {
sprintf(buff, "btn%d", btn_i);
if (GET_ARG(buff)) {
@@ -416,7 +422,7 @@ cgiTermCfgSetParams(HttpdConnData *connData)
httpd_cgi_state ICACHE_FLASH_ATTR
tplTermCfg(HttpdConnData *connData, char *token, void **arg)
{
#define BUFLEN TERM_TITLE_LEN
#define BUFLEN 100 // large enough for backdrop
char buff[BUFLEN];
char buff2[10];
@@ -492,6 +498,9 @@ tplTermCfg(HttpdConnData *connData, char *token, void **arg)
else if (streq(token, "term_title")) {
strncpy_safe(buff, termconf->title, BUFLEN);
}
else if (streq(token, "backdrop")) {
strncpy_safe(buff, termconf->backdrop, BUFLEN);
}
else if (streq(token, "uart_baud")) {
sprintf(buff, "%d", sysconf->uart_baudrate);
}
+1 -16
View File
@@ -617,22 +617,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token,
}
}
else if (streq(token, "sta_active_ip")) {
x = wifi_get_opmode();
connectStatus = wifi_station_get_connect_status();
if (x == SOFTAP_MODE || connectStatus != STATION_GOT_IP || wificonf->opmode == SOFTAP_MODE) {
strcpy(buff, "");
}
else {
struct ip_info info;
wifi_get_ip_info(STATION_IF, &info);
sprintf(buff, IPSTR, GOOD_IP2STR(info.ip.addr));
// sprintf(buff, "ip: "IPSTR", mask: "IPSTR", gw: "IPSTR,
// GOOD_IP2STR(info.ip.addr),
// GOOD_IP2STR(info.netmask.addr),
// GOOD_IP2STR(info.gw.addr));
}
getStaIpAsString(buff);
}
tplSend(connData, buff, -1);
+336 -127
View File
@@ -19,143 +19,352 @@
* Based on rxvt-unicode screen.C table.
*/
static const u16 codepage_0[] ESP_CONST_DATA =
{// Unicode ASCII SYM
{ // Unicode ASCII SYM
// %%BEGIN:0%%
0x2666, // 96 `
0x2592, // 97 a
0x2409, // 98 b HT
0x240c, // 99 c FF
0x240d, // 100 d CR
0x240a, // 101 e LF
0x00b0, // 102 f °
0x00b1, // 103 g ±
0x2424, // 104 h NL
0x240b, // 105 i VT
0x2518, // 106 j
0x2510, // 107 k
0x250c, // 108 l
0x2514, // 109 m
0x253c, // 110 n
0x23ba, // 111 o
0x23bb, // 112 p
0x2500, // 113 q
0x23bc, // 114 r
0x23bd, // 115 s
0x251c, // 116 t
0x2524, // 117 u
0x2534, // 118 v
0x252c, // 119 w
0x2502, // 120 x
0x2264, // 121 y
0x2265, // 122 z
0x03c0, // 123 { π
0x2260, // 124 |
0x20a4, // 125 } £
0x00b7, // 126 ~ ·
u'', // 0x2666 96 `
u'', // 0x2592 97 a
u'', // 0x2409 98 b
u'', // 0x240c 99 c FF
u'', // 0x240d 100 d CR
u'', // 0x240a 101 e LF
u'°', // 0x00b0 102 f
u'±', // 0x00b1 103 g
u'', // 0x2424 104 h NL
u'', // 0x240b 105 i VT
u'', // 0x2518 106 j
u'', // 0x2510 107 k
u'', // 0x250c 108 l
u'', // 0x2514 109 m
u'', // 0x253c 110 n
u'', // 0x23ba 111 o
u'', // 0x23bb 112 p
u'', // 0x2500 113 q
u'', // 0x23bc 114 r
u'', // 0x23bd 115 s
u'', // 0x251c 116 t
u'', // 0x2524 117 u
u'', // 0x2534 118 v
u'', // 0x252c 119 w
u'', // 0x2502 120 x
u'', // 0x2264 121 y
u'', // 0x2265 122 z
u'π', // 0x03c0 123 {
u'', // 0x2260 124 |
u'£', // 0x20a4 125 }
u'·', // 0x00b7 126 ~
// %%END:0%%
};
#define CODEPAGE_1_BEGIN 33
#define CODEPAGE_1_END 126
// DOS, thin and double lines, arrows, angles, diagonals, thick border
static const u16 codepage_1[] ESP_CONST_DATA =
{// Unicode ASCII SYM DOS
{// Unicode ASCII DOS
// %%BEGIN:1%%
0x263A, // 33 ! (1) - low ASCII symbols from DOS, moved to +32
0x263B, // 34 " (2)
0x2665, // 35 # (3)
0x2666, // 36 $ (4)
0x2663, // 37 % (5)
0x2660, // 38 & (6)
0x2022, // 39 ' (7) - inverse dot and circle left out, can be done with SGR
0x231B, // 40 ( ⌛ - hourglass (timer icon)
0x25CB, // 41 ) (9)
0x21AF, // 42 * ↯ - electricity (lightning monitor...)
0x266A, // 43 + (13)
0x266B, // 44 , (14)
0x263C, // 45 - (15)
0x2302, // 46 . (127)
0x2622, // 47 / ☢ - radioactivity (geiger counter...)
0x2591, // 48 0 (176) - this block is kept aligned and ordered from DOS, moved -128
0x2592, // 49 1 (177)
0x2593, // 50 2 (178)
0x2502, // 51 3 (179)
0x2524, // 52 4 (180)
0x2561, // 53 5 (181)
0x2562, // 54 6 (182)
0x2556, // 55 7 (183)
0x2555, // 56 8 (184)
0x2563, // 57 9 (185)
0x2551, // 58 : (186)
0x2557, // 59 ; (187)
0x255D, // 60 < (188)
0x255C, // 61 = (189)
0x255B, // 62 > (190)
0x2510, // 63 ? (191)
0x2514, // 64 @ (192)
0x2534, // 65 A (193)
0x252C, // 66 B (194)
0x251C, // 67 C (195)
0x2500, // 68 D (196)
0x253C, // 69 E (197)
0x255E, // 70 F (198)
0x255F, // 71 G (199)
0x255A, // 72 H (200)
0x2554, // 73 I (201)
0x2569, // 74 J (202)
0x2566, // 75 K (203)
0x2560, // 76 L (204)
0x2550, // 77 M (205)
0x256C, // 78 N (206)
0x2567, // 79 O (207)
0x2568, // 80 P (208)
0x2564, // 81 Q (209)
0x2565, // 82 R (210)
0x2559, // 83 S (211)
0x2558, // 84 T (212)
0x2552, // 85 U (213)
0x2553, // 86 V (214)
0x256B, // 87 W (215)
0x256A, // 88 X (216)
0x2518, // 89 Y (217)
0x250C, // 90 Z (218)
0x2588, // 91 [ (219)
0x2584, // 92 \ (220)
0x258C, // 93 ] (221)
0x2590, // 94 ^ (222)
0x2580, // 95 _ (223)
0x2195, // 96 ` (18) - moved from low DOS ASCII
0x2191, // 97 a (24)
0x2193, // 98 b (25)
0x2192, // 99 c (26)
0x2190, // 100 d (27)
0x2194, // 101 e (29)
0x25B2, // 102 f (30)
0x25BC, // 103 g (31)
0x25BA, // 104 h (16)
0x25C4, // 105 i (17)
0x25E2, // 106 j ◢ - added for slanted corners
0x25E3, // 107 k
0x25E4, // 108 l
0x25E5, // 109 m
0x256D, // 110 n ╭ - rounded corners
0x256E, // 111 o
0x256F, // 112 p
0x2570, // 113 q
0x0, // 114 r - free positions for future expansion
0x0, // 115 s
0x0, // 116 t
0x0, // 117 u
0x0, // 118 v
0x0, // 119 w
0x0, // 120 x
0x0, // 121 y
0x0, // 122 z
0x0, // 123 {
0x0, // 124 |
0x2714, // 125 } ✔ - checkboxes or checklist items
0x2718, // 126 ~
u'', // 0x263A, 33 ! (1) - low ASCII symbols from DOS, moved to +32
u'', // 0x263B, 34 " (2)
u'', // 0x2665, 35 # (3)
u'', // 0x2666, 36 $ (4)
u'', // 0x2663, 37 % (5)
u'', // 0x2660, 38 & (6)
u'', // 0x2022, 39 ' (7) - inverse dot and circle left out, can be done with SGR
u'', // 0x231B, 40 ( - hourglass (timer icon)
u'', // 0x25CB, 41 ) (9)
u'', // 0x21AF, 42 * - electricity (lightning monitor...)
u'', // 0x266A, 43 + (13)
u'', // 0x266B, 44 , (14)
u'', // 0x263C, 45 - (15)
u'', // 0x2302, 46 . (127)
u'', // 0x2622, 47 / - radioactivity (geiger counter...)
u'', // 0x2591, 48 0 (176) - this block is kept aligned and ordered from DOS, moved -128
u'', // 0x2592, 49 1 (177)
u'', // 0x2593, 50 2 (178)
u'', // 0x2502, 51 3 (179)
u'', // 0x2524, 52 4 (180)
u'', // 0x2561, 53 5 (181)
u'', // 0x2562, 54 6 (182)
u'', // 0x2556, 55 7 (183)
u'', // 0x2555, 56 8 (184)
u'', // 0x2563, 57 9 (185)
u'', // 0x2551, 58 : (186)
u'', // 0x2557, 59 ; (187)
u'', // 0x255D, 60 < (188)
u'', // 0x255C, 61 = (189)
u'', // 0x255B, 62 > (190)
u'', // 0x2510, 63 ? (191)
u'', // 0x2514, 64 @ (192)
u'', // 0x2534, 65 A (193)
u'', // 0x252C, 66 B (194)
u'', // 0x251C, 67 C (195)
u'', // 0x2500, 68 D (196)
u'', // 0x253C, 69 E (197)
u'', // 0x255E, 70 F (198)
u'', // 0x255F, 71 G (199)
u'', // 0x255A, 72 H (200)
u'', // 0x2554, 73 I (201)
u'', // 0x2569, 74 J (202)
u'', // 0x2566, 75 K (203)
u'', // 0x2560, 76 L (204)
u'', // 0x2550, 77 M (205)
u'', // 0x256C, 78 N (206)
u'', // 0x2567, 79 O (207)
u'', // 0x2568, 80 P (208)
u'', // 0x2564, 81 Q (209)
u'', // 0x2565, 82 R (210)
u'', // 0x2559, 83 S (211)
u'', // 0x2558, 84 T (212)
u'', // 0x2552, 85 U (213)
u'', // 0x2553, 86 V (214)
u'', // 0x256B, 87 W (215)
u'', // 0x256A, 88 X (216)
u'', // 0x2518, 89 Y (217)
u'', // 0x250C, 90 Z (218)
u'', // 0x2588, 91 [ (219)
u'', // 0x2584, 92 \ (220)
u'', // 0x258C, 93 ] (221)
u'', // 0x2590, 94 ^ (222)
u'', // 0x2580, 95 _ (223)
u'', // 0x2195, 96 ` (18) - moved from low DOS ASCII
u'', // 0x2191, 97 a (24)
u'', // 0x2193, 98 b (25)
u'', // 0x2192, 99 c (26)
u'', // 0x2190, 100 d (27)
u'', // 0x2194, 101 e (29)
u'', // 0x25B2, 102 f (30)
u'', // 0x25BC, 103 g (31)
u'', // 0x25BA, 104 h (16)
u'', // 0x25C4, 105 i (17)
u'', // 0x25E2, 106 j - added for slanted corners
u'', // 0x25E3, 107 k
u'', // 0x25E4, 108 l
u'', // 0x25E5, 109 m
u'', // 0x256D, 110 n - rounded corners
u'', // 0x256E, 111 o
u'', // 0x256F, 112 p
u'', // 0x2570, 113 q
u'', // 0x0, 114 r - right up diagonal
u'', // 0x0, 115 s - right down diagonal
u'', // 0x0, 116 t
u'', // 0x0, 117 u
u'', // 0x0, 118 v
u'', // 0x0, 119 w
u'', // 0x0, 120 x
0xE0B0, // powerline right triangle (filled), 121 y
0xE0B1, // powerline right triangle (hollow), 122 z
0xE0B2, // powerline left triangle (filled), 123 {
0xE0B3, // powerline left triangle (hollow), 124 | - reserved
u'', // 0x2714, 125 } - checkboxes or checklist items
u'', // 0x2718, 126 ~
// %%END:1%%
};
#define CODEPAGE_2_BEGIN 33
#define CODEPAGE_2_END 126
// blocks, thick and split lines, line butts
static const u16 codepage_2[] ESP_CONST_DATA =
{// Unicode ASCII DOS
// %%BEGIN:2%%
u'', // 0x2581, 33 ! - those are ordered this way to allow easy calculating of the right code (for graphs)
u'', // 0x2582, 34 "
u'', // 0x2583, 35 #
u'', // 0x2584, 36 $
u'', // 0x2585, 37 %
u'', // 0x2586, 38 &
u'', // 0x2587, 39 ' - 7-eighths
u'', // 0x2588, 40 ( - full block, shared by both sequences
u'', // 0x2589, 41 ) - those grow thinner, to re-use the full block
u'', // 0x258A, 42 *
u'', // 0x258B, 43 +
u'', // 0x258C, 44 ,
u'', // 0x258D, 45 -
u'', // 0x258E, 46 .
u'', // 0x258F, 47 /
u'', // 0x2594, 48 0 - complementary symbols
u'', // 0x2595, 49 1
u'', // 0x2590, 50 2
u'', // 0x2580, 51 3
u'', // 0x2598, 52 4 - top-left, top-right, bottom-right, bottom-left
u'', // 0x259D, 53 5
u'', // 0x2597, 54 6
u'', // 0x2596, 55 7
u'', // 0x259F, 56 8
u'', // 0x2599, 57 9
u'', // 0x259B, 58 :
u'', // 0x259C, 59 ;
u'', // 0x259E, 60 < - complementary diagonals
u'', // 0x259A, 61 =
u'', // 0x, 62 > - here are thick and thin lines and their joins. it's really quite arbitrary, based on the unicode order, excluding single lines
u'', // 0x, 63 ?
u'', // 0x, 64 @
u'', // 0x, 65 A
u'', // 0x, 66 B
u'', // 0x, 67 C
u'', // 0x, 68 D
u'', // 0x, 69 E
u'', // 0x, 70 F
u'', // 0x, 71 G
u'', // 0x, 72 H
u'', // 0x, 73 I
u'', // 0x, 74 J
u'', // 0x, 75 K
u'', // 0x, 76 L
u'', // 0x, 77 M
u'', // 0x, 78 N
u'', // 0x, 79 O
u'', // 0x, 80 P
u'', // 0x, 81 Q
u'', // 0x, 82 R
u'', // 0x, 83 S
u'', // 0x, 84 T
u'', // 0x, 85 U
u'', // 0x, 86 V
u'', // 0x, 87 W
u'', // 0x, 88 X
u'', // 0x, 89 Y
u'', // 0x, 90 Z
u'', // 0x, 91 [
u'', // 0x, 92 \ .
u'', // 0x, 93 ]
u'', // 0x, 94 ^
u'', // 0x, 95 _
u'', // 0x, 96 `
u'', // 0x, 97 a
u'', // 0x, 98 b
u'', // 0x, 99 c
u'', // 0x, 100 d
u'', // 0x, 101 e
u'', // 0x, 102 f
u'', // 0x, 103 g
u'', // 0x, 104 h
u'', // 0x, 105 i
u'', // 0x, 106 j
u'', // 0x, 107 k
u'', // 0x, 108 l
u'', // 0x, 109 m
u'', // 0x, 110 n
u'', // 0x, 111 o
u'', // 0x, 112 p
u'', // 0x, 113 q
u'', // 0x, 114 r
u'', // 0x, 115 s
u'', // 0x, 116 t
u'', // 0x, 117 u
u'', // 0x, 118 v
u'', // 0x, 119 w - butts
u'', // 0x, 120 x
u'', // 0x, 121 y
u'', // 0x, 122 z
u'', // 0x, 123 {
u'', // 0x, 124 |
u'', // 0x, 125 }
u'', // 0x, 126 ~
// %%END:2%%
};
#define CODEPAGE_3_BEGIN 33
#define CODEPAGE_3_END 48
// dashed lines, split straight lines
static const u16 codepage_3[] ESP_CONST_DATA =
{// Unicode ASCII DOS
// %%BEGIN:3%%
u'', // 0x, 33 !
u'', // 0x, 34 "
u'', // 0x, 35 #
u'', // 0x, 36 $
u'', // 0x, 37 %
u'', // 0x, 38 &
u'', // 0x, 39 '
u'', // 0x, 40 (
u'', // 0x, 41 )
u'', // 0x, 42 *
u'', // 0x, 43 +
u'', // 0x, 44 ,
u'', // 0x, 45 -
u'', // 0x, 46 .
u'', // 0x, 47 /
u'', // 0x, 48 0
// %%END:3%%
// u'\0', // 0x, 49 1
// u'\0', // 0x, 50 2
// u'\0', // 0x, 51 3
// u'\0', // 0x, 52 4
// u'\0', // 0x, 53 5
// u'\0', // 0x, 54 6
// u'\0', // 0x, 55 7
// u'\0', // 0x, 56 8
// u'\0', // 0x, 57 9
// u'\0', // 0x, 58 :
// u'\0', // 0x, 59 ;
// u'\0', // 0x, 60 <
// u'\0', // 0x, 61 =
// u'\0', // 0x, 62 >
// u'\0', // 0x, 63 ?
// u'\0', // 0x, 64 @
// u'\0', // 0x, 65 A
// u'\0', // 0x, 66 B
// u'\0', // 0x, 67 C
// u'\0', // 0x, 68 D
// u'\0', // 0x, 69 E
// u'\0', // 0x, 70 F
// u'\0', // 0x, 71 G
// u'\0', // 0x, 72 H
// u'\0', // 0x, 73 I
// u'\0', // 0x, 74 J
// u'\0', // 0x, 75 K
// u'\0', // 0x, 76 L
// u'\0', // 0x, 77 M
// u'\0', // 0x, 78 N
// u'\0', // 0x, 79 O
// u'\0', // 0x, 80 P
// u'\0', // 0x, 81 Q
// u'\0', // 0x, 82 R
// u'\0', // 0x, 83 S
// u'\0', // 0x, 84 T
// u'\0', // 0x, 85 U
// u'\0', // 0x, 86 V
// u'\0', // 0x, 87 W
// u'\0', // 0x, 88 X
// u'\0', // 0x, 89 Y
// u'\0', // 0x, 90 Z
// u'\0', // 0x, 91 [
// u'\0', // 0x, 92 \ .
// u'\0', // 0x, 93 ]
// u'\0', // 0x, 94 ^
// u'\0', // 0x, 95 _
// u'\0', // 0x, 96 `
// u'\0', // 0x, 97 a
// u'\0', // 0x, 98 b
// u'\0', // 0x, 99 c
// u'\0', // 0x, 100 d
// u'\0', // 0x, 101 e
// u'\0', // 0x, 102 f
// u'\0', // 0x, 103 g
// u'\0', // 0x, 104 h
// u'\0', // 0x, 105 i
// u'\0', // 0x, 106 j
// u'\0', // 0x, 107 k
// u'\0', // 0x, 108 l
// u'\0', // 0x, 109 m
// u'\0', // 0x, 110 n
// u'\0', // 0x, 111 o
// u'\0', // 0x, 112 p
// u'\0', // 0x, 113 q
// u'\0', // 0x, 114 r
// u'\0', // 0x, 115 s
// u'\0', // 0x, 116 t
// u'\0', // 0x, 117 u
// u'\0', // 0x, 118 v
// u'\0', // 0x, 119 w
// u'\0', // 0x, 120 x
// u'\0', // 0x, 121 y
// u'\0', // 0x, 122 z
// u'\0', // 0x, 123 {
// u'\0', // 0x, 124 |
// u'\0', // 0x, 125 }
// u'\0', // 0x, 126 ~
};
#endif //ESPTERM_CHARACTER_SETS_H_H
+57 -7
View File
@@ -213,6 +213,7 @@ terminal_restore_defaults(void)
termconf->debugbar = SCR_DEF_DEBUGBAR;
termconf->allow_decopt_12 = SCR_DEF_DECOPT12;
termconf->ascii_debug = SCR_DEF_ASCIIDEBUG;
termconf->backdrop[0] = 0;
}
/**
@@ -247,6 +248,11 @@ terminal_apply_settings_noclear(void)
termconf->ascii_debug = SCR_DEF_ASCIIDEBUG;
changed = 1;
}
if (termconf->config_version < 4) {
persist_dbg("termconf: Updating to version %d", 1);
termconf->backdrop[0] = 0;
changed = 1;
}
termconf->config_version = TERMCONF_VERSION;
@@ -385,6 +391,7 @@ screen_reset_do(bool size, bool labels)
if (labels) {
strcpy(termconf_live.title, termconf->title);
strcpy(termconf_live.backdrop, termconf->backdrop);
for (int i = 1; i <= TERM_BTN_COUNT; i++) {
strcpy(termconf_live.btn[i], termconf->btn[i]);
@@ -394,7 +401,7 @@ screen_reset_do(bool size, bool labels)
termconf_live.show_buttons = termconf->show_buttons;
termconf_live.show_config_links = termconf->show_config_links;
topics |= TOPIC_CHANGE_TITLE | TOPIC_CHANGE_BUTTONS;
topics |= TOPIC_CHANGE_TITLE | TOPIC_CHANGE_BUTTONS | TOPIC_CHANGE_BACKDROP;
}
// initial values in the save buffer in case of receiving restore without storing first
@@ -1009,6 +1016,18 @@ screen_set_button_text(int num, const char *text)
NOTIFY_DONE(TOPIC_CHANGE_BUTTONS);
}
/**
* Helper function to set terminalbackdrop
* @param url - url
*/
void ICACHE_FLASH_ATTR
screen_set_backdrop(const char *url)
{
NOTIFY_LOCK();
strncpy(termconf_live.backdrop, url, TERM_BACKDROP_LEN);
NOTIFY_DONE(TOPIC_CHANGE_BACKDROP);
}
/**
* Shift screen upwards
*/
@@ -1794,6 +1813,20 @@ utf8_remap(char *out, char g, char charset)
}
break;
case CS_2_BLOCKS_LINES: /* ESPTerm Character Rom 2 */
if ((g >= CODEPAGE_2_BEGIN) && (g <= CODEPAGE_2_END)) {
n = codepage_2[g - CODEPAGE_2_BEGIN];
if (n) utf = n;
}
break;
case CS_3_LINES_EXTRA: /* ESPTerm Character Rom 3 */
if ((g >= CODEPAGE_3_BEGIN) && (g <= CODEPAGE_3_END)) {
n = codepage_3[g - CODEPAGE_3_BEGIN];
if (n) utf = n;
}
break;
case CS_A_UKASCII: /* UK, replaces # with GBP */
if (g == '#') utf = 0x20a4; // £
break;
@@ -1893,6 +1926,7 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics,
#define TOPICMARK_BELL '!'
#define TOPICMARK_CURSOR 'C'
#define TOPICMARK_SCREEN 'S'
#define TOPICMARK_BACKDROP 'W'
if (ss == NULL) {
// START!
@@ -2011,9 +2045,11 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics,
bufput_c(TOPICMARK_TITLE);
int len = (int) strlen(termconf_live.title);
memcpy(bb, termconf_live.title, len);
bb += len;
remain -= len;
if (len > 0) {
memcpy(bb, termconf_live.title, len);
bb += len;
remain -= len;
}
bufput_c('\x01');
END_TOPIC
@@ -2024,13 +2060,27 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics,
for (int i = 0; i < TERM_BTN_COUNT; i++) {
int len = (int) strlen(termconf_live.btn[i]);
memcpy(bb, termconf_live.btn[i], len);
bb += len;
remain -= len;
if (len > 0) {
memcpy(bb, termconf_live.btn[i], len);
bb += len;
remain -= len;
}
bufput_c('\x01');
}
END_TOPIC
BEGIN_TOPIC(TOPIC_CHANGE_BACKDROP, TERM_BACKDROP_LEN+1+1)
bufput_c(TOPICMARK_BACKDROP);
int len = (int) strlen(termconf_live.backdrop);
if (len > 0) {
memcpy(bb, termconf_live.backdrop, len);
bb += len;
remain -= len;
}
bufput_c('\x01');
END_TOPIC
BEGIN_TOPIC(TOPIC_INTERNAL, 45)
bufput_c(TOPICMARK_DEBUG);
// General flags
+10 -2
View File
@@ -38,6 +38,7 @@
#define TERM_BTN_MSG_LEN 10
#define TERM_TITLE_LEN 64
#define TERM_BTN_COUNT 5
#define TERM_BACKDROP_LEN 100
#define SCR_DEF_DISPLAY_TOUT_MS 12
#define SCR_DEF_DISPLAY_COOLDOWN_MS 35
@@ -74,8 +75,8 @@ enum CursorShape {
// Size designed for the terminal config structure
// Must be constant to avoid corrupting user config after upgrade
#define TERMCONF_SIZE 300
#define TERMCONF_VERSION 3
#define TERMCONF_SIZE 400
#define TERMCONF_VERSION 4
typedef struct {
u32 width;
@@ -100,6 +101,7 @@ typedef struct {
bool debugbar;
bool allow_decopt_12;
bool ascii_debug;
char backdrop[TERM_BACKDROP_LEN];
} TerminalConfigBundle;
// Live config
@@ -148,6 +150,8 @@ void screen_resize(int rows, int cols);
void screen_set_title(const char *title);
/** Set a button text */
void screen_set_button_text(int num, const char *text);
/** Change backdrop */
void screen_set_backdrop(const char *url);
// --- Encoding ---
@@ -156,6 +160,8 @@ typedef enum {
CS_A_UKASCII = 'A',
CS_0_DEC_SUPPLEMENTAL = '0',
CS_1_DOS_437 = '1',
CS_2_BLOCKS_LINES = '2',
CS_3_LINES_EXTRA = '3',
} CHARSET;
enum ScreenSerializeTopic {
@@ -167,6 +173,7 @@ enum ScreenSerializeTopic {
TOPIC_CHANGE_CURSOR = (1<<5),
TOPIC_INTERNAL = (1<<6), // debugging internal state
TOPIC_BELL = (1<<7), // beep
TOPIC_CHANGE_BACKDROP = (1<<8),
TOPIC_FLAG_NOCLEAN = (1<<15), // do not clean dirty extents
// combos
@@ -175,6 +182,7 @@ enum ScreenSerializeTopic {
TOPIC_CHANGE_CONTENT_ALL |
TOPIC_CHANGE_CURSOR |
TOPIC_CHANGE_TITLE |
TOPIC_CHANGE_BACKDROP |
TOPIC_CHANGE_BUTTONS,
};
+9 -7
View File
@@ -74,12 +74,12 @@ static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg)
if (diff == 0) {
if (cnt == 5) {
// only every 5 secs if no change
dbg("Rx: %2d%c, Tx: %2d%c, Hp: %d", rxp, '%', txp, '%', heap);
dbg("Rx/Tx: %d/%d%c, Hp: %d", rxp, txp, '%', heap);
cnt = 0;
}
} else {
// report change
dbg("Rx: %2d%c, Tx: %2d%c, Hp: %d (%s%d)", rxp, '%', txp, '%', heap, cc, diff);
dbg("Rx/Tx: %d/%d%c, Hp: %d (%s%d)", rxp, txp, '%', heap, cc, diff);
cnt = 0;
}
@@ -131,11 +131,6 @@ void ICACHE_FLASH_ATTR user_init(void)
espFsInit((void *) (webpages_espfs_start));
#endif
#if DEBUG_HEAP
// Heap use timer & blink
TIMER_START(&prHeapTimer, prHeapTimerCb, HEAP_TIMER_MS, 1);
#endif
// do later (some functions do not work if called from user_init)
TIMER_START(&userStartTimer, user_start, 10, 0);
}
@@ -154,6 +149,13 @@ static void ICACHE_FLASH_ATTR user_start(void *unused)
// 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, CAN, UART_TIMEOUT_US); // 0x18 - 24 - CAN
dbg("tsize=%d", sizeof(TerminalConfigBundle));
#if DEBUG_HEAP
// Heap use timer & blink
TIMER_START(&prHeapTimer, prHeapTimerCb, HEAP_TIMER_MS, 1);
#endif
}
// ---- unused funcs removed from sdk to save space ---
+3 -4
View File
@@ -9,11 +9,10 @@
#define STR(x) STR_HELPER(x)
#define FW_V_MAJOR 2
#define FW_V_MINOR 1
#define FW_V_MINOR 2
#define FW_V_PATCH 0
#define FW_V_SUFFIX "-beta3"
//#define FW_V_SUFFIX ""
#define FW_CODENAME "Anthill" // 2.1.0
#define FW_V_SUFFIX ""
#define FW_CODENAME "Bluet" // 2.2
#define FW_CODENAME_QUOTED "\""FW_CODENAME"\""
#define FW_VERSION STR(FW_V_MAJOR) "." STR(FW_V_MINOR) "." STR(FW_V_PATCH) FW_V_SUFFIX
+16
View File
@@ -8,6 +8,22 @@
WiFiConfigBundle * const wificonf = &persist.current.wificonf;
WiFiConfChangeFlags wifi_change_flags;
int ICACHE_FLASH_ATTR getStaIpAsString(char *buffer)
{
WIFI_MODE x = wifi_get_opmode();
STATION_STATUS connectStatus = wifi_station_get_connect_status();
if (x == SOFTAP_MODE || connectStatus != STATION_GOT_IP || wificonf->opmode == SOFTAP_MODE) {
strcpy(buffer, "");
return 0;
}
else {
struct ip_info info;
wifi_get_ip_info(STATION_IF, &info);
return sprintf(buffer, IPSTR, GOOD_IP2STR(info.ip.addr));
}
}
/**
* Restore defaults in the WiFi config block.
* This is to be called if the WiFi config is corrupted on startup,
+2
View File
@@ -60,6 +60,8 @@ void wifimgr_restore_defaults(void);
void wifimgr_apply_settings(void);
int getStaIpAsString(char *buffer);
#if DEBUG_WIFI
#define wifi_warn warn
#define wifi_dbg dbg