NetBurner 3.1
websockets.h
1 /*NB_REVISION*/
2 
3 /*NB_COPYRIGHT*/
4 
5 #ifndef __WEBSOCKETS_H
6 #define __WEBSOCKETS_H
7 
8 // NB Definitions
9 #include <predef.h>
10 
11 // NB Libs
12 #include <buffers.h>
13 #include <http.h>
14 #include <iosys.h>
15 #include <nbrtos.h>
16 #include <nettypes.h>
17 
18 #define WS_BUFFER_SEGMENTS 4
19 #define WS_MAX_SOCKS 4
20 #define WS_BUFFER_MIN 10
21 #define WS_ACCUM_DLY ((TICKS_PER_SECOND / 4) + 1)
22 #define WS_FLUSH_TIMEOUT 0
23 
24 #define WS_FIN_BIT 0x80
25 
26 #define WS_OP_CONT 0x0
27 #define WS_OP_TEXT 0x1
28 #define WS_OP_BIN 0x2
29 #define WS_OP_CLOSE 0x8
30 #define WS_OP_PING 0x9
31 #define WS_OP_PONG 0xA
32 
33 #define WS_SO_TEXT 0x8
34 
35 namespace NB
36 {
37 class WebSocket
38 {
39  struct WS_Client_Short
40  {
41  uint8_t opAndFin;
42  uint8_t maskAndLen;
43  uint32_t mask;
44  uint8_t pData[];
45  } __attribute__((packed));
46  struct WS_Client_Med
47  {
48  uint8_t opAndFin;
49  uint8_t maskAndLen;
50  beuint16_t length;
51  uint32_t mask;
52  uint8_t pData[];
53  } __attribute__((packed));
54  struct WS_Client_Long
55  {
56  uint8_t opAndFin;
57  uint8_t maskAndLen;
58  beuint32_t lengthHi;
59  beuint32_t lengthLo;
60  uint32_t mask;
61  uint8_t pData[];
62  } __attribute__((packed));
63  struct WS_Server_Short
64  {
65  uint8_t opAndFin;
66  uint8_t maskAndLen;
67  uint8_t pData[];
68  } __attribute__((packed));
69  struct WS_Server_Med
70  {
71  uint8_t opAndFin;
72  uint8_t maskAndLen;
73  beuint16_t length;
74  uint8_t pData[];
75  } __attribute__((packed));
76  struct WS_Server_Long
77  {
78  uint8_t opAndFin;
79  uint8_t maskAndLen;
80  beuint32_t lengthHi;
81  beuint32_t lengthLo;
82  uint8_t pData[];
83  } __attribute__((packed));
84 
85  enum WS_State
86  {
87  WS_INIT,
88  WS_CONNECTING,
89  WS_ESTABLISHED,
90  WS_CLOSE_PENDING,
91  WS_CLOSE_SENT,
92  WS_CLOSE_RECV,
93  WS_TCP_CLOSED,
94  WS_CLOSED,
95  WS_ABORT,
96  WS_FAIL
97  };
98 
99  static const char * WS_StateStr(WS_State state);
100  enum WS_StatusCode
101  {
102  WS_STAT_NORM_CLOSE = 1000,
103  WS_STAT_GOING_AWAY = 1001,
104  WS_STAT_PROT_ERROR = 1002,
105  WS_STAT_UNACCEPT_TYPE = 1003,
106  WS_STAT_NONE = 1005, // Must not be sent
107  WS_STAT_NONE_ABNORMAL = 1006, // Must not be sent
108  WS_STAT_NOT_CONSISTENT = 1007,
109  WS_STAT_POLICY_VIOLATION = 1008,
110  WS_STAT_MSG_TOO_BIG = 1009,
111  WS_STAT_EXPECTED_EXTENSION = 1010,
112  WS_STAT_UNEXPECTED_COND = 1011,
113  WS_STAT_TLS_FAILURE = 1015, // Must not be sent
114  };
115 
116  fifo_buffer_storage rxBuffer;
117  fifo_buffer_storage ctlBuffer;
118  fifo_buffer_storage txBuffer;
119 
120 public:
121  int m_fd_tcp;
122  int m_fd_ws;
123  OS_CRIT socket_crit;
124 private:
125  WS_State m_state;
126  int m_options;
127  uint32_t m_SendTime;
128  uint32_t m_AccumDly;
129  bool m_serverNotClient;
130 
131  volatile bool m_CtlBlock;
132  uint32_t m_currentIndex;
133  uint32_t m_remLen;
134 
135  uint8_t m_frameHeadBuf[14];
136  uint8_t m_frameHeadNext;
137  bool m_gotLen;
138  uint32_t m_currentMask;
139  uint32_t m_remainingLen;
140 
141  uint8_t m_txFrameHeadBuf[14];
142  uint8_t m_txFrameHeadNext;
143  uint8_t m_txFrameHeadLen;
144  uint32_t m_txCurrMask;
145  uint32_t m_txRemLen;
146  bool m_txFlushInProgress;
147  bool m_txCtlSendInProgress;
148  OS_SEM *m_ctlWaitSem;
149 
150  uint32_t m_txBufferMin;
151 
152  void ServerRxFromTCP();
153  bool ReadRemainingHeader();
154  void ProcessCtlFrame();
155  void Close(bool closedAfterSend, uint16_t code = 0, const char *reason = NULL, int len = 0);
156  void RemoteClose();
157  void CleanUp();
158  void SendCtlFrame();
159  void Init(int fd_tcp, int fd_ws, bool serverNotClient);
160  void Flush_Header(uint8_t *buf, uint32_t mask, uint32_t len);
161 
162  static uint32_t s_flushTick;
163  static fd_set s_pendingCtlSocks;
164  static OS_CRIT s_ws_crit_obj;
165  static bool s_bFinishedInit;
166 
167  static void StaticInit();
168  static int GetNewSocket(int fd_tcp, bool serverNotClient);
169 
170  static WebSocket *GetRecordFromTCP(int fd);
171 
172  static int CoreConnect(IPADDR ip, const char *host, const char *resource, int portnum, bool useSSL = false);
173 
174  public:
175  int WriteData(const char *buf, int nbytes);
176  int ReadData(char *buf, int nbytes);
177  void Flush();
178  void Pong(uint32_t len);
179  inline WS_State GetState() { return m_state; }
180 
181  int setoption(int option);
182  int clroption(int option);
183  int getoption();
184 
185  inline int GetWriteSpace() { return txBuffer.SpaceAvail(); }
186 
187  static int s_openSocketCount; // really should be private, but can't figure how
188  static WebSocket WSSockStructs[WS_MAX_SOCKS];
189 
190  static int ws_readwto(int fd, char *buf, int nbytes, int timeout);
191  static int ws_read(int fd, char *buf, int nbytes);
192  static int ws_write(int fd, const char *buf, int nbytes);
193  static int ws_externalclose(int fd);
194  static void ws_flush(int fd);
195  static int ws_setoption(int fd, int option);
196  static int ws_clroption(int fd, int option);
197  static int ws_getoption(int fd);
198 
199  static WebSocket *GetWebSocketRecord(int fd);
200  static int promote_tcp_ws(int tcp_fd);
201  static void ws_read_notify(int fd); // tcp data rx callback
202  static void ws_write_notify(int fd); // tcp data tx space callback
203  static void GetFlushTime();
204 
205  static void RunSkippedCallBack();
206 
207  static int Connect(const char *host, const char *resource, int portnum = 80, bool useSSL = false);
208  static int Connect(IPADDR host, const char *resource, int portnum = 80, bool useSSL = false);
209 
210  void DumpSock();
211  static void DumpSockets();
212 };
213 
214 } // namespace NB
215 
216 int WSUpgrade(HTTP_Request *req, int sock);
217 #endif /* ----- #ifndef __WEBSOCKETS_H ----- */
NetBurner Real-Time Operating System API.
NetBurner I/O System Library API.
Used to hold and manipulate IPv4 and IPv6 addresses in dual stack mode.
Definition: ipv6_addr.h:28
Semaphores are used to control access to shared resource critical section, or to communicate between ...
Definition: nbrtos.h:318
NetBurner HTTP Web Server Header File.
Definition: dhcpv6_internal.h:34
An OS_CRIT object is used to establish critical sections of code that can only be run by one task at ...
Definition: nbrtos.h:893
#define NULL
Definition: nm_bsp.h:76
NetBurner Buffers API.
void WriteData(int fd, const char *c, int siz)
Definition: gifCompress.cpp:142