Merge branch 'http-comm' into work
This commit is contained in:
@@ -216,7 +216,7 @@ libesphttpd/Makefile:
|
||||
$(Q) [[ -e "libesphttpd/Makefile" ]] || echo -e "\e[31mlibesphttpd submodule missing.\nIf build fails, run \"git submodule init\" and \"git submodule update\".\e[0m"
|
||||
|
||||
libesphttpd: libesphttpd/Makefile
|
||||
$(Q) make -C libesphttpd USE_OPENSDK=$(USE_OPENSDK) SERVERNAME_PREFIX="ESPTerm " -j4
|
||||
$(Q) make -C libesphttpd USE_OPENSDK=$(USE_OPENSDK) -j4
|
||||
|
||||
$(APP_AR): libesphttpd $(OBJ)
|
||||
$(vecho) "AR $@"
|
||||
|
||||
@@ -39,6 +39,8 @@ OUTPUT_TYPE = combined
|
||||
ESP_SPI_FLASH_SIZE_K = 1024
|
||||
|
||||
GLOBAL_CFLAGS = \
|
||||
-DASYNC_LOG=1 \
|
||||
-DDEBUG_D2D=0 \
|
||||
-DDEBUG_ROUTER=0 \
|
||||
-DDEBUG_CAPTDNS=0 \
|
||||
-DDEBUG_HTTP=0 \
|
||||
|
||||
+1
-1
Submodule front-end updated: 29b813457c...6f165da9b6
+1
-1
Submodule libesphttpd updated: 7fce947439...348420959b
+30
-33
@@ -36,10 +36,6 @@ static const int ansi_en_main = 1;
|
||||
/* #line 12 "user/ansi_parser.rl" */
|
||||
|
||||
|
||||
// Max nr of CSI parameters
|
||||
#define CSI_N_MAX 10
|
||||
#define ANSI_STR_LEN 64
|
||||
|
||||
static volatile int cs = -1;
|
||||
static volatile bool inside_string = false;
|
||||
|
||||
@@ -123,12 +119,12 @@ ansi_parser(char newchar)
|
||||
// Init Ragel on the first run
|
||||
if (cs == -1) {
|
||||
|
||||
/* #line 127 "user/ansi_parser.c" */
|
||||
/* #line 123 "user/ansi_parser.c" */
|
||||
{
|
||||
cs = ansi_start;
|
||||
}
|
||||
|
||||
/* #line 101 "user/ansi_parser.rl" */
|
||||
/* #line 97 "user/ansi_parser.rl" */
|
||||
|
||||
#if DEBUG_ANSI
|
||||
memset(history, 0, sizeof(history));
|
||||
@@ -142,6 +138,13 @@ ansi_parser(char newchar)
|
||||
history[HISTORY_LEN-1] = newchar;
|
||||
#endif
|
||||
|
||||
// THose should work always, even inside a string
|
||||
if (newchar == CAN || newchar == SUB) {
|
||||
// Cancel the active sequence
|
||||
cs = ansi_start;
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle simple characters immediately (bypass parser)
|
||||
if (newchar < ' ' && !inside_string) {
|
||||
switch (newchar) {
|
||||
@@ -183,12 +186,6 @@ ansi_parser(char newchar)
|
||||
apars_handle_enq();
|
||||
return;
|
||||
|
||||
// Cancel the active sequence
|
||||
case CAN:
|
||||
case SUB:
|
||||
cs = ansi_start;
|
||||
return;
|
||||
|
||||
default:
|
||||
// Discard all other control codes
|
||||
return;
|
||||
@@ -208,7 +205,7 @@ ansi_parser(char newchar)
|
||||
|
||||
// The parser
|
||||
|
||||
/* #line 212 "user/ansi_parser.c" */
|
||||
/* #line 209 "user/ansi_parser.c" */
|
||||
{
|
||||
const char *_acts;
|
||||
unsigned int _nacts;
|
||||
@@ -398,7 +395,7 @@ execFuncs:
|
||||
while ( _nacts-- > 0 ) {
|
||||
switch ( *_acts++ ) {
|
||||
case 0:
|
||||
/* #line 188 "user/ansi_parser.rl" */
|
||||
/* #line 185 "user/ansi_parser.rl" */
|
||||
{
|
||||
ansi_warn("Parser error.");
|
||||
apars_show_context();
|
||||
@@ -407,7 +404,7 @@ execFuncs:
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* #line 197 "user/ansi_parser.rl" */
|
||||
/* #line 194 "user/ansi_parser.rl" */
|
||||
{
|
||||
if ((*p) != 0) {
|
||||
apars_handle_plainchar((*p));
|
||||
@@ -415,7 +412,7 @@ execFuncs:
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
/* #line 205 "user/ansi_parser.rl" */
|
||||
/* #line 202 "user/ansi_parser.rl" */
|
||||
{
|
||||
// Reset the CSI builder
|
||||
leadchar = NUL;
|
||||
@@ -432,13 +429,13 @@ execFuncs:
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
/* #line 220 "user/ansi_parser.rl" */
|
||||
/* #line 217 "user/ansi_parser.rl" */
|
||||
{
|
||||
leadchar = (*p);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
/* #line 224 "user/ansi_parser.rl" */
|
||||
/* #line 221 "user/ansi_parser.rl" */
|
||||
{
|
||||
if (arg_cnt == 0) arg_cnt = 1;
|
||||
// x10 + digit
|
||||
@@ -448,7 +445,7 @@ execFuncs:
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
/* #line 232 "user/ansi_parser.rl" */
|
||||
/* #line 229 "user/ansi_parser.rl" */
|
||||
{
|
||||
if (arg_cnt == 0) arg_cnt = 1; // handle case when first arg is empty
|
||||
arg_cnt++;
|
||||
@@ -456,20 +453,20 @@ execFuncs:
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
/* #line 238 "user/ansi_parser.rl" */
|
||||
/* #line 235 "user/ansi_parser.rl" */
|
||||
{
|
||||
interchar = (*p);
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
/* #line 242 "user/ansi_parser.rl" */
|
||||
/* #line 239 "user/ansi_parser.rl" */
|
||||
{
|
||||
apars_handle_csi(leadchar, arg, arg_cnt, interchar, (*p));
|
||||
{cs = 1;goto _again;}
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
/* #line 254 "user/ansi_parser.rl" */
|
||||
/* #line 251 "user/ansi_parser.rl" */
|
||||
{
|
||||
leadchar = (*p);
|
||||
str_ni = 0;
|
||||
@@ -479,13 +476,13 @@ execFuncs:
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
/* #line 262 "user/ansi_parser.rl" */
|
||||
/* #line 259 "user/ansi_parser.rl" */
|
||||
{
|
||||
string_buffer[str_ni++] = (*p);
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
/* #line 266 "user/ansi_parser.rl" */
|
||||
/* #line 263 "user/ansi_parser.rl" */
|
||||
{
|
||||
inside_string = false;
|
||||
string_buffer[str_ni++] = '\0';
|
||||
@@ -494,41 +491,41 @@ execFuncs:
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
/* #line 279 "user/ansi_parser.rl" */
|
||||
/* #line 276 "user/ansi_parser.rl" */
|
||||
{
|
||||
apars_handle_hash_cmd((*p));
|
||||
{cs = 1;goto _again;}
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
/* #line 284 "user/ansi_parser.rl" */
|
||||
/* #line 281 "user/ansi_parser.rl" */
|
||||
{
|
||||
apars_handle_short_cmd((*p));
|
||||
{cs = 1;goto _again;}
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
/* #line 289 "user/ansi_parser.rl" */
|
||||
/* #line 286 "user/ansi_parser.rl" */
|
||||
{
|
||||
apars_handle_space_cmd((*p));
|
||||
{cs = 1;goto _again;}
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
/* #line 296 "user/ansi_parser.rl" */
|
||||
/* #line 293 "user/ansi_parser.rl" */
|
||||
{
|
||||
leadchar = (*p);
|
||||
{cs = 10;goto _again;}
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
/* #line 301 "user/ansi_parser.rl" */
|
||||
/* #line 298 "user/ansi_parser.rl" */
|
||||
{
|
||||
apars_handle_chs_designate(leadchar, (*p));
|
||||
{cs = 1;goto _again;}
|
||||
}
|
||||
break;
|
||||
/* #line 532 "user/ansi_parser.c" */
|
||||
/* #line 529 "user/ansi_parser.c" */
|
||||
}
|
||||
}
|
||||
goto _again;
|
||||
@@ -546,7 +543,7 @@ _again:
|
||||
while ( __nacts-- > 0 ) {
|
||||
switch ( *__acts++ ) {
|
||||
case 0:
|
||||
/* #line 188 "user/ansi_parser.rl" */
|
||||
/* #line 185 "user/ansi_parser.rl" */
|
||||
{
|
||||
ansi_warn("Parser error.");
|
||||
apars_show_context();
|
||||
@@ -556,7 +553,7 @@ _again:
|
||||
goto _again;}
|
||||
}
|
||||
break;
|
||||
/* #line 560 "user/ansi_parser.c" */
|
||||
/* #line 557 "user/ansi_parser.c" */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -564,6 +561,6 @@ goto _again;}
|
||||
_out: {}
|
||||
}
|
||||
|
||||
/* #line 324 "user/ansi_parser.rl" */
|
||||
/* #line 321 "user/ansi_parser.rl" */
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define CSI_N_MAX 12
|
||||
#define ANSI_STR_LEN 256
|
||||
|
||||
extern volatile bool ansi_parser_inhibit; // discard all characters
|
||||
|
||||
void ansi_parser_reset(void);
|
||||
|
||||
+7
-10
@@ -11,10 +11,6 @@
|
||||
write data;
|
||||
}%%
|
||||
|
||||
// Max nr of CSI parameters
|
||||
#define CSI_N_MAX 10
|
||||
#define ANSI_STR_LEN 64
|
||||
|
||||
static volatile int cs = -1;
|
||||
static volatile bool inside_string = false;
|
||||
|
||||
@@ -111,6 +107,13 @@ ansi_parser(char newchar)
|
||||
history[HISTORY_LEN-1] = newchar;
|
||||
#endif
|
||||
|
||||
// THose should work always, even inside a string
|
||||
if (newchar == CAN || newchar == SUB) {
|
||||
// Cancel the active sequence
|
||||
cs = ansi_start;
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle simple characters immediately (bypass parser)
|
||||
if (newchar < ' ' && !inside_string) {
|
||||
switch (newchar) {
|
||||
@@ -152,12 +155,6 @@ ansi_parser(char newchar)
|
||||
apars_handle_enq();
|
||||
return;
|
||||
|
||||
// Cancel the active sequence
|
||||
case CAN:
|
||||
case SUB:
|
||||
cs = ansi_start;
|
||||
return;
|
||||
|
||||
default:
|
||||
// Discard all other control codes
|
||||
return;
|
||||
|
||||
@@ -11,6 +11,14 @@
|
||||
#include "version.h"
|
||||
#include "uart_buffer.h"
|
||||
#include "screen.h"
|
||||
#include "uart_driver.h"
|
||||
|
||||
volatile bool enquiry_suppressed = false;
|
||||
ETSTimer enqTimer;
|
||||
void ICACHE_FLASH_ATTR enqTimerCb(void *unused)
|
||||
{
|
||||
enquiry_suppressed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a response to UART0
|
||||
@@ -19,7 +27,8 @@
|
||||
void ICACHE_FLASH_ATTR
|
||||
apars_respond(const char *str)
|
||||
{
|
||||
UART_SendAsync(str, -1);
|
||||
UART_WriteString(UART0, str, UART_TIMEOUT_US);
|
||||
//UART_SendAsync(str, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,8 +46,16 @@ apars_handle_bel(void)
|
||||
void ICACHE_FLASH_ATTR
|
||||
apars_handle_enq(void)
|
||||
{
|
||||
if (enquiry_suppressed) return;
|
||||
|
||||
// version encased in SOS and ST
|
||||
apars_respond("\x1bXESPTerm " FIRMWARE_VERSION "\x1b\\");
|
||||
|
||||
// Throttle enquiry - this is a single-character-invoked response,
|
||||
// so it tends to happen randomly when throwing garbage at the ESP.
|
||||
// We don't want to fill the output buffer with dozens of enquiry responses
|
||||
enquiry_suppressed = true;
|
||||
TIMER_START(&enqTimer, enqTimerCb, 500, 0);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@
|
||||
* @param buffer - the DCS body (after DCS and before ST)
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
apars_handle_dcs(const char *buffer)
|
||||
apars_handle_dcs(char *buffer)
|
||||
{
|
||||
char buf[64]; // just about big enough for full-house SGR
|
||||
size_t len = strlen(buffer);
|
||||
|
||||
+1
-1
@@ -5,6 +5,6 @@
|
||||
#ifndef ESP_VT100_FIRMWARE_APARS_DCS_H
|
||||
#define ESP_VT100_FIRMWARE_APARS_DCS_H
|
||||
|
||||
void apars_handle_dcs(const char *buffer);
|
||||
void apars_handle_dcs(char *buffer);
|
||||
|
||||
#endif //ESP_VT100_FIRMWARE_APARS_DCS_H
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// Created by MightyPork on 2017/08/20.
|
||||
//
|
||||
// Handle privacy messages
|
||||
// PM Pt ST
|
||||
// (PM = ESC ^)
|
||||
//
|
||||
// Those are used for device-to-device communication.
|
||||
// They were not used for anything in the original VT100 and are not
|
||||
// used by Xterm or any other common emulator, but they should be safely discarded.
|
||||
//
|
||||
|
||||
#include <esp8266.h>
|
||||
#include <httpclient.h>
|
||||
#include "apars_pm.h"
|
||||
#include "version.h"
|
||||
#include "ansi_parser_callbacks.h"
|
||||
#include "screen.h"
|
||||
#include "apars_logging.h"
|
||||
#include "cgi_d2d.h"
|
||||
|
||||
/**
|
||||
* Helper function to parse incoming DCS (Device Control String)
|
||||
* @param msg - the DCS body (after DCS and before ST)
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
apars_handle_pm(char *msg)
|
||||
{
|
||||
if (d2d_parse_command(msg)) return;
|
||||
|
||||
return;
|
||||
fail:
|
||||
ansi_warn("D2D message error: %s", msg);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
//
|
||||
// Created by MightyPork on 2017/08/20.
|
||||
//
|
||||
|
||||
#ifndef ESP_VT100_FIRMWARE_APARS_PM_H
|
||||
#define ESP_VT100_FIRMWARE_APARS_PM_H
|
||||
|
||||
void apars_handle_pm(char *msg);
|
||||
|
||||
#endif //ESP_VT100_FIRMWARE_APARS_PM_H
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "apars_short.h"
|
||||
#include "apars_logging.h"
|
||||
#include "screen.h"
|
||||
#include "ansi_parser_callbacks.h"
|
||||
|
||||
// ----- Character Set ---
|
||||
|
||||
|
||||
+3
-1
@@ -17,6 +17,7 @@
|
||||
#include "apars_logging.h"
|
||||
#include "ansi_parser_callbacks.h"
|
||||
#include "screen.h"
|
||||
#include "apars_pm.h"
|
||||
|
||||
// ----- Generic String cmd - disambiguation -----
|
||||
|
||||
@@ -24,7 +25,7 @@ void ICACHE_FLASH_ATTR
|
||||
apars_handle_string_cmd(char leadchar, char *buffer)
|
||||
{
|
||||
switch (leadchar) {
|
||||
case 'k': // ESC k TITLE ST (defined in GNU screen manpage)
|
||||
case 'k': // ESC k TITLE ST (defined in GNU screen manpage, probably not standard)
|
||||
screen_set_title(buffer);
|
||||
break;
|
||||
|
||||
@@ -37,6 +38,7 @@ apars_handle_string_cmd(char leadchar, char *buffer)
|
||||
break;
|
||||
|
||||
case '^': // PM - Privacy Message
|
||||
apars_handle_pm(buffer);
|
||||
break;
|
||||
|
||||
case '_': // APC - Application Program Command
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// Created by MightyPork on 2017/10/01.
|
||||
//
|
||||
|
||||
#ifndef ESPTERM_API_H
|
||||
#define ESPTERM_API_H
|
||||
|
||||
// TODO use X-MACRO for access restrictions etc
|
||||
|
||||
#define API_D2D_MSG "/api/v1/msg"
|
||||
#define API_REBOOT "/api/v1/reboot"
|
||||
#define API_PING "/api/v1/ping"
|
||||
#define API_CLEAR "/api/v1/clear"
|
||||
|
||||
#endif //ESPTERM_API_H
|
||||
+316
@@ -0,0 +1,316 @@
|
||||
//
|
||||
// Created by MightyPork on 2017/10/01.
|
||||
//
|
||||
|
||||
#include <esp8266.h>
|
||||
#include "cgi_d2d.h"
|
||||
#include "version.h"
|
||||
#include "ansi_parser_callbacks.h"
|
||||
#include "api.h"
|
||||
#include <httpclient.h>
|
||||
#include <esp_utils.h>
|
||||
|
||||
#define D2D_TIMEOUT_MS 2000
|
||||
|
||||
#define D2D_HEADERS \
|
||||
"User-Agent: ESPTerm "FIRMWARE_VERSION" like curl wget HTTPie\r\n" \
|
||||
"Content-Type: text/plain; charset=utf-8\r\n" \
|
||||
"Accept-Encoding: identity\r\n" \
|
||||
"Accept-Charset: utf-8\r\n" \
|
||||
"Accept: text/*, application/json\r\n" \
|
||||
"Cache-Control: no-cache,private,max-age=0\r\n"
|
||||
|
||||
struct d2d_request_opts {
|
||||
bool want_body;
|
||||
bool want_head;
|
||||
size_t max_result_len;
|
||||
char *nonce;
|
||||
};
|
||||
|
||||
volatile bool request_pending = false;
|
||||
|
||||
static void ICACHE_FLASH_ATTR
|
||||
requestNoopCb(int http_status,
|
||||
char *response_headers,
|
||||
char *response_body,
|
||||
size_t body_size,
|
||||
void *userArg)
|
||||
{
|
||||
request_pending = false;
|
||||
if (userArg != NULL) free(userArg);
|
||||
}
|
||||
|
||||
static void ICACHE_FLASH_ATTR
|
||||
requestCb(int http_status,
|
||||
char *response_headers,
|
||||
char *response_body,
|
||||
size_t body_size,
|
||||
void *userArg)
|
||||
{
|
||||
if (userArg == NULL) {
|
||||
request_pending = false;
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
char buff100[100];
|
||||
int len = 0;
|
||||
size_t headers_size = strlen(response_headers);
|
||||
|
||||
if (opts->want_head) len += headers_size;
|
||||
if (opts->want_body) len += body_size + (opts->want_head*2);
|
||||
if (opts->max_result_len > 0 && len > opts->max_result_len)
|
||||
len = (int) opts->max_result_len;
|
||||
|
||||
char *bb = buff100;
|
||||
bb += sprintf(bb, "\x1b^h;%d;", http_status);
|
||||
const char *comma = "";
|
||||
|
||||
if (opts->want_head) {
|
||||
bb += sprintf(bb, "%sH", comma);
|
||||
comma = ",";
|
||||
}
|
||||
|
||||
if (opts->want_body) {
|
||||
bb += sprintf(bb, "%sB", comma);
|
||||
comma = ",";
|
||||
}
|
||||
|
||||
if (opts->nonce) {
|
||||
bb += sprintf(bb, "%sN=%s", comma, opts->nonce);
|
||||
comma = ",";
|
||||
}
|
||||
|
||||
if (opts->want_head || opts->want_body) {
|
||||
bb += sprintf(bb, "%sL=%d", comma, len);
|
||||
//comma = ",";
|
||||
}
|
||||
|
||||
// semicolon only if more data is to be sent
|
||||
if (opts->want_head || opts->want_body) sprintf(bb, ";");
|
||||
|
||||
apars_respond(buff100);
|
||||
|
||||
//d2d_dbg("Headers (part) %100s", response_headers);
|
||||
//d2d_dbg("Body (part) %100s", response_body);
|
||||
|
||||
// head and payload separated by \r\n\r\n (one \r\n is at the end of head - maybe)
|
||||
if (opts->want_head) {
|
||||
// truncate
|
||||
if (headers_size > len) {
|
||||
response_headers[len] = 0;
|
||||
opts->want_body = false; // soz, it wouldn't fit
|
||||
}
|
||||
apars_respond(response_headers);
|
||||
if(opts->want_body) apars_respond("\r\n");
|
||||
}
|
||||
|
||||
if(opts->want_body) {
|
||||
// truncate
|
||||
if (opts->want_head*(headers_size+2)+body_size > len) {
|
||||
response_body[len - (opts->want_head*(headers_size+2))] = 0;
|
||||
}
|
||||
|
||||
apars_respond(response_body);
|
||||
}
|
||||
|
||||
apars_respond("\a");
|
||||
|
||||
free(opts->nonce);
|
||||
free(opts);
|
||||
|
||||
request_pending = false;
|
||||
}
|
||||
|
||||
bool ICACHE_FLASH_ATTR
|
||||
d2d_parse_command(char *msg)
|
||||
{
|
||||
char buff40[40];
|
||||
char *p;
|
||||
|
||||
#define FIND_NEXT(target, delim) do { \
|
||||
p = strchr(msg, (delim)); \
|
||||
if (p == NULL) return false; \
|
||||
*p = '\0'; \
|
||||
(target) = msg; \
|
||||
msg = p + 1; \
|
||||
} while(0) \
|
||||
|
||||
if (strstarts(msg, "M;")) {
|
||||
if (request_pending) return false;
|
||||
|
||||
// Send a esp-esp message
|
||||
msg += 2;
|
||||
const char *ip;
|
||||
FIND_NEXT(ip, ';');
|
||||
const char *payload = msg;
|
||||
|
||||
d2d_dbg("D2D Tx,dest=%s,msg=%s", ip, payload);
|
||||
sprintf(buff40, "http://%s" API_D2D_MSG, ip);
|
||||
|
||||
httpclient_args args;
|
||||
httpclient_args_init(&args);
|
||||
args.method = HTTPD_METHOD_POST;
|
||||
args.body = payload;
|
||||
args.headers = D2D_HEADERS;
|
||||
args.timeout = D2D_TIMEOUT_MS;
|
||||
args.url = buff40; // "escapes scope" warning - can ignore, strdup is used
|
||||
|
||||
request_pending = true;
|
||||
http_request(&args, requestNoopCb);
|
||||
return true;
|
||||
}
|
||||
else if (strstarts(msg, "H;")) {
|
||||
if (request_pending) return false;
|
||||
|
||||
// Send a esp-esp message
|
||||
msg += 2;
|
||||
const char *method = NULL;
|
||||
const char *params = NULL;
|
||||
const char *nonce = NULL;
|
||||
const char *url = NULL;
|
||||
const char *payload = NULL;
|
||||
httpd_method methodNum;
|
||||
|
||||
FIND_NEXT(method, ';');
|
||||
|
||||
if (streq(method, "GET")) methodNum = HTTPD_METHOD_GET;
|
||||
else if (streq(method, "POST")) methodNum = HTTPD_METHOD_POST;
|
||||
else if (streq(method, "OPTIONS")) methodNum = HTTPD_METHOD_OPTIONS;
|
||||
else if (streq(method, "PUT")) methodNum = HTTPD_METHOD_PUT;
|
||||
else if (streq(method, "DELETE")) methodNum = HTTPD_METHOD_DELETE;
|
||||
else if (streq(method, "PATCH")) methodNum = HTTPD_METHOD_PATCH;
|
||||
else if (streq(method, "HEAD")) methodNum = HTTPD_METHOD_HEAD;
|
||||
else {
|
||||
d2d_warn("BAD METHOD: %s", method);
|
||||
return false;
|
||||
}
|
||||
|
||||
FIND_NEXT(params, ';');
|
||||
|
||||
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;
|
||||
bool want_body = 0;
|
||||
bool want_head = 0;
|
||||
bool no_resp = 0;
|
||||
|
||||
do {
|
||||
p = strchr(params, ',');
|
||||
if (p != NULL) *p = '\0';
|
||||
const char *param = params;
|
||||
if (params[0] == 0) break; // no params
|
||||
|
||||
if(streq(param, "H")) want_head = 1; // Return head
|
||||
else if(streq(param, "B")) want_body = 1; // Return body
|
||||
else if(streq(param, "X")) no_resp = 1; // X - no response, no callback
|
||||
else if(strstarts(param, "l=")) { // max buffer length
|
||||
max_buf_len = (size_t) atoi(param + 2);
|
||||
} else if(strstarts(param, "L=")) { // max length
|
||||
max_result_len = (size_t) atoi(param + 2);
|
||||
} else if(strstarts(param, "T=")) { // timeout
|
||||
timeout = (uint) atoi(param + 2);
|
||||
} else if(strstarts(param, "N=")) { // Nonce
|
||||
nonce = param+2;
|
||||
} else {
|
||||
d2d_warn("BAD PARAM: %s", param);
|
||||
return false;
|
||||
}
|
||||
|
||||
d2d_dbg("- param %s", params);
|
||||
|
||||
if (p == NULL) break;
|
||||
params = p + 1;
|
||||
} while(1);
|
||||
|
||||
p = strchr(msg, '\n');
|
||||
if (p != NULL) *p = '\0';
|
||||
url = msg;
|
||||
d2d_dbg("URL: %s", url);
|
||||
|
||||
if (p != NULL) {
|
||||
payload = p + 1;
|
||||
d2d_dbg("Payload: %s", payload);
|
||||
} else {
|
||||
payload = NULL;
|
||||
}
|
||||
|
||||
httpclient_args args;
|
||||
httpclient_args_init(&args);
|
||||
args.method = methodNum;
|
||||
args.body = payload;
|
||||
args.headers = D2D_HEADERS;
|
||||
args.timeout = timeout;
|
||||
args.max_response_len = max_buf_len;
|
||||
args.url = url;
|
||||
|
||||
if (!no_resp) {
|
||||
struct d2d_request_opts *opts = malloc(sizeof(struct d2d_request_opts));
|
||||
opts->want_body = want_body;
|
||||
opts->want_head = want_head;
|
||||
opts->max_result_len = max_result_len;
|
||||
opts->nonce = esp_strdup(nonce);
|
||||
args.userData = opts;
|
||||
}
|
||||
|
||||
request_pending = true;
|
||||
http_request(&args, no_resp ? requestNoopCb : requestCb);
|
||||
|
||||
d2d_dbg("Done");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
httpd_cgi_state ICACHE_FLASH_ATTR cgiD2DMessage(HttpdConnData *connData)
|
||||
{
|
||||
if (connData->conn==NULL) {
|
||||
//Connection aborted. Clean up.
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
|
||||
size_t len = 0;
|
||||
if (connData->post && connData->post->buff)
|
||||
len = strlen(connData->post->buff);
|
||||
else if (connData->getArgs)
|
||||
len = strlen(connData->getArgs);
|
||||
else
|
||||
len = 0;
|
||||
|
||||
u8 *ip = connData->remote_ip;
|
||||
char buf[20];
|
||||
sprintf(buf, "\x1b^m;"IPSTR";L=%d;", ip[0], ip[1], ip[2], ip[3], (int)len);
|
||||
apars_respond(buf);
|
||||
|
||||
if (connData->post && connData->post->buff)
|
||||
apars_respond(connData->post->buff);
|
||||
else if (connData->getArgs)
|
||||
apars_respond(connData->getArgs);
|
||||
|
||||
apars_respond("\a");
|
||||
|
||||
d2d_dbg("D2D Rx src="IPSTR",len=%d", ip[0], ip[1], ip[2], ip[3],len);
|
||||
|
||||
// Received a msg
|
||||
|
||||
httdResponseOptions(connData, 0);
|
||||
httdSetTransferMode(connData, HTTPD_TRANSFER_CLOSE);
|
||||
|
||||
httpdStartResponse(connData, 200);
|
||||
httpdHeader(connData, "Content-Type", "text/plain");
|
||||
httpdEndHeaders(connData);
|
||||
|
||||
httpdSend(connData, "message received\r\n", -1);
|
||||
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// Created by MightyPork on 2017/10/01.
|
||||
//
|
||||
|
||||
#ifndef ESPTERM_CGI_D2D_H
|
||||
#define ESPTERM_CGI_D2D_H
|
||||
|
||||
#include <esp8266.h>
|
||||
#include <httpd.h>
|
||||
|
||||
#if DEBUG_D2D
|
||||
#define d2d_warn warn
|
||||
#define d2d_dbg dbg
|
||||
#define d2d_info info
|
||||
#else
|
||||
#define d2d_warn(fmt, ...)
|
||||
#define d2d_dbg(fmt, ...)
|
||||
#define d2d_info(fmt, ...)
|
||||
#endif
|
||||
|
||||
bool d2d_parse_command(char *msg);
|
||||
|
||||
httpd_cgi_state cgiD2DMessage(HttpdConnData *connData);
|
||||
|
||||
#endif //ESPTERM_CGI_D2D_H
|
||||
+10
-4
@@ -69,7 +69,7 @@ updateNotify_do(Websock *ws, ScreenNotifyTopics topics)
|
||||
}
|
||||
httpd_cgi_state cont = screenSerializeToBuffer(sock_buff, SOCK_BUF_LEN, topics, &data);
|
||||
|
||||
int flg = WEBSOCK_FLAG_BIN;
|
||||
int flg = 0; //WEBSOCK_FLAG_BIN
|
||||
if (cont == HTTPD_CGI_MORE) flg |= WEBSOCK_FLAG_MORE;
|
||||
if (i > 0) flg |= WEBSOCK_FLAG_CONT;
|
||||
if (ws) {
|
||||
@@ -260,7 +260,7 @@ static void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int
|
||||
|
||||
// TODO base this on the actual buffer empty space, not rx chunk size
|
||||
if ((UART_AsyncTxGetEmptySpace() < 256) && !browser_wants_xon) {
|
||||
UART_WriteChar(UART1, '-', 100);
|
||||
//UART_WriteChar(UART1, '-', 100);
|
||||
cgiWebsockBroadcast(URL_WS_UPDATE, "-", 1, 0);
|
||||
browser_wants_xon = true;
|
||||
|
||||
@@ -304,13 +304,17 @@ static void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int
|
||||
/** Send a heartbeat msg */
|
||||
static void ICACHE_FLASH_ATTR heartbeatTimCb(void *unused)
|
||||
{
|
||||
static u32 hbcnt=0;
|
||||
|
||||
if (term_active_clients > 0) {
|
||||
if (notify_available) {
|
||||
inp_dbg(".");
|
||||
|
||||
// Heartbeat packet - indicate we're still connected
|
||||
// JS reloads the page if heartbeat is lost for a couple seconds
|
||||
cgiWebsockBroadcast(URL_WS_UPDATE, ".", 1, 0);
|
||||
char buf[10];
|
||||
sprintf(buf, ".%d", hbcnt++);
|
||||
cgiWebsockBroadcast(URL_WS_UPDATE, buf, (int) strlen(buf), 0);
|
||||
|
||||
// schedule next tick
|
||||
TIMER_START(&heartbeatTim, heartbeatTimCb, HB_TIME, 0);
|
||||
@@ -331,6 +335,7 @@ static void ICACHE_FLASH_ATTR resetHeartbeatTimer(void)
|
||||
static void ICACHE_FLASH_ATTR closeSockCb(Websock *ws)
|
||||
{
|
||||
term_active_clients--;
|
||||
inp_dbg("Close socket CB, remain %d clients", term_active_clients);
|
||||
if (term_active_clients <= 0) {
|
||||
term_active_clients = 0;
|
||||
|
||||
@@ -340,6 +345,7 @@ static void ICACHE_FLASH_ATTR closeSockCb(Websock *ws)
|
||||
|
||||
// stop the timer
|
||||
os_timer_disarm(&heartbeatTim);
|
||||
inp_dbg("Stop HB timer");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,7 +371,7 @@ ETSTimer xonTim;
|
||||
|
||||
static void ICACHE_FLASH_ATTR notify_empty_txbuf_cb(void *unused)
|
||||
{
|
||||
UART_WriteChar(UART1, '+', 100);
|
||||
//UART_WriteChar(UART1, '+', 100);
|
||||
cgiWebsockBroadcast(URL_WS_UPDATE, "+", 1, 0);
|
||||
resetHeartbeatTimer();
|
||||
browser_wants_xon = false;
|
||||
|
||||
+2
-2
@@ -50,7 +50,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiResetDevice(HttpdConnData *connData)
|
||||
os_timer_setfn(&tmr, tmrCb, NULL);
|
||||
os_timer_arm(&tmr, 100, false);
|
||||
|
||||
httpdSend(connData, "system reset\n", -1);
|
||||
httpdSend(connData, "system reset\r\n", -1);
|
||||
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
@@ -66,7 +66,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiPing(HttpdConnData *connData)
|
||||
httpdHeader(connData, "Content-Type", "text/plain");
|
||||
httpdEndHeaders(connData);
|
||||
|
||||
httpdSend(connData, "pong\n", -1);
|
||||
httpdSend(connData, "pong\r\n", -1);
|
||||
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
|
||||
+15
-7
@@ -14,6 +14,8 @@
|
||||
#include "cgi_persist.h"
|
||||
#include "syscfg.h"
|
||||
#include "persist.h"
|
||||
#include "api.h"
|
||||
#include "cgi_d2d.h"
|
||||
|
||||
/**
|
||||
* Password for WiFi config
|
||||
@@ -45,7 +47,8 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiOptionalPwLock(HttpdConnData *connData)
|
||||
break;
|
||||
|
||||
case PWLOCK_SETTINGS_NOTERM:
|
||||
protect = strstarts(connData->url, "/cfg") && !strstarts(connData->url, "/cfg/term");
|
||||
protect = strstarts(connData->url, "/cfg") &&
|
||||
!strstarts(connData->url, "/cfg/term");
|
||||
break;
|
||||
|
||||
case PWLOCK_SETTINGS_ALL:
|
||||
@@ -53,7 +56,9 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiOptionalPwLock(HttpdConnData *connData)
|
||||
break;
|
||||
|
||||
case PWLOCK_MENUS:
|
||||
protect = strstarts(connData->url, "/cfg") || strstarts(connData->url, "/about") || strstarts(connData->url, "/help");
|
||||
protect = strstarts(connData->url, "/cfg") ||
|
||||
strstarts(connData->url, "/about") ||
|
||||
strstarts(connData->url, "/help");
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -64,11 +69,11 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiOptionalPwLock(HttpdConnData *connData)
|
||||
// pages outside the normal scope
|
||||
|
||||
if (sysconf->pwlock > PWLOCK_NONE) {
|
||||
if (strstarts(connData->url, "/system/reset")) protect = true;
|
||||
if (strstarts(connData->url, "/api/v1/reboot")) protect = true;
|
||||
}
|
||||
|
||||
if (sysconf->pwlock > PWLOCK_SETTINGS_NOTERM) {
|
||||
if (strstarts(connData->url, "/system/cls")) protect = true;
|
||||
if (strstarts(connData->url, "/api/v1/clear")) protect = true;
|
||||
}
|
||||
|
||||
if (sysconf->access_pw[0] == 0) {
|
||||
@@ -103,9 +108,12 @@ const HttpdBuiltInUrl routes[] ESP_CONST_DATA = {
|
||||
ROUTE_WS(URL_WS_UPDATE, updateSockConnect),
|
||||
|
||||
// --- System control ---
|
||||
ROUTE_CGI("/system/reset/?", cgiResetDevice),
|
||||
ROUTE_CGI("/system/ping/?", cgiPing),
|
||||
ROUTE_CGI("/system/cls/?", cgiResetScreen),
|
||||
|
||||
// API endpoints
|
||||
ROUTE_CGI(API_REBOOT"/?", cgiResetDevice),
|
||||
ROUTE_CGI(API_PING"/?", cgiPing),
|
||||
ROUTE_CGI(API_CLEAR"/?", cgiResetScreen),
|
||||
ROUTE_CGI(API_D2D_MSG"/?", cgiD2DMessage),
|
||||
|
||||
ROUTE_REDIRECT("/cfg/?", "/cfg/wifi"),
|
||||
|
||||
|
||||
+8
-5
@@ -40,10 +40,10 @@ buf_pop(void *unused)
|
||||
}
|
||||
}
|
||||
|
||||
//LOCAL void my_putc(char c)
|
||||
//{
|
||||
// UART_WriteCharCRLF(UART1, (u8) c, 10);
|
||||
//}
|
||||
LOCAL void my_putc(char c)
|
||||
{
|
||||
UART_WriteCharCRLF(UART1, (u8) c, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the serial ports
|
||||
@@ -56,8 +56,11 @@ void ICACHE_FLASH_ATTR serialInitBase(void)
|
||||
UART_SetStopBits(UART1, ONE_STOP_BIT);
|
||||
UART_SetBaudrate(UART1, BIT_RATE_115200);
|
||||
UART_SetPrintPort(UART1);
|
||||
#if ASYNC_LOG
|
||||
os_install_putc1(buf_putc);
|
||||
//os_install_putc1(my_putc);
|
||||
#else
|
||||
os_install_putc1(my_putc);
|
||||
#endif
|
||||
UART_SetupAsyncReceiver();
|
||||
|
||||
// 1 ms timer
|
||||
|
||||
+46
-39
@@ -8,8 +8,8 @@
|
||||
#include <esp8266.h>
|
||||
#include <uart_register.h>
|
||||
|
||||
#define UART_TX_BUFFER_SIZE 512 //Ring buffer length of tx buffer
|
||||
#define UART_RX_BUFFER_SIZE 600 //Ring buffer length of rx buffer
|
||||
//#define buf_dbg(format, ...) printf(format "\r\n", ##__VA_ARGS__)
|
||||
#define buf_dbg(format, ...) (void)format
|
||||
|
||||
struct UartBuffer {
|
||||
uint32 UartBuffSize;
|
||||
@@ -22,12 +22,15 @@ struct UartBuffer {
|
||||
static struct UartBuffer *pTxBuffer = NULL;
|
||||
static struct UartBuffer *pRxBuffer = NULL;
|
||||
|
||||
static struct UartBuffer *UART_AsyncBufferInit(uint32 buf_size);
|
||||
static u8 rxArray[UART_RX_BUFFER_SIZE];
|
||||
static u8 txArray[UART_TX_BUFFER_SIZE];
|
||||
|
||||
static struct UartBuffer *UART_AsyncBufferInit(uint32 buf_size, u8 *buffer);
|
||||
|
||||
void ICACHE_FLASH_ATTR UART_AllocBuffers(void)
|
||||
{
|
||||
pTxBuffer = UART_AsyncBufferInit(UART_TX_BUFFER_SIZE);
|
||||
pRxBuffer = UART_AsyncBufferInit(UART_RX_BUFFER_SIZE);
|
||||
pTxBuffer = UART_AsyncBufferInit(UART_TX_BUFFER_SIZE, txArray);
|
||||
pRxBuffer = UART_AsyncBufferInit(UART_RX_BUFFER_SIZE, rxArray);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -37,7 +40,7 @@ void ICACHE_FLASH_ATTR UART_AllocBuffers(void)
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
static struct UartBuffer *ICACHE_FLASH_ATTR
|
||||
UART_AsyncBufferInit(uint32 buf_size)
|
||||
UART_AsyncBufferInit(uint32 buf_size, u8 *buffer)
|
||||
{
|
||||
uint32 heap_size = system_get_free_heap_size();
|
||||
if (heap_size <= buf_size) {
|
||||
@@ -47,7 +50,7 @@ UART_AsyncBufferInit(uint32 buf_size)
|
||||
else {
|
||||
struct UartBuffer *pBuff = (struct UartBuffer *) malloc(sizeof(struct UartBuffer));
|
||||
pBuff->UartBuffSize = buf_size;
|
||||
pBuff->pUartBuff = (uint8 *) malloc(pBuff->UartBuffSize);
|
||||
pBuff->pUartBuff = buffer != NULL ? buffer : (uint8 *) malloc(pBuff->UartBuffSize);
|
||||
pBuff->pInPos = pBuff->pUartBuff;
|
||||
pBuff->pOutPos = pBuff->pUartBuff;
|
||||
pBuff->Space = (uint16) pBuff->UartBuffSize;
|
||||
@@ -55,6 +58,13 @@ UART_AsyncBufferInit(uint32 buf_size)
|
||||
}
|
||||
}
|
||||
|
||||
static void ICACHE_FLASH_ATTR
|
||||
UART_AsyncBufferReset(struct UartBuffer *pBuff)
|
||||
{
|
||||
pBuff->pInPos = pBuff->pUartBuff;
|
||||
pBuff->pOutPos = pBuff->pUartBuff;
|
||||
pBuff->Space = (uint16) pBuff->UartBuffSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy data onto Buffer
|
||||
@@ -67,23 +77,30 @@ UART_WriteToAsyncBuffer(struct UartBuffer *pCur, const char *pdata, uint16 data_
|
||||
{
|
||||
if (data_len == 0) return;
|
||||
|
||||
buf_dbg("WTAB %d, space %d", data_len, pCur->Space);
|
||||
|
||||
uint16 tail_len = (uint16) (pCur->pUartBuff + pCur->UartBuffSize - pCur->pInPos);
|
||||
if (tail_len >= data_len) { //do not need to loop back the queue
|
||||
buf_dbg("tail %d, no fold", tail_len);
|
||||
memcpy(pCur->pInPos, pdata, data_len);
|
||||
pCur->pInPos += (data_len);
|
||||
pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize);
|
||||
pCur->Space -= data_len;
|
||||
}
|
||||
else {
|
||||
buf_dbg("tail only %d, folding", tail_len);
|
||||
memcpy(pCur->pInPos, pdata, tail_len);
|
||||
buf_dbg("chunk 1, %d", tail_len);
|
||||
pCur->pInPos += (tail_len);
|
||||
pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize);
|
||||
pCur->Space -= tail_len;
|
||||
buf_dbg("chunk 2, %d", data_len - tail_len);
|
||||
memcpy(pCur->pInPos, pdata + tail_len, data_len - tail_len);
|
||||
pCur->pInPos += (data_len - tail_len);
|
||||
pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize);
|
||||
pCur->Space -= (data_len - tail_len);
|
||||
}
|
||||
buf_dbg("new space %d", pCur->Space);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -158,9 +175,8 @@ void UART_RxFifoCollect(void)
|
||||
uint8 fifo_data;
|
||||
fifo_len = (uint8) ((READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT);
|
||||
if (fifo_len >= pRxBuffer->Space) {
|
||||
// try to read at least the bit we can
|
||||
fifo_len = (uint8) (pRxBuffer->Space - 1);
|
||||
UART_WriteChar(UART1, '%', 1);
|
||||
UART_WriteChar(UART1, '#', 10);
|
||||
// discard contents of the FIFO - would loop forever
|
||||
buf_idx = 0;
|
||||
while (buf_idx < fifo_len) {
|
||||
@@ -193,35 +209,30 @@ u16 ICACHE_FLASH_ATTR UART_AsyncTxGetEmptySpace(void)
|
||||
return pTxBuffer->Space;
|
||||
}
|
||||
|
||||
u16 ICACHE_FLASH_ATTR UART_AsyncTxCount(void)
|
||||
{
|
||||
return (u16) (pTxBuffer->UartBuffSize - pTxBuffer->Space);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule data to be sent
|
||||
* @param pdata
|
||||
* @param data_len - can be -1 for strlen
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
UART_SendAsync(const char *pdata, int16_t data_len)
|
||||
UART_SendAsync(const char *pdata, int data_len)
|
||||
{
|
||||
u16 real_len = (u16) data_len;
|
||||
if (data_len <= 0) real_len = (u16) strlen(pdata);
|
||||
size_t real_len = (data_len) <= 0 ? strlen(pdata) : (size_t) data_len;
|
||||
|
||||
// if (pTxBuffer == NULL) {
|
||||
// printf("init tx buf\n\r");
|
||||
// pTxBuffer = UART_AsyncBufferInit(UART_TX_BUFFER_SIZE);
|
||||
// if (pTxBuffer != NULL) {
|
||||
// UART_WriteToAsyncBuffer(pTxBuffer, pdata, real_len);
|
||||
// }
|
||||
// else {
|
||||
// printf("tx alloc fail\r\n");
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
if (real_len <= pTxBuffer->Space) {
|
||||
UART_WriteToAsyncBuffer(pTxBuffer, pdata, real_len);
|
||||
}
|
||||
else {
|
||||
UART_WriteChar(UART1, '^', 1);
|
||||
}
|
||||
// }
|
||||
buf_dbg("Send Async %d", real_len);
|
||||
if (real_len <= pTxBuffer->Space) {
|
||||
buf_dbg("accepted, space %d", pTxBuffer->Space);
|
||||
UART_WriteToAsyncBuffer(pTxBuffer, pdata, (uint16) real_len);
|
||||
}
|
||||
else {
|
||||
buf_dbg("FULL!");
|
||||
UART_WriteChar(UART1, '=', 10);
|
||||
}
|
||||
|
||||
// Here we enable TX empty interrupt that will take care of sending the content
|
||||
SET_PERI_REG_MASK(UART_CONF1(UART0), (UART_TX_EMPTY_THRESH_VAL & UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S);
|
||||
@@ -257,8 +268,8 @@ void UART_DispatchFromTxBuffer(uint8 uart_no)
|
||||
uint8 len_tmp;
|
||||
uint16 data_len;
|
||||
|
||||
// if (pTxBuffer) {
|
||||
data_len = (uint8) (pTxBuffer->UartBuffSize - pTxBuffer->Space);
|
||||
data_len = (uint16) (pTxBuffer->UartBuffSize - pTxBuffer->Space);
|
||||
buf_dbg("rem %d",data_len);
|
||||
if (data_len > fifo_remain) {
|
||||
len_tmp = fifo_remain;
|
||||
UART_TxFifoEnq(pTxBuffer, len_tmp, uart_no);
|
||||
@@ -268,8 +279,9 @@ void UART_DispatchFromTxBuffer(uint8 uart_no)
|
||||
len_tmp = (uint8) data_len;
|
||||
UART_TxFifoEnq(pTxBuffer, len_tmp, uart_no);
|
||||
|
||||
// we get one more IT after fifo ends even if we have 0 more bytes
|
||||
// for notify
|
||||
// We get one more IT after fifo ends even if we have 0 more bytes,
|
||||
// for notify. Otherwise we would say we have space while the FIFO
|
||||
// was still running
|
||||
if (next_empty_it_only_for_notify) {
|
||||
notify_empty_txbuf();
|
||||
next_empty_it_only_for_notify = 0;
|
||||
@@ -279,9 +291,4 @@ void UART_DispatchFromTxBuffer(uint8 uart_no)
|
||||
SET_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
|
||||
}
|
||||
}
|
||||
|
||||
// }
|
||||
// else {
|
||||
// error("pTxBuff null \n\r");
|
||||
// }
|
||||
}
|
||||
|
||||
+5
-1
@@ -7,6 +7,9 @@
|
||||
|
||||
#include <esp8266.h>
|
||||
|
||||
#define UART_TX_BUFFER_SIZE 1000 //Ring buffer length of tx buffer
|
||||
#define UART_RX_BUFFER_SIZE 600 //Ring buffer length of rx buffer
|
||||
|
||||
// the init func
|
||||
void UART_AllocBuffers(void);
|
||||
|
||||
@@ -14,7 +17,7 @@ void UART_AllocBuffers(void);
|
||||
uint16 UART_ReadAsync(char *pdata, uint16 data_len);
|
||||
|
||||
// write to tx buffer
|
||||
void UART_SendAsync(const char *pdata, int16_t data_len);
|
||||
void UART_SendAsync(const char *pdata, int data_len);
|
||||
|
||||
//move data from uart fifo to rx buffer
|
||||
void UART_RxFifoCollect(void);
|
||||
@@ -22,6 +25,7 @@ void UART_RxFifoCollect(void);
|
||||
void UART_DispatchFromTxBuffer(uint8 uart_no);
|
||||
|
||||
u16 UART_AsyncRxCount(void);
|
||||
u16 UART_AsyncTxCount(void);
|
||||
|
||||
u16 UART_AsyncTxGetEmptySpace(void);
|
||||
|
||||
|
||||
+4
-4
@@ -24,8 +24,8 @@ static void uart_recvTask(os_event_t *events);
|
||||
static void uart_processTask(os_event_t *events);
|
||||
|
||||
// Those heavily affect the byte loss ratio
|
||||
#define PROCESS_CHUNK_LEN 1
|
||||
#define FIFO_FULL_THRES 32
|
||||
#define PROCESS_CHUNK_LEN 10
|
||||
#define RX_FIFO_FULL_THRES 40
|
||||
|
||||
#define uart_recvTaskPrio 1
|
||||
#define uart_recvTaskQueueLen 25
|
||||
@@ -78,8 +78,8 @@ void ICACHE_FLASH_ATTR UART_SetupAsyncReceiver(void)
|
||||
ETS_UART_INTR_ATTACH((void *)uart0_rx_intr_handler, &(UartDev.rcv_buff)); // the buf will be used as an arg
|
||||
|
||||
// fifo threshold config (max: UART_RXFIFO_FULL_THRHD = 127)
|
||||
uint32_t conf = ((FIFO_FULL_THRES & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S);
|
||||
conf |= ((0x10 & UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S);
|
||||
uint32_t conf = ((RX_FIFO_FULL_THRES & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S);
|
||||
conf |= ((0x05 & UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S);
|
||||
// timeout config
|
||||
conf |= ((0x06 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S); // timeout threshold
|
||||
conf |= UART_RX_TOUT_EN; // enable timeout
|
||||
|
||||
+14
-4
@@ -30,6 +30,7 @@
|
||||
#include "persist.h"
|
||||
#include "ansi_parser.h"
|
||||
#include "ascii.h"
|
||||
#include "uart_buffer.h"
|
||||
|
||||
#ifdef ESPFS_POS
|
||||
CgiUploadFlashDef uploadParams={
|
||||
@@ -51,6 +52,7 @@ CgiUploadFlashDef uploadParams={
|
||||
#define INCLUDE_FLASH_FNS
|
||||
#endif
|
||||
|
||||
#define HEAP_TIMER_MS 1000
|
||||
/** Periodically show heap usage */
|
||||
static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg)
|
||||
{
|
||||
@@ -60,18 +62,24 @@ static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg)
|
||||
int heap = system_get_free_heap_size();
|
||||
int diff = (heap-last);
|
||||
|
||||
int rxc = UART_AsyncRxCount();
|
||||
int txc = UART_AsyncTxCount();
|
||||
|
||||
int rxp = ((rxc*10000) / UART_RX_BUFFER_SIZE)/100;
|
||||
int txp = ((txc*10000) / UART_TX_BUFFER_SIZE)/100;
|
||||
|
||||
const char *cc = "+";
|
||||
if (diff<0) cc = "";
|
||||
|
||||
if (diff == 0) {
|
||||
if (cnt == 5) {
|
||||
// only every 5 secs if no change
|
||||
dbg("FH: %d", heap);
|
||||
dbg("Rx: %2d%c, Tx: %2d%c, Hp: %d", rxp, '%', txp, '%', heap);
|
||||
cnt = 0;
|
||||
}
|
||||
} else {
|
||||
// report change
|
||||
dbg("FH: %d (%s%d)", heap, cc, diff);
|
||||
dbg("Rx: %2d%c, Tx: %2d%c, Hp: %d (%s%d)", rxp, '%', txp, '%', heap, cc, diff);
|
||||
cnt = 0;
|
||||
}
|
||||
|
||||
@@ -101,7 +109,8 @@ void ICACHE_FLASH_ATTR user_init(void)
|
||||
banner_info("Firmware (c) Ondrej Hruska, 2017");
|
||||
banner_info(TERMINAL_GITHUB_REPO);
|
||||
banner_info("");
|
||||
banner_info("Version "FIRMWARE_VERSION", built " __DATE__ " at " __TIME__ " " __TIMEZONE__);
|
||||
banner_info("Version "FIRMWARE_VERSION",");
|
||||
banner_info("built " __DATE__ " at " __TIME__ " " __TIMEZONE__);
|
||||
printf("\r\n");
|
||||
|
||||
ioInit();
|
||||
@@ -116,7 +125,7 @@ void ICACHE_FLASH_ATTR user_init(void)
|
||||
|
||||
#if DEBUG_HEAP
|
||||
// Heap use timer & blink
|
||||
TIMER_START(&prHeapTimer, prHeapTimerCb, 1000, 1);
|
||||
TIMER_START(&prHeapTimer, prHeapTimerCb, HEAP_TIMER_MS, 1);
|
||||
#endif
|
||||
|
||||
// do later (some functions do not work if called from user_init)
|
||||
@@ -130,6 +139,7 @@ static void ICACHE_FLASH_ATTR user_start(void *unused)
|
||||
|
||||
captdnsInit();
|
||||
httpdInit(routes, 80);
|
||||
httpdSetName("ESPTerm " FIRMWARE_VERSION);
|
||||
|
||||
ansi_parser_inhibit = false;
|
||||
|
||||
|
||||
+4
-1
@@ -5,11 +5,14 @@
|
||||
#ifndef ESP_VT100_FIRMWARE_VERSION_H
|
||||
#define ESP_VT100_FIRMWARE_VERSION_H
|
||||
|
||||
#include "helpers.h"
|
||||
|
||||
#define FW_V_MAJOR 2
|
||||
#define FW_V_MINOR 1
|
||||
#define FW_V_PATCH 0
|
||||
#define FW_CODENAME "Anthill" // 2.1.0
|
||||
|
||||
#define FIRMWARE_VERSION STR(FW_V_MAJOR) "." STR(FW_V_MINOR) "." STR(FW_V_PATCH)
|
||||
#define FIRMWARE_VERSION STR(FW_V_MAJOR) "." STR(FW_V_MINOR) "." STR(FW_V_PATCH) " \"" FW_CODENAME "\""
|
||||
#define FIRMWARE_VERSION_NUM (FW_V_MAJOR*1000 + FW_V_MINOR*10 + FW_V_PATCH) // this is used in ID queries
|
||||
#define TERMINAL_GITHUB_REPO "https://github.com/espterm/espterm-firmware"
|
||||
#define TERMINAL_GITHUB_REPO_FRONT "https://github.com/espterm/espterm-front-end"
|
||||
|
||||
Reference in New Issue
Block a user