|
1 /** |
|
2 * @file websocket.h |
|
3 * @brief Websocket functions. |
|
4 * @author Blake Felt - blake.w.felt@gmail.com` |
|
5 */ |
|
6 |
|
7 |
|
8 #ifdef __cplusplus |
|
9 extern "C" { |
|
10 #endif |
|
11 |
|
12 #ifndef WEBSOCKET_H |
|
13 #define WEBSOCKET_H |
|
14 |
|
15 #include "lwip/api.h" |
|
16 |
|
17 |
|
18 /** |
|
19 * @brief the different codes for the callbacks |
|
20 */ |
|
21 typedef enum { |
|
22 WEBSOCKET_CONNECT, ///< Connect |
|
23 WEBSOCKET_DISCONNECT_EXTERNAL, ///< the other side disconnected |
|
24 WEBSOCKET_DISCONNECT_INTERNAL, ///< the esp32 disconnected |
|
25 WEBSOCKET_DISCONNECT_ERROR, ///< disconnect due to error |
|
26 WEBSOCKET_TEXT, ///< Text message |
|
27 WEBSOCKET_BIN, ///< Binary message |
|
28 WEBSOCKET_PING, ///< PING message |
|
29 WEBSOCKET_PONG ///< PONG message |
|
30 } WEBSOCKET_TYPE_t; |
|
31 |
|
32 |
|
33 |
|
34 /** |
|
35 * @brief websocket operation codes |
|
36 */ |
|
37 typedef enum { |
|
38 WEBSOCKET_OPCODE_CONT = 0x0, ///< Continue |
|
39 WEBSOCKET_OPCODE_TEXT = 0x1, ///< Text |
|
40 WEBSOCKET_OPCODE_BIN = 0x2, ///< Binary |
|
41 WEBSOCKET_OPCODE_CLOSE = 0x8, ///< Close connection |
|
42 WEBSOCKET_OPCODE_PING = 0x9, ///< PING message |
|
43 WEBSOCKET_OPCODE_PONG = 0xA ///< PONG message |
|
44 } WEBSOCKET_OPCODES_t; |
|
45 |
|
46 |
|
47 /** |
|
48 * @brief the header, useful for creating and quickly passing to functions |
|
49 */ |
|
50 typedef struct { |
|
51 union { |
|
52 struct { |
|
53 uint16_t LEN:7; ///< bits 0.. 6 |
|
54 uint16_t MASK:1; ///< bit 7 |
|
55 uint16_t OPCODE:4; ///< bits 8.. 11 |
|
56 uint16_t :3; ///< bits 12.. 14 reserved |
|
57 uint16_t FIN:1; ///< bit 15 |
|
58 } bit; |
|
59 struct { |
|
60 uint16_t ONE:8; ///< bits 0.. 7 |
|
61 uint16_t ZERO:8; ///< bits 8.. 15 |
|
62 } pos; |
|
63 } param; ///< the initial parameters of the header |
|
64 uint64_t length; ///< actual message length |
|
65 union { |
|
66 char part[4]; ///< the mask, array |
|
67 uint32_t full; ///< the mask, all 32 bits |
|
68 } key; ///< masking key |
|
69 bool received; ///< was a message successfully received? |
|
70 } ws_header_t; |
|
71 |
|
72 |
|
73 /** |
|
74 * @brief A client, with space for a server callback or a client callback (depending on use) |
|
75 */ |
|
76 typedef struct { |
|
77 struct netconn* conn; ///< the connection |
|
78 bool connected; ///< connection state |
|
79 char* url; ///< the associated url, null terminated |
|
80 char* protocol; ///< the associated protocol, null terminated |
|
81 bool ping; ///< did we send a ping? |
|
82 WEBSOCKET_OPCODES_t last_opcode; ///< the previous opcode |
|
83 char* contin; ///< any continuation piece |
|
84 bool contin_text; ///< is the continue a binary or text? |
|
85 uint64_t len; ///< length of continuation |
|
86 uint32_t unfinished; ///< sometimes netconn doesn't read a full frame, treated similarly to a continuation frame |
|
87 void (*ccallback)(WEBSOCKET_TYPE_t type,char* msg,uint64_t len); ///< client callback |
|
88 void (*scallback)(uint8_t num,WEBSOCKET_TYPE_t type,char* msg,uint64_t len); ///< server callback |
|
89 } ws_client_t; |
|
90 |
|
91 |
|
92 /** |
|
93 * @brief returns the populated client struct |
|
94 * does not send any header, assumes the proper handshake has already occurred |
|
95 * @param conn The network connection |
|
96 * @param url The connection url. |
|
97 * @param ccallback callback for client (userspace) |
|
98 * @param scallback callback for server (userspace) |
|
99 * @return The Websocket client structure. |
|
100 */ |
|
101 ws_client_t ws_connect_client(struct netconn* conn, |
|
102 char* url, |
|
103 void (*ccallback)(WEBSOCKET_TYPE_t type,char* msg,uint64_t len), |
|
104 void (*scallback)(uint8_t num,WEBSOCKET_TYPE_t type,char* msg,uint64_t len) |
|
105 ); |
|
106 |
|
107 |
|
108 /** |
|
109 * @brief Disconnect a websocket client. |
|
110 * @param client The ws_client_t structure with the client information. |
|
111 */ |
|
112 void ws_disconnect_client(ws_client_t* client); |
|
113 |
|
114 /** |
|
115 * @briek Test if the client is connected. |
|
116 * status updates after send/read/connect/disconnect. |
|
117 * @param client The ws_client_t structure with the client information. |
|
118 * @return True if connected, false if not. |
|
119 */ |
|
120 bool ws_is_connected(ws_client_t client); |
|
121 |
|
122 /** |
|
123 * @brief Send data via websocjet to a client. This function performs the masking. |
|
124 * @param client The ws_client_t structure with the client information. |
|
125 * @param opcode The opcode to send the message. |
|
126 * @param msg The message itself. |
|
127 * @param len The length of the message. |
|
128 * @param mask Encrypt?? |
|
129 * @return error code or ERR_OK |
|
130 */ |
|
131 err_t ws_send(ws_client_t* client,WEBSOCKET_OPCODES_t opcode,char* msg,uint64_t len,bool mask); |
|
132 |
|
133 /** |
|
134 * @brief Receive a message from a websocket connection. |
|
135 * @param client The ws_client_t structure with the client information. |
|
136 * @param header unmasks and returns message. populates header. |
|
137 * @return Unmasks and returns message. populates header. |
|
138 */ |
|
139 char* ws_read(ws_client_t* client,ws_header_t* header); |
|
140 |
|
141 /** |
|
142 * @brief Create a handshake hashed string. |
|
143 * @param key The key for the hash. |
|
144 * @param len The length. |
|
145 * @return The string of output. |
|
146 */ |
|
147 char* ws_hash_handshake(char* key,uint8_t len); |
|
148 |
|
149 #endif // ifndef WEBSOCKET_H |
|
150 |
|
151 #ifdef __cplusplus |
|
152 } |
|
153 #endif |