Skip to content

Commit e1e6280

Browse files
committed
first working WebSocketClient
add LGPLv2.1
1 parent 6d46f22 commit e1e6280

12 files changed

+769
-338
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@
2626
*.exe
2727
*.out
2828
*.app
29+
/tests/webSocketServer/node_modules

LICENSE

+414-252
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* WebSocketClient.ino
3+
*
4+
* Created on: 24.05.2015
5+
*
6+
*/
7+
8+
#include <Arduino.h>
9+
10+
#include <ESP8266WiFi.h>
11+
#include <ESP8266WiFiMulti.h>
12+
13+
#include <WebSocketsClient.h>
14+
15+
#include <Hash.h>
16+
17+
ESP8266WiFiMulti WiFiMulti;
18+
WebSocketsClient webSocket;
19+
20+
21+
void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) {
22+
23+
24+
switch(type) {
25+
case WStype_DISCONNECTED:
26+
Serial1.printf("[WSc] Disconnected!\n");
27+
break;
28+
case WStype_CONNECTED:
29+
{
30+
Serial1.printf("[WSc] Connected to url: %s\n", payload);
31+
}
32+
break;
33+
case WStype_TEXT:
34+
Serial1.printf("[WSc] get text: %s\n", lenght);
35+
36+
// send data to back to Server
37+
webSocket.sendTXT(payload, lenght);
38+
break;
39+
case WStype_BIN:
40+
Serial1.printf("[WSc] get binary lenght: %u\n", lenght);
41+
hexdump(payload, lenght);
42+
43+
// echo data back to Server
44+
webSocket.sendBIN(payload, lenght);
45+
break;
46+
}
47+
48+
}
49+
50+
51+
void setup() {
52+
Serial.begin(921600);
53+
Serial1.begin(921600);
54+
55+
//Serial.setDebugOutput(true);
56+
Serial1.setDebugOutput(true);
57+
58+
Serial1.println();
59+
Serial1.println();
60+
Serial1.println();
61+
62+
for(uint8_t t = 4; t > 0; t--) {
63+
Serial1.printf("[SETUP] BOOT WAIT %d...\n", t);
64+
Serial1.flush();
65+
delay(1000);
66+
}
67+
68+
WiFiMulti.addAP("SSID", "passpasspass");
69+
70+
//WiFi.disconnect();
71+
while(WiFiMulti.run() != WL_CONNECTED) {
72+
delay(100);
73+
}
74+
75+
webSocket.begin("192.168.0.123", 81);
76+
webSocket.onEvent(webSocketEvent);
77+
78+
}
79+
80+
81+
82+
void loop() {
83+
webSocket.loop();
84+
}

examples/WebSocketsServer/WebSocketsServer.ino examples/WebSocketServer/WebSocketServer.ino

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* WebSocketsServer.ino
2+
* WebSocketServer.ino
33
*
44
* Created on: 22.05.2015
55
*

src/WebSockets.cpp

+46-18
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ extern "C" {
3838
* @param reasonLen
3939
*/
4040
void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * reason, size_t reasonLen) {
41-
DEBUG_WEBSOCKETS("[WS-Server][%d][handleWebsocket] clientDisconnect code: %u\n", client->num, code);
41+
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] clientDisconnect code: %u\n", client->num, code);
4242
if(client->status == WSC_CONNECTED && code) {
4343
if(reason) {
4444
sendFrame(client, WSop_close, (uint8_t *) reason, reasonLen);
@@ -59,22 +59,36 @@ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * rea
5959
* @param payload uint8_t *
6060
* @param length size_t
6161
*/
62-
void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length) {
62+
void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool mask) {
63+
64+
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] ------- send massage frame -------\n", client->num);
65+
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] opCode: %u mask: %u length: %u\n", client->num, opcode, mask, length);
66+
67+
if(opcode == WSop_text) {
68+
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] text: %s\n", client->num, payload);
69+
}
6370

6471
if(!client->tcp.connected()) {
72+
DEBUG_WEBSOCKETS("[WS][%d][sendFrame] not Connected!?\n", client->num);
6573
return;
6674
}
6775

76+
uint8_t maskKey[4] = { 0 };
6877
uint8_t buffer[16] = { 0 };
6978
uint8_t i = 0;
7079

7180
//create header
81+
buffer[i] = bit(7); // set Fin
82+
buffer[i++] |= opcode; // set opcode
7283

73-
buffer[i] = bit(7); // set Fin
74-
buffer[i++] |= opcode; // set opcode
84+
buffer[i] = 0x00;
85+
86+
if(mask) {
87+
buffer[i] |= bit(7); // set mask
88+
}
7589

7690
if(length < 126) {
77-
buffer[i++] = length;
91+
buffer[i++] |= length;
7892

7993
} else if(length < 0xFFFF) {
8094
buffer[i++] = 126;
@@ -93,6 +107,20 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay
93107
buffer[i++] = (length & 0xFF);
94108
}
95109

110+
if(mask) {
111+
// todo generate random mask key
112+
for(uint8_t x = 0; x < sizeof(maskKey); x++) {
113+
// maskKey[x] = random(0xFF);
114+
maskKey[x] = 0x00; // fake xor (0x00 0x00 0x00 0x00)
115+
buffer[i++] = maskKey[x];
116+
}
117+
118+
// todo encode XOR
119+
//for(size_t x = 0; x < length; x++) {
120+
// payload[x] = (payload[x] ^ maskKey[x % 4]);
121+
//}
122+
}
123+
96124
// send header
97125
client->tcp.write(&buffer[0], i);
98126

@@ -123,7 +151,7 @@ void WebSockets::handleWebsocket(WSclient_t * client) {
123151

124152
uint8_t * payload = NULL;
125153

126-
DEBUG_WEBSOCKETS("[WS-Server][%d][handleWebsocket] ------- read massage frame -------\n", client->num);
154+
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] ------- read massage frame -------\n", client->num);
127155

128156
if(!readWait(client, buffer, 2)) {
129157
//timeout
@@ -164,11 +192,11 @@ void WebSockets::handleWebsocket(WSclient_t * client) {
164192
}
165193
}
166194

167-
DEBUG_WEBSOCKETS("[WS-Server][%d][handleWebsocket] fin: %u rsv1: %u rsv2: %u rsv3 %u opCode: %u\n", client->num, fin, rsv1, rsv2, rsv3, opCode);
168-
DEBUG_WEBSOCKETS("[WS-Server][%d][handleWebsocket] mask: %u payloadLen: %u\n", client->num, mask, payloadLen);
195+
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] fin: %u rsv1: %u rsv2: %u rsv3 %u opCode: %u\n", client->num, fin, rsv1, rsv2, rsv3, opCode);
196+
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] mask: %u payloadLen: %u\n", client->num, mask, payloadLen);
169197

170198
if(payloadLen > WEBSOCKETS_MAX_DATA_SIZE) {
171-
DEBUG_WEBSOCKETS("[WS-Server][%d][handleWebsocket] payload to big! (%u)\n", client->num, payloadLen);
199+
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] payload to big! (%u)\n", client->num, payloadLen);
172200
clientDisconnect(client, 1009);
173201
return;
174202
}
@@ -182,13 +210,13 @@ void WebSockets::handleWebsocket(WSclient_t * client) {
182210
payload = (uint8_t *) malloc(payloadLen + 1);
183211

184212
if(!payload) {
185-
DEBUG_WEBSOCKETS("[WS-Server][%d][handleWebsocket] to less memory to handle payload %d!\n", client->num, payloadLen);
213+
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] to less memory to handle payload %d!\n", client->num, payloadLen);
186214
clientDisconnect(client, 1011);
187215
return;
188216
}
189217

190218
if(!readWait(client, payload, payloadLen)) {
191-
DEBUG_WEBSOCKETS("[WS-Server][%d][handleWebsocket] missing data!\n", client->num);
219+
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] missing data!\n", client->num);
192220
free(payload);
193221
clientDisconnect(client, 1002);
194222
return;
@@ -206,7 +234,7 @@ void WebSockets::handleWebsocket(WSclient_t * client) {
206234

207235
switch(opCode) {
208236
case WSop_text:
209-
DEBUG_WEBSOCKETS("[WS-Server][%d][handleWebsocket] text: %s\n", client->num, payload);
237+
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] text: %s\n", client->num, payload);
210238
// no break here!
211239
case WSop_binary:
212240
messageRecived(client, opCode, payload, payloadLen);
@@ -216,7 +244,7 @@ void WebSockets::handleWebsocket(WSclient_t * client) {
216244
sendFrame(client, WSop_pong, payload, payloadLen);
217245
break;
218246
case WSop_pong:
219-
DEBUG_WEBSOCKETS("[WS-Server][%d][handleWebsocket] get pong from Client (%s)\n", client->num, payload);
247+
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload);
220248
break;
221249
case WSop_close:
222250
{
@@ -225,9 +253,9 @@ void WebSockets::handleWebsocket(WSclient_t * client) {
225253
reasonCode = payload[0] << 8 | payload[1];
226254
}
227255

228-
DEBUG_WEBSOCKETS("[WS-Server][%d][handleWebsocket] client ask for close. Code: %d", client->num, reasonCode);
256+
DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get ask for close. Code: %d", client->num, reasonCode);
229257
if(payloadLen > 2) {
230-
DEBUG_WEBSOCKETS("(%s)\n", (payload+2));
258+
DEBUG_WEBSOCKETS(" (%s)\n", (payload+2));
231259
} else {
232260
DEBUG_WEBSOCKETS("\n");
233261
}
@@ -271,8 +299,8 @@ String WebSockets::acceptKey(String clientKey) {
271299
* @return base64 encoded String
272300
*/
273301
String WebSockets::base64_encode(uint8_t * data, size_t length) {
274-
275-
char * buffer = (char *) malloc((length*1.4)+1);
302+
size_t size = ((length*1.6f)+1);
303+
char * buffer = (char *) malloc(size);
276304
if(buffer) {
277305
base64_encodestate _state;
278306
base64_init_encodestate(&_state);
@@ -283,7 +311,7 @@ String WebSockets::base64_encode(uint8_t * data, size_t length) {
283311
free(buffer);
284312
return base64;
285313
}
286-
return "-FAIL-";
314+
return String("-FAIL-");
287315
}
288316

289317
/**

src/WebSockets.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#endif
3838
#endif
3939

40-
#define DEBUG_WEBSOCKETS(...) Serial1.printf( __VA_ARGS__ );
40+
//#define DEBUG_WEBSOCKETS(...) Serial1.printf( __VA_ARGS__ )
4141

4242
#ifndef DEBUG_WEBSOCKETS
4343
#define DEBUG_WEBSOCKETS(...)
@@ -85,14 +85,16 @@ typedef struct {
8585
#endif
8686
#endif
8787
String cUrl; ///< http url
88+
uint16_t cCode; ///< http code
8889

8990
bool cIsUpgrade; ///< Connection == Upgrade
9091
bool cIsWebsocket; ///< Upgrade == websocket
9192

9293
String cKey; ///< client Sec-WebSocket-Key
94+
String cAccept; ///< client Sec-WebSocket-Accept
9395
String cProtocol; ///< client Sec-WebSocket-Protocol
9496
String cExtensions; ///< client Sec-WebSocket-Extensions
95-
int cVersion; ///< client Sec-WebSocket-Version
97+
uint16_t cVersion; ///< client Sec-WebSocket-Version
9698

9799
} WSclient_t;
98100

@@ -104,7 +106,7 @@ class WebSockets {
104106
virtual void messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length);
105107

106108
void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0);
107-
void sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0);
109+
void sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false);
108110

109111

110112
void handleWebsocket(WSclient_t * client);
@@ -113,6 +115,7 @@ class WebSockets {
113115

114116
String acceptKey(String clientKey);
115117
String base64_encode(uint8_t * data, size_t length);
118+
116119
};
117120

118121
#endif /* WEBSOCKETS_H_ */

0 commit comments

Comments
 (0)