DeterministicESPAsyncWebServer 1.2.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
websocket.h File Reference

Layer 6 (Presentation) – WebSocket frame parser and connection pool. More...

#include "DetWebServerConfig.h"
#include "transport.h"

Go to the source code of this file.

Classes

struct  WsConn
 WebSocket connection state stored in ws_pool[]. More...
 

Enumerations

enum  WsOpcode {
  WS_OP_CONTINUATION = 0x0 , WS_OP_TEXT = 0x1 , WS_OP_BINARY = 0x2 , WS_OP_CLOSE = 0x8 ,
  WS_OP_PING = 0x9 , WS_OP_PONG = 0xA
}
 WebSocket frame opcodes. More...
 
enum  WsCloseCode {
  WS_CLOSE_NORMAL = 1000 , WS_CLOSE_GOING_AWAY = 1001 , WS_CLOSE_PROTOCOL = 1002 , WS_CLOSE_UNSUPPORTED =1003 ,
  WS_CLOSE_TOO_BIG = 1009
}
 WebSocket close status codes (RFC 6455 §7.4.1). More...
 
enum  WsParseState {
  WS_HEADER1 , WS_HEADER2 , WS_LEN16_HI , WS_LEN16_LO ,
  WS_LEN64 , WS_MASK0 , WS_MASK1 , WS_MASK2 ,
  WS_MASK3 , WS_PAYLOAD , WS_FRAME_READY , WS_CLOSED ,
  WS_ERROR
}
 States of the WebSocket frame parser. More...
 

Functions

void ws_init ()
 Initialise all WebSocket pool slots to inactive.
 
WsConnws_alloc (uint8_t slot_id)
 Allocate a WsConn slot and bind it to a TCP slot.
 
WsConnws_find (uint8_t slot_id)
 Find the WsConn for a given TCP slot, or nullptr if none.
 
void ws_free (uint8_t slot_id)
 Free the WsConn associated with a TCP slot.
 
void ws_parse (WsConn *ws)
 Drain the ring buffer for slot_id and feed bytes to the WS parser.
 
void ws_reset_frame (WsConn *ws)
 Reset the frame parser back to WS_HEADER1, ready for the next frame.
 
bool ws_send_frame (WsConn *ws, WsOpcode opcode, const uint8_t *payload, uint16_t len)
 Send a WebSocket frame to the client.
 
void ws_close (WsConn *ws, WsCloseCode code)
 Send a Close frame and mark the slot WS_CLOSED.
 

Variables

WsConn ws_pool [MAX_WS_CONNS]
 Pool of WebSocket connection state, one per MAX_WS_CONNS.
 

Detailed Description

Layer 6 (Presentation) – WebSocket frame parser and connection pool.

Implements RFC 6455 framing with a fixed-size payload buffer per slot. Connections are tracked in ws_pool[MAX_WS_CONNS]; each entry maps to one TCP slot in conn_pool[] via slot_id.

Frame format (client to server)

0 1 2 3
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| payload len | extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| +-------------------------------+
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - -+
| extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - -+-------------------------------+
| | masking key, if MASK set |
+-------------------------------+-------------------------------+
| masking key (continued) | payload data |
+-------------------------------- - - - - - - - - - - - - - - -+
: payload data continued :
+---------------------------------------------------------------+

State machine

WS_HEADER1 -- read FIN + opcode byte
WS_HEADER2 -- read MASK + 7-bit payload length
WS_LEN16_HI -- read extended 16-bit length high byte
WS_LEN16_LO -- read extended 16-bit length low byte
WS_LEN64 -- consume 8-byte 64-bit length (reject; too large)
WS_MASK0..3 -- read 4-byte masking key
WS_PAYLOAD -- accumulate payload bytes (unmasked)
WS_FRAME_READY -- complete frame waiting for dispatch
WS_CLOSED -- connection closed; slot may be recycled
WS_ERROR -- protocol error; close frame sent
@ WS_LEN16_LO
Reading extended 16-bit length, low byte.
Definition websocket.h:96
@ WS_HEADER1
Awaiting first header byte (FIN, RSV, opcode).
Definition websocket.h:93
@ WS_MASK0
Reading masking key byte 0.
Definition websocket.h:98
@ WS_FRAME_READY
Complete frame ready for dispatch.
Definition websocket.h:103
@ WS_HEADER2
Awaiting second header byte (MASK, 7-bit length).
Definition websocket.h:94
@ WS_LEN16_HI
Reading extended 16-bit length, high byte.
Definition websocket.h:95
@ WS_ERROR
Protocol error; close frame has been queued.
Definition websocket.h:105
@ WS_CLOSED
Connection closed; slot may be recycled.
Definition websocket.h:104
@ WS_PAYLOAD
Accumulating payload bytes.
Definition websocket.h:102
@ WS_LEN64
Consuming 8-byte 64-bit length (always rejected).
Definition websocket.h:97

Limitations

  • Fragmented messages are not supported (FIN=0 frames close with 1003).
  • Payload larger than WS_FRAME_SIZE closes with 1009.
  • RSV bits must be zero (no extensions supported).
Author
Douglas Quigg (dstroy0)
Date
2026

Definition in file websocket.h.

Enumeration Type Documentation

◆ WsOpcode

enum WsOpcode

WebSocket frame opcodes.

Enumerator
WS_OP_CONTINUATION 

Continuation frame (fragmentation – rejected).

WS_OP_TEXT 

UTF-8 text payload.

WS_OP_BINARY 

Binary payload.

WS_OP_CLOSE 

Connection close.

WS_OP_PING 

Ping (auto-ponged by the library).

WS_OP_PONG 

Pong (echoed ping; ignored by library).

Definition at line 66 of file websocket.h.

◆ WsCloseCode

WebSocket close status codes (RFC 6455 §7.4.1).

Enumerator
WS_CLOSE_NORMAL 

Normal closure.

WS_CLOSE_GOING_AWAY 

Endpoint going away.

WS_CLOSE_PROTOCOL 

Protocol error.

WS_CLOSE_UNSUPPORTED 

Unsupported data (e.g. fragmented message).

WS_CLOSE_TOO_BIG 

Payload too large for WS_FRAME_SIZE.

Definition at line 77 of file websocket.h.

◆ WsParseState

States of the WebSocket frame parser.

Enumerator
WS_HEADER1 

Awaiting first header byte (FIN, RSV, opcode).

WS_HEADER2 

Awaiting second header byte (MASK, 7-bit length).

WS_LEN16_HI 

Reading extended 16-bit length, high byte.

WS_LEN16_LO 

Reading extended 16-bit length, low byte.

WS_LEN64 

Consuming 8-byte 64-bit length (always rejected).

WS_MASK0 

Reading masking key byte 0.

WS_MASK1 

Reading masking key byte 1.

WS_MASK2 

Reading masking key byte 2.

WS_MASK3 

Reading masking key byte 3.

WS_PAYLOAD 

Accumulating payload bytes.

WS_FRAME_READY 

Complete frame ready for dispatch.

WS_CLOSED 

Connection closed; slot may be recycled.

WS_ERROR 

Protocol error; close frame has been queued.

Definition at line 91 of file websocket.h.

Function Documentation

◆ ws_init()

void ws_init ( )

Initialise all WebSocket pool slots to inactive.

Called once from DetWebServer::begin().

Definition at line 24 of file websocket.cpp.

References MAX_WS_CONNS, WsConn::ws_id, and ws_pool.

Referenced by DetWebServer::begin(), and DetWebServer::stop().

◆ ws_alloc()

WsConn * ws_alloc ( uint8_t  slot_id)

Allocate a WsConn slot and bind it to a TCP slot.

Parameters
slot_idTCP connection slot that just completed an upgrade.
Returns
Pointer to the allocated WsConn, or nullptr if the pool is full.

Definition at line 33 of file websocket.cpp.

References WsConn::active, MAX_WS_CONNS, WsConn::parse_state, WsConn::slot_id, WS_HEADER1, WsConn::ws_id, and ws_pool.

◆ ws_find()

WsConn * ws_find ( uint8_t  slot_id)

Find the WsConn for a given TCP slot, or nullptr if none.

Parameters
slot_idTCP connection slot index.

Definition at line 50 of file websocket.cpp.

References MAX_WS_CONNS, and ws_pool.

Referenced by DetWebServer::handle().

◆ ws_free()

void ws_free ( uint8_t  slot_id)

Free the WsConn associated with a TCP slot.

Parameters
slot_idTCP connection slot index.

Definition at line 60 of file websocket.cpp.

References MAX_WS_CONNS, WsConn::ws_id, and ws_pool.

Referenced by DetWebServer::handle().

◆ ws_parse()

void ws_parse ( WsConn ws)

◆ ws_reset_frame()

void ws_reset_frame ( WsConn ws)

Reset the frame parser back to WS_HEADER1, ready for the next frame.

Does not change ws->active or ws->slot_id.

Parameters
wsWebSocket connection to reset.

Definition at line 73 of file websocket.cpp.

References WsConn::buf, WsConn::fin, WsConn::len64_count, WsConn::mask_key, WsConn::masked, WsConn::opcode, WsConn::parse_state, WsConn::payload_idx, WsConn::payload_len, WS_HEADER1, and WS_OP_TEXT.

Referenced by DetWebServer::handle(), and ws_parse().

◆ ws_send_frame()

bool ws_send_frame ( WsConn ws,
WsOpcode  opcode,
const uint8_t *  payload,
uint16_t  len 
)

Send a WebSocket frame to the client.

Builds the header (no masking – server-to-client frames are never masked) and hands both to tcp_write(). The caller is responsible for calling tcp_output() afterwards.

Parameters
wsWebSocket connection.
opcodeFrame opcode (WS_OP_TEXT, WS_OP_BINARY, WS_OP_PONG, etc.).
payloadPayload bytes (may be nullptr for zero-length frames).
lenPayload length in bytes.
Returns
true on success, false if the TCP slot is not active.

Definition at line 90 of file websocket.cpp.

References CONN_ACTIVE, conn_pool, TcpConn::pcb, WsConn::slot_id, and TcpConn::state.

Referenced by ws_close(), and ws_parse().

◆ ws_close()

void ws_close ( WsConn ws,
WsCloseCode  code 
)

Send a Close frame and mark the slot WS_CLOSED.

Parameters
wsWebSocket connection.
codeClose status code (e.g. WS_CLOSE_NORMAL).

Definition at line 123 of file websocket.cpp.

References conn_pool, WsConn::parse_state, TcpConn::pcb, WsConn::slot_id, WS_CLOSED, WS_OP_CLOSE, and ws_send_frame().

Referenced by DetWebServer::handle(), and ws_parse().

Variable Documentation

◆ ws_pool

WsConn ws_pool[MAX_WS_CONNS]
extern

Pool of WebSocket connection state, one per MAX_WS_CONNS.

Definition at line 22 of file websocket.cpp.

Referenced by ws_alloc(), ws_find(), ws_free(), and ws_init().