Skip to content

Commit 8d9c995

Browse files
committed
Support ping & close. Refine html and js for serial
1 parent a4035aa commit 8d9c995

File tree

3 files changed

+89
-23
lines changed

3 files changed

+89
-23
lines changed

supervisor/shared/web_workflow/static/serial.html

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@
77
</head>
88
<body>
99
<pre id="log"></pre>
10-
<form onsubmit="onSubmit(); return false;">
11-
<input type="text" id="input">
12-
<input type="submit" value="Send">
13-
<button onclick="onCloseClick(); return false;">close</button>
14-
</form>
10+
<textarea id="input" rows="1" spellcheck="false" wrap="off" style="resize: none;"></textarea>
11+
<button onclick="onSubmit(); return false;">Send</button>
12+
<button onclick="onCloseClick(); return false;">close</button>
1513
</body>
1614
</html>

supervisor/shared/web_workflow/static/serial.js

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11

22
var ws;
3+
var input = document.getElementById("input");
4+
var title = document.querySelector("title");
5+
6+
function set_enabled(enabled) {
7+
input.disabled = !enabled;
8+
var buttons = document.querySelectorAll("button");
9+
for (button of buttons) {
10+
button.disabled = !enabled;
11+
}
12+
}
13+
14+
set_enabled(false);
315

416
function onSubmit() {
5-
var input = document.getElementById("input");
17+
console.log("submit");
618
// You can send message to the Web Socket using ws.send.
719
ws.send(input.value);
820
// output("send: " + input.value);
@@ -11,6 +23,7 @@ function onSubmit() {
1123
}
1224

1325
function onCloseClick() {
26+
console.log("close clicked");
1427
ws.close();
1528
}
1629

@@ -26,18 +39,35 @@ ws = new WebSocket("ws://cpy-f57ce8.local/cp/serial/");
2639
// Set event handlers.
2740
ws.onopen = function() {
2841
console.log("onopen");
42+
set_enabled(true);
2943
};
3044

45+
var setting_title = false;
3146
ws.onmessage = function(e) {
3247
// e.data contains received string.
33-
output(e.data);
48+
if (e.data == "\x1b]0;") {
49+
setting_title = true;
50+
title.textContent = "";
51+
} else if (e.data == "\x1b\\") {
52+
setting_title = false;
53+
} else if (setting_title) {
54+
title.textContent += e.data;
55+
} else {
56+
output(e.data);
57+
}
3458
};
3559

3660
ws.onclose = function() {
3761
console.log("onclose");
62+
set_enabled(false);
3863
};
3964

4065
ws.onerror = function(e) {
4166
// output("onerror");
42-
console.log(e)
67+
console.log(e);
68+
set_enabled(false);
4369
};
70+
71+
input.onbeforeinput = function(e) {
72+
console.log(e);
73+
}

supervisor/shared/web_workflow/websocket.c

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ typedef struct {
3232
uint8_t frame_len;
3333
uint8_t payload_len_size;
3434
bool masked;
35+
bool closed;
3536
uint8_t mask[4];
3637
int frame_index;
3738
size_t payload_remaining;
@@ -49,14 +50,18 @@ void websocket_init(void) {
4950
void websocket_handoff(socketpool_socket_obj_t *socket) {
5051
ESP_LOGI(TAG, "socket handed off");
5152
cp_serial.socket = *socket;
53+
cp_serial.closed = false;
54+
cp_serial.opcode = 0;
55+
cp_serial.frame_index = 0;
56+
cp_serial.frame_len = 2;
5257
// Mark the original socket object as closed without telling the lower level.
5358
socket->connected = false;
5459
socket->num = -1;
5560
ESP_LOGI(TAG, "socket hand off done");
5661
}
5762

5863
bool websocket_connected(void) {
59-
return common_hal_socketpool_socket_get_connected(&cp_serial.socket);
64+
return !cp_serial.closed && common_hal_socketpool_socket_get_connected(&cp_serial.socket);
6065
}
6166

6267
static bool _read_byte(uint8_t *c) {
@@ -70,6 +75,16 @@ static bool _read_byte(uint8_t *c) {
7075
return true;
7176
}
7277

78+
static void _send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len) {
79+
int sent = -EAGAIN;
80+
while (sent == -EAGAIN) {
81+
sent = socketpool_socket_send(socket, buf, len);
82+
}
83+
if (sent < len) {
84+
ESP_LOGE(TAG, "short send on %d err %d len %d", socket->num, sent, len);
85+
}
86+
}
87+
7388
static void _read_next_frame_header(void) {
7489
uint8_t h;
7590
if (cp_serial.frame_index == 0 && _read_byte(&h)) {
@@ -111,20 +126,53 @@ static void _read_next_frame_header(void) {
111126
cp_serial.frame_index++;
112127
ESP_LOGI(TAG, "mask %08x", (uint32_t)*cp_serial.mask);
113128
}
129+
// Reply to PINGs and CLOSE.
130+
while ((cp_serial.opcode == 0x8 ||
131+
cp_serial.opcode == 0x9) &&
132+
cp_serial.frame_index >= cp_serial.frame_len) {
133+
134+
if (cp_serial.frame_index == cp_serial.frame_len) {
135+
uint8_t opcode = 0x8; // CLOSE
136+
if (cp_serial.opcode == 0x9) {
137+
ESP_LOGI(TAG, "websocket ping");
138+
opcode = 0xA; // PONG
139+
}
140+
uint8_t frame_header[2];
141+
frame_header[0] = 1 << 7 | opcode;
142+
if (cp_serial.payload_remaining > 125) {
143+
ESP_LOGE(TAG, "CLOSE or PING has long payload");
144+
}
145+
frame_header[1] = cp_serial.payload_remaining;
146+
_send_raw(&cp_serial.socket, (const uint8_t *)frame_header, 2);
147+
}
148+
149+
if (cp_serial.payload_remaining > 0 && _read_byte(&h)) {
150+
// Send the payload back to the client.
151+
cp_serial.frame_index++;
152+
cp_serial.payload_remaining--;
153+
_send_raw(&cp_serial.socket, &h, 1);
154+
}
155+
156+
if (cp_serial.payload_remaining == 0) {
157+
cp_serial.frame_index = 0;
158+
if (cp_serial.opcode == 0x8) {
159+
ESP_LOGI(TAG, "websocket closed");
160+
cp_serial.closed = true;
161+
}
162+
}
163+
}
114164
}
115165

116166
static bool _read_next_payload_byte(uint8_t *c) {
117167
_read_next_frame_header();
118-
if (cp_serial.frame_index >= cp_serial.frame_len &&
168+
if (cp_serial.opcode == 0x1 &&
169+
cp_serial.frame_index >= cp_serial.frame_len &&
119170
cp_serial.payload_remaining > 0) {
120171
if (_read_byte(c)) {
121172
uint8_t mask_offset = (cp_serial.frame_index - cp_serial.frame_len) % 4;
122-
ESP_LOGI(TAG, "payload byte read %02x mask offset %d", *c, mask_offset);
123173
*c ^= cp_serial.mask[mask_offset];
124-
ESP_LOGI(TAG, "byte unmasked %02x", *c);
125174
cp_serial.frame_index++;
126175
cp_serial.payload_remaining--;
127-
ESP_LOGI(TAG, "payload remaining %d", cp_serial.payload_remaining);
128176
if (cp_serial.payload_remaining == 0) {
129177
cp_serial.frame_index = 0;
130178
}
@@ -148,16 +196,6 @@ char websocket_read_char(void) {
148196
return c;
149197
}
150198

151-
static void _send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len) {
152-
int sent = -EAGAIN;
153-
while (sent == -EAGAIN) {
154-
sent = socketpool_socket_send(socket, buf, len);
155-
}
156-
if (sent < len) {
157-
ESP_LOGE(TAG, "short send %d %d", sent, len);
158-
}
159-
}
160-
161199
static void _websocket_send(_websocket *ws, const char *text, size_t len) {
162200
if (!websocket_connected()) {
163201
return;

0 commit comments

Comments
 (0)