-
Notifications
You must be signed in to change notification settings - Fork 721
/
console.c
152 lines (134 loc) · 3.91 KB
/
console.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <esp8266.h>
#include "uart.h"
#include "cgi.h"
#include "uart.h"
#include "serbridge.h"
#include "console.h"
// Microcontroller console capturing the last 1024 characters received on the uart so
// they can be shown on a web page
// Buffer to hold concole contents.
// Invariants:
// - console_rd==console_wr <=> buffer empty
// - *console_rd == next char to read
// - *console_wr == next char to write
// - 0 <= console_xx < BUF_MAX
// - (console_wr+1)%BUF_MAX) == console_rd <=> buffer full
#define BUF_MAX (1024)
static char console_buf[BUF_MAX];
static int console_wr, console_rd;
static int console_pos; // offset since reset of buffer
static void ICACHE_FLASH_ATTR
console_write(char c) {
console_buf[console_wr] = c;
console_wr = (console_wr+1) % BUF_MAX;
if (console_wr == console_rd) {
// full, we write anyway and loose the oldest char
console_rd = (console_rd+1) % BUF_MAX; // full, eat first char
console_pos++;
}
}
// return previous character in console, 0 if at start
static char ICACHE_FLASH_ATTR
console_prev(void) {
if (console_wr == console_rd) return 0;
return console_buf[(console_wr-1+BUF_MAX)%BUF_MAX];
}
void ICACHE_FLASH_ATTR
console_write_char(char c) {
if (c == '\n' && console_prev() != '\r') console_write('\r');
console_write(c);
}
void ICACHE_FLASH_ATTR
jsonHeader(HttpdConnData *connData, int code) {
httpdStartResponse(connData, code);
httpdHeader(connData, "Content-Type", "application/json");
httpdEndHeaders(connData);
}
int ICACHE_FLASH_ATTR
ajaxConsoleReset(HttpdConnData *connData) {
jsonHeader(connData, 200);
serbridgeReset();
return HTTPD_CGI_DONE;
}
int ICACHE_FLASH_ATTR
ajaxConsoleBaud(HttpdConnData *connData) {
char buff[2048];
int len;
len = httpdFindArg(connData->getArgs, "rate", buff, sizeof(buff));
if (len > 0) {
int rate = atoi(buff);
if (rate >= 9600 && rate <= 1000000) {
jsonHeader(connData, 200);
uart0_baud(rate);
return HTTPD_CGI_DONE;
}
}
jsonHeader(connData, 400);
return HTTPD_CGI_DONE;
}
int ICACHE_FLASH_ATTR
ajaxConsole(HttpdConnData *connData) {
char buff[2048];
int len; // length of text in buff
int console_len = (console_wr+BUF_MAX-console_rd) % BUF_MAX; // num chars in console_buf
int start = 0; // offset onto console_wr to start sending out chars
jsonHeader(connData, 200);
// figure out where to start in buffer based on URI param
len = httpdFindArg(connData->getArgs, "start", buff, sizeof(buff));
if (len > 0) {
start = atoi(buff);
if (start < console_pos) {
start = 0;
} else if (start >= console_pos+console_len) {
start = console_len;
} else {
start = start - console_pos;
}
}
// start outputting
len = os_sprintf(buff, "{\"len\":%d, \"start\":%d, \"text\": \"",
console_len-start, console_pos+start);
int rd = (console_rd+start) % BUF_MAX;
while (len < 2040 && rd != console_wr) {
uint8_t c = console_buf[rd];
if (c == '\\' || c == '"') {
buff[len++] = '\\';
buff[len++] = c;
} else if (c < ' ') {
len += os_sprintf(buff+len, "\\u%04x", c);
} else {
buff[len++] = c;
}
rd = (rd + 1) % BUF_MAX;
}
os_strcpy(buff+len, "\"}"); len+=2;
httpdSend(connData, buff, len);
return HTTPD_CGI_DONE;
}
//===== Display a web page with the console
int ICACHE_FLASH_ATTR
tplConsole(HttpdConnData *connData, char *token, void **arg) {
if (token==NULL) return HTTPD_CGI_DONE;
/*
if (os_strcmp(token, "console") == 0) {
if (console_wr > console_rd) {
httpdSend(connData, console_buf+console_rd, console_wr-console_rd);
} else if (console_rd != console_wr) {
httpdSend(connData, console_buf+console_rd, BUF_MAX-console_rd);
httpdSend(connData, console_buf, console_wr);
} else {
httpdSend(connData, "<buffer empty>", -1);
}
} else if (os_strcmp(token, "head")==0) {
*/
if (os_strcmp(token, "head")==0) {
printHead(connData);
} else {
httpdSend(connData, "Unknown\n", -1);
}
return HTTPD_CGI_DONE;
}
void ICACHE_FLASH_ATTR consoleInit() {
console_wr = 0;
console_rd = 0;
}