fixed off-by one etc errors in the rewritten functions, fixed a lag due to heartbeat packet

http-comm
Ondřej Hruška 7 years ago
parent 674e89c8c3
commit 7eb1bdeec6
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 16
      esphttpdconfig.mk
  2. 27
      user/cgi_sockets.c
  3. 115
      user/screen.c
  4. 33
      user/utf8.c
  5. 8
      user/utf8.h

@ -39,15 +39,15 @@ OUTPUT_TYPE = combined
ESP_SPI_FLASH_SIZE_K = 1024
GLOBAL_CFLAGS = \
-DDEBUG_ROUTER=0 \
-DDEBUG_CAPTDNS=0 \
-DDEBUG_HTTP=0 \
-DDEBUG_ESPFS=0 \
-DDEBUG_PERSIST=0 \
-DDEBUG_UTFCACHE=0 \
-DDEBUG_ROUTER=1 \
-DDEBUG_CAPTDNS=1 \
-DDEBUG_HTTP=1 \
-DDEBUG_ESPFS=1 \
-DDEBUG_PERSIST=1 \
-DDEBUG_UTFCACHE=1 \
-DDEBUG_CGI=0 \
-DDEBUG_WIFI=0 \
-DDEBUG_WS=0 \
-DDEBUG_WS=1 \
-DDEBUG_ANSI=1 \
-DDEBUG_ANSI_NOIMPL=1 \
-DDEBUG_INPUT=0 \
@ -56,6 +56,6 @@ GLOBAL_CFLAGS = \
-DHTTPD_MAX_BACKLOG_SIZE=8192 \
-DHTTPD_MAX_HEAD_LEN=1024 \
-DHTTPD_MAX_POST_LEN=512 \
-DDEBUG_LOGBUF_SIZE=1024 \
-DDEBUG_LOGBUF_SIZE=2048 \
-mforce-l32 \
-DUSE_OPTIMIZE_PRINTF=1

@ -35,6 +35,8 @@ volatile int active_clients = 0;
// this might glitch, very rarely.
// it's recommended to put some delay between setting labels and updating the screen.
static void resetHeartbeatTimer(void);
/**
* Cooldown delay is over
* @param arg
@ -66,6 +68,8 @@ notifyContentTimCb(void *arg)
}
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;
@ -108,6 +112,7 @@ notifyLabelsTimCb(void *arg)
screenSerializeLabelsToBuffer(sock_buff, SOCK_BUF_LEN);
cgiWebsockBroadcast(URL_WS_UPDATE, sock_buff, (int) strlen(sock_buff), 0);
resetHeartbeatTimer();
notify_cooldown = true;
notify_available = true;
@ -123,6 +128,7 @@ send_beep(void)
// here's some potential for a race error with the other broadcast functions :C
cgiWebsockBroadcast(URL_WS_UPDATE, "B", 1, 0);
resetHeartbeatTimer();
}
@ -135,6 +141,7 @@ notify_growl(char *msg)
// TODO via timer...
// here's some potential for a race error with the other broadcast functions :C
cgiWebsockBroadcast(URL_WS_UPDATE, msg, (int) strlen(msg), 0);
resetHeartbeatTimer();
}
@ -170,7 +177,7 @@ void ICACHE_FLASH_ATTR screen_notifyChange(ScreenNotifyChangeTopic topic)
* @param button - which button, 1-based. 0=none
* @param mods - modifier keys bitmap: meta|alt|shift|ctrl
*/
void ICACHE_FLASH_ATTR sendMouseAction(char evt, int y, int x, int button, u8 mods)
static void ICACHE_FLASH_ATTR sendMouseAction(char evt, int y, int x, int button, u8 mods)
{
// one-based
x++;
@ -239,7 +246,7 @@ void ICACHE_FLASH_ATTR sendMouseAction(char evt, int y, int x, int button, u8 mo
}
/** Socket received a message */
void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int flags)
static void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int flags)
{
// Add terminator if missing (seems to randomly happen)
data[len] = 0;
@ -304,7 +311,7 @@ void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int flags)
}
/** Send a heartbeat msg */
void ICACHE_FLASH_ATTR heartbeatTimCb(void *unused)
static void ICACHE_FLASH_ATTR heartbeatTimCb(void *unused)
{
if (notify_available && active_clients > 0) {
// Heartbeat packet - indicate we're still connected
@ -313,7 +320,13 @@ void ICACHE_FLASH_ATTR heartbeatTimCb(void *unused)
}
}
void ICACHE_FLASH_ATTR closeSockCb(Websock *ws)
static void ICACHE_FLASH_ATTR resetHeartbeatTimer(void)
{
TIMER_START(&heartbeatTim, heartbeatTimCb, HB_TIME, 1);
}
static void ICACHE_FLASH_ATTR closeSockCb(Websock *ws)
{
active_clients--;
if (active_clients <= 0) {
@ -340,7 +353,7 @@ void ICACHE_FLASH_ATTR updateSockConnect(Websock *ws)
UART_SendAsync("\x1b[I", 3);
}
TIMER_START(&heartbeatTim, heartbeatTimCb, HB_TIME, 1);
resetHeartbeatTimer();
}
active_clients++;
@ -348,14 +361,14 @@ void ICACHE_FLASH_ATTR updateSockConnect(Websock *ws)
ETSTimer xonTim;
void ICACHE_FLASH_ATTR notify_empty_txbuf_cb(void *unused)
static void ICACHE_FLASH_ATTR notify_empty_txbuf_cb(void *unused)
{
UART_WriteChar(UART1, '+', 100);
cgiWebsockBroadcast(URL_WS_UPDATE, "+", 1, 0);
resetHeartbeatTimer();
browser_wants_xon = false;
}
void notify_empty_txbuf(void)
{
if (browser_wants_xon) {

@ -545,6 +545,10 @@ screen_tab_reverse(int count)
/**
* Clear range, inclusive
*
* @param from - starting absolute position
* @param to - ending absolute position
* @param clear_utf - release any encountered utf8
*/
static void ICACHE_FLASH_ATTR
clear_range_do(unsigned int from, unsigned int to, bool clear_utf)
@ -566,7 +570,10 @@ clear_range_do(unsigned int from, unsigned int to, bool clear_utf)
}
/**
* Clear range, inclusive
* Clear range, inclusive, freeing any encountered UTF8 from the cache
*
* @param from - starting absolute position
* @param to - ending absolute position
*/
static inline void ICACHE_FLASH_ATTR
clear_range_utf(unsigned int from, unsigned int to)
@ -576,6 +583,9 @@ clear_range_utf(unsigned int from, unsigned int to)
/**
* Clear range, inclusive. Do not release utf characters
*
* @param from - starting absolute position
* @param to - ending absolute position
*/
static inline void ICACHE_FLASH_ATTR
clear_range_noutf(unsigned int from, unsigned int to)
@ -583,44 +593,105 @@ clear_range_noutf(unsigned int from, unsigned int to)
clear_range_do(from, to, false);
}
/**
* Free a utf8 reference character in a cell
*
* @param row
* @param col
*/
static inline void ICACHE_FLASH_ATTR
utf_free_cell(int row, int i)
utf_free_cell(int row, int col)
{
UnicodeCacheRef symbol = screen[row * W + i].symbol;
UnicodeCacheRef symbol = screen[row * W + col].symbol;
if (IS_UNICODE_CACHE_REF(symbol))
unicode_cache_remove(symbol);
}
/**
* Back-up utf8 reference in a cell (i.e. increment the counter,
* so 1 subsequent free has no effect)
*
* @param row
* @param col
*/
static inline void ICACHE_FLASH_ATTR
utf_free_row(int r)
utf_backup_cell(int row, int col)
{
for (int i = 0; i < W; i++) {
utf_free_cell(r, i);
UnicodeCacheRef symbol = screen[row * W + col].symbol;
if (IS_UNICODE_CACHE_REF(symbol))
unicode_cache_inc(symbol);
}
/**
* Free all utf8 on a row
*
* @param row
*/
static inline void ICACHE_FLASH_ATTR
utf_free_row(int row)
{
for (int col = 0; col < W; col++) {
utf_free_cell(row, col);
}
}
/**
* Back-up all utf8 refs on a row
*
* @param row
*/
static inline void ICACHE_FLASH_ATTR
utf_backup_row(int row)
{
for (int col = 0; col < W; col++) {
utf_backup_cell(row, col);
}
}
/**
* Duplicate a row
*
* @param dest - destination row number (0-based)
* @param src - source row number (0-based)
*/
static inline void ICACHE_FLASH_ATTR
copy_row(int dest, int src)
{
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
*
* @param row
*/
static inline void ICACHE_FLASH_ATTR
clear_row_noutf(int r)
clear_row_noutf(int row)
{
clear_range_noutf(r * W, (r + 1) * W - 1);
clear_range_noutf(row * W, (row + 1) * W - 1);
}
/**
* Clear a row, freeing any utf8 refs
*
* @param row
*/
static inline void ICACHE_FLASH_ATTR
clear_row_utf(int r)
clear_row_utf(int row)
{
clear_range_utf(r * W, (r + 1) * W - 1);
clear_range_utf(row * W, (row + 1) * W - 1);
}
/**
@ -633,7 +704,8 @@ screen_clear(ClearMode mode)
NOTIFY_LOCK();
switch (mode) {
case CLEAR_ALL:
clear_range_utf(0, W * H - 1);
clear_range_noutf(0, W * H - 1);
unicode_cache_clear();
break;
case CLEAR_FROM_CURSOR:
@ -691,21 +763,21 @@ screen_insert_lines(unsigned int lines)
// shift the following lines
int targetStart = cursor.y + lines;
if (targetStart > BTM) {
targetStart = BTM - 1;
clear_range_utf(cursor.y*W, (BTM+1)*W-1);
} else {
// do the moving
for (int i = BTM; i >= targetStart; i--) {
utf_free_row(i); // release old characters
copy_row(i, i - lines);
}
}
// clear the first line
clear_row_noutf(CLEAR_ALL);
clear_row_noutf(cursor.y);
// copy it to the rest of the cleared region
for (int i = cursor.y+1; i < targetStart; i++) {
copy_row(i, cursor.y);
}
}
NOTIFY_DONE();
}
@ -716,18 +788,18 @@ screen_delete_lines(unsigned int lines)
NOTIFY_LOCK();
// shift lines up
int targetEnd = BTM - lines - 1;
if (targetEnd <= cursor.y) {
int movedBlockEnd = BTM - lines ;
if (movedBlockEnd <= cursor.y) {
// clear the entire rest of the screen
targetEnd = cursor.y;
clear_range_utf(targetEnd * W, W * BTM);
movedBlockEnd = cursor.y;
clear_range_utf(movedBlockEnd*W, W * BTM);
} else {
// move some lines up, clear the rest
for (int i = cursor.y; i <= targetEnd; i++) {
for (int i = cursor.y; i <= movedBlockEnd; i++) {
utf_free_row(i);
copy_row(i, i+lines);
}
clear_range_noutf(targetEnd*W, W*BTM);
clear_range_noutf((movedBlockEnd+1)*W, (BTM+1)*W-1);
}
NOTIFY_DONE();
@ -743,8 +815,7 @@ screen_insert_characters(unsigned int count)
int targetStart = cursor.x + count;
if (targetStart >= W) {
// all rest of line was cleared
targetStart = W-1;
clear_range_utf(cursor.y * W + cursor.x, cursor.y * W + targetStart - 1);
clear_range_utf(cursor.y * W + cursor.x, (cursor.y + 1) * W - 1);
} else {
// do the moving
for (int i = W-1; i >= targetStart; i--) {

@ -20,7 +20,8 @@ static UnicodeCacheSlot cache[UNICODE_CACHE_SIZE];
* @return
*/
void ICACHE_FLASH_ATTR
unicode_cache_clear(void) {
unicode_cache_clear(void)
{
utfc_dbg("utf8 cache clear!");
for (int slot = 0; slot < UNICODE_CACHE_SIZE; slot++) {
cache[slot].count=0;
@ -35,7 +36,8 @@ unicode_cache_clear(void) {
* @return the obtained look-up reference
*/
UnicodeCacheRef ICACHE_FLASH_ATTR
unicode_cache_add(const u8 *bytes) {
unicode_cache_add(const u8 *bytes)
{
if (bytes[0] < 32) {
utfc_warn("utf8 cache bad char '%c'", bytes[0]);
return '?';
@ -69,6 +71,27 @@ unicode_cache_add(const u8 *bytes) {
return ID_TO_REF(slot);
}
/**
* Increment a reference
*
* @param ref - reference
* @return success
*/
bool ICACHE_FLASH_ATTR
unicode_cache_inc(UnicodeCacheRef ref)
{
if (!IS_UNICODE_CACHE_REF(ref)) return true; // ASCII
int slot = REF_TO_ID(ref);
if (cache[slot].count == 0) {
utfc_warn("utf8 cache inc-after-free ref @ %d", ref);
return false;
}
cache[slot].count++;
utfc_dbg("utf8 cache inc '%.4s' @ %d, %d uses", cache[slot].bytes, slot, cache[slot].count);
return true;
}
/**
* Look up a code point in the cache by reference. Do not change the use counter.
*
@ -77,7 +100,8 @@ unicode_cache_add(const u8 *bytes) {
* @return true if the look-up succeeded
*/
bool ICACHE_FLASH_ATTR
unicode_cache_retrieve(UnicodeCacheRef ref, u8 *target) {
unicode_cache_retrieve(UnicodeCacheRef ref, u8 *target)
{
if (!IS_UNICODE_CACHE_REF(ref)) {
// ASCII, bypass
target[0] = ref;
@ -107,7 +131,8 @@ unicode_cache_retrieve(UnicodeCacheRef ref, u8 *target) {
* @return true if the code point was found in the cache
*/
bool ICACHE_FLASH_ATTR
unicode_cache_remove(UnicodeCacheRef ref) {
unicode_cache_remove(UnicodeCacheRef ref)
{
if (!IS_UNICODE_CACHE_REF(ref)) return true; // ASCII, bypass
u8 slot = REF_TO_ID(ref);

@ -28,6 +28,14 @@ void unicode_cache_clear(void);
*/
UnicodeCacheRef unicode_cache_add(const u8 *bytes);
/**
* Increment a reference
*
* @param ref - reference
* @return success
*/
bool unicode_cache_inc(UnicodeCacheRef ref);
/**
* Look up a code point in the cache by reference. Do not change the use counter.
*

Loading…
Cancel
Save