From c2593c22071d65264ad7a85fef74300c76d164d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Tue, 24 Jan 2017 11:38:17 +0100 Subject: [PATCH] implemented browser-esp comm; uart1 not working for some reason --- libesphttpd | 2 +- user/serial.c | 2 +- user/user_main.c | 128 ++++++++++++----------------------------------- user/web.c | 110 ++++++++++++++++++++++++++++++++++++++++ user/web.h | 12 +++++ 5 files changed, 155 insertions(+), 99 deletions(-) create mode 100644 user/web.c create mode 100644 user/web.h diff --git a/libesphttpd b/libesphttpd index 1a69994..e594412 160000 --- a/libesphttpd +++ b/libesphttpd @@ -1 +1 @@ -Subproject commit 1a699948bb07d789f827d831f3994fc1b2d962de +Subproject commit e5944123376d0d0a4f8547cd27b3aa7bef166f2a diff --git a/user/serial.c b/user/serial.c index 6b63602..65b6eb9 100644 --- a/user/serial.c +++ b/user/serial.c @@ -31,4 +31,4 @@ void ICACHE_FLASH_ATTR UART_HandleRxByte(char c) } else { warn("Bad char %d ('%c')", (unsigned char)c, c); } -} \ No newline at end of file +} diff --git a/user/user_main.c b/user/user_main.c index 9cc89cc..040ea66 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -1,3 +1,9 @@ +/** + * This is the ESP8266 Remote Terminal project main file. + * + * Front-end URLs and handlers are defined in web.c + */ + /* * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): @@ -7,84 +13,18 @@ * ---------------------------------------------------------------------------- */ -/** - * This is the ESP8266 Remote Terminal project main file. - */ - #include #include -#include #include #include #include #include "serial.h" #include "io.h" #include "screen.h" +#include "web.h" #define FIRMWARE_VERSION "0.1" -/** - * Broadcast screen state to sockets - */ -void screen_notifyChange() { - // TODO cooldown / buffering to reduce nr of such events - dbg("Screen notifyChange"); - - void *data = NULL; - - const int bufsiz = 512; - char buff[bufsiz]; - for (int i = 0; i < 20; i++) { - httpd_cgi_state cont = screenSerializeToBuffer(buff, bufsiz, &data); - int flg = 0; - if (cont == HTTPD_CGI_MORE) flg |= WEBSOCK_FLAG_MORE; - if (i > 0) flg |= WEBSOCK_FLAG_CONT; - cgiWebsockBroadcast("/ws/update.cgi", buff, (int)strlen(buff), flg); - if (cont == HTTPD_CGI_DONE) break; - } -} - -void myWebsocketRecv(Websock *ws, char *data, int len, int flags) { - dbg("Sock RX str: %s, len %d", data, len); -} - -/** Socket connected for updates */ -void ICACHE_FLASH_ATTR myWebsocketConnect(Websock *ws) { - dbg("Socket connected."); - ws->recvCb=myWebsocketRecv; -} - -/** - * Main page template substitution - * - * @param connData - * @param token - * @param arg - * @return - */ -httpd_cgi_state ICACHE_FLASH_ATTR tplScreen(HttpdConnData *connData, char *token, void **arg) { - if (token==NULL) { - // Release data object - screenSerializeToBuffer(NULL, 0, arg); - return HTTPD_CGI_DONE; - } - - const int bufsiz = 512; - char buff[bufsiz]; - - if (streq(token, "screenData")) { - httpd_cgi_state cont = screenSerializeToBuffer(buff, bufsiz, arg); - - dbg("Sending buf: %s", buff); - - httpdSend(connData, buff, -1); - return cont; - } - - return HTTPD_CGI_DONE; -} - - #ifdef ESPFS_POS CgiUploadFlashDef uploadParams={ .type=CGIFLASH_TYPE_ESPFS, @@ -105,34 +45,19 @@ CgiUploadFlashDef uploadParams={ #define INCLUDE_FLASH_FNS #endif -/** Routes */ -HttpdBuiltInUrl builtInUrls[]={ //ICACHE_RODATA_ATTR - // redirect func for the captive portal - ROUTE_CGI_ARG("*", cgiRedirectApClientToHostname, "esp8266.nonet"), - - ROUTE_WS("/ws/update.cgi", myWebsocketConnect), - - // TODO add funcs for WiFi management (when web UI is added) - - ROUTE_TPL_FILE("/", tplScreen, "term.tpl"), - ROUTE_FILESYSTEM(), - ROUTE_END(), -}; - static ETSTimer prHeapTimer; /** Blink & show heap usage */ -static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) { +static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) +{ static int led = 0; static unsigned int cnt = 0; - if (cnt==5) { + if (cnt == 5) { dbg("HEAP: %ld bytes free", (unsigned long) system_get_free_heap_size()); cnt = 0; } - //cgiWebsockBroadcast("/ws/update.cgi", "HELLO", 5, WEBSOCK_FLAG_NONE); - ioLed(led); led = !led; @@ -140,14 +65,19 @@ static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) { } //Main routine. Initialize stdout, the I/O, filesystem and the webserver and we're done. -void user_init(void) { +void user_init(void) +{ serialInit(); - banner("ESP8266 Remote Terminal"); - banner_info("Version "FIRMWARE_VERSION", built "__DATE__" at "__TIME__); - dbg("!!! TODO (c) and GitHub link here !!!"); - - //stdoutInit(); + printf("\r\n"); + banner("*** ESP8266 Remote Terminal ***"); + banner_info("Firmware (c) Ondrej Hruska, 2017"); + banner_info("github.com/MightyPork/esp-vt100-firmware"); + banner_info(""); + banner_info("Version " FIRMWARE_VERSION ", built " __DATE__ " at " __TIME__); + banner_info(""); + banner_info("Department of Measurement, CTU Prague"); + banner_info(""); captdnsInit(); ioInit(); @@ -157,7 +87,7 @@ void user_init(void) { #ifdef ESPFS_POS espFsInit((void*)(0x40200000 + ESPFS_POS)); #else - espFsInit((void*)(webpages_espfs_start)); + espFsInit((void *) (webpages_espfs_start)); #endif httpdInit(builtInUrls, 80); @@ -167,23 +97,27 @@ void user_init(void) { os_timer_setfn(&prHeapTimer, prHeapTimerCb, NULL); os_timer_arm(&prHeapTimer, 1000, 1); + // The terminal screen screen_init(); - info("System ready!"); + info("Listening on UART0, 115200-8-N-1!"); } // ---- unused funcs removed from sdk to save space --- -void user_rf_pre_init() { +void user_rf_pre_init() +{ //Not needed, but some SDK versions want this defined. } // вызывается из phy_chip_v6.o -void ICACHE_FLASH_ATTR chip_v6_set_sense(void) { +void ICACHE_FLASH_ATTR chip_v6_set_sense(void) +{ // ret.n } // вызывается из phy_chip_v6.o -int ICACHE_FLASH_ATTR chip_v6_unset_chanfreq(void) { +int ICACHE_FLASH_ATTR chip_v6_unset_chanfreq(void) +{ return 0; -} \ No newline at end of file +} diff --git a/user/web.c b/user/web.c new file mode 100644 index 0000000..2a07af0 --- /dev/null +++ b/user/web.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include + +#include "web.h" +#include "screen.h" +#include "uart_driver.h" + +#define URL_WS_UPDATE "/ws/update.cgi" + +/* Routes are defined at the bottom of the file */ + +/** + * Main page template substitution + * + * @param connData + * @param token + * @param arg + * @return + */ +httpd_cgi_state ICACHE_FLASH_ATTR tplScreen(HttpdConnData *connData, char *token, void **arg) +{ + if (token == NULL) { + // Release data object + screenSerializeToBuffer(NULL, 0, arg); + return HTTPD_CGI_DONE; + } + + const int bufsiz = 512; + char buff[bufsiz]; + + if (streq(token, "screenData")) { + httpd_cgi_state cont = screenSerializeToBuffer(buff, bufsiz, arg); + httpdSend(connData, buff, -1); + return cont; + } + + return HTTPD_CGI_DONE; +} + +// --- Sockets --- + + +/** + * Broadcast screen state to sockets + */ +void ICACHE_FLASH_ATTR screen_notifyChange() +{ + // TODO cooldown / buffering to reduce nr of such events + + void *data = NULL; + + const int bufsiz = 512; + char buff[bufsiz]; + for (int i = 0; i < 20; i++) { + httpd_cgi_state cont = screenSerializeToBuffer(buff, bufsiz, &data); + int flg = 0; + if (cont == HTTPD_CGI_MORE) flg |= WEBSOCK_FLAG_MORE; + if (i > 0) flg |= WEBSOCK_FLAG_CONT; + cgiWebsockBroadcast(URL_WS_UPDATE, buff, (int) strlen(buff), flg); + if (cont == HTTPD_CGI_DONE) break; + } +} + +/** Socket received a message */ +void ICACHE_FLASH_ATTR myWebsocketRecv(Websock *ws, char *data, int len, int flags) +{ + dbg("Sock RX str: %s, len %d", data, len); + + if (strstarts(data, "STR:")) { + // pass string verbatim + UART_WriteString(UART0, data+4, UART_TIMEOUT_US); + } + else if (strstarts(data, "BTN:")) { + // send button as low ASCII value 1-9 + int btnNum = data[4] - '0'; + if (btnNum > 0 && btnNum < 10) { + UART_WriteChar(UART0, (unsigned char)btnNum, UART_TIMEOUT_US); + } + } + else if (strstarts(data, "TAP:")) { + // TODO + warn("TODO mouse input handling not implemented!"); + } + else { + warn("Bad command."); + } +} + +/** Socket connected for updates */ +void ICACHE_FLASH_ATTR myWebsocketConnect(Websock *ws) +{ + info("Socket connected to "URL_WS_UPDATE); + ws->recvCb = myWebsocketRecv; +} + +/** Routes */ +HttpdBuiltInUrl builtInUrls[] = { //ICACHE_RODATA_ATTR + // redirect func for the captive portal + ROUTE_CGI_ARG("*", cgiRedirectApClientToHostname, "esp8266.nonet"), + + ROUTE_WS(URL_WS_UPDATE, myWebsocketConnect), + + // TODO add funcs for WiFi management (when web UI is added) + + ROUTE_TPL_FILE("/", tplScreen, "term.tpl"), + ROUTE_FILESYSTEM(), + ROUTE_END(), +}; diff --git a/user/web.h b/user/web.h new file mode 100644 index 0000000..c33ede5 --- /dev/null +++ b/user/web.h @@ -0,0 +1,12 @@ +#ifndef WEB_H +#define WEB_H + +#include +#include + +extern HttpdBuiltInUrl builtInUrls[]; + +/** Broadcast screen state to sockets */ +void screen_notifyChange(); + +#endif //WEB_H