FIXED A BUG

http-comm
Ondřej Hruška 7 years ago
parent 7eb1bdeec6
commit 58bd27a082
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 10
      esphttpdconfig.mk
  2. 48
      user/cgi_sockets.c
  3. 8
      user/cgi_term_cfg.c
  4. 118
      user/screen.c

@ -39,11 +39,11 @@ OUTPUT_TYPE = combined
ESP_SPI_FLASH_SIZE_K = 1024
GLOBAL_CFLAGS = \
-DDEBUG_ROUTER=1 \
-DDEBUG_CAPTDNS=1 \
-DDEBUG_HTTP=1 \
-DDEBUG_ESPFS=1 \
-DDEBUG_PERSIST=1 \
-DDEBUG_ROUTER=0 \
-DDEBUG_CAPTDNS=0 \
-DDEBUG_HTTP=0 \
-DDEBUG_ESPFS=0 \
-DDEBUG_PERSIST=0 \
-DDEBUG_UTFCACHE=1 \
-DDEBUG_CGI=0 \
-DDEBUG_WIFI=0 \

@ -63,13 +63,12 @@ notifyContentTimCb(void *arg)
if (!notify_available || notify_cooldown || (max_bl > 2048)) { // do not send if we have anything significant backlogged
// postpone a little
TIMER_START(&notifyContentTim, notifyContentTimCb, 5, 0);
TIMER_START(&notifyContentTim, notifyContentTimCb, 4, 0);
inp_dbg("postpone notify content");
return;
}
notify_available = false;
resetHeartbeatTimer();
for (int i = 0; i < 20; i++) {
httpd_cgi_state cont = screenSerializeToBuffer(sock_buff, SOCK_BUF_LEN, &data);
int flg = 0;
@ -79,6 +78,7 @@ notifyContentTimCb(void *arg)
cgiWebsocketSend(ws, sock_buff, (int) strlen(sock_buff), flg);
} else {
cgiWebsockBroadcast(URL_WS_UPDATE, sock_buff, (int) strlen(sock_buff), flg);
resetHeartbeatTimer();
}
if (cont == HTTPD_CGI_DONE) break;
@ -101,18 +101,25 @@ notifyContentTimCb(void *arg)
static void ICACHE_FLASH_ATTR
notifyLabelsTimCb(void *arg)
{
Websock *ws = arg;
char sock_buff[SOCK_BUF_LEN];
if (!notify_available || notify_cooldown) {
// postpone a little
TIMER_START(&notifyLabelsTim, notifyLabelsTimCb, 1, 0);
TIMER_START(&notifyLabelsTim, notifyLabelsTimCb, 7, 0);
inp_dbg("postpone notify labels");
return;
}
notify_available = false;
screenSerializeLabelsToBuffer(sock_buff, SOCK_BUF_LEN);
cgiWebsockBroadcast(URL_WS_UPDATE, sock_buff, (int) strlen(sock_buff), 0);
resetHeartbeatTimer();
if (ws) {
cgiWebsocketSend(ws, sock_buff, (int) strlen(sock_buff), 0);
} else {
cgiWebsockBroadcast(URL_WS_UPDATE, sock_buff, (int) strlen(sock_buff), 0);
resetHeartbeatTimer();
}
notify_cooldown = true;
notify_available = true;
@ -155,13 +162,14 @@ void ICACHE_FLASH_ATTR screen_notifyChange(ScreenNotifyChangeTopic topic)
if (active_clients == 0) return;
// this is probably not needed here - ensure timeout is not 0
if (termconf->display_tout_ms == 0) termconf->display_tout_ms = SCR_DEF_DISPLAY_TOUT_MS;
if (termconf->display_tout_ms == 0)
termconf->display_tout_ms = SCR_DEF_DISPLAY_TOUT_MS;
// NOTE: the timers are restarted if already running
if (topic == CHANGE_LABELS) {
// separate timer from content change timer, to avoid losing that update
TIMER_START(&notifyLabelsTim, notifyLabelsTimCb, termconf->display_tout_ms, 0);
TIMER_START(&notifyLabelsTim, notifyLabelsTimCb, termconf->display_tout_ms+2, 0); // this delay is useful when both are fired at once on screen reset
}
else if (topic == CHANGE_CONTENT) {
// throttle delay
@ -288,7 +296,8 @@ static void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int
case 'i':
// requests initial load
inp_dbg("Client requests initial load");
notifyContentTimCb(ws);
notifyContentTimCb(ws); // delay??
notifyLabelsTimCb(ws);
break;
case 'm':
@ -313,16 +322,27 @@ 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)
{
if (notify_available && active_clients > 0) {
// 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);
if (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);
// schedule next tick
TIMER_START(&heartbeatTim, heartbeatTimCb, HB_TIME, 0);
} else {
// postpone...
TIMER_START(&heartbeatTim, heartbeatTimCb, 10, 0);
inp_dbg("postpone heartbeat");
}
}
}
static void ICACHE_FLASH_ATTR resetHeartbeatTimer(void)
{
TIMER_START(&heartbeatTim, heartbeatTimCb, HB_TIME, 1);
TIMER_START(&heartbeatTim, heartbeatTimCb, HB_TIME, 0);
}

@ -43,10 +43,10 @@ cgiTermCfgSetParams(HttpdConnData *connData)
// width and height must always go together so we can do max size validation
if (GET_ARG("term_width")) {
cgi_dbg("Default screen width: %s", buff);
w = atoi(buff);
do {
if (w <= 1) {
cgi_dbg("Default screen width: %s", buff);
w = atoi(buff);
if (w < 1) {
cgi_warn("Bad width: \"%s\"", buff);
redir_url += sprintf(redir_url, "term_width,");
break;
@ -61,7 +61,7 @@ cgiTermCfgSetParams(HttpdConnData *connData)
cgi_dbg("Default screen height: %s", buff);
h = atoi(buff);
if (h <= 1) {
if (h < 1) {
cgi_warn("Bad height: \"%s\"", buff);
redir_url += sprintf(redir_url, "term_height,");
break;

@ -248,18 +248,7 @@ screen_init(void)
{
if(DEBUG_HEAP) dbg("Screen buffer size = %d bytes", sizeof(screen));
NOTIFY_LOCK();
Cell sample;
sample.symbol = ' ';
sample.fg = 0;
sample.bg = 0;
sample.attrs = 0; // use default colors
for (unsigned int i = 0; i < MAX_SCREEN_SIZE; i++) {
memcpy(&screen[i], &sample, sizeof(Cell));
}
screen_reset();
NOTIFY_DONE();
}
/**
@ -288,16 +277,13 @@ screen_reset_on_resize(void)
ansi_dbg("Screen partial reset due to resize");
NOTIFY_LOCK();
cursor.x = 0;
cursor.y = 0;
cursor.hanging = false;
cursor_reset();
scr.vm0 = 0;
scr.vm1 = H-1;
// size is left unchanged
screen_clear(CLEAR_ALL);
unicode_cache_clear();
screen_clear(CLEAR_ALL); // also clears utf cache
NOTIFY_DONE();
}
@ -314,18 +300,11 @@ screen_reset_sgr(void)
cursor.conceal = false;
}
/**
* Reset the screen - called by ESC c
*/
void ICACHE_FLASH_ATTR
screen_reset(void)
static void ICACHE_FLASH_ATTR
screen_reset_do(bool size, bool labels)
{
ansi_dbg("Screen reset.");
NOTIFY_LOCK();
cursor_reset();
unicode_cache_clear();
// DECopts
scr.cursor_visible = true;
scr.insert_mode = false;
@ -339,17 +318,21 @@ screen_reset(void)
termconf_live.crlf_mode = termconf->crlf_mode;
scr.reverse_video = false;
scr.vm0 = 0;
scr.vm1 = H-1;
state_backup.alternate_active = false;
mouse_tracking.encoding = MTE_SIMPLE;
mouse_tracking.focus_tracking = false;
mouse_tracking.mode = MTM_NONE;
// size is left unchanged
screen_clear(CLEAR_ALL);
if (size) {
W = termconf->width;
H = termconf->height;
}
scr.vm0 = 0;
scr.vm1 = H - 1;
cursor_reset();
screen_clear(CLEAR_ALL); // also clears utf cache
// Set initial tabstops
for (int i = 0; i < TABSTOP_WORDS; i++) {
@ -372,8 +355,30 @@ screen_reset(void)
opt_backup.show_config_links = termconf_live.show_config_links;
NOTIFY_DONE();
if (labels) {
strcpy(termconf_live.title, termconf->title);
for (int i = 1; i <= TERM_BTN_COUNT; i++) {
strcpy(termconf_live.btn[i], termconf->btn[i]);
strcpy(termconf_live.btn_msg[i], termconf->btn_msg[i]);
}
screen_notifyChange(CHANGE_LABELS);
}
}
/**
* Reset the screen - called by ESC c
*/
void ICACHE_FLASH_ATTR
screen_reset(void)
{
ansi_dbg("Screen reset.");
screen_reset_do(true, true);
}
/**
* Swap screen buffer / state
* this is CSI ? 47/1047/1049 h/l
@ -563,8 +568,10 @@ clear_range_do(unsigned int from, unsigned int to, bool clear_utf)
sample.attrs = (CellAttrs) (cursor.attrs & (ATTR_FG | ATTR_BG));
for (unsigned int i = from; i <= to; i++) {
UnicodeCacheRef symbol = screen[i].symbol;
if (clear_utf && IS_UNICODE_CACHE_REF(symbol)) unicode_cache_remove(symbol);
if (clear_utf) {
UnicodeCacheRef symbol = screen[i].symbol;
if (IS_UNICODE_CACHE_REF(symbol)) unicode_cache_remove(symbol);
}
memcpy(&screen[i], &sample, sizeof(Cell));
}
}
@ -602,6 +609,7 @@ clear_range_noutf(unsigned int from, unsigned int to)
static inline void ICACHE_FLASH_ATTR
utf_free_cell(int row, int col)
{
dbg("free cell (row %d) %d", row, col);
UnicodeCacheRef symbol = screen[row * W + col].symbol;
if (IS_UNICODE_CACHE_REF(symbol))
unicode_cache_remove(symbol);
@ -617,11 +625,25 @@ utf_free_cell(int row, int col)
static inline void ICACHE_FLASH_ATTR
utf_backup_cell(int row, int col)
{
dbg("backup cell (row %d) %d", row, col);
UnicodeCacheRef symbol = screen[row * W + col].symbol;
if (IS_UNICODE_CACHE_REF(symbol))
unicode_cache_inc(symbol);
}
/**
* Duplicate a cell within a row
* @param row - row to work on
* @param dest_col - destination column
* @param src_col - source column
*/
static inline void ICACHE_FLASH_ATTR
copy_cell(int row, int dest_col, int src_col)
{
dbg("copy cell (row %d) %d -> %d", row, src_col, dest_col);
memcpy(screen+row*W+dest_col, screen+row*W+src_col, sizeof(Cell));
}
/**
* Free all utf8 on a row
*
@ -630,6 +652,7 @@ utf_backup_cell(int row, int col)
static inline void ICACHE_FLASH_ATTR
utf_free_row(int row)
{
dbg("free row %d", row);
for (int col = 0; col < W; col++) {
utf_free_cell(row, col);
}
@ -643,6 +666,7 @@ utf_free_row(int row)
static inline void ICACHE_FLASH_ATTR
utf_backup_row(int row)
{
dbg("backup row %d", row);
for (int col = 0; col < W; col++) {
utf_backup_cell(row, col);
}
@ -657,21 +681,10 @@ utf_backup_row(int row)
static inline void ICACHE_FLASH_ATTR
copy_row(int dest, int src)
{
dbg("copy row %d -> %d", src, dest);
memcpy(screen + dest * W, screen + src * W, sizeof(Cell) * W);
}
/**
* Duplicate a cell within a row
* @param row - row to work on
* @param dest_col - destination column
* @param src_col - source column
*/
static inline void ICACHE_FLASH_ATTR
copy_cell(int row, int dest_col, int src_col)
{
memcpy(screen+row*W+dest_col, screen+row*W+src_col, sizeof(Cell));
}
/**
* Clear a row, do nothing with the utf8 cache
*
@ -704,8 +717,9 @@ screen_clear(ClearMode mode)
NOTIFY_LOCK();
switch (mode) {
case CLEAR_ALL:
clear_range_noutf(0, W * H - 1);
unicode_cache_clear();
clear_range_noutf(0, W * H - 1);
scr.last_char[0] = 0;
break;
case CLEAR_FROM_CURSOR:
@ -769,6 +783,7 @@ screen_insert_lines(unsigned int lines)
for (int i = BTM; i >= targetStart; i--) {
utf_free_row(i); // release old characters
copy_row(i, i - lines);
if (i != targetStart) utf_backup_row(i);
}
// clear the first line
@ -792,12 +807,13 @@ screen_delete_lines(unsigned int lines)
if (movedBlockEnd <= cursor.y) {
// clear the entire rest of the screen
movedBlockEnd = cursor.y;
clear_range_utf(movedBlockEnd*W, W * BTM);
clear_range_utf(movedBlockEnd*W, (BTM+1)*W-1);
} else {
// move some lines up, clear the rest
for (int i = cursor.y; i <= movedBlockEnd; i++) {
utf_free_row(i);
copy_row(i, i+lines);
if (i != movedBlockEnd) utf_backup_row(i);
}
clear_range_noutf((movedBlockEnd+1)*W, (BTM+1)*W-1);
}
@ -821,8 +837,9 @@ screen_insert_characters(unsigned int count)
for (int i = W-1; i >= targetStart; i--) {
utf_free_cell(cursor.y, i);
copy_cell(cursor.y, i, i - count);
utf_backup_cell(cursor.y, i);
}
clear_range_noutf(cursor.y * W + cursor.x, cursor.y * W + targetStart - 1);
clear_range_utf(cursor.y * W + cursor.x, cursor.y * W + targetStart - 1);
}
NOTIFY_DONE();
}
@ -841,9 +858,10 @@ screen_delete_characters(unsigned int count)
for (int i = cursor.x; i <= movedBlockEnd; i++) {
utf_free_cell(cursor.y, i);
copy_cell(cursor.y, i, i + count);
utf_backup_cell(cursor.y, i);
}
// clear original positions of the moved characters
clear_range_utf(cursor.y * W + (W - count), (cursor.y + 1) * W - 1);
clear_range_noutf(cursor.y * W + (W - count), (cursor.y + 1) * W - 1);
} else {
// all rest was cleared
screen_clear_line(CLEAR_FROM_CURSOR);
@ -859,7 +877,7 @@ void ICACHE_FLASH_ATTR
screen_fill_with_E(void)
{
NOTIFY_LOCK();
screen_reset(); // based on observation from xterm
screen_reset_do(false, false); // based on observation from xterm
Cell sample;
sample.symbol = 'E';
@ -943,6 +961,7 @@ screen_scroll_up(unsigned int lines)
for (y = TOP; y <= BTM - lines; y++) {
utf_free_row(y);
copy_row(y, y+lines);
if (y < BTM - lines) utf_backup_row(y);
}
clear_range_noutf(y * W, (BTM + 1) * W - 1);
@ -973,6 +992,7 @@ screen_scroll_down(unsigned int lines)
for (y = BTM; y >= TOP+lines; y--) {
utf_free_row(y);
copy_row(y, y-lines);
if (y > TOP + lines) utf_backup_row(y);
}
clear_range_noutf(TOP * W, TOP * W + lines * W - 1);

Loading…
Cancel
Save