Webserver+3d print

Dependents:   Nucleo

Committer:
Sergunb
Date:
Sat Feb 04 18:15:49 2017 +0000
Revision:
0:8918a71cdbe9
nothing else

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sergunb 0:8918a71cdbe9 1 /**
Sergunb 0:8918a71cdbe9 2 * @file web_socket.h
Sergunb 0:8918a71cdbe9 3 * @brief WebSocket API (client and server)
Sergunb 0:8918a71cdbe9 4 *
Sergunb 0:8918a71cdbe9 5 * @section License
Sergunb 0:8918a71cdbe9 6 *
Sergunb 0:8918a71cdbe9 7 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
Sergunb 0:8918a71cdbe9 8 *
Sergunb 0:8918a71cdbe9 9 * This file is part of CycloneTCP Open.
Sergunb 0:8918a71cdbe9 10 *
Sergunb 0:8918a71cdbe9 11 * This program is free software; you can redistribute it and/or
Sergunb 0:8918a71cdbe9 12 * modify it under the terms of the GNU General Public License
Sergunb 0:8918a71cdbe9 13 * as published by the Free Software Foundation; either version 2
Sergunb 0:8918a71cdbe9 14 * of the License, or (at your option) any later version.
Sergunb 0:8918a71cdbe9 15 *
Sergunb 0:8918a71cdbe9 16 * This program is distributed in the hope that it will be useful,
Sergunb 0:8918a71cdbe9 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Sergunb 0:8918a71cdbe9 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Sergunb 0:8918a71cdbe9 19 * GNU General Public License for more details.
Sergunb 0:8918a71cdbe9 20 *
Sergunb 0:8918a71cdbe9 21 * You should have received a copy of the GNU General Public License
Sergunb 0:8918a71cdbe9 22 * along with this program; if not, write to the Free Software Foundation,
Sergunb 0:8918a71cdbe9 23 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Sergunb 0:8918a71cdbe9 24 *
Sergunb 0:8918a71cdbe9 25 * @author Oryx Embedded SARL (www.oryx-embedded.com)
Sergunb 0:8918a71cdbe9 26 * @version 1.7.6
Sergunb 0:8918a71cdbe9 27 **/
Sergunb 0:8918a71cdbe9 28
Sergunb 0:8918a71cdbe9 29 #ifndef _WEB_SOCKET_H
Sergunb 0:8918a71cdbe9 30 #define _WEB_SOCKET_H
Sergunb 0:8918a71cdbe9 31
Sergunb 0:8918a71cdbe9 32 //Dependencies
Sergunb 0:8918a71cdbe9 33 #include "core/net.h"
Sergunb 0:8918a71cdbe9 34 #include "core/socket.h"
Sergunb 0:8918a71cdbe9 35
Sergunb 0:8918a71cdbe9 36 //WebSocket support
Sergunb 0:8918a71cdbe9 37 #ifndef WEB_SOCKET_SUPPORT
Sergunb 0:8918a71cdbe9 38 #define WEB_SOCKET_SUPPORT DISABLED
Sergunb 0:8918a71cdbe9 39 #elif (WEB_SOCKET_SUPPORT != ENABLED && WEB_SOCKET_SUPPORT != DISABLED)
Sergunb 0:8918a71cdbe9 40 #error WEB_SOCKET_SUPPORT parameter is not valid
Sergunb 0:8918a71cdbe9 41 #endif
Sergunb 0:8918a71cdbe9 42
Sergunb 0:8918a71cdbe9 43 //Number of WebSockets that can be opened simultaneously
Sergunb 0:8918a71cdbe9 44 #ifndef WEB_SOCKET_MAX_COUNT
Sergunb 0:8918a71cdbe9 45 #define WEB_SOCKET_MAX_COUNT 4
Sergunb 0:8918a71cdbe9 46 #elif (WEB_SOCKET_MAX_COUNT < 1)
Sergunb 0:8918a71cdbe9 47 #error WEB_SOCKET_MAX_COUNT parameter is not valid
Sergunb 0:8918a71cdbe9 48 #endif
Sergunb 0:8918a71cdbe9 49
Sergunb 0:8918a71cdbe9 50 //Support for WebSocket connections over SSL/TLS
Sergunb 0:8918a71cdbe9 51 #ifndef WEB_SOCKET_TLS_SUPPORT
Sergunb 0:8918a71cdbe9 52 #define WEB_SOCKET_TLS_SUPPORT DISABLED
Sergunb 0:8918a71cdbe9 53 #elif (WEB_SOCKET_TLS_SUPPORT != ENABLED && WEB_SOCKET_TLS_SUPPORT != DISABLED)
Sergunb 0:8918a71cdbe9 54 #error WEB_SOCKET_TLS_SUPPORT parameter is not valid
Sergunb 0:8918a71cdbe9 55 #endif
Sergunb 0:8918a71cdbe9 56
Sergunb 0:8918a71cdbe9 57 //Basic access authentication support
Sergunb 0:8918a71cdbe9 58 #ifndef WEB_SOCKET_BASIC_AUTH_SUPPORT
Sergunb 0:8918a71cdbe9 59 #define WEB_SOCKET_BASIC_AUTH_SUPPORT DISABLED
Sergunb 0:8918a71cdbe9 60 #elif (WEB_SOCKET_BASIC_AUTH_SUPPORT != ENABLED && WEB_SOCKET_BASIC_AUTH_SUPPORT != DISABLED)
Sergunb 0:8918a71cdbe9 61 #error WEB_SOCKET_BASIC_AUTH_SUPPORT parameter is not valid
Sergunb 0:8918a71cdbe9 62 #endif
Sergunb 0:8918a71cdbe9 63
Sergunb 0:8918a71cdbe9 64 //Digest access authentication support
Sergunb 0:8918a71cdbe9 65 #ifndef WEB_SOCKET_DIGEST_AUTH_SUPPORT
Sergunb 0:8918a71cdbe9 66 #define WEB_SOCKET_DIGEST_AUTH_SUPPORT DISABLED
Sergunb 0:8918a71cdbe9 67 #elif (WEB_SOCKET_DIGEST_AUTH_SUPPORT != ENABLED && WEB_SOCKET_DIGEST_AUTH_SUPPORT != DISABLED)
Sergunb 0:8918a71cdbe9 68 #error WEB_SOCKET_DIGEST_AUTH_SUPPORT parameter is not valid
Sergunb 0:8918a71cdbe9 69 #endif
Sergunb 0:8918a71cdbe9 70
Sergunb 0:8918a71cdbe9 71 //Maximum number of connection attempts
Sergunb 0:8918a71cdbe9 72 #ifndef WEB_SOCKET_MAX_CONN_RETRIES
Sergunb 0:8918a71cdbe9 73 #define WEB_SOCKET_MAX_CONN_RETRIES 3
Sergunb 0:8918a71cdbe9 74 #elif (WEB_SOCKET_MAX_CONN_RETRIES < 1)
Sergunb 0:8918a71cdbe9 75 #error WEB_SOCKET_MAX_CONN_RETRIES parameter is not valid
Sergunb 0:8918a71cdbe9 76 #endif
Sergunb 0:8918a71cdbe9 77
Sergunb 0:8918a71cdbe9 78 //Size of the WebSocket buffer
Sergunb 0:8918a71cdbe9 79 #ifndef WEB_SOCKET_BUFFER_SIZE
Sergunb 0:8918a71cdbe9 80 #define WEB_SOCKET_BUFFER_SIZE 1024
Sergunb 0:8918a71cdbe9 81 #elif (WEB_SOCKET_BUFFER_SIZE < 128)
Sergunb 0:8918a71cdbe9 82 #error WEB_SOCKET_BUFFER_SIZE parameter is not valid
Sergunb 0:8918a71cdbe9 83 #endif
Sergunb 0:8918a71cdbe9 84
Sergunb 0:8918a71cdbe9 85 //Maximum length of the hostname
Sergunb 0:8918a71cdbe9 86 #ifndef WEB_SOCKET_HOST_MAX_LEN
Sergunb 0:8918a71cdbe9 87 #define WEB_SOCKET_HOST_MAX_LEN 32
Sergunb 0:8918a71cdbe9 88 #elif (WEB_SOCKET_HOST_MAX_LEN < 1)
Sergunb 0:8918a71cdbe9 89 #error WEB_SOCKET_HOST_MAX_LEN parameter is not valid
Sergunb 0:8918a71cdbe9 90 #endif
Sergunb 0:8918a71cdbe9 91
Sergunb 0:8918a71cdbe9 92 //Maximum length of the origin header field
Sergunb 0:8918a71cdbe9 93 #ifndef WEB_SOCKET_ORIGIN_MAX_LEN
Sergunb 0:8918a71cdbe9 94 #define WEB_SOCKET_ORIGIN_MAX_LEN 16
Sergunb 0:8918a71cdbe9 95 #elif (WEB_SOCKET_ORIGIN_MAX_LEN < 1)
Sergunb 0:8918a71cdbe9 96 #error WEB_SOCKET_ORIGIN_MAX_LEN parameter is not valid
Sergunb 0:8918a71cdbe9 97 #endif
Sergunb 0:8918a71cdbe9 98
Sergunb 0:8918a71cdbe9 99 //Maximum length of the sub-protocol
Sergunb 0:8918a71cdbe9 100 #ifndef WEB_SOCKET_SUB_PROTOCOL_MAX_LEN
Sergunb 0:8918a71cdbe9 101 #define WEB_SOCKET_SUB_PROTOCOL_MAX_LEN 8
Sergunb 0:8918a71cdbe9 102 #elif (WEB_SOCKET_SUB_PROTOCOL_MAX_LEN < 1)
Sergunb 0:8918a71cdbe9 103 #error WEB_SOCKET_SUB_PROTOCOL_MAX_LEN parameter is not valid
Sergunb 0:8918a71cdbe9 104 #endif
Sergunb 0:8918a71cdbe9 105
Sergunb 0:8918a71cdbe9 106 //Maximum length of the URI
Sergunb 0:8918a71cdbe9 107 #ifndef WEB_SOCKET_URI_MAX_LEN
Sergunb 0:8918a71cdbe9 108 #define WEB_SOCKET_URI_MAX_LEN 32
Sergunb 0:8918a71cdbe9 109 #elif (WEB_SOCKET_URI_MAX_LEN < 1)
Sergunb 0:8918a71cdbe9 110 #error WEB_SOCKET_URI_MAX_LEN parameter is not valid
Sergunb 0:8918a71cdbe9 111 #endif
Sergunb 0:8918a71cdbe9 112
Sergunb 0:8918a71cdbe9 113 //Maximum length of the query string
Sergunb 0:8918a71cdbe9 114 #ifndef WEB_SOCKET_QUERY_STRING_MAX_LEN
Sergunb 0:8918a71cdbe9 115 #define WEB_SOCKET_QUERY_STRING_MAX_LEN 32
Sergunb 0:8918a71cdbe9 116 #elif (WEB_SOCKET_QUERY_STRING_MAX_LEN < 1)
Sergunb 0:8918a71cdbe9 117 #error WEB_SOCKET_QUERY_STRING_MAX_LEN parameter is not valid
Sergunb 0:8918a71cdbe9 118 #endif
Sergunb 0:8918a71cdbe9 119
Sergunb 0:8918a71cdbe9 120 //Maximum length of the realm
Sergunb 0:8918a71cdbe9 121 #ifndef WEB_SOCKET_REALM_MAX_LEN
Sergunb 0:8918a71cdbe9 122 #define WEB_SOCKET_REALM_MAX_LEN 32
Sergunb 0:8918a71cdbe9 123 #elif (WEB_SOCKET_REALM_MAX_LEN < 1)
Sergunb 0:8918a71cdbe9 124 #error WEB_SOCKET_REALM_MAX_LEN parameter is not valid
Sergunb 0:8918a71cdbe9 125 #endif
Sergunb 0:8918a71cdbe9 126
Sergunb 0:8918a71cdbe9 127 //Maximum length of the user name
Sergunb 0:8918a71cdbe9 128 #ifndef WEB_SOCKET_USERNAME_MAX_LEN
Sergunb 0:8918a71cdbe9 129 #define WEB_SOCKET_USERNAME_MAX_LEN 16
Sergunb 0:8918a71cdbe9 130 #elif (WEB_SOCKET_USERNAME_MAX_LEN < 1)
Sergunb 0:8918a71cdbe9 131 #error WEB_SOCKET_USERNAME_MAX_LEN parameter is not valid
Sergunb 0:8918a71cdbe9 132 #endif
Sergunb 0:8918a71cdbe9 133
Sergunb 0:8918a71cdbe9 134 //Maximum length of the password
Sergunb 0:8918a71cdbe9 135 #ifndef WEB_SOCKET_PASSWORD_MAX_LEN
Sergunb 0:8918a71cdbe9 136 #define WEB_SOCKET_PASSWORD_MAX_LEN 16
Sergunb 0:8918a71cdbe9 137 #elif (WEB_SOCKET_PASSWORD_MAX_LEN < 1)
Sergunb 0:8918a71cdbe9 138 #error WEB_SOCKET_PASSWORD_MAX_LEN parameter is not valid
Sergunb 0:8918a71cdbe9 139 #endif
Sergunb 0:8918a71cdbe9 140
Sergunb 0:8918a71cdbe9 141 //Maximum length of the nonce
Sergunb 0:8918a71cdbe9 142 #ifndef WEB_SOCKET_NONCE_MAX_LEN
Sergunb 0:8918a71cdbe9 143 #define WEB_SOCKET_NONCE_MAX_LEN 32
Sergunb 0:8918a71cdbe9 144 #elif (WEB_SOCKET_NONCE_MAX_LEN < 1)
Sergunb 0:8918a71cdbe9 145 #error WEB_SOCKET_NONCE_MAX_LEN parameter is not valid
Sergunb 0:8918a71cdbe9 146 #endif
Sergunb 0:8918a71cdbe9 147
Sergunb 0:8918a71cdbe9 148 //Maximum length of the opaque parameter
Sergunb 0:8918a71cdbe9 149 #ifndef WEB_SOCKET_OPAQUE_MAX_LEN
Sergunb 0:8918a71cdbe9 150 #define WEB_SOCKET_OPAQUE_MAX_LEN 32
Sergunb 0:8918a71cdbe9 151 #elif (WEB_SOCKET_OPAQUE_MAX_LEN < 1)
Sergunb 0:8918a71cdbe9 152 #error WEB_SOCKET_OPAQUE_MAX_LEN parameter is not valid
Sergunb 0:8918a71cdbe9 153 #endif
Sergunb 0:8918a71cdbe9 154
Sergunb 0:8918a71cdbe9 155 //Cnonce size
Sergunb 0:8918a71cdbe9 156 #ifndef WEB_SOCKET_CNONCE_SIZE
Sergunb 0:8918a71cdbe9 157 #define WEB_SOCKET_CNONCE_SIZE 16
Sergunb 0:8918a71cdbe9 158 #elif (WEB_SOCKET_CNONCE_SIZE < 1)
Sergunb 0:8918a71cdbe9 159 #error WEB_SOCKET_CNONCE_SIZE parameter is not valid
Sergunb 0:8918a71cdbe9 160 #endif
Sergunb 0:8918a71cdbe9 161
Sergunb 0:8918a71cdbe9 162 //TLS supported?
Sergunb 0:8918a71cdbe9 163 #if (WEB_SOCKET_TLS_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 164 #include "crypto.h"
Sergunb 0:8918a71cdbe9 165 #include "tls.h"
Sergunb 0:8918a71cdbe9 166 #endif
Sergunb 0:8918a71cdbe9 167
Sergunb 0:8918a71cdbe9 168 //Client key size
Sergunb 0:8918a71cdbe9 169 #define WEB_SOCKET_CLIENT_KEY_SIZE 24
Sergunb 0:8918a71cdbe9 170 //Server key size
Sergunb 0:8918a71cdbe9 171 #define WEB_SOCKET_SERVER_KEY_SIZE 28
Sergunb 0:8918a71cdbe9 172
Sergunb 0:8918a71cdbe9 173 //Forward declaration of WebSocket structure
Sergunb 0:8918a71cdbe9 174 struct _WebSocket;
Sergunb 0:8918a71cdbe9 175 #define WebSocket struct _WebSocket
Sergunb 0:8918a71cdbe9 176
Sergunb 0:8918a71cdbe9 177
Sergunb 0:8918a71cdbe9 178 /**
Sergunb 0:8918a71cdbe9 179 * @brief WebSocket endpoint types
Sergunb 0:8918a71cdbe9 180 **/
Sergunb 0:8918a71cdbe9 181
Sergunb 0:8918a71cdbe9 182 typedef enum
Sergunb 0:8918a71cdbe9 183 {
Sergunb 0:8918a71cdbe9 184 WS_ENDPOINT_CLIENT = 0,
Sergunb 0:8918a71cdbe9 185 WS_ENDPOINT_SERVER = 1
Sergunb 0:8918a71cdbe9 186 } WebSocketEndpoint;
Sergunb 0:8918a71cdbe9 187
Sergunb 0:8918a71cdbe9 188
Sergunb 0:8918a71cdbe9 189 /**
Sergunb 0:8918a71cdbe9 190 * @brief HTTP version numbers
Sergunb 0:8918a71cdbe9 191 **/
Sergunb 0:8918a71cdbe9 192
Sergunb 0:8918a71cdbe9 193 typedef enum
Sergunb 0:8918a71cdbe9 194 {
Sergunb 0:8918a71cdbe9 195 WS_HTTP_VERSION_0_9 = 0x0009,
Sergunb 0:8918a71cdbe9 196 WS_HTTP_VERSION_1_0 = 0x0100,
Sergunb 0:8918a71cdbe9 197 WS_HTTP_VERSION_1_1 = 0x0101
Sergunb 0:8918a71cdbe9 198 } WebSocketHttpVersion;
Sergunb 0:8918a71cdbe9 199
Sergunb 0:8918a71cdbe9 200
Sergunb 0:8918a71cdbe9 201 /**
Sergunb 0:8918a71cdbe9 202 * @brief Authentication schemes
Sergunb 0:8918a71cdbe9 203 **/
Sergunb 0:8918a71cdbe9 204
Sergunb 0:8918a71cdbe9 205 typedef enum
Sergunb 0:8918a71cdbe9 206 {
Sergunb 0:8918a71cdbe9 207 WS_AUTH_MODE_NONE = 0x00,
Sergunb 0:8918a71cdbe9 208 WS_AUTH_MODE_BASIC = 0x01,
Sergunb 0:8918a71cdbe9 209 WS_AUTH_MODE_DIGEST = 0x02
Sergunb 0:8918a71cdbe9 210 } WebSocketAuthMode;
Sergunb 0:8918a71cdbe9 211
Sergunb 0:8918a71cdbe9 212
Sergunb 0:8918a71cdbe9 213 /**
Sergunb 0:8918a71cdbe9 214 * @brief WebSocket states
Sergunb 0:8918a71cdbe9 215 **/
Sergunb 0:8918a71cdbe9 216
Sergunb 0:8918a71cdbe9 217 typedef enum
Sergunb 0:8918a71cdbe9 218 {
Sergunb 0:8918a71cdbe9 219 WS_STATE_UNUSED = 0,
Sergunb 0:8918a71cdbe9 220 WS_STATE_CLOSED = 1,
Sergunb 0:8918a71cdbe9 221 WS_STATE_INIT = 2,
Sergunb 0:8918a71cdbe9 222 WS_STATE_CONNECTING = 3,
Sergunb 0:8918a71cdbe9 223 WS_STATE_CLIENT_HANDSHAKE = 4,
Sergunb 0:8918a71cdbe9 224 WS_STATE_SERVER_HANDSHAKE = 5,
Sergunb 0:8918a71cdbe9 225 WS_STATE_SERVER_RESP_BODY = 6,
Sergunb 0:8918a71cdbe9 226 WS_STATE_OPEN = 7,
Sergunb 0:8918a71cdbe9 227 WS_STATE_CLOSING_TX = 8,
Sergunb 0:8918a71cdbe9 228 WS_STATE_CLOSING_RX = 9,
Sergunb 0:8918a71cdbe9 229 WS_STATE_SHUTDOWN = 10,
Sergunb 0:8918a71cdbe9 230 } WebSocketState;
Sergunb 0:8918a71cdbe9 231
Sergunb 0:8918a71cdbe9 232
Sergunb 0:8918a71cdbe9 233 /**
Sergunb 0:8918a71cdbe9 234 * @brief WebSocket sub-states
Sergunb 0:8918a71cdbe9 235 **/
Sergunb 0:8918a71cdbe9 236
Sergunb 0:8918a71cdbe9 237 typedef enum
Sergunb 0:8918a71cdbe9 238 {
Sergunb 0:8918a71cdbe9 239 WS_SUB_STATE_INIT = 0,
Sergunb 0:8918a71cdbe9 240 //Handshake decoding
Sergunb 0:8918a71cdbe9 241 WS_SUB_STATE_HANDSHAKE_LEADING_LINE = 1,
Sergunb 0:8918a71cdbe9 242 WS_SUB_STATE_HANDSHAKE_HEADER_FIELD = 2,
Sergunb 0:8918a71cdbe9 243 WS_SUB_STATE_HANDSHAKE_LWSP = 3,
Sergunb 0:8918a71cdbe9 244 //WebSocket frame decoding
Sergunb 0:8918a71cdbe9 245 WS_SUB_STATE_FRAME_HEADER = 4,
Sergunb 0:8918a71cdbe9 246 WS_SUB_STATE_FRAME_EXT_HEADER = 5,
Sergunb 0:8918a71cdbe9 247 WS_SUB_STATE_FRAME_PAYLOAD = 6
Sergunb 0:8918a71cdbe9 248 } WebSocketSubState;
Sergunb 0:8918a71cdbe9 249
Sergunb 0:8918a71cdbe9 250
Sergunb 0:8918a71cdbe9 251 /**
Sergunb 0:8918a71cdbe9 252 * @brief WebSocket frame types
Sergunb 0:8918a71cdbe9 253 **/
Sergunb 0:8918a71cdbe9 254
Sergunb 0:8918a71cdbe9 255 typedef enum
Sergunb 0:8918a71cdbe9 256 {
Sergunb 0:8918a71cdbe9 257 WS_FRAME_TYPE_CONTINUATION = 0x00,
Sergunb 0:8918a71cdbe9 258 WS_FRAME_TYPE_TEXT = 0x01,
Sergunb 0:8918a71cdbe9 259 WS_FRAME_TYPE_BINARY = 0x02,
Sergunb 0:8918a71cdbe9 260 WS_FRAME_TYPE_CLOSE = 0x08,
Sergunb 0:8918a71cdbe9 261 WS_FRAME_TYPE_PING = 0x09,
Sergunb 0:8918a71cdbe9 262 WS_FRAME_TYPE_PONG = 0x0A
Sergunb 0:8918a71cdbe9 263 } WebSocketFrameType;
Sergunb 0:8918a71cdbe9 264
Sergunb 0:8918a71cdbe9 265
Sergunb 0:8918a71cdbe9 266 /**
Sergunb 0:8918a71cdbe9 267 * @brief WebSocket status codes
Sergunb 0:8918a71cdbe9 268 **/
Sergunb 0:8918a71cdbe9 269
Sergunb 0:8918a71cdbe9 270 typedef enum
Sergunb 0:8918a71cdbe9 271 {
Sergunb 0:8918a71cdbe9 272 WS_STATUS_CODE_NORMAL_CLOSURE = 1000,
Sergunb 0:8918a71cdbe9 273 WS_STATUS_CODE_GOING_AWAY = 1001,
Sergunb 0:8918a71cdbe9 274 WS_STATUS_CODE_PROTOCOL_ERROR = 1002,
Sergunb 0:8918a71cdbe9 275 WS_STATUS_CODE_UNSUPPORTED_DATA = 1003,
Sergunb 0:8918a71cdbe9 276 WS_STATUS_CODE_NO_STATUS_RCVD = 1005,
Sergunb 0:8918a71cdbe9 277 WS_STATUS_CODE_ABNORMAL_CLOSURE = 1006,
Sergunb 0:8918a71cdbe9 278 WS_STATUS_CODE_INVALID_PAYLOAD_DATA = 1007,
Sergunb 0:8918a71cdbe9 279 WS_STATUS_CODE_POLICY_VIOLATION = 1008,
Sergunb 0:8918a71cdbe9 280 WS_STATUS_CODE_MESSAGE_TOO_BIG = 1009,
Sergunb 0:8918a71cdbe9 281 WS_STATUS_CODE_MANDATORY_EXT = 1010,
Sergunb 0:8918a71cdbe9 282 WS_STATUS_CODE_INTERNAL_ERROR = 1011,
Sergunb 0:8918a71cdbe9 283 WS_STATUS_CODE_TLS_HANDSHAKE = 1015
Sergunb 0:8918a71cdbe9 284 } WebSocketStatusCode;
Sergunb 0:8918a71cdbe9 285
Sergunb 0:8918a71cdbe9 286
Sergunb 0:8918a71cdbe9 287 //CodeWarrior or Win32 compiler?
Sergunb 0:8918a71cdbe9 288 #if defined(__CWCC__) || defined(_WIN32)
Sergunb 0:8918a71cdbe9 289 #pragma pack(push, 1)
Sergunb 0:8918a71cdbe9 290 #endif
Sergunb 0:8918a71cdbe9 291
Sergunb 0:8918a71cdbe9 292
Sergunb 0:8918a71cdbe9 293 /**
Sergunb 0:8918a71cdbe9 294 * @brief WebSocket frame
Sergunb 0:8918a71cdbe9 295 **/
Sergunb 0:8918a71cdbe9 296
Sergunb 0:8918a71cdbe9 297 typedef __start_packed struct
Sergunb 0:8918a71cdbe9 298 {
Sergunb 0:8918a71cdbe9 299 #ifdef _CPU_BIG_ENDIAN
Sergunb 0:8918a71cdbe9 300 uint8_t fin : 1; //0
Sergunb 0:8918a71cdbe9 301 uint8_t reserved : 3;
Sergunb 0:8918a71cdbe9 302 uint8_t opcode : 4;
Sergunb 0:8918a71cdbe9 303 uint8_t mask : 1; //1
Sergunb 0:8918a71cdbe9 304 uint8_t payloadLen: 7;
Sergunb 0:8918a71cdbe9 305 #else
Sergunb 0:8918a71cdbe9 306 uint8_t opcode : 4; //0
Sergunb 0:8918a71cdbe9 307 uint8_t reserved : 3;
Sergunb 0:8918a71cdbe9 308 uint8_t fin : 1;
Sergunb 0:8918a71cdbe9 309 uint8_t payloadLen: 7; //1
Sergunb 0:8918a71cdbe9 310 uint8_t mask : 1;
Sergunb 0:8918a71cdbe9 311 #endif
Sergunb 0:8918a71cdbe9 312 uint8_t extPayloadLen[]; //2
Sergunb 0:8918a71cdbe9 313 } __end_packed WebSocketFrame;
Sergunb 0:8918a71cdbe9 314
Sergunb 0:8918a71cdbe9 315
Sergunb 0:8918a71cdbe9 316 //CodeWarrior or Win32 compiler?
Sergunb 0:8918a71cdbe9 317 #if defined(__CWCC__) || defined(_WIN32)
Sergunb 0:8918a71cdbe9 318 #pragma pack(pop)
Sergunb 0:8918a71cdbe9 319 #endif
Sergunb 0:8918a71cdbe9 320
Sergunb 0:8918a71cdbe9 321
Sergunb 0:8918a71cdbe9 322 /**
Sergunb 0:8918a71cdbe9 323 * @brief Random data generation callback function
Sergunb 0:8918a71cdbe9 324 **/
Sergunb 0:8918a71cdbe9 325
Sergunb 0:8918a71cdbe9 326 typedef error_t (*WebSocketRandCallback)(uint8_t *data, size_t length);
Sergunb 0:8918a71cdbe9 327
Sergunb 0:8918a71cdbe9 328
Sergunb 0:8918a71cdbe9 329 //WebSocket connections over SSL/TLS supported?
Sergunb 0:8918a71cdbe9 330 #if (WEB_SOCKET_TLS_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 331
Sergunb 0:8918a71cdbe9 332 /**
Sergunb 0:8918a71cdbe9 333 * @brief SSL/TLS initialization callback function
Sergunb 0:8918a71cdbe9 334 **/
Sergunb 0:8918a71cdbe9 335
Sergunb 0:8918a71cdbe9 336 typedef error_t (*WebSocketTlsInitCallback)(WebSocket *webSocket,
Sergunb 0:8918a71cdbe9 337 TlsContext *tlsContext);
Sergunb 0:8918a71cdbe9 338
Sergunb 0:8918a71cdbe9 339 #endif
Sergunb 0:8918a71cdbe9 340
Sergunb 0:8918a71cdbe9 341
Sergunb 0:8918a71cdbe9 342 /**
Sergunb 0:8918a71cdbe9 343 * @brief Authentication context
Sergunb 0:8918a71cdbe9 344 **/
Sergunb 0:8918a71cdbe9 345
Sergunb 0:8918a71cdbe9 346 typedef struct
Sergunb 0:8918a71cdbe9 347 {
Sergunb 0:8918a71cdbe9 348 uint_t allowedAuthModes;
Sergunb 0:8918a71cdbe9 349 WebSocketAuthMode requiredAuthMode;
Sergunb 0:8918a71cdbe9 350 WebSocketAuthMode selectedAuthMode;
Sergunb 0:8918a71cdbe9 351 char_t username[WEB_SOCKET_USERNAME_MAX_LEN + 1];
Sergunb 0:8918a71cdbe9 352 char_t password[WEB_SOCKET_PASSWORD_MAX_LEN + 1];
Sergunb 0:8918a71cdbe9 353 char_t realm[WEB_SOCKET_REALM_MAX_LEN + 1];
Sergunb 0:8918a71cdbe9 354 #if (WEB_SOCKET_DIGEST_AUTH_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 355 uint32_t nc;
Sergunb 0:8918a71cdbe9 356 char_t nonce[WEB_SOCKET_NONCE_MAX_LEN + 1];
Sergunb 0:8918a71cdbe9 357 char_t cnonce[WEB_SOCKET_CNONCE_SIZE * 2 + 1];
Sergunb 0:8918a71cdbe9 358 char_t opaque[WEB_SOCKET_OPAQUE_MAX_LEN + 1];
Sergunb 0:8918a71cdbe9 359 bool_t stale;
Sergunb 0:8918a71cdbe9 360 #endif
Sergunb 0:8918a71cdbe9 361 } WebSocketAuthContext;
Sergunb 0:8918a71cdbe9 362
Sergunb 0:8918a71cdbe9 363
Sergunb 0:8918a71cdbe9 364 /**
Sergunb 0:8918a71cdbe9 365 * @brief Handshake context
Sergunb 0:8918a71cdbe9 366 **/
Sergunb 0:8918a71cdbe9 367
Sergunb 0:8918a71cdbe9 368 typedef struct
Sergunb 0:8918a71cdbe9 369 {
Sergunb 0:8918a71cdbe9 370 uint_t version;
Sergunb 0:8918a71cdbe9 371 uint_t statusCode;
Sergunb 0:8918a71cdbe9 372 bool_t upgradeWebSocket;
Sergunb 0:8918a71cdbe9 373 bool_t connectionUpgrade;
Sergunb 0:8918a71cdbe9 374 bool_t connectionClose;
Sergunb 0:8918a71cdbe9 375 size_t contentLength;
Sergunb 0:8918a71cdbe9 376 char_t clientKey[WEB_SOCKET_CLIENT_KEY_SIZE + 1];
Sergunb 0:8918a71cdbe9 377 char_t serverKey[WEB_SOCKET_SERVER_KEY_SIZE + 1];
Sergunb 0:8918a71cdbe9 378 bool_t closingFrameSent;
Sergunb 0:8918a71cdbe9 379 bool_t closingFrameReceived;
Sergunb 0:8918a71cdbe9 380 } WebSocketHandshakeContext;
Sergunb 0:8918a71cdbe9 381
Sergunb 0:8918a71cdbe9 382
Sergunb 0:8918a71cdbe9 383 /**
Sergunb 0:8918a71cdbe9 384 * @brief Frame encoding/decoding context
Sergunb 0:8918a71cdbe9 385 **/
Sergunb 0:8918a71cdbe9 386
Sergunb 0:8918a71cdbe9 387 typedef struct
Sergunb 0:8918a71cdbe9 388 {
Sergunb 0:8918a71cdbe9 389 WebSocketSubState state; ///FSM state
Sergunb 0:8918a71cdbe9 390 WebSocketFrameType dataFrameType; ///<Data frame type
Sergunb 0:8918a71cdbe9 391 WebSocketFrameType controlFrameType; ///<Control frame type
Sergunb 0:8918a71cdbe9 392 bool_t fin; ///<Final fragment in a message
Sergunb 0:8918a71cdbe9 393 bool_t mask; ///<Defines whether the payload data is masked
Sergunb 0:8918a71cdbe9 394 uint8_t maskingKey[4]; ///<Masking key
Sergunb 0:8918a71cdbe9 395 size_t payloadLen; ///<Payload length
Sergunb 0:8918a71cdbe9 396 size_t payloadPos; ///<Current position
Sergunb 0:8918a71cdbe9 397 uint8_t buffer[WEB_SOCKET_BUFFER_SIZE]; ///<Data buffer
Sergunb 0:8918a71cdbe9 398 size_t bufferLen; ///<Length of the data buffer
Sergunb 0:8918a71cdbe9 399 size_t bufferPos; ///<Current position
Sergunb 0:8918a71cdbe9 400 } WebSocketFrameContext;
Sergunb 0:8918a71cdbe9 401
Sergunb 0:8918a71cdbe9 402
Sergunb 0:8918a71cdbe9 403 /**
Sergunb 0:8918a71cdbe9 404 * @brief UTF-8 decoding context
Sergunb 0:8918a71cdbe9 405 **/
Sergunb 0:8918a71cdbe9 406
Sergunb 0:8918a71cdbe9 407 typedef struct
Sergunb 0:8918a71cdbe9 408 {
Sergunb 0:8918a71cdbe9 409 uint_t utf8CharSize;
Sergunb 0:8918a71cdbe9 410 uint_t utf8CharIndex;
Sergunb 0:8918a71cdbe9 411 uint32_t utf8CodePoint;
Sergunb 0:8918a71cdbe9 412 } WebSocketUtf8Context;
Sergunb 0:8918a71cdbe9 413
Sergunb 0:8918a71cdbe9 414
Sergunb 0:8918a71cdbe9 415 /**
Sergunb 0:8918a71cdbe9 416 * @brief Structure describing a WebSocket
Sergunb 0:8918a71cdbe9 417 **/
Sergunb 0:8918a71cdbe9 418
Sergunb 0:8918a71cdbe9 419 struct _WebSocket
Sergunb 0:8918a71cdbe9 420 {
Sergunb 0:8918a71cdbe9 421 WebSocketEndpoint endpoint; ///<Endpoint type (client or server)
Sergunb 0:8918a71cdbe9 422 WebSocketState state; ///<WebSocket connection state
Sergunb 0:8918a71cdbe9 423 uint16_t statusCode;
Sergunb 0:8918a71cdbe9 424 systime_t timestamp;
Sergunb 0:8918a71cdbe9 425 uint_t retryCount;
Sergunb 0:8918a71cdbe9 426 char_t host[WEB_SOCKET_HOST_MAX_LEN + 1];
Sergunb 0:8918a71cdbe9 427 char_t origin[WEB_SOCKET_ORIGIN_MAX_LEN + 1];
Sergunb 0:8918a71cdbe9 428 char_t subProtocol[WEB_SOCKET_SUB_PROTOCOL_MAX_LEN + 1];
Sergunb 0:8918a71cdbe9 429 char_t uri[WEB_SOCKET_URI_MAX_LEN + 1];
Sergunb 0:8918a71cdbe9 430 char_t queryString[WEB_SOCKET_QUERY_STRING_MAX_LEN + 1];
Sergunb 0:8918a71cdbe9 431 systime_t timeout; ///<timeout value for blocking operations
Sergunb 0:8918a71cdbe9 432 NetInterface *interface; ///<Underlying network interface
Sergunb 0:8918a71cdbe9 433 Socket *socket; ///<Underlying TCP socket
Sergunb 0:8918a71cdbe9 434 #if (WEB_SOCKET_TLS_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 435 TlsContext *tlsContext; ///<SSL/TLS context
Sergunb 0:8918a71cdbe9 436 TlsSession tlsSession; ///<SSL/TLS session
Sergunb 0:8918a71cdbe9 437 WebSocketTlsInitCallback tlsInitCallback; ///<SSL/TLS initialization callback function
Sergunb 0:8918a71cdbe9 438 #endif
Sergunb 0:8918a71cdbe9 439 #if (WEB_SOCKET_BASIC_AUTH_SUPPORT == ENABLED || WEB_SOCKET_DIGEST_AUTH_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 440 WebSocketAuthContext authContext;
Sergunb 0:8918a71cdbe9 441 #endif
Sergunb 0:8918a71cdbe9 442 WebSocketHandshakeContext handshakeContext;
Sergunb 0:8918a71cdbe9 443 WebSocketFrameContext txContext;
Sergunb 0:8918a71cdbe9 444 WebSocketFrameContext rxContext;
Sergunb 0:8918a71cdbe9 445 WebSocketUtf8Context utf8Context;
Sergunb 0:8918a71cdbe9 446 };
Sergunb 0:8918a71cdbe9 447
Sergunb 0:8918a71cdbe9 448
Sergunb 0:8918a71cdbe9 449 //Random data generation callback function
Sergunb 0:8918a71cdbe9 450 extern WebSocketRandCallback webSockRandCallback;
Sergunb 0:8918a71cdbe9 451
Sergunb 0:8918a71cdbe9 452 //WebSocket related functions
Sergunb 0:8918a71cdbe9 453 error_t webSocketInit(void);
Sergunb 0:8918a71cdbe9 454
Sergunb 0:8918a71cdbe9 455 error_t webSocketRegisterRandCallback(WebSocketRandCallback callback);
Sergunb 0:8918a71cdbe9 456
Sergunb 0:8918a71cdbe9 457 WebSocket *webSocketOpen(void);
Sergunb 0:8918a71cdbe9 458 WebSocket *webSocketUpgradeSocket(Socket *socket);
Sergunb 0:8918a71cdbe9 459
Sergunb 0:8918a71cdbe9 460 #if (WEB_SOCKET_TLS_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 461
Sergunb 0:8918a71cdbe9 462 WebSocket *webSocketUpgradeSecureSocket(Socket *socket, TlsContext *tlsContext);
Sergunb 0:8918a71cdbe9 463
Sergunb 0:8918a71cdbe9 464 error_t webSocketRegisterTlsInitCallback(WebSocket *webSocket,
Sergunb 0:8918a71cdbe9 465 WebSocketTlsInitCallback callback);
Sergunb 0:8918a71cdbe9 466
Sergunb 0:8918a71cdbe9 467 #endif
Sergunb 0:8918a71cdbe9 468
Sergunb 0:8918a71cdbe9 469 error_t webSocketSetTimeout(WebSocket *webSocket, systime_t timeout);
Sergunb 0:8918a71cdbe9 470
Sergunb 0:8918a71cdbe9 471 error_t webSocketSetHost(WebSocket *webSocket, const char_t *host);
Sergunb 0:8918a71cdbe9 472 error_t webSocketSetOrigin(WebSocket *webSocket, const char_t *origin);
Sergunb 0:8918a71cdbe9 473 error_t webSocketSetSubProtocol(WebSocket *webSocket, const char_t *subProtocol);
Sergunb 0:8918a71cdbe9 474
Sergunb 0:8918a71cdbe9 475 error_t webSocketSetAuthInfo(WebSocket *webSocket, const char_t *username,
Sergunb 0:8918a71cdbe9 476 const char_t *password, uint_t allowedAuthModes);
Sergunb 0:8918a71cdbe9 477
Sergunb 0:8918a71cdbe9 478 error_t webSocketBindToInterface(WebSocket *webSocket, NetInterface *interface);
Sergunb 0:8918a71cdbe9 479
Sergunb 0:8918a71cdbe9 480 error_t webSocketConnect(WebSocket *webSocket, const IpAddr *serverIpAddr,
Sergunb 0:8918a71cdbe9 481 uint16_t serverPort, const char_t *uri);
Sergunb 0:8918a71cdbe9 482
Sergunb 0:8918a71cdbe9 483 error_t webSocketSetClientKey(WebSocket *webSocket, const char_t *clientKey);
Sergunb 0:8918a71cdbe9 484 error_t webSocketParseClientHandshake(WebSocket *webSocket);
Sergunb 0:8918a71cdbe9 485 error_t webSocketSendServerHandshake(WebSocket *webSocket);
Sergunb 0:8918a71cdbe9 486
Sergunb 0:8918a71cdbe9 487 error_t webSocketSendErrorResponse(WebSocket *webSocket,
Sergunb 0:8918a71cdbe9 488 uint_t statusCode, const char_t *message);
Sergunb 0:8918a71cdbe9 489
Sergunb 0:8918a71cdbe9 490 error_t webSocketSend(WebSocket *webSocket, const void *data,
Sergunb 0:8918a71cdbe9 491 size_t length, WebSocketFrameType type, size_t *written);
Sergunb 0:8918a71cdbe9 492
Sergunb 0:8918a71cdbe9 493 error_t webSocketSendEx(WebSocket *webSocket, const void *data, size_t length,
Sergunb 0:8918a71cdbe9 494 WebSocketFrameType type, size_t *written, bool_t firstFrag, bool_t lastFrag);
Sergunb 0:8918a71cdbe9 495
Sergunb 0:8918a71cdbe9 496 error_t webSocketReceive(WebSocket *webSocket, void *data,
Sergunb 0:8918a71cdbe9 497 size_t size, WebSocketFrameType *type, size_t *received);
Sergunb 0:8918a71cdbe9 498
Sergunb 0:8918a71cdbe9 499 error_t webSocketReceiveEx(WebSocket *webSocket, void *data, size_t size,
Sergunb 0:8918a71cdbe9 500 WebSocketFrameType *type, size_t *received, bool_t *firstFrag, bool_t *lastFrag);
Sergunb 0:8918a71cdbe9 501
Sergunb 0:8918a71cdbe9 502 bool_t webSocketIsRxReady(WebSocket *webSocket);
Sergunb 0:8918a71cdbe9 503 error_t webSocketShutdown(WebSocket *webSocket);
Sergunb 0:8918a71cdbe9 504 void webSocketClose(WebSocket *webSocket);
Sergunb 0:8918a71cdbe9 505
Sergunb 0:8918a71cdbe9 506 #endif
Sergunb 0:8918a71cdbe9 507