1 /** @file
2  @brief Websocket private header
3 
4  This is not to be included by the application.
5  */
6 
7 /*
8  * Copyright (c) 2019 Intel Corporation
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 
13 #include <zephyr/toolchain/common.h>
14 
15 #define WS_SHA1_OUTPUT_LEN 20
16 
17 /* Min Websocket header length */
18 #define MIN_HEADER_LEN 2
19 
20 /* Max Websocket header length */
21 #define MAX_HEADER_LEN 14
22 
23 /* From RFC 6455 chapter 4.2.2 */
24 #define WS_MAGIC "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
25 
26 /**
27  * Websocket parser states
28  */
29 enum websocket_parser_state {
30 	WEBSOCKET_PARSER_STATE_OPCODE,
31 	WEBSOCKET_PARSER_STATE_LENGTH,
32 	WEBSOCKET_PARSER_STATE_EXT_LEN,
33 	WEBSOCKET_PARSER_STATE_MASK,
34 	WEBSOCKET_PARSER_STATE_PAYLOAD,
35 };
36 
37 /**
38  * Description of external buffers for payload and receiving
39  */
40 struct websocket_buffer {
41 	/* external buffer */
42 	uint8_t *buf;
43 	/* size of external buffer */
44 	size_t size;
45 	/* data length in external buffer */
46 	size_t count;
47 };
48 
49 /**
50  * Websocket connection information
51  */
52 __net_socket struct websocket_context {
53 	union {
54 		/** User data.
55 		 */
56 		void *user_data;
57 
58 		/** This is used during HTTP handshake to verify that the
59 		 * peer sent proper Sec-WebSocket-Accept key.
60 		 */
61 		uint8_t *sec_accept_key;
62 	};
63 
64 	/** Reference count.
65 	 */
66 	atomic_t refcount;
67 
68 	/** Internal lock for protecting this context from multiple access.
69 	 */
70 	struct k_mutex lock;
71 
72 	/* The socket number is valid only after HTTP handshake is done
73 	 * so we can share the memory for these.
74 	 */
75 	union {
76 		/** HTTP parser settings for the application usage */
77 		const struct http_parser_settings *http_cb;
78 
79 		/** The Websocket socket id. If data is sent via this socket, it
80 		 * will automatically add Websocket headers etc into the data.
81 		 */
82 		int sock;
83 	};
84 
85 	/** Buffer for receiving from TCP socket.
86 	 * This buffer used for HTTP handshakes and Websocket packet parser.
87 	 * User must provide the actual buffer where the data are
88 	 * stored temporarily.
89 	 */
90 	struct websocket_buffer recv_buf;
91 
92 	/** The real TCP socket to use when sending Websocket data to peer.
93 	 */
94 	int real_sock;
95 
96 	/** Websocket connection masking value */
97 	uint32_t masking_value;
98 
99 	/** Message length */
100 	uint64_t message_len;
101 
102 	/** Message type */
103 	uint32_t message_type;
104 
105 	/** Parser remaining length in current state */
106 	uint64_t parser_remaining;
107 
108 	/** Parser state */
109 	enum websocket_parser_state parser_state;
110 
111 	/** Is the message masked */
112 	uint8_t masked : 1;
113 
114 	/** Did we receive Sec-WebSocket-Accept: field */
115 	uint8_t sec_accept_present : 1;
116 
117 	/** Is Sec-WebSocket-Accept field correct */
118 	uint8_t sec_accept_ok : 1;
119 
120 	/** Did we receive all from peer during HTTP handshake */
121 	uint8_t all_received : 1;
122 };
123 
124 #if defined(CONFIG_NET_TEST)
125 /**
126  * Websocket unit test does not use socket layer but feeds
127  * the data directly here when testing this function.
128  */
129 struct test_data {
130 	/** pointer to data "tx" buffer */
131 	uint8_t *input_buf;
132 
133 	/** "tx" buffer data length */
134 	size_t input_len;
135 
136 	/** "tx" buffer read (recv) position */
137 	size_t input_pos;
138 
139 	/** external test context */
140 	struct websocket_context *ctx;
141 };
142 #endif /* CONFIG_NET_TEST */
143 
144 /**
145  * @brief Disconnect the Websocket.
146  *
147  * @param sock Websocket id returned by websocket_connect() call.
148  *
149  * @return 0 if ok, <0 if error
150  */
151 int websocket_disconnect(int sock);
152 
153 /**
154  * @typedef websocket_context_cb_t
155  * @brief Callback used while iterating over websocket contexts
156  *
157  * @param context A valid pointer on current websocket context
158  * @param user_data A valid pointer on some user data or NULL
159  */
160 typedef void (*websocket_context_cb_t)(struct websocket_context *ctx,
161 				       void *user_data);
162 
163 /**
164  * @brief Iterate over websocket context. This is mainly used by net-shell
165  * to show information about websockets.
166  *
167  * @param cb Websocket context callback
168  * @param user_data Caller specific data.
169  */
170 void websocket_context_foreach(websocket_context_cb_t cb, void *user_data);
171