20#include <mbedtls/sha1.h>
21#include <mbedtls/base64.h>
25#if VSF_USE_MBEDTLS != ENABLED
26# error sha1 in mbedtls is used as handshake algo, please enable VSF_USE_MBEDTLS
33 WEBSOCKET_STATE_CONNECTING,
34 WEBSOCKET_STATE_CONNECTTED,
35 WEBSOCKET_STATE_PARSE_HEADER = WEBSOCKET_STATE_CONNECTTED,
36 WEBSOCKET_STATE_PARSE_REALLEN,
37 WEBSOCKET_STATE_PARSE_MASKING,
38 WEBSOCKET_STATE_PARSE_DATA,
39 WEBSOCKET_STATE_CLOSING,
40 WEBSOCKET_STATE_CLOSED,
52static char __websocket_magic[] =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
57 .
init_fn = __vsf_linux_httpd_urihandler_websocket_init,
58 .fini_fn = __vsf_linux_httpd_urihandler_websocket_fini,
59 .serve_fn = __vsf_linux_httpd_urihandler_websocket_serve,
60 .stream_evthandler_fn = __vsf_linux_httpd_urihandler_socket_stream_evthandler,
76 switch (urihandler_websocket->
state) {
77 case WEBSOCKET_STATE_PARSE_HEADER:
81 urihandler_websocket->
is_fin = !!(header[0] * 0x80);
82 urihandler_websocket->
opcode = header[0] & 0x0F;
83 switch (urihandler_websocket->
opcode) {
85 urihandler_websocket->
is_start =
false;
87 urihandler_websocket->
is_masking = !!(header[1] & 0x80);
92 urihandler_websocket->
state = WEBSOCKET_STATE_PARSE_REALLEN;
96 urihandler_websocket->
state = WEBSOCKET_STATE_PARSE_REALLEN;
106 urihandler_websocket->
is_start =
true;
110 urihandler_websocket->
is_start =
true;
119 case WEBSOCKET_STATE_PARSE_REALLEN:
123 switch (urihandler_websocket->
len_size) {
124 case 2: urihandler_websocket->
payload_len = get_unaligned_be16(header);
break;
125 case 8: urihandler_websocket->
payload_len = get_unaligned_be64(header);
break;
129 urihandler_websocket->
state = WEBSOCKET_STATE_PARSE_MASKING;
131 }
else if (urihandler_websocket->
payload_len > 0) {
132 urihandler_websocket->
state = WEBSOCKET_STATE_PARSE_DATA;
135 urihandler_websocket->
state = WEBSOCKET_STATE_PARSE_HEADER;
140 case WEBSOCKET_STATE_PARSE_MASKING:
147 urihandler_websocket->
state = WEBSOCKET_STATE_PARSE_DATA;
149 urihandler_websocket->
state = WEBSOCKET_STATE_PARSE_HEADER;
153 case WEBSOCKET_STATE_PARSE_DATA:
167 buf[i] ^= urihandler_websocket->
masking_key[masking_pos];
174 switch (urihandler_websocket->
opcode) {
189 urihandler_websocket->
state = WEBSOCKET_STATE_CLOSING;
195 urihandler_websocket->
state = WEBSOCKET_STATE_PARSE_HEADER;
205 switch (urihandler_websocket->
state) {
206 case WEBSOCKET_STATE_CONNECTING:
208 urihandler_websocket->
state = WEBSOCKET_STATE_CONNECTTED;
214 case WEBSOCKET_STATE_CLOSING:
218 urihandler_websocket->
state = WEBSOCKET_STATE_CLOSED;
232 if (!req->websocket || (
NULL == req->websocket_key)) {
239 int bufsize =
sizeof(req->buffer) / 2;
241 urihandler_websocket->
state = WEBSOCKET_STATE_CONNECTING;
244 memset(stream, 0,
sizeof(*stream));
246 stream->buffer = req->buffer;
247 stream->size = bufsize;
249 stream->tx.param = req;
252 req->stream_out = &stream->use_as__vsf_stream_t;
254 stream = &urihandler_websocket->
stream_in;
255 memset(stream, 0,
sizeof(*stream));
257 stream->buffer = req->buffer + bufsize;
258 stream->size = bufsize;
260 stream->rx.param = req;
262 req->stream_in = &stream->use_as__vsf_stream_t;
264 vsf_stream_write_str(req->stream_out,
"HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Accept: ");
266 char secbuf[32 +
sizeof(__websocket_magic)];
267 strcpy(secbuf, req->websocket_key);
268 strcat(secbuf, __websocket_magic);
269 free(req->websocket_key);
270 req->websocket_key =
NULL;
272 mbedtls_sha1_context ctx;
274 mbedtls_sha1_init(&ctx);
275 mbedtls_sha1_starts(&ctx);
276 mbedtls_sha1_update(&ctx, (
const unsigned char *)secbuf,
strlen(secbuf));
277 mbedtls_sha1_finish(&ctx, sha1_output);
278 mbedtls_sha1_free(&ctx);
281 mbedtls_base64_encode((
unsigned char *)secbuf,
sizeof(secbuf), &olen,
282 (
const unsigned char *)sha1_output,
sizeof(sha1_output));
303 if (
NULL == stream) {
307 uint8_t len_size = len < 126 ? 1 : len < 65535 ? 2 : 8;
314 header[0] = is_string ? 0x81 : 0x82;
318 len =
vsf_min(len, size_dst - 2);
326 len =
vsf_min(len, size_dst - 4);
328 put_unaligned_be16(len, &header[2]);
336 len =
vsf_min(len, size_dst - 10);
338 put_unaligned_be64(len, &header[2]);
#define vsf_min(__a, __b)
Definition __type.h:152
vsf_err_t
Definition __type.h:42
@ VSF_ERR_NONE
none error
Definition __type.h:44
@ VSF_ERR_FAIL
failed
Definition __type.h:51
const vsf_linux_httpd_urihandler_op_t vsf_linux_httpd_urihandler_websocket_op
int vsf_linux_httpd_websocket_write(vsf_linux_httpd_request_t *req, uint8_t *buf, int len, bool is_string)
Definition vsf_fifo_stream.h:99
Definition vsf_linux_httpd.h:251
bool is_stream_out_started
Definition vsf_linux_httpd.h:291
char * uri
Definition vsf_linux_httpd.h:291
Definition vsf_simple_stream.h:254
uint_fast32_t vsf_stream_get_free_size(vsf_stream_t *stream)
Definition vsf_simple_stream.c:120
#define VSF_STREAM_CONNECT_TX(__stream)
Definition vsf_simple_stream.h:136
uint_fast32_t vsf_stream_get_rbuf(vsf_stream_t *stream, uint8_t **ptr)
Definition vsf_simple_stream.c:139
uint_fast32_t vsf_stream_read(vsf_stream_t *stream, uint8_t *buf, uint_fast32_t size)
Definition vsf_simple_stream.c:76
uint_fast32_t vsf_stream_write(vsf_stream_t *stream, uint8_t *buf, uint_fast32_t size)
Definition vsf_simple_stream.c:84
#define VSF_STREAM_INIT(__stream)
Definition vsf_simple_stream.h:126
uint_fast32_t vsf_stream_get_data_size(vsf_stream_t *stream)
Definition vsf_simple_stream.c:114
vsf_stream_evt_t
Definition vsf_simple_stream.h:160
void vsf_stream_disconnect_tx(vsf_stream_t *stream)
Definition vsf_simple_stream.c:211
#define VSF_STREAM_CONNECT_RX(__stream)
Definition vsf_simple_stream.h:135
void vsf_stream_disconnect_rx(vsf_stream_t *stream)
Definition vsf_simple_stream.c:205
@ VSF_STREAM_ON_OUT
Definition vsf_simple_stream.h:165
@ VSF_STREAM_ON_IN
Definition vsf_simple_stream.h:163
struct ieee80211_ext_chansw_ie data
Definition ieee80211.h:80
#define NULL
Definition lvgl.h:26
unsigned char uint8_t
Definition lvgl.h:40
unsigned int uint_fast32_t
Definition stdint.h:27
#define free
Definition stdlib.h:30
size_t strlen(const char *str)
char * strcat(char *dest, const char *src)
void * memset(void *s, int ch, size_t n)
char * strcpy(char *dest, const char *src)
Definition vsf_linux_httpd.h:170
vsf_err_t(* init_fn)(vsf_linux_httpd_request_t *req, uint8_t *data, uint_fast32_t size)
Definition vsf_linux_httpd.h:171
Definition vsf_linux_httpd.h:208
vsf_linux_httpd_websocket_onmessage_t on_message
Definition vsf_linux_httpd.h:237
struct vsf_linux_httpd_urihandler_t::@836::@839 websocket
vsf_linux_httpd_websocket_onclose_t on_close
Definition vsf_linux_httpd.h:235
vsf_linux_httpd_websocket_onopen_t on_open
Definition vsf_linux_httpd.h:234
Definition __vsf_linux_urihandler_websocket.h:33
uint8_t opcode
Definition __vsf_linux_urihandler_websocket.h:40
vsf_fifo_stream_t stream_in
Definition __vsf_linux_urihandler_websocket.h:34
uint8_t is_start
Definition __vsf_linux_urihandler_websocket.h:41
uint8_t masking_key[4]
Definition __vsf_linux_urihandler_websocket.h:37
uint8_t is_string
Definition __vsf_linux_urihandler_websocket.h:43
uint8_t len_size
Definition __vsf_linux_urihandler_websocket.h:38
uint8_t is_fin
Definition __vsf_linux_urihandler_websocket.h:42
uint8_t masking_pos
Definition __vsf_linux_urihandler_websocket.h:45
uint8_t is_masking
Definition __vsf_linux_urihandler_websocket.h:44
vsf_fifo_stream_t stream_out
Definition __vsf_linux_urihandler_websocket.h:35
uint8_t state
Definition __vsf_linux_urihandler_websocket.h:39
uint64_t payload_len
Definition __vsf_linux_urihandler_websocket.h:36
const vsf_stream_op_t vsf_fifo_stream_op
Definition vsf_fifo_stream.c:45
#define VSF_LINUX_ASSERT
Definition vsf_linux_cfg.h:31
#define vsf_stream_write_str(__stream, __str)
Definition vsf_linux_httpd.c:76
@ VSF_LINUX_HTTPD_BAD_REQUEST
Definition vsf_linux_httpd.h:143
@ VSF_LINUX_HTTPD_OK
Definition vsf_linux_httpd.h:139
uint32_t size
Definition vsf_memfs.h:50