Support ping & close. Refine html and js for serial
This commit is contained in:
parent
a4035aa1f7
commit
8d9c995298
@ -7,10 +7,8 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<pre id="log"></pre>
|
<pre id="log"></pre>
|
||||||
<form onsubmit="onSubmit(); return false;">
|
<textarea id="input" rows="1" spellcheck="false" wrap="off" style="resize: none;"></textarea>
|
||||||
<input type="text" id="input">
|
<button onclick="onSubmit(); return false;">Send</button>
|
||||||
<input type="submit" value="Send">
|
|
||||||
<button onclick="onCloseClick(); return false;">close</button>
|
<button onclick="onCloseClick(); return false;">close</button>
|
||||||
</form>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,8 +1,20 @@
|
|||||||
|
|
||||||
var ws;
|
var ws;
|
||||||
|
var input = document.getElementById("input");
|
||||||
|
var title = document.querySelector("title");
|
||||||
|
|
||||||
|
function set_enabled(enabled) {
|
||||||
|
input.disabled = !enabled;
|
||||||
|
var buttons = document.querySelectorAll("button");
|
||||||
|
for (button of buttons) {
|
||||||
|
button.disabled = !enabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_enabled(false);
|
||||||
|
|
||||||
function onSubmit() {
|
function onSubmit() {
|
||||||
var input = document.getElementById("input");
|
console.log("submit");
|
||||||
// You can send message to the Web Socket using ws.send.
|
// You can send message to the Web Socket using ws.send.
|
||||||
ws.send(input.value);
|
ws.send(input.value);
|
||||||
// output("send: " + input.value);
|
// output("send: " + input.value);
|
||||||
@ -11,6 +23,7 @@ function onSubmit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onCloseClick() {
|
function onCloseClick() {
|
||||||
|
console.log("close clicked");
|
||||||
ws.close();
|
ws.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,18 +39,35 @@ ws = new WebSocket("ws://cpy-f57ce8.local/cp/serial/");
|
|||||||
// Set event handlers.
|
// Set event handlers.
|
||||||
ws.onopen = function() {
|
ws.onopen = function() {
|
||||||
console.log("onopen");
|
console.log("onopen");
|
||||||
|
set_enabled(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var setting_title = false;
|
||||||
ws.onmessage = function(e) {
|
ws.onmessage = function(e) {
|
||||||
// e.data contains received string.
|
// e.data contains received string.
|
||||||
|
if (e.data == "\x1b]0;") {
|
||||||
|
setting_title = true;
|
||||||
|
title.textContent = "";
|
||||||
|
} else if (e.data == "\x1b\\") {
|
||||||
|
setting_title = false;
|
||||||
|
} else if (setting_title) {
|
||||||
|
title.textContent += e.data;
|
||||||
|
} else {
|
||||||
output(e.data);
|
output(e.data);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onclose = function() {
|
ws.onclose = function() {
|
||||||
console.log("onclose");
|
console.log("onclose");
|
||||||
|
set_enabled(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onerror = function(e) {
|
ws.onerror = function(e) {
|
||||||
// output("onerror");
|
// output("onerror");
|
||||||
console.log(e)
|
console.log(e);
|
||||||
|
set_enabled(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
input.onbeforeinput = function(e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
@ -32,6 +32,7 @@ typedef struct {
|
|||||||
uint8_t frame_len;
|
uint8_t frame_len;
|
||||||
uint8_t payload_len_size;
|
uint8_t payload_len_size;
|
||||||
bool masked;
|
bool masked;
|
||||||
|
bool closed;
|
||||||
uint8_t mask[4];
|
uint8_t mask[4];
|
||||||
int frame_index;
|
int frame_index;
|
||||||
size_t payload_remaining;
|
size_t payload_remaining;
|
||||||
@ -49,6 +50,10 @@ void websocket_init(void) {
|
|||||||
void websocket_handoff(socketpool_socket_obj_t *socket) {
|
void websocket_handoff(socketpool_socket_obj_t *socket) {
|
||||||
ESP_LOGI(TAG, "socket handed off");
|
ESP_LOGI(TAG, "socket handed off");
|
||||||
cp_serial.socket = *socket;
|
cp_serial.socket = *socket;
|
||||||
|
cp_serial.closed = false;
|
||||||
|
cp_serial.opcode = 0;
|
||||||
|
cp_serial.frame_index = 0;
|
||||||
|
cp_serial.frame_len = 2;
|
||||||
// Mark the original socket object as closed without telling the lower level.
|
// Mark the original socket object as closed without telling the lower level.
|
||||||
socket->connected = false;
|
socket->connected = false;
|
||||||
socket->num = -1;
|
socket->num = -1;
|
||||||
@ -56,7 +61,7 @@ void websocket_handoff(socketpool_socket_obj_t *socket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool websocket_connected(void) {
|
bool websocket_connected(void) {
|
||||||
return common_hal_socketpool_socket_get_connected(&cp_serial.socket);
|
return !cp_serial.closed && common_hal_socketpool_socket_get_connected(&cp_serial.socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _read_byte(uint8_t *c) {
|
static bool _read_byte(uint8_t *c) {
|
||||||
@ -70,6 +75,16 @@ static bool _read_byte(uint8_t *c) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len) {
|
||||||
|
int sent = -EAGAIN;
|
||||||
|
while (sent == -EAGAIN) {
|
||||||
|
sent = socketpool_socket_send(socket, buf, len);
|
||||||
|
}
|
||||||
|
if (sent < len) {
|
||||||
|
ESP_LOGE(TAG, "short send on %d err %d len %d", socket->num, sent, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void _read_next_frame_header(void) {
|
static void _read_next_frame_header(void) {
|
||||||
uint8_t h;
|
uint8_t h;
|
||||||
if (cp_serial.frame_index == 0 && _read_byte(&h)) {
|
if (cp_serial.frame_index == 0 && _read_byte(&h)) {
|
||||||
@ -111,20 +126,53 @@ static void _read_next_frame_header(void) {
|
|||||||
cp_serial.frame_index++;
|
cp_serial.frame_index++;
|
||||||
ESP_LOGI(TAG, "mask %08x", (uint32_t)*cp_serial.mask);
|
ESP_LOGI(TAG, "mask %08x", (uint32_t)*cp_serial.mask);
|
||||||
}
|
}
|
||||||
|
// Reply to PINGs and CLOSE.
|
||||||
|
while ((cp_serial.opcode == 0x8 ||
|
||||||
|
cp_serial.opcode == 0x9) &&
|
||||||
|
cp_serial.frame_index >= cp_serial.frame_len) {
|
||||||
|
|
||||||
|
if (cp_serial.frame_index == cp_serial.frame_len) {
|
||||||
|
uint8_t opcode = 0x8; // CLOSE
|
||||||
|
if (cp_serial.opcode == 0x9) {
|
||||||
|
ESP_LOGI(TAG, "websocket ping");
|
||||||
|
opcode = 0xA; // PONG
|
||||||
|
}
|
||||||
|
uint8_t frame_header[2];
|
||||||
|
frame_header[0] = 1 << 7 | opcode;
|
||||||
|
if (cp_serial.payload_remaining > 125) {
|
||||||
|
ESP_LOGE(TAG, "CLOSE or PING has long payload");
|
||||||
|
}
|
||||||
|
frame_header[1] = cp_serial.payload_remaining;
|
||||||
|
_send_raw(&cp_serial.socket, (const uint8_t *)frame_header, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cp_serial.payload_remaining > 0 && _read_byte(&h)) {
|
||||||
|
// Send the payload back to the client.
|
||||||
|
cp_serial.frame_index++;
|
||||||
|
cp_serial.payload_remaining--;
|
||||||
|
_send_raw(&cp_serial.socket, &h, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cp_serial.payload_remaining == 0) {
|
||||||
|
cp_serial.frame_index = 0;
|
||||||
|
if (cp_serial.opcode == 0x8) {
|
||||||
|
ESP_LOGI(TAG, "websocket closed");
|
||||||
|
cp_serial.closed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _read_next_payload_byte(uint8_t *c) {
|
static bool _read_next_payload_byte(uint8_t *c) {
|
||||||
_read_next_frame_header();
|
_read_next_frame_header();
|
||||||
if (cp_serial.frame_index >= cp_serial.frame_len &&
|
if (cp_serial.opcode == 0x1 &&
|
||||||
|
cp_serial.frame_index >= cp_serial.frame_len &&
|
||||||
cp_serial.payload_remaining > 0) {
|
cp_serial.payload_remaining > 0) {
|
||||||
if (_read_byte(c)) {
|
if (_read_byte(c)) {
|
||||||
uint8_t mask_offset = (cp_serial.frame_index - cp_serial.frame_len) % 4;
|
uint8_t mask_offset = (cp_serial.frame_index - cp_serial.frame_len) % 4;
|
||||||
ESP_LOGI(TAG, "payload byte read %02x mask offset %d", *c, mask_offset);
|
|
||||||
*c ^= cp_serial.mask[mask_offset];
|
*c ^= cp_serial.mask[mask_offset];
|
||||||
ESP_LOGI(TAG, "byte unmasked %02x", *c);
|
|
||||||
cp_serial.frame_index++;
|
cp_serial.frame_index++;
|
||||||
cp_serial.payload_remaining--;
|
cp_serial.payload_remaining--;
|
||||||
ESP_LOGI(TAG, "payload remaining %d", cp_serial.payload_remaining);
|
|
||||||
if (cp_serial.payload_remaining == 0) {
|
if (cp_serial.payload_remaining == 0) {
|
||||||
cp_serial.frame_index = 0;
|
cp_serial.frame_index = 0;
|
||||||
}
|
}
|
||||||
@ -148,16 +196,6 @@ char websocket_read_char(void) {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _send_raw(socketpool_socket_obj_t *socket, const uint8_t *buf, int len) {
|
|
||||||
int sent = -EAGAIN;
|
|
||||||
while (sent == -EAGAIN) {
|
|
||||||
sent = socketpool_socket_send(socket, buf, len);
|
|
||||||
}
|
|
||||||
if (sent < len) {
|
|
||||||
ESP_LOGE(TAG, "short send %d %d", sent, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _websocket_send(_websocket *ws, const char *text, size_t len) {
|
static void _websocket_send(_websocket *ws, const char *text, size_t len) {
|
||||||
if (!websocket_connected()) {
|
if (!websocket_connected()) {
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user