You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
3.5 KiB
120 lines
3.5 KiB
#pragma once
|
|
|
|
#include "httpd.h"
|
|
|
|
/**
|
|
* Websocket handle
|
|
*/
|
|
typedef struct Websock Websock;
|
|
|
|
#define WEBSOCK_FLAG_NONE 0
|
|
#define WEBSOCK_FLAG_MORE (1<<0) // Set if the data is not the final data in the message; more follows
|
|
#define WEBSOCK_FLAG_BIN (1<<1) // Set if the data is binary instead of text
|
|
#define WEBSOCK_FLAG_CONT (1<<2) // set if this is a continuation frame (after WEBSOCK_FLAG_MORE)
|
|
|
|
/* https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1 */
|
|
typedef enum websock_close_reason {
|
|
/// Normal close
|
|
WS_CLOSE_OK = 1000,
|
|
/// Server shutting down
|
|
WS_CLOSE_GONE = 1001,
|
|
/// Protocol error
|
|
WS_CLOSE_PROTOCOL_ERR = 1002,
|
|
/// Data type error (e.g. binary frame on a text socket)
|
|
WS_CLOSE_DATA_TYPE_ERR = 1003,
|
|
/// Data format error (e.g. malformed UTF-8)
|
|
WS_CLOSE_DATA_FORMAT_ERR = 1007,
|
|
/// Policy violation of some kind
|
|
WS_CLOSE_POLICY_ERR = 1008,
|
|
/// Message too big to handle
|
|
WS_CLOSE_MESSAGE_TOO_BIG = 1009,
|
|
/// Internal server error
|
|
WS_CLOSE_SERVER_ERROR = 1011,
|
|
} websock_close_reason;
|
|
|
|
/** Type for the WS connect callback */
|
|
typedef void(*WsConnectedCb)(Websock *ws);
|
|
|
|
/** Type for the WS receive callback */
|
|
typedef void(*WsRecvCb)(Websock *ws, uint8_t *data, size_t len, int flags);
|
|
|
|
/** Type for the WS sending done callback */
|
|
typedef void(*WsSentCb)(Websock *ws);
|
|
|
|
/** Type for the WS close callback */
|
|
typedef void(*WsCloseCb)(Websock *ws);
|
|
|
|
/** Internal websocket struct (opaque) */
|
|
typedef struct WebsockPriv WebsockPriv;
|
|
|
|
// TODO convert to container_of and avoid separate malloc for priv
|
|
|
|
struct Websock {
|
|
/// Connection pointer
|
|
HttpdConnData *conn;
|
|
/// Receive callback - new data; optional, set by user in WsConnectedCb
|
|
WsRecvCb recvCb;
|
|
/// Sent callback - last sending finished; optional, set by user in WsConnectedCb
|
|
WsSentCb sentCb;
|
|
/// Close callback - socket was closed, either by client or server ; optional, set by user in WsConnectedCb
|
|
WsCloseCb closeCb;
|
|
/// Websocket private data
|
|
WebsockPriv *priv;
|
|
};
|
|
|
|
/**
|
|
* CGI function for a websocket endpoint
|
|
*
|
|
* @param connData
|
|
* @return CGI state
|
|
*/
|
|
httpd_cgi_state cgiWebsocket(HttpdConnData *connData);
|
|
|
|
/**
|
|
* Send data to a websocket
|
|
*
|
|
* @param ws - Websocket handle
|
|
* @param data - data to send
|
|
* @param len - data len
|
|
* @param flags - flags, OR'ed WEBSOCK_FLAG_X constants
|
|
* @return 1 = OK
|
|
*/
|
|
int cgiWebsocketSend(Websock *ws, const uint8_t *data, size_t len, int flags);
|
|
|
|
/**
|
|
* Close a websocket
|
|
*
|
|
* @param ws - Websocket handle
|
|
* @param reason - close reason (2 bytes). Normally 1000
|
|
*/
|
|
void cgiWebsocketClose(Websock *ws, websock_close_reason reason);
|
|
|
|
/**
|
|
* Websocket endpoint receive handler (used in the CGI route)
|
|
*
|
|
* @param connData - connection
|
|
* @param data - bytes received
|
|
* @param len - data len
|
|
* @return CGI state
|
|
*/
|
|
httpd_cgi_state cgiWebSocketRecv(HttpdConnData *connData, uint8_t *data, size_t len);
|
|
|
|
/**
|
|
* Broadcast a message to all open websockets at a given endpoint
|
|
*
|
|
* @param resource - websocket path
|
|
* @param data - bytes received
|
|
* @param len - data len
|
|
* @param flags - OR'ed WEBSOCK_FLAG_X constants
|
|
* @return Returns the amount of connections sent to, -1 if sending failed
|
|
*/
|
|
int cgiWebsockBroadcast(const char *resource, const uint8_t *data, size_t len, int flags);
|
|
|
|
/**
|
|
* Measure websockets backlog (debug telemetry)
|
|
*
|
|
* @param resource - websocket path
|
|
* @param[out] total - the total backlog for the path is stored here
|
|
* @param[out] max - the max backlog per websock is stored here
|
|
*/
|
|
void cgiWebsockMeasureBacklog(const char *resource, size_t *total, size_t *max);
|
|
|