mikroSDK Reference Manual
web_socket.h
Go to the documentation of this file.
1
31#ifndef _WEB_SOCKET_H
32#define _WEB_SOCKET_H
33
34//Dependencies
35#include "core/net.h"
36#include "core/socket.h"
37
38//WebSocket support
39#ifndef WEB_SOCKET_SUPPORT
40 #define WEB_SOCKET_SUPPORT DISABLED
41#elif (WEB_SOCKET_SUPPORT != ENABLED && WEB_SOCKET_SUPPORT != DISABLED)
42 #error WEB_SOCKET_SUPPORT parameter is not valid
43#endif
44
45//Number of WebSockets that can be opened simultaneously
46#ifndef WEB_SOCKET_MAX_COUNT
47 #define WEB_SOCKET_MAX_COUNT 4
48#elif (WEB_SOCKET_MAX_COUNT < 1)
49 #error WEB_SOCKET_MAX_COUNT parameter is not valid
50#endif
51
52//Support for WebSocket connections over TLS
53#ifndef WEB_SOCKET_TLS_SUPPORT
54 #define WEB_SOCKET_TLS_SUPPORT DISABLED
55#elif (WEB_SOCKET_TLS_SUPPORT != ENABLED && WEB_SOCKET_TLS_SUPPORT != DISABLED)
56 #error WEB_SOCKET_TLS_SUPPORT parameter is not valid
57#endif
58
59//Basic access authentication support
60#ifndef WEB_SOCKET_BASIC_AUTH_SUPPORT
61 #define WEB_SOCKET_BASIC_AUTH_SUPPORT DISABLED
62#elif (WEB_SOCKET_BASIC_AUTH_SUPPORT != ENABLED && WEB_SOCKET_BASIC_AUTH_SUPPORT != DISABLED)
63 #error WEB_SOCKET_BASIC_AUTH_SUPPORT parameter is not valid
64#endif
65
66//Digest access authentication support
67#ifndef WEB_SOCKET_DIGEST_AUTH_SUPPORT
68 #define WEB_SOCKET_DIGEST_AUTH_SUPPORT DISABLED
69#elif (WEB_SOCKET_DIGEST_AUTH_SUPPORT != ENABLED && WEB_SOCKET_DIGEST_AUTH_SUPPORT != DISABLED)
70 #error WEB_SOCKET_DIGEST_AUTH_SUPPORT parameter is not valid
71#endif
72
73//Maximum number of connection attempts
74#ifndef WEB_SOCKET_MAX_CONN_RETRIES
75 #define WEB_SOCKET_MAX_CONN_RETRIES 3
76#elif (WEB_SOCKET_MAX_CONN_RETRIES < 1)
77 #error WEB_SOCKET_MAX_CONN_RETRIES parameter is not valid
78#endif
79
80//Size of the WebSocket buffer
81#ifndef WEB_SOCKET_BUFFER_SIZE
82 #define WEB_SOCKET_BUFFER_SIZE 1024
83#elif (WEB_SOCKET_BUFFER_SIZE < 128)
84 #error WEB_SOCKET_BUFFER_SIZE parameter is not valid
85#endif
86
87//Maximum length of the hostname
88#ifndef WEB_SOCKET_HOST_MAX_LEN
89 #define WEB_SOCKET_HOST_MAX_LEN 32
90#elif (WEB_SOCKET_HOST_MAX_LEN < 1)
91 #error WEB_SOCKET_HOST_MAX_LEN parameter is not valid
92#endif
93
94//Maximum length of the origin header field
95#ifndef WEB_SOCKET_ORIGIN_MAX_LEN
96 #define WEB_SOCKET_ORIGIN_MAX_LEN 16
97#elif (WEB_SOCKET_ORIGIN_MAX_LEN < 1)
98 #error WEB_SOCKET_ORIGIN_MAX_LEN parameter is not valid
99#endif
100
101//Maximum length of the sub-protocol
102#ifndef WEB_SOCKET_SUB_PROTOCOL_MAX_LEN
103 #define WEB_SOCKET_SUB_PROTOCOL_MAX_LEN 8
104#elif (WEB_SOCKET_SUB_PROTOCOL_MAX_LEN < 1)
105 #error WEB_SOCKET_SUB_PROTOCOL_MAX_LEN parameter is not valid
106#endif
107
108//Maximum length of the URI
109#ifndef WEB_SOCKET_URI_MAX_LEN
110 #define WEB_SOCKET_URI_MAX_LEN 32
111#elif (WEB_SOCKET_URI_MAX_LEN < 1)
112 #error WEB_SOCKET_URI_MAX_LEN parameter is not valid
113#endif
114
115//Maximum length of the query string
116#ifndef WEB_SOCKET_QUERY_STRING_MAX_LEN
117 #define WEB_SOCKET_QUERY_STRING_MAX_LEN 32
118#elif (WEB_SOCKET_QUERY_STRING_MAX_LEN < 1)
119 #error WEB_SOCKET_QUERY_STRING_MAX_LEN parameter is not valid
120#endif
121
122//Maximum length of the realm
123#ifndef WEB_SOCKET_REALM_MAX_LEN
124 #define WEB_SOCKET_REALM_MAX_LEN 32
125#elif (WEB_SOCKET_REALM_MAX_LEN < 1)
126 #error WEB_SOCKET_REALM_MAX_LEN parameter is not valid
127#endif
128
129//Maximum length of the user name
130#ifndef WEB_SOCKET_USERNAME_MAX_LEN
131 #define WEB_SOCKET_USERNAME_MAX_LEN 16
132#elif (WEB_SOCKET_USERNAME_MAX_LEN < 1)
133 #error WEB_SOCKET_USERNAME_MAX_LEN parameter is not valid
134#endif
135
136//Maximum length of the password
137#ifndef WEB_SOCKET_PASSWORD_MAX_LEN
138 #define WEB_SOCKET_PASSWORD_MAX_LEN 16
139#elif (WEB_SOCKET_PASSWORD_MAX_LEN < 1)
140 #error WEB_SOCKET_PASSWORD_MAX_LEN parameter is not valid
141#endif
142
143//Maximum length of the nonce
144#ifndef WEB_SOCKET_NONCE_MAX_LEN
145 #define WEB_SOCKET_NONCE_MAX_LEN 32
146#elif (WEB_SOCKET_NONCE_MAX_LEN < 1)
147 #error WEB_SOCKET_NONCE_MAX_LEN parameter is not valid
148#endif
149
150//Maximum length of the opaque parameter
151#ifndef WEB_SOCKET_OPAQUE_MAX_LEN
152 #define WEB_SOCKET_OPAQUE_MAX_LEN 32
153#elif (WEB_SOCKET_OPAQUE_MAX_LEN < 1)
154 #error WEB_SOCKET_OPAQUE_MAX_LEN parameter is not valid
155#endif
156
157//Cnonce size
158#ifndef WEB_SOCKET_CNONCE_SIZE
159 #define WEB_SOCKET_CNONCE_SIZE 16
160#elif (WEB_SOCKET_CNONCE_SIZE < 1)
161 #error WEB_SOCKET_CNONCE_SIZE parameter is not valid
162#endif
163
164//TLS supported?
165#if (WEB_SOCKET_TLS_SUPPORT == ENABLED)
166 #include "core/crypto.h"
167 #include "tls.h"
168#endif
169
170//Client key size
171#define WEB_SOCKET_CLIENT_KEY_SIZE 24
172//Server key size
173#define WEB_SOCKET_SERVER_KEY_SIZE 28
174
175//Forward declaration of WebSocket structure
176struct _WebSocket;
177#define WebSocket struct _WebSocket
178
179//C++ guard
180#ifdef __cplusplus
181extern "C" {
182#endif
183
184
189typedef enum
190{
191 WS_ENDPOINT_CLIENT = 0,
192 WS_ENDPOINT_SERVER = 1
194
195
200typedef enum
201{
202 WS_HTTP_VERSION_0_9 = 0x0009,
203 WS_HTTP_VERSION_1_0 = 0x0100,
204 WS_HTTP_VERSION_1_1 = 0x0101
206
207
212typedef enum
213{
214 WS_AUTH_MODE_NONE = 0x00,
215 WS_AUTH_MODE_BASIC = 0x01,
216 WS_AUTH_MODE_DIGEST = 0x02
218
219
224typedef enum
225{
226 WS_STATE_UNUSED = 0,
227 WS_STATE_CLOSED = 1,
228 WS_STATE_INIT = 2,
229 WS_STATE_CONNECTING = 3,
230 WS_STATE_CLIENT_HANDSHAKE = 4,
231 WS_STATE_SERVER_HANDSHAKE = 5,
232 WS_STATE_SERVER_RESP_BODY = 6,
233 WS_STATE_OPEN = 7,
234 WS_STATE_CLOSING_TX = 8,
235 WS_STATE_CLOSING_RX = 9,
236 WS_STATE_SHUTDOWN = 10,
238
239
244typedef enum
245{
246 WS_SUB_STATE_INIT = 0,
247 //Handshake decoding
248 WS_SUB_STATE_HANDSHAKE_LEADING_LINE = 1,
249 WS_SUB_STATE_HANDSHAKE_HEADER_FIELD = 2,
250 WS_SUB_STATE_HANDSHAKE_LWSP = 3,
251 //WebSocket frame decoding
252 WS_SUB_STATE_FRAME_HEADER = 4,
253 WS_SUB_STATE_FRAME_EXT_HEADER = 5,
254 WS_SUB_STATE_FRAME_PAYLOAD = 6
256
257
262typedef enum
263{
264 WS_FRAME_TYPE_CONTINUATION = 0x00,
265 WS_FRAME_TYPE_TEXT = 0x01,
266 WS_FRAME_TYPE_BINARY = 0x02,
267 WS_FRAME_TYPE_CLOSE = 0x08,
268 WS_FRAME_TYPE_PING = 0x09,
269 WS_FRAME_TYPE_PONG = 0x0A
271
272
277typedef enum
278{
279 WS_STATUS_CODE_NORMAL_CLOSURE = 1000,
280 WS_STATUS_CODE_GOING_AWAY = 1001,
281 WS_STATUS_CODE_PROTOCOL_ERROR = 1002,
282 WS_STATUS_CODE_UNSUPPORTED_DATA = 1003,
283 WS_STATUS_CODE_NO_STATUS_RCVD = 1005,
284 WS_STATUS_CODE_ABNORMAL_CLOSURE = 1006,
285 WS_STATUS_CODE_INVALID_PAYLOAD_DATA = 1007,
286 WS_STATUS_CODE_POLICY_VIOLATION = 1008,
287 WS_STATUS_CODE_MESSAGE_TOO_BIG = 1009,
288 WS_STATUS_CODE_MANDATORY_EXT = 1010,
289 WS_STATUS_CODE_INTERNAL_ERROR = 1011,
290 WS_STATUS_CODE_TLS_HANDSHAKE = 1015
292
293
294//CodeWarrior or Win32 compiler?
295#if defined(__CWCC__) || defined(_WIN32)
296 #pragma pack(push, 1)
297#endif
298
299
305{
306#if defined(_CPU_BIG_ENDIAN) && !defined(__ICCRX__)
307 uint8_t fin : 1; //0
308 uint8_t reserved : 3;
309 uint8_t opcode : 4;
310 uint8_t mask : 1; //1
311 uint8_t payloadLen : 7;
312#else
313 uint8_t opcode : 4; //0
314 uint8_t reserved : 3;
315 uint8_t fin : 1;
316 uint8_t payloadLen : 7; //1
317 uint8_t mask : 1;
318#endif
319 uint8_t extPayloadLen[]; //2
320} WebSocketFrame;
321
322
323//CodeWarrior or Win32 compiler?
324#if defined(__CWCC__) || defined(_WIN32)
325 #pragma pack(pop)
326#endif
327
328
333typedef error_t (*WebSocketRandCallback)(uint8_t *data, size_t length);
334
335
336//TLS supported?
337#if (WEB_SOCKET_TLS_SUPPORT == ENABLED)
338
343typedef error_t (*WebSocketTlsInitCallback)(WebSocket *webSocket,
344 TlsContext *tlsContext);
345
346#endif
347
348
353typedef struct
354{
355 uint_t allowedAuthModes;
356 WebSocketAuthMode requiredAuthMode;
357 WebSocketAuthMode selectedAuthMode;
358 char_t username[WEB_SOCKET_USERNAME_MAX_LEN + 1];
359 char_t password[WEB_SOCKET_PASSWORD_MAX_LEN + 1];
360 char_t realm[WEB_SOCKET_REALM_MAX_LEN + 1];
361#if (WEB_SOCKET_DIGEST_AUTH_SUPPORT == ENABLED)
362 uint32_t nc;
363 char_t nonce[WEB_SOCKET_NONCE_MAX_LEN + 1];
364 char_t cnonce[WEB_SOCKET_CNONCE_SIZE * 2 + 1];
365 char_t opaque[WEB_SOCKET_OPAQUE_MAX_LEN + 1];
366 bool_t stale;
367#endif
369
370
375typedef struct
376{
377 uint_t version;
378 uint_t statusCode;
379 bool_t upgradeWebSocket;
380 bool_t connectionUpgrade;
381 bool_t connectionClose;
382 size_t contentLength;
383 char_t clientKey[WEB_SOCKET_CLIENT_KEY_SIZE + 1];
384 char_t serverKey[WEB_SOCKET_SERVER_KEY_SIZE + 1];
385 bool_t closingFrameSent;
386 bool_t closingFrameReceived;
388
389
394typedef struct
395{
399 bool_t fin;
400 bool_t mask;
401 uint8_t maskingKey[4];
402 size_t payloadLen;
403 size_t payloadPos;
404 uint8_t buffer[WEB_SOCKET_BUFFER_SIZE];
405 size_t bufferLen;
406 size_t bufferPos;
408
409
414typedef struct
415{
416 uint_t utf8CharSize;
417 uint_t utf8CharIndex;
418 uint32_t utf8CodePoint;
420
421
427{
430 uint16_t statusCode;
431 systime_t timestamp;
432 uint_t retryCount;
433 char_t host[WEB_SOCKET_HOST_MAX_LEN + 1];
434 char_t origin[WEB_SOCKET_ORIGIN_MAX_LEN + 1];
435 char_t subProtocol[WEB_SOCKET_SUB_PROTOCOL_MAX_LEN + 1];
436 char_t uri[WEB_SOCKET_URI_MAX_LEN + 1];
437 char_t queryString[WEB_SOCKET_QUERY_STRING_MAX_LEN + 1];
439 NetInterface *interface;
440 Socket *socket;
441#if (WEB_SOCKET_TLS_SUPPORT == ENABLED)
442 TlsContext *tlsContext;
443 TlsSessionState tlsSession;
446#endif
447#if (WEB_SOCKET_BASIC_AUTH_SUPPORT == ENABLED || WEB_SOCKET_DIGEST_AUTH_SUPPORT == ENABLED)
448 WebSocketAuthContext authContext;
449#endif
450 WebSocketHandshakeContext handshakeContext;
451 WebSocketFrameContext txContext;
452 WebSocketFrameContext rxContext;
453 WebSocketUtf8Context utf8Context;
454};
455
456
457//Random data generation callback function
458extern WebSocketRandCallback webSockRandCallback;
459
460//WebSocket related functions
461error_t webSocketInit(void);
462
463error_t webSocketRegisterRandCallback(WebSocketRandCallback callback);
464
465WebSocket *webSocketOpen(void);
466WebSocket *webSocketUpgradeSocket(Socket *socket);
467
468#if (WEB_SOCKET_TLS_SUPPORT == ENABLED)
469
470WebSocket *webSocketUpgradeSecureSocket(Socket *socket, TlsContext *tlsContext);
471
472error_t webSocketRegisterTlsInitCallback(WebSocket *webSocket,
473 WebSocketTlsInitCallback callback);
474
475#endif
476
477error_t webSocketSetTimeout(WebSocket *webSocket, systime_t timeout);
478
479error_t webSocketSetHost(WebSocket *webSocket, const char_t *host);
480error_t webSocketSetOrigin(WebSocket *webSocket, const char_t *origin);
481error_t webSocketSetSubProtocol(WebSocket *webSocket, const char_t *subProtocol);
482
483error_t webSocketSetAuthInfo(WebSocket *webSocket, const char_t *username,
484 const char_t *password, uint_t allowedAuthModes);
485
486error_t webSocketBindToInterface(WebSocket *webSocket, NetInterface *interface);
487
488error_t webSocketConnect(WebSocket *webSocket, const IpAddr *serverIpAddr,
489 uint16_t serverPort, const char_t *uri);
490
491error_t webSocketSetClientKey(WebSocket *webSocket, const char_t *clientKey);
492error_t webSocketParseClientHandshake(WebSocket *webSocket);
493error_t webSocketSendServerHandshake(WebSocket *webSocket);
494
495error_t webSocketSendErrorResponse(WebSocket *webSocket,
496 uint_t statusCode, const char_t *message);
497
498error_t webSocketSend(WebSocket *webSocket, const void *data,
499 size_t length, WebSocketFrameType type, size_t *written);
500
501error_t webSocketSendEx(WebSocket *webSocket, const void *data, size_t length,
502 WebSocketFrameType type, size_t *written, bool_t firstFrag, bool_t lastFrag);
503
504error_t webSocketReceive(WebSocket *webSocket, void *data,
505 size_t size, WebSocketFrameType *type, size_t *received);
506
507error_t webSocketReceiveEx(WebSocket *webSocket, void *data, size_t size,
508 WebSocketFrameType *type, size_t *received, bool_t *firstFrag, bool_t *lastFrag);
509
510bool_t webSocketIsRxReady(WebSocket *webSocket);
511error_t webSocketShutdown(WebSocket *webSocket);
512void webSocketClose(WebSocket *webSocket);
513
514//C++ guard
515#ifdef __cplusplus
516}
517#endif
518
519#endif
error_t
Error codes.
Definition error.h:43
TCP/IP stack core.
uint32_t systime_t
System time.
Definition os_port_none.h:90
Socket API.
IP network address.
Definition ip.h:72
Authentication context.
Definition web_socket.h:354
Frame encoding/decoding context.
Definition web_socket.h:395
WebSocketFrameType dataFrameType
FSM state.
Definition web_socket.h:397
bool_t fin
Final fragment in a message.
Definition web_socket.h:399
size_t payloadPos
Current position.
Definition web_socket.h:403
size_t payloadLen
Payload length.
Definition web_socket.h:402
WebSocketFrameType controlFrameType
Control frame type.
Definition web_socket.h:398
bool_t mask
Defines whether the payload data is masked.
Definition web_socket.h:400
size_t bufferLen
Length of the data buffer.
Definition web_socket.h:405
size_t bufferPos
Current position.
Definition web_socket.h:406
Handshake context.
Definition web_socket.h:376
UTF-8 decoding context.
Definition web_socket.h:415
Structure describing a WebSocket.
Definition web_socket.h:427
NetInterface * interface
Underlying network interface.
Definition web_socket.h:439
Socket * socket
Underlying TCP socket.
Definition web_socket.h:440
systime_t timeout
timeout value for blocking operations
Definition web_socket.h:438
WebSocketTlsInitCallback tlsInitCallback
TLS initialization callback function.
Definition web_socket.h:444
TlsSessionState tlsSession
TLS session state.
Definition web_socket.h:443
WebSocketState state
WebSocket connection state.
Definition web_socket.h:429
TlsContext * tlsContext
TLS context.
Definition web_socket.h:442
void * tlsInitParam
Opaque pointer passed to the TLS initialization callback function.
Definition web_socket.h:445
char_t host[WEB_SOCKET_HOST_MAX_LEN+1]
Domain name of the server (for virtual hosting)
Definition web_socket.h:433
WebSocketEndpoint endpoint
Endpoint type (client or server)
Definition web_socket.h:428
WebSocketHttpVersion
HTTP version numbers.
Definition web_socket.h:201
WebSocketAuthMode
Authentication schemes.
Definition web_socket.h:213
WebSocketFrameType
WebSocket frame types.
Definition web_socket.h:263
WebSocketState
WebSocket states.
Definition web_socket.h:225
error_t(* WebSocketTlsInitCallback)(WebSocket *webSocket, TlsContext *tlsContext)
TLS initialization callback function.
Definition web_socket.h:343
typedef __packed_struct
WebSocket frame.
Definition web_socket.h:305
WebSocketStatusCode
WebSocket status codes.
Definition web_socket.h:278
WebSocketSubState
WebSocket sub-states.
Definition web_socket.h:245
error_t(* WebSocketRandCallback)(uint8_t *data, size_t length)
Random data generation callback function.
Definition web_socket.h:333
WebSocketEndpoint
WebSocket endpoint types.
Definition web_socket.h:190