create overloaded functions for send and broadcast for easy usage

void sendTXT(uint8_t num, uint8_t * payload, size_t length = 0);
        void sendTXT(uint8_t num, const uint8_t * payload, size_t length = 0);
        void sendTXT(uint8_t num, char * payload, size_t length = 0);
        void sendTXT(uint8_t num, const char * payload, size_t length = 0);
        void sendTXT(uint8_t num, String payload);

        void broadcastTXT(uint8_t * payload, size_t length = 0);
        void broadcastTXT(const uint8_t * payload, size_t length = 0);
        void broadcastTXT(char * payload, size_t length = 0);
        void broadcastTXT(const char * payload, size_t length = 0);
        void broadcastTXT(String payload);

        void sendBIN(uint8_t num, uint8_t * payload, size_t length);
        void sendBIN(uint8_t num, const uint8_t * payload, size_t length);

        void broadcastBIN(uint8_t * payload, size_t length);
        void broadcastBIN(const uint8_t * payload, size_t length);

send URL as payload on WStype_CONNECTED event
move Sec-WebSocket-Accept generation in function
This commit is contained in:
Markus Sattler
2015-05-23 09:02:59 +02:00
parent 2af71ab97a
commit 27a9a22908
5 changed files with 105 additions and 29 deletions

View File

@ -24,6 +24,12 @@
#include "WebSockets.h" #include "WebSockets.h"
extern "C" {
#include "libb64/cencode.h"
}
#include <Hash.h>
/** /**
* *
* @param client WSclient_t * ptr to the client struct * @param client WSclient_t * ptr to the client struct
@ -195,8 +201,7 @@ void WebSockets::handleWebsocket(WSclient_t * client) {
switch(opCode) { switch(opCode) {
case WSop_text: case WSop_text:
DEBUG_WEBSOCKETS("[WS-Server][%d][handleWebsocket] text: %s\n", client->num, payload) DEBUG_WEBSOCKETS("[WS-Server][%d][handleWebsocket] text: %s\n", client->num, payload);
;
// no break here! // no break here!
case WSop_binary: case WSop_binary:
messageRecived(client, opCode, payload, payloadLen); messageRecived(client, opCode, payload, payloadLen);
@ -206,8 +211,7 @@ void WebSockets::handleWebsocket(WSclient_t * client) {
sendFrame(client, WSop_pong, payload, payloadLen); sendFrame(client, WSop_pong, payload, payloadLen);
break; break;
case WSop_pong: case WSop_pong:
DEBUG_WEBSOCKETS("[WS-Server][%d][handleWebsocket] get pong from Client (%s)\n", client->num, payload) DEBUG_WEBSOCKETS("[WS-Server][%d][handleWebsocket] get pong from Client (%s)\n", client->num, payload);
;
break; break;
case WSop_close: case WSop_close:
{ {
@ -240,6 +244,43 @@ void WebSockets::handleWebsocket(WSclient_t * client) {
} }
/**
* generate the key for Sec-WebSocket-Accept
* @param clientKey String
* @return String Accept Key
*/
String WebSockets::acceptKey(String clientKey) {
uint8_t sha1HashBin[20] = { 0 };
sha1(clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", &sha1HashBin[0]);
String key = base64_encode(sha1HashBin, 20);
key.trim();
return key;
}
/**
* base64_encode
* @param data uint8_t *
* @param length size_t
* @return base64 encoded String
*/
String WebSockets::base64_encode(uint8_t * data, size_t length) {
char * buffer = (char *) malloc((length*1.4)+1);
if(buffer) {
base64_encodestate _state;
base64_init_encodestate(&_state);
int len = base64_encode_block((const char *) &data[0], length, &buffer[0], &_state);
len = base64_encode_blockend((buffer + len), &_state);
String base64 = String(buffer);
free(buffer);
return base64;
}
return "-FAIL-";
}
/** /**
* read x byte from tcp or get timeout * read x byte from tcp or get timeout
* @param client WSclient_t * * @param client WSclient_t *

View File

@ -104,6 +104,9 @@ class WebSockets {
void handleWebsocket(WSclient_t * client); void handleWebsocket(WSclient_t * client);
bool readWait(WSclient_t * client, uint8_t *out, size_t n); bool readWait(WSclient_t * client, uint8_t *out, size_t n);
String acceptKey(String clientKey);
String base64_encode(uint8_t * data, size_t length);
}; };
#endif /* WEBSOCKETS_H_ */ #endif /* WEBSOCKETS_H_ */

View File

@ -25,12 +25,6 @@
#include "WebSockets.h" #include "WebSockets.h"
#include "WebSocketsServer.h" #include "WebSocketsServer.h"
extern "C" {
#include "libb64/cencode.h"
}
#include <Hash.h>
WebSocketsServer::WebSocketsServer(uint16_t port) { WebSocketsServer::WebSocketsServer(uint16_t port) {
_port = port; _port = port;
_server = new WiFiServer(port); _server = new WiFiServer(port);
@ -95,12 +89,27 @@ void WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length) {
if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) { if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) {
return; return;
} }
if(length == 0) {
length = strlen((const char *) payload);
}
WSclient_t * client = &_clients[num]; WSclient_t * client = &_clients[num];
if(clientIsConnected(client)) { if(clientIsConnected(client)) {
sendFrame(client, WSop_text, payload, length); sendFrame(client, WSop_text, payload, length);
} }
} }
void WebSocketsServer::sendTXT(uint8_t num, const uint8_t * payload, size_t length) {
sendTXT(num, (uint8_t *) payload, length);
}
void WebSocketsServer::sendTXT(uint8_t num, char * payload, size_t length) {
sendTXT(num, (uint8_t *) payload, length);
}
void WebSocketsServer::sendTXT(uint8_t num, const char * payload, size_t length) {
sendTXT(num, (uint8_t *) payload, length);
}
void WebSocketsServer::sendTXT(uint8_t num, String payload) { void WebSocketsServer::sendTXT(uint8_t num, String payload) {
sendTXT(num, (uint8_t *) payload.c_str(), payload.length()); sendTXT(num, (uint8_t *) payload.c_str(), payload.length());
} }
@ -112,6 +121,9 @@ void WebSocketsServer::sendTXT(uint8_t num, String payload) {
*/ */
void WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length) { void WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length) {
WSclient_t * client; WSclient_t * client;
if(length == 0) {
length = strlen((const char *) payload);
}
for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) {
client = &_clients[i]; client = &_clients[i];
if(clientIsConnected(client)) { if(clientIsConnected(client)) {
@ -120,6 +132,18 @@ void WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length) {
} }
} }
void WebSocketsServer::broadcastTXT(const uint8_t * payload, size_t length) {
broadcastTXT((uint8_t *) payload, length);
}
void WebSocketsServer::broadcastTXT(char * payload, size_t length) {
broadcastTXT((uint8_t *) payload, length);
}
void WebSocketsServer::broadcastTXT(const char * payload, size_t length) {
broadcastTXT((uint8_t *) payload, length);
}
void WebSocketsServer::broadcastTXT(String payload) { void WebSocketsServer::broadcastTXT(String payload) {
broadcastTXT((uint8_t *) payload.c_str(), payload.length()); broadcastTXT((uint8_t *) payload.c_str(), payload.length());
} }
@ -140,6 +164,10 @@ void WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length) {
} }
} }
void WebSocketsServer::sendBIN(uint8_t num, const uint8_t * payload, size_t length) {
sendBIN(num, (uint8_t *) payload, length);
}
/** /**
* send binary data to client all * send binary data to client all
* @param payload uint8_t * * @param payload uint8_t *
@ -155,6 +183,10 @@ void WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length) {
} }
} }
void WebSocketsServer::broadcastBIN(const uint8_t * payload, size_t length) {
broadcastBIN((uint8_t *) payload, length);
}
//################################################################################# //#################################################################################
//################################################################################# //#################################################################################
//################################################################################# //#################################################################################
@ -289,7 +321,7 @@ void WebSocketsServer::handleClientData(void) {
WebSockets::handleWebsocket(client); WebSockets::handleWebsocket(client);
break; break;
default: default:
clientDisconnect(client); WebSockets::clientDisconnect(client, 1002);
break; break;
} }
} }
@ -363,19 +395,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client) {
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incomming.\n", client->num); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incomming.\n", client->num);
// generate Sec-WebSocket-Accept key // generate Sec-WebSocket-Accept key
uint8_t sha1HashBin[20] = { 0 }; client->sKey = acceptKey(client->cKey);
sha1(client->cKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", &sha1HashBin[0]);
char sha1Base64[64] = { 0 };
int len = 0;
base64_encodestate _state;
base64_init_encodestate(&_state);
len = base64_encode_block((const char *) &sha1HashBin[0], 20, &sha1Base64[0], &_state);
base64_encode_blockend((sha1Base64 + len), &_state);
client->sKey = sha1Base64;
client->sKey.trim();
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - sKey: %s\n", client->num, client->sKey.c_str()); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - sKey: %s\n", client->num, client->sKey.c_str());
@ -398,8 +418,11 @@ void WebSocketsServer::handleHeader(WSclient_t * client) {
// header end // header end
client->tcp.write("\r\n"); client->tcp.write("\r\n");
// send ping
WebSockets::sendFrame(client, WSop_ping);
if(_cbEvent) { if(_cbEvent) {
_cbEvent(client->num, WStype_CONNECTED, NULL, 0); _cbEvent(client->num, WStype_CONNECTED, (uint8_t *)client->cUrl.c_str(), client->cUrl.length());
} }
} else { } else {

View File

@ -65,14 +65,23 @@ public:
void onEvent(WebSocketServerEvent cbEvent); void onEvent(WebSocketServerEvent cbEvent);
void sendTXT(uint8_t num, uint8_t * payload, size_t length); void sendTXT(uint8_t num, uint8_t * payload, size_t length = 0);
void broadcastTXT(uint8_t * payload, size_t length); void sendTXT(uint8_t num, const uint8_t * payload, size_t length = 0);
void sendTXT(uint8_t num, char * payload, size_t length = 0);
void sendTXT(uint8_t num, const char * payload, size_t length = 0);
void sendTXT(uint8_t num, String payload); void sendTXT(uint8_t num, String payload);
void broadcastTXT(uint8_t * payload, size_t length = 0);
void broadcastTXT(const uint8_t * payload, size_t length = 0);
void broadcastTXT(char * payload, size_t length = 0);
void broadcastTXT(const char * payload, size_t length = 0);
void broadcastTXT(String payload); void broadcastTXT(String payload);
void sendBIN(uint8_t num, uint8_t * payload, size_t length); void sendBIN(uint8_t num, uint8_t * payload, size_t length);
void sendBIN(uint8_t num, const uint8_t * payload, size_t length);
void broadcastBIN(uint8_t * payload, size_t length); void broadcastBIN(uint8_t * payload, size_t length);
void broadcastBIN(const uint8_t * payload, size_t length);
private: private:
uint16_t _port; uint16_t _port;

View File

@ -102,7 +102,7 @@ int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
case step_A: case step_A:
break; break;
} }
*codechar++ = '\n'; *codechar++ = 0x00;
return codechar - code_out; return codechar - code_out;
} }