From 3aa0deac748c5726c665ec5c7cbc3ebccb970815 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 26 Nov 2015 15:19:07 +0100 Subject: [PATCH 001/347] add LED control example command out all echos --- examples/WebSocketClient/WebSocketClient.ino | 14 +- examples/WebSocketServer/WebSocketServer.ino | 13 +- .../WebSocketServer_LEDcontrol.ino | 122 ++++++++++++++++++ tests/webSocket.html | 27 +++- 4 files changed, 159 insertions(+), 17 deletions(-) create mode 100644 examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino diff --git a/examples/WebSocketClient/WebSocketClient.ino b/examples/WebSocketClient/WebSocketClient.ino index aa769f0..39dcaf0 100644 --- a/examples/WebSocketClient/WebSocketClient.ino +++ b/examples/WebSocketClient/WebSocketClient.ino @@ -30,26 +30,28 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { case WStype_CONNECTED: { USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); + + // send message to server when Connected + webSocket.sendTXT(num, "Connected"); } break; case WStype_TEXT: USE_SERIAL.printf("[WSc] get text: %s\n", payload); - // send data to back to Server - webSocket.sendTXT(payload, lenght); + // send message to server + // webSocket.sendTXT("message here"); break; case WStype_BIN: USE_SERIAL.printf("[WSc] get binary lenght: %u\n", lenght); hexdump(payload, lenght); - // echo data back to Server - webSocket.sendBIN(payload, lenght); + // send data to server + // webSocket.sendBIN(payload, lenght); break; } } - void setup() { // USE_SERIAL.begin(921600); USE_SERIAL.begin(115200); @@ -79,8 +81,6 @@ void setup() { } - - void loop() { webSocket.loop(); } diff --git a/examples/WebSocketServer/WebSocketServer.ino b/examples/WebSocketServer/WebSocketServer.ino index 2c171ae..795d9a6 100644 --- a/examples/WebSocketServer/WebSocketServer.ino +++ b/examples/WebSocketServer/WebSocketServer.ino @@ -28,23 +28,26 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght { IPAddress ip = webSocket.remoteIP(num); USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); + + // send message to client + webSocket.sendTXT(num, "Connected"); } break; case WStype_TEXT: USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); - // echo data back to browser - webSocket.sendTXT(num, payload, lenght); + // send message to client + // webSocket.sendTXT(num, "message here"); // send data to all connected clients - webSocket.broadcastTXT(payload, lenght); + // webSocket.broadcastTXT("message here"); break; case WStype_BIN: USE_SERIAL.printf("[%u] get binary lenght: %u\n", num, lenght); hexdump(payload, lenght); - // echo data back to browser - webSocket.sendBIN(num, payload, lenght); + // send message to client + // webSocket.sendBIN(num, payload, lenght); break; } diff --git a/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino b/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino new file mode 100644 index 0000000..b95d12e --- /dev/null +++ b/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino @@ -0,0 +1,122 @@ +/* + * WebSocketServer_LEDcontrol.ino + * + * Created on: 26.11.2015 + * + */ + +#include + +#include +#include +#include +#include +#include +#include + +#define LED_RED 15 +#define LED_GREEN 12 +#define LED_BLUE 13 + +#define USE_SERIAL Serial + + +ESP8266WiFiMulti WiFiMulti; + +ESP8266WebServer server = ESP8266WebServer(80); +WebSocketsServer webSocket = WebSocketsServer(81); + +void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) { + + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[%u] Disconnected!\n", num); + break; + case WStype_CONNECTED: { + IPAddress ip = webSocket.remoteIP(num); + USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); + + // send message to client + webSocket.sendTXT(num, "Connected"); + } + break; + case WStype_TEXT: + USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); + + if(payload[0] == '#') { + // we get RGB data + + // decode rgb data + uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16); + + analogWrite(LED_RED, ((rgb >> 16) & 0xFF)); + analogWrite(LED_GREEN, ((rgb >> 8) & 0xFF)); + analogWrite(LED_BLUE, ((rgb >> 0) & 0xFF)); + } + + break; + } + +} + +void setup() { + USE_SERIAL.begin(921600); + //USE_SERIAL.begin(115200); + + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + pinMode(LED_RED, OUTPUT); + pinMode(LED_GREEN, OUTPUT); + pinMode(LED_BLUE, OUTPUT); + + digitalWrite(LED_RED, 1); + digitalWrite(LED_GREEN, 1); + digitalWrite(LED_BLUE, 1); + + WiFiMulti.addAP("SSID", "passpasspass"); + + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + // start webSocket server + webSocket.begin(); + webSocket.onEvent(webSocketEvent); + + if(MDNS.begin("esp8266")) { + Serial.println("MDNS responder started"); + } + + // handle index + server.on("/", []() { + // send index.html + server.send(200, "text/html", "LED Control:

R:
G:
B:
"); + }); + + server.begin(); + + // Add service to MDNS + MDNS.addService("http", "tcp", 80); + MDNS.addService("ws", "tcp", 81); + + digitalWrite(LED_RED, 0); + digitalWrite(LED_GREEN, 0); + digitalWrite(LED_BLUE, 0); + +} + +void loop() { + webSocket.loop(); + server.handleClient(); +} + diff --git a/tests/webSocket.html b/tests/webSocket.html index c23ee78..1760886 100644 --- a/tests/webSocket.html +++ b/tests/webSocket.html @@ -2,11 +2,16 @@ -Test Websocket. +LED Control:
+
+R:
+G:
+B:
\ No newline at end of file From fb47a92f35c5ba9be105ac66dd6701328916cf0e Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 26 Nov 2015 15:20:14 +0100 Subject: [PATCH 002/347] bump version --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index cfae5f4..bbdf97c 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=1.1 +version=1.2 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From 082f5192c046a933ef19185f5ba6cd76349ee049 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Fri, 27 Nov 2015 00:44:52 +0100 Subject: [PATCH 003/347] add Gitter fix examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino --- README.md | 2 ++ .../WebSocketServer_LEDcontrol.ino | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8655250..29d652b 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ a WebSocket Server and Client for Arduino based on RFC6455. ### Issues ### Submit issues to: https://github.com/Links2004/arduinoWebSockets/issues +[![Join the chat at https://gitter.im/Links2004/arduinoWebSockets](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Links2004/arduinoWebSockets?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + ### License and credits ### The library is licensed under [LGPLv2.1](https://github.com/Links2004/arduinoWebSockets/blob/master/LICENSE) diff --git a/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino b/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino index b95d12e..96a74ac 100644 --- a/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino +++ b/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino @@ -60,10 +60,10 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght } void setup() { - USE_SERIAL.begin(921600); - //USE_SERIAL.begin(115200); + //USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); - USE_SERIAL.setDebugOutput(true); + //USE_SERIAL.setDebugOutput(true); USE_SERIAL.println(); USE_SERIAL.println(); @@ -94,7 +94,7 @@ void setup() { webSocket.onEvent(webSocketEvent); if(MDNS.begin("esp8266")) { - Serial.println("MDNS responder started"); + USE_SERIAL.println("MDNS responder started"); } // handle index From 92a63e9129f2a4f8c5a0e4372736f9a95a2004d9 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 30 Nov 2015 19:46:37 +0100 Subject: [PATCH 004/347] fix problems with ESP8266 core version 2.0.0 --- src/WebSockets.cpp | 10 +++++++++- src/libb64/cdecode.c | 8 +++++++- src/libb64/{cdecode.h => cdecode_inc.h} | 0 src/libb64/cencode.c | 8 +++++++- src/libb64/{cencode.h => cencode_inc.h} | 0 5 files changed, 23 insertions(+), 3 deletions(-) rename src/libb64/{cdecode.h => cdecode_inc.h} (100%) rename src/libb64/{cencode.h => cencode_inc.h} (100%) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 0b5736f..b3ad336 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -24,8 +24,16 @@ #include "WebSockets.h" +#ifdef ESP8266 +#include +#endif + extern "C" { -#include "libb64/cencode.h" +#ifdef CORE_HAS_LIBB64 + #include +#else + #include "libb64/cencode_inc.h" +#endif } #ifdef ESP8266 diff --git a/src/libb64/cdecode.c b/src/libb64/cdecode.c index bb4b07c..0d86d0e 100644 --- a/src/libb64/cdecode.c +++ b/src/libb64/cdecode.c @@ -5,7 +5,12 @@ This is part of the libb64 project, and has been placed in the public domain. For details, see http://sourceforge.net/projects/libb64 */ -#include "cdecode.h" +#ifdef ESP8266 +#include +#endif + +#ifndef CORE_HAS_LIBB64 +#include "cdecode_inc.h" int base64_decode_value(char value_in) { @@ -86,3 +91,4 @@ int base64_decode_block(const char* code_in, const int length_in, char* plaintex return plainchar - plaintext_out; } +#endif diff --git a/src/libb64/cdecode.h b/src/libb64/cdecode_inc.h similarity index 100% rename from src/libb64/cdecode.h rename to src/libb64/cdecode_inc.h diff --git a/src/libb64/cencode.c b/src/libb64/cencode.c index a15b5dc..7367135 100644 --- a/src/libb64/cencode.c +++ b/src/libb64/cencode.c @@ -5,7 +5,12 @@ This is part of the libb64 project, and has been placed in the public domain. For details, see http://sourceforge.net/projects/libb64 */ -#include "cencode.h" +#ifdef ESP8266 +#include +#endif + +#ifndef CORE_HAS_LIBB64 +#include "cencode_inc.h" const int CHARS_PER_LINE = 72; @@ -107,3 +112,4 @@ int base64_encode_blockend(char* code_out, base64_encodestate* state_in) return codechar - code_out; } +#endif diff --git a/src/libb64/cencode.h b/src/libb64/cencode_inc.h similarity index 100% rename from src/libb64/cencode.h rename to src/libb64/cencode_inc.h From 7a22dad9d11bb81b5949b5692388e21f9ee8f0f3 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 5 Dec 2015 11:43:03 +0100 Subject: [PATCH 005/347] try to improve see: #23 --- src/WebSockets.cpp | 6 +++++- src/WebSockets.h | 2 +- src/WebSocketsClient.cpp | 18 +++++++++++------- src/WebSocketsServer.cpp | 18 +++++++++++------- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index b3ad336..ce4017b 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -254,7 +254,11 @@ void WebSockets::handleWebsocket(WSclient_t * client) { } if(mask) { - client->tcp.read(maskKey, 4); + if(!readWait(client, maskKey, 4)) { + //timeout + clientDisconnect(client, 1002); + return; + } } if(payloadLen > 0) { diff --git a/src/WebSockets.h b/src/WebSockets.h index b52f135..44a8c6e 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -44,7 +44,7 @@ #endif #define WEBSOCKETS_MAX_DATA_SIZE (15*1024) -#define WEBSOCKETS_TCP_TIMEOUT (1000) +#define WEBSOCKETS_TCP_TIMEOUT (1500) typedef enum { WSC_NOT_CONNECTED, diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index dac1308..210bd6b 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -218,13 +218,17 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { */ bool WebSocketsClient::clientIsConnected(WSclient_t * client) { - if(client->status != WSC_NOT_CONNECTED && client->tcp.connected()) { - return true; - } - - if(client->status != WSC_NOT_CONNECTED) { - // cleanup - clientDisconnect(&_client); + if(client->tcp.connected()) { + if(client->status != WSC_NOT_CONNECTED) { + return true; + } + } else { + // client lost + if(client->status != WSC_NOT_CONNECTED) { + DEBUG_WEBSOCKETS("[WS-Client] connection lost.\n"); + // do cleanup + clientDisconnect(client); + } } return false; } diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 0982b35..f8ca998 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -302,13 +302,17 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { */ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { - if(client->status != WSC_NOT_CONNECTED && client->tcp.connected()) { - return true; - } - - if(client->status != WSC_NOT_CONNECTED) { - // cleanup - clientDisconnect(client); + if(client->tcp.connected()) { + if(client->status != WSC_NOT_CONNECTED) { + return true; + } + } else { + // client lost + if(client->status != WSC_NOT_CONNECTED) { + DEBUG_WEBSOCKETS("[WS-Server][%d] client connection lost.\n", client->num); + // do cleanup + clientDisconnect(client); + } } return false; } From 093797a815466836fa576e27fb3d63071b8ab6a3 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 10 Dec 2015 09:36:18 +0100 Subject: [PATCH 006/347] first step for SSL (wss) support --- src/WebSockets.cpp | 14 +++--- src/WebSockets.h | 69 ++++++++++++++++++++++-------- src/WebSocketsClient.cpp | 87 +++++++++++++++++++++++++++++++------ src/WebSocketsServer.cpp | 92 ++++++++++++++++++++++++++++++---------- src/WebSocketsServer.h | 13 +----- 5 files changed, 204 insertions(+), 71 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index ce4017b..28407f3 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -74,7 +74,7 @@ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * rea */ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool mask, bool fin, bool headerToPayload) { - if(!client->tcp.connected()) { + if(client->tcp && !client->tcp->connected()) { DEBUG_WEBSOCKETS("[WS][%d][sendFrame] not Connected!?\n", client->num); return; } @@ -171,14 +171,14 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay // header has be added to payload // payload is forced to reserved 14 Byte but we may not need all based on the length and mask settings // offset in payload is calculatetd 14 - headerSize - client->tcp.write(&payload[(14 - headerSize)], (length + headerSize)); + client->tcp->write(&payload[(14 - headerSize)], (length + headerSize)); } else { // send header - client->tcp.write(&buffer[0], headerSize); + client->tcp->write(&buffer[0], headerSize); if(payload && length > 0) { // send payload - client->tcp.write(&payload[0], length); + client->tcp->write(&payload[0], length); } } } @@ -385,7 +385,7 @@ bool WebSockets::readWait(WSclient_t * client, uint8_t *out, size_t n) { size_t len; while(n > 0) { - if(!client->tcp.connected()) { + if(client->tcp && !client->tcp->connected()) { DEBUG_WEBSOCKETS("[readWait] not connected!\n"); return false; } @@ -395,14 +395,14 @@ bool WebSockets::readWait(WSclient_t * client, uint8_t *out, size_t n) { return false; } - if(!client->tcp.available()) { + if(!client->tcp->available()) { #ifdef ESP8266 delay(0); #endif continue; } - len = client->tcp.read((uint8_t*) out, n); + len = client->tcp->read((uint8_t*) out, n); if(len) { t = millis(); out += len; diff --git a/src/WebSockets.h b/src/WebSockets.h index 44a8c6e..1b34ffc 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -27,24 +27,58 @@ #include +#define DEBUG_WEBSOCKETS(...) Serial1.printf( __VA_ARGS__ ) + +#ifndef DEBUG_WEBSOCKETS +#define DEBUG_WEBSOCKETS(...) +#endif + #ifdef ESP8266 -#include +#define WEBSOCKETS_MAX_DATA_SIZE (15*1024) #else -#include -#ifndef UIPETHERNET_H -#include -#include +//atmega328p has only 2KB ram! +#define WEBSOCKETS_MAX_DATA_SIZE (1024) #endif + +#define WEBSOCKETS_TCP_TIMEOUT (1500) + +#define NETWORK_ESP8266 (1) +#define NETWORK_W5100 (2) +#define NETWORK_ENC28J60 (3) + + +// select Network type based +#ifdef ESP8266 +#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 +#else +#define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 #endif -//#define DEBUG_WEBSOCKETS(...) Serial1.printf( __VA_ARGS__ ) -#ifndef DEBUG_WEBSOCKETS -#define DEBUG_WEBSOCKETS(...) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + +#ifndef ESP8266 +#error "network type ESP8266 only possible on the ESP mcu!" +#endif + +#include +#define WEBSOCKETS_NETWORK_CLASS WiFiClient + +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_W5100) + +#include +#include +#define WEBSOCKETS_NETWORK_CLASS EthernetClient + +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ENC28J60) + +#include +#define WEBSOCKETS_NETWORK_CLASS UIPClient + +#else +#error "no network type selected!" #endif -#define WEBSOCKETS_MAX_DATA_SIZE (15*1024) -#define WEBSOCKETS_TCP_TIMEOUT (1500) typedef enum { WSC_NOT_CONNECTED, @@ -75,15 +109,14 @@ typedef struct { uint8_t num; ///< connection number WSclientsStatus_t status; -#ifdef ESP8266 - WiFiClient tcp; -#else -#ifdef UIPETHERNET_H - UIPClient tcp; -#else - EthernetClient tcp; -#endif + + WEBSOCKETS_NETWORK_CLASS * tcp; + +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + bool isSSL; ///< run in ssl mode + WiFiClientSecure * ssl; #endif + String cUrl; ///< http url uint16_t cCode; ///< http code diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 210bd6b..2848893 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -28,7 +28,6 @@ WebSocketsClient::WebSocketsClient() { _cbEvent = NULL; _client.num = 0; - } WebSocketsClient::~WebSocketsClient() { @@ -42,7 +41,13 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) _host = host; _port = port; + _client.num = 0; _client.status = WSC_NOT_CONNECTED; + _client.tcp = NULL; +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + _client.isSSL = false; + _client.ssl = NULL; +#endif _client.cUrl = url; _client.cCode = 0; _client.cIsUpgrade = false; @@ -53,8 +58,12 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) _client.cExtensions = ""; _client.cVersion = 0; +#ifdef ESP8266 + randomSeed(RANDOM_REG32); +#else // todo find better seed randomSeed(millis()); +#endif } void WebSocketsClient::begin(String host, uint16_t port, String url) { @@ -66,16 +75,44 @@ void WebSocketsClient::begin(String host, uint16_t port, String url) { */ void WebSocketsClient::loop(void) { if(!clientIsConnected(&_client)) { - if(_client.tcp.connect(_host.c_str(), _port)) { + +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + if(_client.isSSL) { + DEBUG_WEBSOCKETS("[WS-Client] connect wss...\n"); + if(_client.ssl) { + delete _client.ssl; + _client.ssl = NULL; + _client.tcp = NULL; + } + _client.ssl = new WiFiClientSecure(); + _client.tcp = _client.ssl; + } else { + DEBUG_WEBSOCKETS("[WS-Client] connect ws...\n"); + if(_client.tcp) { + delete _client.tcp; + _client.tcp = NULL; + } + _client.tcp = new WiFiClient(); + } +#else + _client.tcp = new WEBSOCKETS_NETWORK_CLASS(); +#endif + + if(!_client.tcp) { + DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); + return; + } + + if(_client.tcp->connect(_host.c_str(), _port)) { DEBUG_WEBSOCKETS("[WS-Client] connected to %s:%u.\n", _host.c_str(), _port); _client.status = WSC_HEADER; // set Timeout for readBytesUntil and readStringUntil - _client.tcp.setTimeout(WEBSOCKETS_TCP_TIMEOUT); + _client.tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); -#ifdef ESP8266 - _client.tcp.setNoDelay(true); +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + _client.tcp->setNoDelay(true); #endif // send Header to Server @@ -190,9 +227,25 @@ void WebSocketsClient::messageRecived(WSclient_t * client, WSopcode_t opcode, ui */ void WebSocketsClient::clientDisconnect(WSclient_t * client) { +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + if(client->isSSL && client->ssl) { + if(client->ssl->connected()) { + client->ssl->flush(); + client->ssl->stop(); + } + delete client->ssl; + client->ssl = NULL; + client->tcp = NULL; + } +#endif + if(client->tcp) { - client->tcp.flush(); - client->tcp.stop(); + if(client->tcp->connected()) { + client->tcp->flush(); + client->tcp->stop(); + } + delete client->tcp; + client->tcp = NULL; } client->cCode = 0; @@ -218,7 +271,11 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { */ bool WebSocketsClient::clientIsConnected(WSclient_t * client) { - if(client->tcp.connected()) { + if(!client->tcp) { + return false; + } + + if(client->tcp->connected()) { if(client->status != WSC_NOT_CONNECTED) { return true; } @@ -230,6 +287,12 @@ bool WebSocketsClient::clientIsConnected(WSclient_t * client) { clientDisconnect(client); } } + + if(client->tcp) { + // do cleanup + clientDisconnect(client); + } + return false; } @@ -237,7 +300,7 @@ bool WebSocketsClient::clientIsConnected(WSclient_t * client) { * Handel incomming data from Client */ void WebSocketsClient::handleClientData(void) { - int len = _client.tcp.available(); + int len = _client.tcp->available(); if(len > 0) { switch(_client.status) { case WSC_HEADER: @@ -289,7 +352,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { handshake += "\r\n"; - client->tcp.write(handshake.c_str(), handshake.length()); + client->tcp->write(handshake.c_str(), handshake.length()); DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header... Done (%uus).\n", (micros() - start)); @@ -301,7 +364,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { */ void WebSocketsClient::handleHeader(WSclient_t * client) { - String headerLine = client->tcp.readStringUntil('\n'); + String headerLine = client->tcp->readStringUntil('\n'); headerLine.trim(); // remove \r if(headerLine.length() > 0) { @@ -392,7 +455,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client) { } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); - client->tcp.write("This is a webSocket client!"); + client->tcp->write("This is a webSocket client!"); clientDisconnect(client); } } diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index f8ca998..df147d1 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -34,7 +34,10 @@ WebSocketsServer::WebSocketsServer(uint16_t port) { } WebSocketsServer::~WebSocketsServer() { - // todo how to close server? + // disconnect all clients + disconnect(); + + // TODO how to close server? } /** @@ -48,20 +51,31 @@ void WebSocketsServer::begin(void) { client = &_clients[i]; client->num = i; + client->status = WSC_NOT_CONNECTED; + client->tcp = NULL; +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + client->isSSL = false; + client->ssl = NULL; +#endif client->cUrl = ""; + client->cCode = 0; client->cKey = ""; client->cProtocol = ""; client->cVersion = 0; client->cIsUpgrade = false; client->cIsWebsocket = false; - - client->status = WSC_NOT_CONNECTED; } - // todo find better seed +#ifdef ESP8266 + randomSeed(RANDOM_REG32); +#else + // TODO find better seed randomSeed(millis()); +#endif _server->begin(); + + DEBUG_WEBSOCKETS("[WS-Server] Server Started.\n"); } /** @@ -235,7 +249,7 @@ IPAddress WebSocketsServer::remoteIP(uint8_t num) { if(num < WEBSOCKETS_SERVER_CLIENT_MAX) { WSclient_t * client = &_clients[num]; if(clientIsConnected(client)) { - return client->tcp.remoteIP(); + return client->tcp->remoteIP(); } } @@ -275,9 +289,26 @@ void WebSocketsServer::messageRecived(WSclient_t * client, WSopcode_t opcode, ui */ void WebSocketsServer::clientDisconnect(WSclient_t * client) { + +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + if(client->isSSL && client->ssl) { + if(client->ssl->connected()) { + client->ssl->flush(); + client->ssl->stop(); + } + delete client->ssl; + client->ssl = NULL; + client->tcp = NULL; + } +#endif + if(client->tcp) { - client->tcp.flush(); - client->tcp.stop(); + if(client->tcp->connected()) { + client->tcp->flush(); + client->tcp->stop(); + } + delete client->tcp; + client->tcp = NULL; } client->cUrl = ""; @@ -302,7 +333,11 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { */ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { - if(client->tcp.connected()) { + if(!client->tcp) { + return false; + } + + if(client->tcp->connected()) { if(client->status != WSC_NOT_CONNECTED) { return true; } @@ -314,6 +349,12 @@ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { clientDisconnect(client); } } + + if(client->tcp) { + // do cleanup + clientDisconnect(client); + } + return false; } @@ -332,15 +373,22 @@ void WebSocketsServer::handleNewClients(void) { if(!clientIsConnected(client)) { // store new connection - client->tcp = _server->available(); -#ifdef ESP8266 - client->tcp.setNoDelay(true); + client->tcp = new WEBSOCKETS_NETWORK_CLASS(_server->available()); + + if(!client->tcp) { + DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); + return; + } + +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + client->isSSL = false; + client->tcp->setNoDelay(true); #endif // set Timeout for readBytesUntil and readStringUntil - client->tcp.setTimeout(WEBSOCKETS_TCP_TIMEOUT); + client->tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); client->status = WSC_HEADER; - IPAddress ip = client->tcp.remoteIP(); + IPAddress ip = client->tcp->remoteIP(); DEBUG_WEBSOCKETS("[WS-Server][%d] new client from %d.%d.%d.%d\n", client->num, ip[0], ip[1], ip[2], ip[3]); ok = true; break; @@ -349,7 +397,7 @@ void WebSocketsServer::handleNewClients(void) { if(!ok) { // no free space to handle client - WiFiClient tcpClient = _server->available(); + WEBSOCKETS_NETWORK_CLASS tcpClient = _server->available(); IPAddress ip = tcpClient.remoteIP(); DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); tcpClient.stop(); @@ -370,7 +418,7 @@ void WebSocketsServer::handleClientData(void) { for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { client = &_clients[i]; if(clientIsConnected(client)) { - int len = client->tcp.available(); + int len = client->tcp->available(); if(len > 0) { switch(client->status) { @@ -398,7 +446,7 @@ void WebSocketsServer::handleClientData(void) { */ void WebSocketsServer::handleHeader(WSclient_t * client) { - String headerLine = client->tcp.readStringUntil('\n'); + String headerLine = client->tcp->readStringUntil('\n'); headerLine.trim(); // remove \r if(headerLine.length() > 0) { @@ -470,22 +518,22 @@ void WebSocketsServer::handleHeader(WSclient_t * client) { client->status = WSC_CONNECTED; - client->tcp.write("HTTP/1.1 101 Switching Protocols\r\n" + client->tcp->write("HTTP/1.1 101 Switching Protocols\r\n" "Server: arduino-WebSocketsServer\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Version: 13\r\n" "Sec-WebSocket-Accept: "); - client->tcp.write(sKey.c_str(), sKey.length()); - client->tcp.write("\r\n"); + client->tcp->write(sKey.c_str(), sKey.length()); + client->tcp->write("\r\n"); if(client->cProtocol.length() > 0) { - // todo add api to set Protocol of Server - client->tcp.write("Sec-WebSocket-Protocol: arduino\r\n"); + // TODO add api to set Protocol of Server + client->tcp->write("Sec-WebSocket-Protocol: arduino\r\n"); } // header end - client->tcp.write("\r\n"); + client->tcp->write("\r\n"); // send ping WebSockets::sendFrame(client, WSop_ping); diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 86ad970..bef170e 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -26,17 +26,6 @@ #define WEBSOCKETSSERVER_H_ #include - -#ifdef ESP8266 -#include -#else -#include -#ifndef UIPETHERNET_H -#include -#include -#endif -#endif - #include "WebSockets.h" #define WEBSOCKETS_SERVER_CLIENT_MAX (5) @@ -115,7 +104,7 @@ class WebSocketsServer: private WebSockets { */ virtual void handleNonWebsocketConnection(WSclient_t * client) { DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] no Websocket connection close.\n", client->num); - client->tcp.write("HTTP/1.1 400 Bad Request\r\n" + client->tcp->write("HTTP/1.1 400 Bad Request\r\n" "Server: arduino-WebSocket-Server\r\n" "Content-Type: text/plain\r\n" "Content-Length: 32\r\n" From 098c488ff0767672dc1a3d6631aee58ba42d8440 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 10 Dec 2015 10:10:06 +0100 Subject: [PATCH 007/347] add beginSSL --- examples/WebSocketClient/WebSocketClient.ino | 2 +- .../WebSocketClientSSL/WebSocketClientSSL.ino | 88 +++++++++++++++++++ src/WebSocketsClient.cpp | 11 +++ src/WebSocketsClient.h | 5 ++ 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 examples/WebSocketClientSSL/WebSocketClientSSL.ino diff --git a/examples/WebSocketClient/WebSocketClient.ino b/examples/WebSocketClient/WebSocketClient.ino index 39dcaf0..e68e97c 100644 --- a/examples/WebSocketClient/WebSocketClient.ino +++ b/examples/WebSocketClient/WebSocketClient.ino @@ -32,7 +32,7 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); // send message to server when Connected - webSocket.sendTXT(num, "Connected"); + webSocket.sendTXT("Connected"); } break; case WStype_TEXT: diff --git a/examples/WebSocketClientSSL/WebSocketClientSSL.ino b/examples/WebSocketClientSSL/WebSocketClientSSL.ino new file mode 100644 index 0000000..f4bced1 --- /dev/null +++ b/examples/WebSocketClientSSL/WebSocketClientSSL.ino @@ -0,0 +1,88 @@ +/* + * WebSocketClientSSL.ino + * + * Created on: 10.12.2015 + * + * note SSL is only possible with the ESP8266 + * + */ + +#include + +#include +#include + +#include + +#include + +ESP8266WiFiMulti WiFiMulti; +WebSocketsClient webSocket; + + +#define USE_SERIAL Serial1 + +void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { + + + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[WSc] Disconnected!\n"); + break; + case WStype_CONNECTED: + { + USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); + + // send message to server when Connected + webSocket.sendTXT("Connected"); + } + break; + case WStype_TEXT: + USE_SERIAL.printf("[WSc] get text: %s\n", payload); + + // send message to server + // webSocket.sendTXT("message here"); + break; + case WStype_BIN: + USE_SERIAL.printf("[WSc] get binary lenght: %u\n", lenght); + hexdump(payload, lenght); + + // send data to server + // webSocket.sendBIN(payload, lenght); + break; + } + +} + +void setup() { + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + //Serial.setDebugOutput(true); + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFiMulti.addAP("SSID", "passpasspass"); + + //WiFi.disconnect(); + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + webSocket.beginSSL("192.168.0.123", 81); + webSocket.onEvent(webSocketEvent); + +} + +void loop() { + webSocket.loop(); +} diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 2848893..9d2edeb 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -70,6 +70,17 @@ void WebSocketsClient::begin(String host, uint16_t port, String url) { begin(host.c_str(), port, url.c_str()); } +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +void WebSocketsClient::beginSSL(const char *host, uint16_t port, const char * url) { + begin(host, port, url); + _client.isSSL = true; +} + +void WebSocketsClient::beginSSL(String host, uint16_t port, String url) { + beginSSL(host.c_str(), port, url.c_str()); +} +#endif + /** * called in arduino loop */ diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index f590edc..7e42cc4 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -50,6 +50,11 @@ class WebSocketsClient: private WebSockets { void begin(const char *host, uint16_t port, const char * url = "/"); void begin(String host, uint16_t port, String url = "/"); +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + void beginSSL(const char *host, uint16_t port, const char * url = "/"); + void beginSSL(String host, uint16_t port, String url = "/"); +#endif + void loop(void); void onEvent(WebSocketClientEvent cbEvent); From 83ac64b72b8aafb6c12725221b643548898c9244 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 10 Dec 2015 11:16:08 +0100 Subject: [PATCH 008/347] add support for AVR this need some more testing but basics are done --- README.md | 15 ++- library.properties | 2 +- src/WebSockets.cpp | 13 ++- src/WebSockets.h | 5 +- src/WebSocketsClient.h | 11 --- src/WebSocketsServer.cpp | 25 ++++- src/WebSocketsServer.h | 12 +-- src/libsha1/libsha1.c | 202 +++++++++++++++++++++++++++++++++++++++ src/libsha1/libsha1.h | 21 ++++ 9 files changed, 273 insertions(+), 33 deletions(-) create mode 100644 src/libsha1/libsha1.c create mode 100644 src/libsha1/libsha1.h diff --git a/README.md b/README.md index 29d652b..14dafa3 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ WebSocket Server and Client for Arduino a WebSocket Server and Client for Arduino based on RFC6455. + ##### Supported features of RFC6455 ##### - text frame - binary frame @@ -16,14 +17,18 @@ a WebSocket Server and Client for Arduino based on RFC6455. ##### Limitations ##### - max input length is limited to the ram size and the ```WEBSOCKETS_MAX_DATA_SIZE``` define - max output length has no limit (the hardware is the limit) - - Client send masked frames always with mask 0x00000000 (open todo) + - Client send masked frames always with mask 0x00000000 ##### Supported Hardware ##### - ESP8266 [Arduino for ESP8266](https://github.com/Links2004/Arduino) - - ATmega328 with Ethernet Shield (planed) - - ATmega328 with enc28j60 (planed) - - ATmega2560 with Ethernet Shield (planed) - - ATmega2560 with enc28j60 (planed) + - ATmega328 with Ethernet Shield (alpha) + - ATmega328 with enc28j60 (alpha) + - ATmega2560 with Ethernet Shield (alpha) + - ATmega2560 with enc28j60 (alpha) + +### wss / SSL ### + supported for: + - wss client on the ESP8266 ### Issues ### Submit issues to: https://github.com/Links2004/arduinoWebSockets/issues diff --git a/library.properties b/library.properties index bbdf97c..92613b3 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=1.2 +version=1.3 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 28407f3..0aacaf9 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -38,6 +38,12 @@ extern "C" { #ifdef ESP8266 #include +#else + +extern "C" { +#include "libsha1/libsha1.h" +} + #endif /** @@ -343,8 +349,13 @@ String WebSockets::acceptKey(String clientKey) { #ifdef ESP8266 sha1(clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", &sha1HashBin[0]); #else -#error todo implement sha1 for AVR + clientKey =+ "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + SHA1_CTX ctx; + SHA1Init(&ctx); + SHA1Update(&ctx, (const unsigned char*)clientKey.c_str(), clientKey.length()); + SHA1Final(&sha1HashBin[0], &ctx); #endif + String key = base64_encode(sha1HashBin, 20); key.trim(); diff --git a/src/WebSockets.h b/src/WebSockets.h index 1b34ffc..32f83bb 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -27,7 +27,7 @@ #include -#define DEBUG_WEBSOCKETS(...) Serial1.printf( __VA_ARGS__ ) +//#define DEBUG_WEBSOCKETS(...) Serial1.printf( __VA_ARGS__ ) #ifndef DEBUG_WEBSOCKETS #define DEBUG_WEBSOCKETS(...) @@ -63,17 +63,20 @@ #include #define WEBSOCKETS_NETWORK_CLASS WiFiClient +#define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer #elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_W5100) #include #include #define WEBSOCKETS_NETWORK_CLASS EthernetClient +#define WEBSOCKETS_NETWORK_SERVER_CLASS EthernetServer #elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ENC28J60) #include #define WEBSOCKETS_NETWORK_CLASS UIPClient +#define WEBSOCKETS_NETWORK_SERVER_CLASS UIPServer #else #error "no network type selected!" diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 7e42cc4..588e951 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -26,17 +26,6 @@ #define WEBSOCKETSCLIENT_H_ #include - -#ifdef ESP8266 -#include -#else -#include -#ifndef UIPETHERNET_H -#include -#include -#endif -#endif - #include "WebSockets.h" class WebSocketsClient: private WebSockets { diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index df147d1..5ec4eca 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -27,7 +27,7 @@ WebSocketsServer::WebSocketsServer(uint16_t port) { _port = port; - _server = new WiFiServer(port); + _server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port); _cbEvent = NULL; @@ -240,6 +240,7 @@ void WebSocketsServer::disconnect(uint8_t num) { } } +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) /** * get an IP for a client * @param num uint8_t client id @@ -255,6 +256,7 @@ IPAddress WebSocketsServer::remoteIP(uint8_t num) { return IPAddress(); } +#endif //################################################################################# //################################################################################# @@ -363,7 +365,9 @@ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { */ void WebSocketsServer::handleNewClients(void) { WSclient_t * client; +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) while(_server->hasClient()) { +#endif bool ok = false; // search free list entry for client for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { @@ -371,10 +375,12 @@ void WebSocketsServer::handleNewClients(void) { // state is not connected or tcp connection is lost if(!clientIsConnected(client)) { - +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) // store new connection client->tcp = new WEBSOCKETS_NETWORK_CLASS(_server->available()); - +#else + client->tcp = new WEBSOCKETS_NETWORK_CLASS(_server->available()); +#endif if(!client->tcp) { DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); return; @@ -387,9 +393,12 @@ void WebSocketsServer::handleNewClients(void) { // set Timeout for readBytesUntil and readStringUntil client->tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); client->status = WSC_HEADER; - +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) IPAddress ip = client->tcp->remoteIP(); DEBUG_WEBSOCKETS("[WS-Server][%d] new client from %d.%d.%d.%d\n", client->num, ip[0], ip[1], ip[2], ip[3]); +#else + DEBUG_WEBSOCKETS("[WS-Server][%d] new client\n", client->num); +#endif ok = true; break; } @@ -398,15 +407,21 @@ void WebSocketsServer::handleNewClients(void) { if(!ok) { // no free space to handle client WEBSOCKETS_NETWORK_CLASS tcpClient = _server->available(); - IPAddress ip = tcpClient.remoteIP(); +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + IPAddress ip = client->tcp->remoteIP(); DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); +#else + DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n"); +#endif tcpClient.stop(); } #ifdef ESP8266 delay(0); #endif +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) } +#endif } /** diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index bef170e..ebc76b2 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -68,20 +68,14 @@ class WebSocketsServer: private WebSockets { void disconnect(void); void disconnect(uint8_t num); +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) IPAddress remoteIP(uint8_t num); +#endif protected: uint16_t _port; -#ifdef ESP8266 - WiFiServer * _server; -#else -#ifdef UIPETHERNET_H - UIPServer * _server; -#else - EthernetServer * _server; -#endif -#endif + WEBSOCKETS_NETWORK_SERVER_CLASS * _server; WSclient_t _clients[WEBSOCKETS_SERVER_CLIENT_MAX]; diff --git a/src/libsha1/libsha1.c b/src/libsha1/libsha1.c new file mode 100644 index 0000000..7ff3846 --- /dev/null +++ b/src/libsha1/libsha1.c @@ -0,0 +1,202 @@ +/* from valgrind tests */ + +/* ================ sha1.c ================ */ +/* +SHA-1 in C +By Steve Reid +100% Public Domain + +Test Vectors (from FIPS PUB 180-1) +"abc" + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D +"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 +A million repetitions of "a" + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */ +/* #define SHA1HANDSOFF * Copies data before messing with it. */ + +#ifndef ESP8266 + +#define SHA1HANDSOFF + +#include +#include +#include + +#include "libsha1.h" + + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#if BYTE_ORDER == LITTLE_ENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#elif BYTE_ORDER == BIG_ENDIAN +#define blk0(i) block->l[i] +#else +#error "Endianness not defined!" +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) +{ + uint32_t a, b, c, d, e; + typedef union { + unsigned char c[64]; + uint32_t l[16]; + } CHAR64LONG16; +#ifdef SHA1HANDSOFF + CHAR64LONG16 block[1]; /* use array to appear as a pointer */ + memcpy(block, buffer, 64); +#else + /* The following had better never be used because it causes the + * pointer-to-const buffer to be cast into a pointer to non-const. + * And the result is written through. I threw a "const" in, hoping + * this will cause a diagnostic. + */ + CHAR64LONG16* block = (const CHAR64LONG16*)buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +#ifdef SHA1HANDSOFF + memset(block, '\0', sizeof(block)); +#endif +} + + +/* SHA1Init - Initialize new context */ + +void SHA1Init(SHA1_CTX* context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len) +{ + uint32_t i, j; + + j = context->count[0]; + if ((context->count[0] += len << 3) < j) + context->count[1]++; + context->count[1] += (len>>29); + j = (j >> 3) & 63; + if ((j + len) > 63) { + memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) { + SHA1Transform(context->state, &data[i]); + } + j = 0; + } + else i = 0; + memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* Add padding and return the message digest. */ + +void SHA1Final(unsigned char digest[20], SHA1_CTX* context) +{ + unsigned i; + unsigned char finalcount[8]; + unsigned char c; + +#if 0 /* untested "improvement" by DHR */ + /* Convert context->count to a sequence of bytes + * in finalcount. Second element first, but + * big-endian order within element. + * But we do it all backwards. + */ + unsigned char *fcp = &finalcount[8]; + + for (i = 0; i < 2; i++) + { + uint32_t t = context->count[i]; + int j; + + for (j = 0; j < 4; t >>= 8, j++) + *--fcp = (unsigned char) t; + } +#else + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } +#endif + c = 0200; + SHA1Update(context, &c, 1); + while ((context->count[0] & 504) != 448) { + c = 0000; + SHA1Update(context, &c, 1); + } + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++) { + digest[i] = (unsigned char) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + /* Wipe variables */ + memset(context, '\0', sizeof(*context)); + memset(&finalcount, '\0', sizeof(finalcount)); +} +/* ================ end of sha1.c ================ */ + + +#endif diff --git a/src/libsha1/libsha1.h b/src/libsha1/libsha1.h new file mode 100644 index 0000000..1f08d0e --- /dev/null +++ b/src/libsha1/libsha1.h @@ -0,0 +1,21 @@ +/* ================ sha1.h ================ */ +/* +SHA-1 in C +By Steve Reid +100% Public Domain +*/ + +#ifndef ESP8266 + +typedef struct { + uint32_t state[5]; + uint32_t count[2]; + unsigned char buffer[64]; +} SHA1_CTX; + +void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]); +void SHA1Init(SHA1_CTX* context); +void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); +void SHA1Final(unsigned char digest[20], SHA1_CTX* context); + +#endif \ No newline at end of file From 24eb13cf449e4ee3fc15663248a45f2427bfcb18 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 10 Dec 2015 11:18:28 +0100 Subject: [PATCH 009/347] add WebSocketClientAVR example --- .../WebSocketClientAVR/WebSocketClientAVR.ino | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 examples/WebSocketClientAVR/WebSocketClientAVR.ino diff --git a/examples/WebSocketClientAVR/WebSocketClientAVR.ino b/examples/WebSocketClientAVR/WebSocketClientAVR.ino new file mode 100644 index 0000000..943d893 --- /dev/null +++ b/examples/WebSocketClientAVR/WebSocketClientAVR.ino @@ -0,0 +1,84 @@ +/* + * WebSocketClientAVR.ino + * + * Created on: 10.12.2015 + * + */ + +#include + +#include +#include + +#include + + + +// Enter a MAC address for your controller below. +// Newer Ethernet shields have a MAC address printed on a sticker on the shield +byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; + +// Set the static IP address to use if the DHCP fails to assign +IPAddress ip(192, 168, 0, 177); + +WebSocketsClient webSocket; + + + +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { + + + switch(type) { + case WStype_DISCONNECTED: + Serial.println("[WSc] Disconnected!\n"); + break; + case WStype_CONNECTED: + { + Serial.print("[WSc] Connected to url: "); + Serial.println((char *)payload); + // send message to server when Connected + webSocket.sendTXT("Connected"); + } + break; + case WStype_TEXT: + Serial.print("[WSc] get text: "); + Serial.println((char *)payload); + // send message to server + // webSocket.sendTXT("message here"); + break; + case WStype_BIN: + Serial.print("[WSc] get binary length: "); + Serial.println(length); + // hexdump(payload, length); + + // send data to server + // webSocket.sendBIN(payload, length); + break; + } + +} + +void setup() +{ + // Open serial communications and wait for port to open: + Serial.begin(115200); + while (!Serial) {} + + // start the Ethernet connection: + if (Ethernet.begin(mac) == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // no point in carrying on, so do nothing forevermore: + // try to congifure using IP address instead of DHCP: + Ethernet.begin(mac, ip); + } + + webSocket.begin("192.168.0.123", 8011); + webSocket.onEvent(webSocketEvent); + +} + + +void loop() +{ + webSocket.loop(); +} From 73680279f5b993b24f10f5424287fcaf2f46f506 Mon Sep 17 00:00:00 2001 From: Chris Hinze Date: Thu, 24 Dec 2015 04:47:11 +0100 Subject: [PATCH 010/347] verify ssl certificate fingerprint --- src/WebSockets.h | 1 + src/WebSocketsClient.cpp | 19 +++++++++++++++++++ src/WebSocketsClient.h | 2 ++ 3 files changed, 22 insertions(+) diff --git a/src/WebSockets.h b/src/WebSockets.h index 32f83bb..4defcf6 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -118,6 +118,7 @@ typedef struct { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) bool isSSL; ///< run in ssl mode WiFiClientSecure * ssl; + const char * fingerprint; #endif String cUrl; ///< http url diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 9d2edeb..71536fe 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -47,6 +47,7 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) _client.isSSL = false; _client.ssl = NULL; + _client.fingerprint = NULL; #endif _client.cUrl = url; _client.cCode = 0; @@ -79,6 +80,17 @@ void WebSocketsClient::beginSSL(const char *host, uint16_t port, const char * ur void WebSocketsClient::beginSSL(String host, uint16_t port, String url) { beginSSL(host.c_str(), port, url.c_str()); } + +void WebSocketsClient::beginSSL(const char *host, uint16_t port, const char * url, const char * fingerprint) { + begin(host, port, url); + _client.isSSL = true; + _client.fingerprint = fingerprint; +} + +void WebSocketsClient::beginSSL(String host, uint16_t port, String url, const char * fingerprint) { + beginSSL(host.c_str(), port, url.c_str()); + _client.fingerprint = fingerprint; +} #endif /** @@ -124,6 +136,13 @@ void WebSocketsClient::loop(void) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) _client.tcp->setNoDelay(true); + + if (_client.isSSL && _client.fingerprint != NULL) { + if (!(((WiFiClientSecure*)_client.tcp)->verify(_client.fingerprint, _host.c_str()))) { + DEBUG_WEBSOCKETS("[WS-Client] certificate mismatch\n"); + return; + } + } #endif // send Header to Server diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 588e951..7b5c29a 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -42,6 +42,8 @@ class WebSocketsClient: private WebSockets { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) void beginSSL(const char *host, uint16_t port, const char * url = "/"); void beginSSL(String host, uint16_t port, String url = "/"); + void beginSSL(const char *host, uint16_t port, const char * url, const char * fingerprint); + void beginSSL(String host, uint16_t port, String url, const char * fingerprint); #endif void loop(void); From 07bd5199400032fa3238146eda8b3fabe7bfebab Mon Sep 17 00:00:00 2001 From: Chris Hinze Date: Thu, 24 Dec 2015 04:52:05 +0100 Subject: [PATCH 011/347] disconnect on certificate mismatch --- src/WebSocketsClient.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 71536fe..f045569 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -140,6 +140,7 @@ void WebSocketsClient::loop(void) { if (_client.isSSL && _client.fingerprint != NULL) { if (!(((WiFiClientSecure*)_client.tcp)->verify(_client.fingerprint, _host.c_str()))) { DEBUG_WEBSOCKETS("[WS-Client] certificate mismatch\n"); + WebSockets::clientDisconnect(&_client, 1000); return; } } From 848979ecf0c3ce16b2e968cd30a724eef510861d Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 24 Dec 2015 12:58:05 +0100 Subject: [PATCH 012/347] use String to store fingerprint (const char * can be invalidate based on which scope it coming from) move _fingerprint to Client class only (server not need it) --- src/WebSockets.h | 1 - src/WebSocketsClient.cpp | 24 +++++++----------------- src/WebSocketsClient.h | 9 +++++---- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 4defcf6..32f83bb 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -118,7 +118,6 @@ typedef struct { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) bool isSSL; ///< run in ssl mode WiFiClientSecure * ssl; - const char * fingerprint; #endif String cUrl; ///< http url diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index f045569..a22fd33 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -40,6 +40,7 @@ WebSocketsClient::~WebSocketsClient() { void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) { _host = host; _port = port; + _fingerprint = ""; _client.num = 0; _client.status = WSC_NOT_CONNECTED; @@ -47,7 +48,6 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) _client.isSSL = false; _client.ssl = NULL; - _client.fingerprint = NULL; #endif _client.cUrl = url; _client.cCode = 0; @@ -72,24 +72,14 @@ void WebSocketsClient::begin(String host, uint16_t port, String url) { } #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) -void WebSocketsClient::beginSSL(const char *host, uint16_t port, const char * url) { - begin(host, port, url); - _client.isSSL = true; -} - -void WebSocketsClient::beginSSL(String host, uint16_t port, String url) { - beginSSL(host.c_str(), port, url.c_str()); -} - void WebSocketsClient::beginSSL(const char *host, uint16_t port, const char * url, const char * fingerprint) { begin(host, port, url); _client.isSSL = true; - _client.fingerprint = fingerprint; + _fingerprint = fingerprint; } -void WebSocketsClient::beginSSL(String host, uint16_t port, String url, const char * fingerprint) { - beginSSL(host.c_str(), port, url.c_str()); - _client.fingerprint = fingerprint; +void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String fingerprint) { + beginSSL(host.c_str(), port, url.c_str(), fingerprint.c_str()); } #endif @@ -136,9 +126,9 @@ void WebSocketsClient::loop(void) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) _client.tcp->setNoDelay(true); - - if (_client.isSSL && _client.fingerprint != NULL) { - if (!(((WiFiClientSecure*)_client.tcp)->verify(_client.fingerprint, _host.c_str()))) { + + if(_client.isSSL && _fingerprint.length()) { + if(!_client.ssl->verify(_fingerprint.c_str(), _host.c_str())) { DEBUG_WEBSOCKETS("[WS-Client] certificate mismatch\n"); WebSockets::clientDisconnect(&_client, 1000); return; diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 7b5c29a..6a2c60e 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -40,10 +40,8 @@ class WebSocketsClient: private WebSockets { void begin(String host, uint16_t port, String url = "/"); #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - void beginSSL(const char *host, uint16_t port, const char * url = "/"); - void beginSSL(String host, uint16_t port, String url = "/"); - void beginSSL(const char *host, uint16_t port, const char * url, const char * fingerprint); - void beginSSL(String host, uint16_t port, String url, const char * fingerprint); + void beginSSL(const char *host, uint16_t port, const char * url = "/", const char * = ""); + void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = ""); #endif void loop(void); @@ -65,6 +63,9 @@ class WebSocketsClient: private WebSockets { String _host; uint16_t _port; +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + String _fingerprint; +#endif WSclient_t _client; WebSocketClientEvent _cbEvent; From ff330563096bbd11e69387e102ec0b2d55e75a6e Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 28 Dec 2015 02:52:55 +0100 Subject: [PATCH 013/347] try to send data in one TCP packed if possible, add random mask support for short frames. may helps with #34 --- README.md | 2 +- src/WebSockets.cpp | 72 +++++++++++++++++++++++++++++++++++----------- src/WebSockets.h | 1 + 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 14dafa3..de5c17c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ a WebSocket Server and Client for Arduino based on RFC6455. ##### Limitations ##### - max input length is limited to the ram size and the ```WEBSOCKETS_MAX_DATA_SIZE``` define - max output length has no limit (the hardware is the limit) - - Client send masked frames always with mask 0x00000000 + - Client send masked send big frames with mask 0x00000000 (on AVR all frames) ##### Supported Hardware ##### - ESP8266 [Arduino for ESP8266](https://github.com/Links2004/Arduino) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 0aacaf9..d270af4 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -46,6 +46,8 @@ extern "C" { #endif +#define WEBSOCKETS_MAX_HEADER_SIZE (14) + /** * * @param client WSclient_t * ptr to the client struct @@ -97,11 +99,13 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay DEBUG_WEBSOCKETS("[WS][%d][sendFrame] text: %s\n", client->num, (payload + (headerToPayload ? 14 : 0))); } - uint8_t maskKey[4] = { 0 }; - uint8_t buffer[14] = { 0 }; + uint8_t maskKey[4] = { 0x00, 0x00, 0x00, 0x00 }; + uint8_t buffer[WEBSOCKETS_MAX_HEADER_SIZE] = { 0 }; uint8_t headerSize; uint8_t * headerPtr; + uint8_t * payloadPtr = payload; + bool useInternBuffer = false; // calculate header Size if(length < 126) { @@ -116,10 +120,26 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay headerSize += 4; } + +#ifdef WEBSOCKETS_USE_BIG_MEM + // only for ESP since AVR has less HEAP + // try to send data in one TCP package (only if some free Heap is there) + if(!headerToPayload && ((length > 0) && (length < 1400)) && (ESP.getFreeHeap() > 6000)) { + DEBUG_WEBSOCKETS("[WS][%d][sendFrame] pack to one TCP package...\n", client->num); + uint8_t * dataPtr = (uint8_t *) malloc(length + WEBSOCKETS_MAX_HEADER_SIZE); + if(dataPtr) { + memcpy((dataPtr + WEBSOCKETS_MAX_HEADER_SIZE), payload, length); + headerToPayload = true; + useInternBuffer = true; + payloadPtr = dataPtr; + } + } +#endif + // set Header Pointer if(headerToPayload) { // calculate offset in payload - headerPtr = (payload + (14 - headerSize)); + headerPtr = (payloadPtr + (WEBSOCKETS_MAX_HEADER_SIZE - headerSize)); } else { headerPtr = &buffer[0]; } @@ -160,33 +180,53 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay } if(mask) { - // todo generate random mask key - for(uint8_t x = 0; x < sizeof(maskKey); x++) { - // maskKey[x] = random(0xFF); - maskKey[x] = 0x00; // fake xor (0x00 0x00 0x00 0x00) - *headerPtr = maskKey[x]; headerPtr++; - } + if(useInternBuffer) { + for(uint8_t x = 0; x < sizeof(maskKey); x++) { + maskKey[x] = random(0xFF); + *headerPtr = maskKey[x]; headerPtr++; + } - // todo encode XOR (note: using payload not working for static content from flash) - //for(size_t x = 0; x < length; x++) { - // payload[x] = (payload[x] ^ maskKey[x % 4]); - //} + uint8_t * dataMaskPtr; + + if(headerToPayload) { + dataMaskPtr = (payloadPtr + WEBSOCKETS_MAX_HEADER_SIZE); + } else { + dataMaskPtr = payloadPtr; + } + + for(size_t x = 0; x < length; x++) { + dataMaskPtr[x] = (dataMaskPtr[x] ^ maskKey[x % 4]); + } + + } else { + *headerPtr = maskKey[0]; headerPtr++; + *headerPtr = maskKey[1]; headerPtr++; + *headerPtr = maskKey[2]; headerPtr++; + *headerPtr = maskKey[3]; headerPtr++; + } } if(headerToPayload) { // header has be added to payload // payload is forced to reserved 14 Byte but we may not need all based on the length and mask settings // offset in payload is calculatetd 14 - headerSize - client->tcp->write(&payload[(14 - headerSize)], (length + headerSize)); + client->tcp->write(&payloadPtr[(WEBSOCKETS_MAX_HEADER_SIZE - headerSize)], (length + headerSize)); } else { // send header client->tcp->write(&buffer[0], headerSize); - if(payload && length > 0) { + if(payloadPtr && length > 0) { // send payload - client->tcp->write(&payload[0], length); + client->tcp->write(&payloadPtr[0], length); } } + +#ifdef WEBSOCKETS_USE_BIG_MEM + if(useInternBuffer && payloadPtr) { + free(payloadPtr); + } +#endif + } /** diff --git a/src/WebSockets.h b/src/WebSockets.h index 32f83bb..002f141 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -35,6 +35,7 @@ #ifdef ESP8266 #define WEBSOCKETS_MAX_DATA_SIZE (15*1024) +#define WEBSOCKETS_USE_BIG_MEM #else //atmega328p has only 2KB ram! #define WEBSOCKETS_MAX_DATA_SIZE (1024) From b24f021d337bd7b4cf8c47bdc47ad853172f5837 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 28 Dec 2015 03:25:01 +0100 Subject: [PATCH 014/347] update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index de5c17c..2cca85f 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ a WebSocket Server and Client for Arduino based on RFC6455. ##### Limitations ##### - max input length is limited to the ram size and the ```WEBSOCKETS_MAX_DATA_SIZE``` define - max output length has no limit (the hardware is the limit) - - Client send masked send big frames with mask 0x00000000 (on AVR all frames) + - Client send big frames with mask 0x00000000 (on AVR all frames) ##### Supported Hardware ##### - ESP8266 [Arduino for ESP8266](https://github.com/Links2004/Arduino) From 21e092d179c79d00b4ff53544b94624c597ee8a2 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 28 Dec 2015 16:33:54 +0100 Subject: [PATCH 015/347] code cleanup improve readWait error handling --- src/WebSockets.cpp | 21 +++++++++++++++++---- src/WebSockets.h | 1 + src/WebSocketsClient.cpp | 4 +++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index d270af4..95809d3 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -151,7 +151,7 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay if(fin) { *headerPtr |= bit(7); ///< set Fin } - *headerPtr |= opcode; ///< set opcode + *headerPtr |= opcode; ///< set opcode headerPtr++; // byte 1 @@ -167,7 +167,7 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay *headerPtr = ((length >> 8) & 0xFF); headerPtr++; *headerPtr = (length & 0xFF); headerPtr++; } else { - // normaly we never get here (to less memory) + // Normally we never get here (to less memory) *headerPtr |= 127; headerPtr++; *headerPtr = 0x00; headerPtr++; *headerPtr = 0x00; headerPtr++; @@ -181,6 +181,8 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay if(mask) { if(useInternBuffer) { + // if we use a Intern Buffer we can modify the data + // by this fact its possible the do the masking for(uint8_t x = 0; x < sizeof(maskKey); x++) { maskKey[x] = random(0xFF); *headerPtr = maskKey[x]; headerPtr++; @@ -206,6 +208,10 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay } } +#ifndef NODEBUG_WEBSOCKETS + unsigned long start = micros(); +#endif + if(headerToPayload) { // header has be added to payload // payload is forced to reserved 14 Byte but we may not need all based on the length and mask settings @@ -221,6 +227,8 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay } } + DEBUG_WEBSOCKETS("[WS][%d][sendFrame] sending Frame Done (%uus).\n", client->num, (micros() - start)); + #ifdef WEBSOCKETS_USE_BIG_MEM if(useInternBuffer && payloadPtr) { free(payloadPtr); @@ -275,7 +283,7 @@ void WebSockets::handleWebsocket(WSclient_t * client) { } payloadLen = buffer[0] << 8 | buffer[1]; } else if(payloadLen == 127) { - // read 64bit inteager as length + // read 64bit integer as length if(!readWait(client, buffer, 8)) { //timeout clientDisconnect(client, 1002); @@ -436,7 +444,12 @@ bool WebSockets::readWait(WSclient_t * client, uint8_t *out, size_t n) { size_t len; while(n > 0) { - if(client->tcp && !client->tcp->connected()) { + if(!client->tcp) { + DEBUG_WEBSOCKETS("[readWait] tcp is null!\n"); + return false; + } + + if(!client->tcp->connected()) { DEBUG_WEBSOCKETS("[readWait] not connected!\n"); return false; } diff --git a/src/WebSockets.h b/src/WebSockets.h index 002f141..ffccf80 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -31,6 +31,7 @@ #ifndef DEBUG_WEBSOCKETS #define DEBUG_WEBSOCKETS(...) +#define NODEBUG_WEBSOCKETS #endif #ifdef ESP8266 diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index a22fd33..3a0a039 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -356,7 +356,9 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { client->cKey = base64_encode(&randomKey[0], 16); +#ifndef NODEBUG_WEBSOCKETS unsigned long start = micros(); +#endif String handshake = "GET " + client->cUrl + " HTTP/1.1\r\n" "Host: " + _host + "\r\n" @@ -448,7 +450,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client) { default: ///< Server dont unterstand requrst ok = false; DEBUG_WEBSOCKETS("[WS-Client][handleHeader] serverCode is not 101 (%d)\n", client->cCode); - clientDisconnect(&_client); + clientDisconnect(client); break; } } From 5f9e30e90887c2fefda0a95c863702c14832f7f1 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 29 Dec 2015 00:45:20 +0200 Subject: [PATCH 016/347] @PlatformIO Library Registry manifest file * This library in Web Registry: http://platformio.org/#!/lib/show/549/WebSockets * Specification: [library.json](http://docs.platformio.org/en/latest/librarymanager/config.html) * Library Manager: http://docs.platformio.org/en/latest/librarymanager/index.html --- library.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 library.json diff --git a/library.json b/library.json new file mode 100644 index 0000000..4583a35 --- /dev/null +++ b/library.json @@ -0,0 +1,13 @@ +{ + "name": "WebSockets", + "keywords": "wifi, http, web, server, websocket", + "description": "WebSocket Server and Client for Arduino based on RFC6455", + "repository": + { + "type": "git", + "url": "https://github.com/Links2004/arduinoWebSockets.git" + }, + "exclude": "tests", + "frameworks": "arduino", + "platforms": "*" +} From ccbef0fced31e3683c41189b9e18463bd678d172 Mon Sep 17 00:00:00 2001 From: Markus Date: Tue, 29 Dec 2015 12:15:18 +0100 Subject: [PATCH 017/347] Update library.json --- library.json | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index 4583a35..14bae5d 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "WebSockets", - "keywords": "wifi, http, web, server, websocket", + "keywords": "wifi, http, web, server, client, websocket", "description": "WebSocket Server and Client for Arduino based on RFC6455", "repository": { @@ -9,5 +9,11 @@ }, "exclude": "tests", "frameworks": "arduino", - "platforms": "*" + "platforms": "*", + "authors": + { + "name": "Markus Sattler", + "url": "https://github.com/Links2004", + "maintainer": true + } } From 21e959c013425e7e281276eda000f99915e3b300 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 7 Jan 2016 01:21:09 +0100 Subject: [PATCH 018/347] fix #38 --- src/WebSockets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 95809d3..4ec9a1f 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -397,7 +397,7 @@ String WebSockets::acceptKey(String clientKey) { #ifdef ESP8266 sha1(clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", &sha1HashBin[0]); #else - clientKey =+ "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + clientKey += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; SHA1_CTX ctx; SHA1Init(&ctx); SHA1Update(&ctx, (const unsigned char*)clientKey.c_str(), clientKey.length()); From cf7652a371e5bc2b85b8c3976ada4a8d0819c8f1 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 11 Jan 2016 10:37:27 +0100 Subject: [PATCH 019/347] allow usage of std::bind for Event callback --- src/WebSocketsClient.h | 2 +- src/WebSocketsServer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 6a2c60e..589a0d7 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -31,7 +31,7 @@ class WebSocketsClient: private WebSockets { public: - typedef void (*WebSocketClientEvent)(WStype_t type, uint8_t * payload, size_t length); + typedef std::function WebSocketClientEvent; WebSocketsClient(void); ~WebSocketsClient(void); diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index ebc76b2..e7c00e6 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -36,7 +36,7 @@ class WebSocketsServer: private WebSockets { public: - typedef void (*WebSocketServerEvent)(uint8_t num, WStype_t type, uint8_t * payload, size_t length); + typedef std::function WebSocketServerEvent; WebSocketsServer(uint16_t port); ~WebSocketsServer(void); From ece771a27548f0425ea7d703eb4f78f8b1b5802a Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Thu, 14 Jan 2016 17:28:00 +0100 Subject: [PATCH 020/347] add support for setting: - Access-Control-Allow-Origin (#25) - Sec-WebSocket-Protocol () add _server->close(); for ESP --- src/WebSocketsServer.cpp | 26 ++++++++++++++++++++++---- src/WebSocketsServer.h | 4 +++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 5ec4eca..1dfcdcd 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -25,8 +25,11 @@ #include "WebSockets.h" #include "WebSocketsServer.h" -WebSocketsServer::WebSocketsServer(uint16_t port) { +WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol) { _port = port; + _origin = origin; + _protocol = protocol; + _server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port); _cbEvent = NULL; @@ -37,7 +40,12 @@ WebSocketsServer::~WebSocketsServer() { // disconnect all clients disconnect(); +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + _server->close(); +#else // TODO how to close server? +#endif + } /** @@ -540,11 +548,21 @@ void WebSocketsServer::handleHeader(WSclient_t * client) { "Sec-WebSocket-Version: 13\r\n" "Sec-WebSocket-Accept: "); client->tcp->write(sKey.c_str(), sKey.length()); - client->tcp->write("\r\n"); + + if(_origin.length() > 0) { + String origin = "\r\nAccess-Control-Allow-Origin: "; + origin += _origin; + origin += "\r\n"; + client->tcp->write(origin.c_str(), origin.length()); + } if(client->cProtocol.length() > 0) { - // TODO add api to set Protocol of Server - client->tcp->write("Sec-WebSocket-Protocol: arduino\r\n"); + String protocol = "\r\nSec-WebSocket-Protocol: "; + protocol += _protocol; + protocol += "\r\n"; + client->tcp->write(protocol.c_str(), protocol.length()); + } else { + client->tcp->write("\r\n"); } // header end diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index e7c00e6..a4155da 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -38,7 +38,7 @@ class WebSocketsServer: private WebSockets { typedef std::function WebSocketServerEvent; - WebSocketsServer(uint16_t port); + WebSocketsServer(uint16_t port, String origin = "", String protocol = "arduino"); ~WebSocketsServer(void); void begin(void); @@ -74,6 +74,8 @@ class WebSocketsServer: private WebSockets { protected: uint16_t _port; + String _origin; + String _protocol; WEBSOCKETS_NETWORK_SERVER_CLASS * _server; From 3e0b0bd377c56117716c162773ae9cbc53bb066b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Tib=C3=A9rio?= Date: Wed, 20 Jan 2016 23:41:03 +0000 Subject: [PATCH 021/347] updated with upstream, added subprotocol to client --- src/WebSockets.h | 2 +- src/WebSocketsClient.cpp | 10 +++++----- src/WebSocketsClient.h | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index ffccf80..31a7db5 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -27,7 +27,7 @@ #include -//#define DEBUG_WEBSOCKETS(...) Serial1.printf( __VA_ARGS__ ) +//#define DEBUG_WEBSOCKETS(...) Serial.printf( __VA_ARGS__ ) #ifndef DEBUG_WEBSOCKETS #define DEBUG_WEBSOCKETS(...) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 3a0a039..05d3755 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -37,7 +37,7 @@ WebSocketsClient::~WebSocketsClient() { /** * calles to init the Websockets server */ -void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) { +void WebSocketsClient::begin(const char *host, uint16_t port, const char * url, const char * Protocol) { _host = host; _port = port; _fingerprint = ""; @@ -55,7 +55,7 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) _client.cIsWebsocket = true; _client.cKey = ""; _client.cAccept = ""; - _client.cProtocol = ""; + _client.cProtocol = Protocol; _client.cExtensions = ""; _client.cVersion = 0; @@ -67,8 +67,8 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) #endif } -void WebSocketsClient::begin(String host, uint16_t port, String url) { - begin(host.c_str(), port, url.c_str()); +void WebSocketsClient::begin(String host, uint16_t port, String url, String Protocol) { + begin(host.c_str(), port, url.c_str(), Protocol.c_str()); } #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) @@ -366,7 +366,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { "Connection: Upgrade\r\n" "User-Agent: arduino-WebSocket-Client\r\n" "Sec-WebSocket-Version: 13\r\n" - "Sec-WebSocket-Protocol: arduino\r\n" + "Sec-WebSocket-Protocol:" + client->cProtocol +"\r\n" "Sec-WebSocket-Key: " + client->cKey + "\r\n"; if(client->cExtensions.length() > 0) { diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 589a0d7..2ba2e49 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -36,8 +36,8 @@ class WebSocketsClient: private WebSockets { WebSocketsClient(void); ~WebSocketsClient(void); - void begin(const char *host, uint16_t port, const char * url = "/"); - void begin(String host, uint16_t port, String url = "/"); + void begin(const char *host, uint16_t port, const char * url = "/", const char * Protocol = "arduino"); + void begin(String host, uint16_t port, String url = "/", String Protocol = "arduino"); #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) void beginSSL(const char *host, uint16_t port, const char * url = "/", const char * = ""); From 57e30e06341ef2cff1ee3df16599f2c4cf5cd3f2 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 23 Jan 2016 16:27:02 +0100 Subject: [PATCH 022/347] First steps to do async --- src/WebSockets.cpp | 333 +++++++++++++++++++++------------ src/WebSockets.h | 67 ++++++- src/WebSocketsClient.cpp | 59 ++++-- src/WebSocketsClient.h | 5 +- src/WebSocketsServer.cpp | 160 ++++++++++------ src/WebSocketsServer.h | 9 +- tests/webSocket.html | 6 +- tests/webSocketServer/index.js | 4 +- 8 files changed, 436 insertions(+), 207 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 4ec9a1f..d45748e 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -30,9 +30,9 @@ extern "C" { #ifdef CORE_HAS_LIBB64 - #include +#include #else - #include "libb64/cencode_inc.h" +#include "libb64/cencode_inc.h" #endif } @@ -46,8 +46,6 @@ extern "C" { #endif -#define WEBSOCKETS_MAX_HEADER_SIZE (14) - /** * * @param client WSclient_t * ptr to the client struct @@ -120,7 +118,6 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay headerSize += 4; } - #ifdef WEBSOCKETS_USE_BIG_MEM // only for ESP since AVR has less HEAP // try to send data in one TCP package (only if some free Heap is there) @@ -161,22 +158,35 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay } if(length < 126) { - *headerPtr |= length; headerPtr++; + *headerPtr |= length; + headerPtr++; } else if(length < 0xFFFF) { - *headerPtr |= 126; headerPtr++; - *headerPtr = ((length >> 8) & 0xFF); headerPtr++; - *headerPtr = (length & 0xFF); headerPtr++; + *headerPtr |= 126; + headerPtr++; + *headerPtr = ((length >> 8) & 0xFF); + headerPtr++; + *headerPtr = (length & 0xFF); + headerPtr++; } else { // Normally we never get here (to less memory) - *headerPtr |= 127; headerPtr++; - *headerPtr = 0x00; headerPtr++; - *headerPtr = 0x00; headerPtr++; - *headerPtr = 0x00; headerPtr++; - *headerPtr = 0x00; headerPtr++; - *headerPtr = ((length >> 24) & 0xFF); headerPtr++; - *headerPtr = ((length >> 16) & 0xFF); headerPtr++; - *headerPtr = ((length >> 8) & 0xFF); headerPtr++; - *headerPtr = (length & 0xFF); headerPtr++; + *headerPtr |= 127; + headerPtr++; + *headerPtr = 0x00; + headerPtr++; + *headerPtr = 0x00; + headerPtr++; + *headerPtr = 0x00; + headerPtr++; + *headerPtr = 0x00; + headerPtr++; + *headerPtr = ((length >> 24) & 0xFF); + headerPtr++; + *headerPtr = ((length >> 16) & 0xFF); + headerPtr++; + *headerPtr = ((length >> 8) & 0xFF); + headerPtr++; + *headerPtr = (length & 0xFF); + headerPtr++; } if(mask) { @@ -185,7 +195,8 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay // by this fact its possible the do the masking for(uint8_t x = 0; x < sizeof(maskKey); x++) { maskKey[x] = random(0xFF); - *headerPtr = maskKey[x]; headerPtr++; + *headerPtr = maskKey[x]; + headerPtr++; } uint8_t * dataMaskPtr; @@ -201,10 +212,14 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay } } else { - *headerPtr = maskKey[0]; headerPtr++; - *headerPtr = maskKey[1]; headerPtr++; - *headerPtr = maskKey[2]; headerPtr++; - *headerPtr = maskKey[3]; headerPtr++; + *headerPtr = maskKey[0]; + headerPtr++; + *headerPtr = maskKey[1]; + headerPtr++; + *headerPtr = maskKey[2]; + headerPtr++; + *headerPtr = maskKey[3]; + headerPtr++; } } @@ -237,154 +252,211 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay } +/** + * callen when HTTP header is done + * @param client WSclient_t * ptr to the client struct + */ +void WebSockets::headerDone(WSclient_t * client) { + client->status = WSC_CONNECTED; + client->cWsRXsize = 0; + DEBUG_WEBSOCKETS("[WS][%d][headerDone] Header Handling Done (%uus).\n", client->num); +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + client->cHttpLine = ""; + handleWebsocket(client); +#endif +} + /** * handle the WebSocket stream * @param client WSclient_t * ptr to the client struct */ void WebSockets::handleWebsocket(WSclient_t * client) { + if(client->cWsRXsize == 0) { + handleWebsocketCb(client); + } +} + +/** + * wait for + * @param client + * @param size + */ +bool WebSockets::handleWebsocketWaitFor(WSclient_t * client, size_t size) { + if(size > WEBSOCKETS_MAX_HEADER_SIZE) { + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocketWaitFor] size: %d to big!\n", client->num, size); + return false; + } - uint8_t buffer[8] = { 0 }; + if(client->cWsRXsize >= size) { + return true; + } - bool fin; - bool rsv1; - bool rsv2; - bool rsv3; - WSopcode_t opCode; - bool mask; - size_t payloadLen; + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocketWaitFor] size: %d cWsRXsize: %d\n", client->num, size, client->cWsRXsize); + readCb(client, &client->cWsHeader[client->cWsRXsize], (size - client->cWsRXsize), std::bind([](WebSockets * server, size_t size, WSclient_t * client, bool ok) { + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocketWaitFor][readCb] size: %d ok: %d\n", client->num, size, ok); + if(ok) { + client->cWsRXsize = size; + server->handleWebsocketCb(client); + } else { + DEBUG_WEBSOCKETS("[WS][%d][readCb] failed.\n", client->num); + client->cWsRXsize = 0; + // timeout or error + server->clientDisconnect(client, 1002); + } + }, this, size, std::placeholders::_1, std::placeholders::_2)); + return false; +} - uint8_t maskKey[4]; +void WebSockets::handleWebsocketCb(WSclient_t * client) { + uint8_t * buffer = client->cWsHeader; + + WSMessageHeader_t * header = &client->cWsHeaderDecode; uint8_t * payload = NULL; - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] ------- read massage frame -------\n", client->num); + uint8_t headerLen = 2; - if(!readWait(client, buffer, 2)) { - //timeout - clientDisconnect(client, 1002); + if(!handleWebsocketWaitFor(client, headerLen)) { return; } // split first 2 bytes in the data - fin = ((buffer[0] >> 7) & 0x01); - rsv1 = ((buffer[0] >> 6) & 0x01); - rsv2 = ((buffer[0] >> 5) & 0x01); - rsv3 = ((buffer[0] >> 4) & 0x01); - opCode = (WSopcode_t) (buffer[0] & 0x0F); - - mask = ((buffer[1] >> 7) & 0x01); - payloadLen = (WSopcode_t) (buffer[1] & 0x7F); - - if(payloadLen == 126) { - if(!readWait(client, buffer, 2)) { - //timeout - clientDisconnect(client, 1002); + header->fin = ((*buffer >> 7) & 0x01); + header->rsv1 = ((*buffer >> 6) & 0x01); + header->rsv2 = ((*buffer >> 5) & 0x01); + header->rsv3 = ((*buffer >> 4) & 0x01); + header->opCode = (WSopcode_t) (*buffer & 0x0F); + buffer++; + + header->mask = ((*buffer >> 7) & 0x01); + header->payloadLen = (WSopcode_t) (*buffer & 0x7F); + buffer++; + + if(header->payloadLen == 126) { + headerLen += 4; + if(!handleWebsocketWaitFor(client, headerLen)) { return; } - payloadLen = buffer[0] << 8 | buffer[1]; - } else if(payloadLen == 127) { + header->payloadLen = buffer[0] << 8 | buffer[1]; + buffer += 2; + } else if(header->payloadLen == 127) { + headerLen += 8; // read 64bit integer as length - if(!readWait(client, buffer, 8)) { - //timeout - clientDisconnect(client, 1002); + if(!handleWebsocketWaitFor(client, headerLen)) { return; } if(buffer[0] != 0 || buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0) { // really to big! - payloadLen = 0xFFFFFFFF; + header->payloadLen = 0xFFFFFFFF; } else { - payloadLen = buffer[4] << 24 | buffer[5] << 16 | buffer[6] << 8 | buffer[7]; + header->payloadLen = buffer[4] << 24 | buffer[5] << 16 | buffer[6] << 8 | buffer[7]; } + buffer += 8; } - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] fin: %u rsv1: %u rsv2: %u rsv3 %u opCode: %u\n", client->num, fin, rsv1, rsv2, rsv3, opCode); - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] mask: %u payloadLen: %u\n", client->num, mask, payloadLen); + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] ------- read massage frame -------\n", client->num); + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] fin: %u rsv1: %u rsv2: %u rsv3 %u opCode: %u\n", client->num, header->fin, header->rsv1, header->rsv2, header->rsv3, header->opCode); + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] mask: %u payloadLen: %u\n", client->num, header->mask, header->payloadLen); - if(payloadLen > WEBSOCKETS_MAX_DATA_SIZE) { - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] payload to big! (%u)\n", client->num, payloadLen); + if(header->payloadLen > WEBSOCKETS_MAX_DATA_SIZE) { + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] payload to big! (%u)\n", client->num, header->payloadLen); clientDisconnect(client, 1009); return; } - if(mask) { - if(!readWait(client, maskKey, 4)) { - //timeout - clientDisconnect(client, 1002); + if(header->mask) { + headerLen += 4; + if(!handleWebsocketWaitFor(client, headerLen)) { return; } + header->maskKey = buffer; + buffer += 4; } - if(payloadLen > 0) { + if(header->payloadLen > 0) { // if text data we need one more - payload = (uint8_t *) malloc(payloadLen + 1); + payload = (uint8_t *) malloc(header->payloadLen + 1); if(!payload) { - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] to less memory to handle payload %d!\n", client->num, payloadLen); + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] to less memory to handle payload %d!\n", client->num, header->payloadLen); clientDisconnect(client, 1011); return; } + readCb(client, payload, header->payloadLen, std::bind(&WebSockets::handleWebsocketPayloadCb, this, std::placeholders::_1, std::placeholders::_2, payload)); + } else { + handleWebsocketPayloadCb(client, true, NULL); + } +} - if(!readWait(client, payload, payloadLen)) { - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] missing data!\n", client->num); - free(payload); - clientDisconnect(client, 1002); - return; - } - - payload[payloadLen] = 0x00; +void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload) { + WSMessageHeader_t * header = &client->cWsHeaderDecode; + if(ok) { + if(header->payloadLen > 0) { + payload[header->payloadLen] = 0x00; - if(mask) { - //decode XOR - for(size_t i = 0; i < payloadLen; i++) { - payload[i] = (payload[i] ^ maskKey[i % 4]); + if(header->mask) { + //decode XOR + for(size_t i = 0; i < header->payloadLen; i++) { + payload[i] = (payload[i] ^ header->maskKey[i % 4]); + } } } - } - switch(opCode) { - case WSop_text: - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] text: %s\n", client->num, payload); - // no break here! - case WSop_binary: - messageRecived(client, opCode, payload, payloadLen); - break; - case WSop_ping: - // send pong back - sendFrame(client, WSop_pong, payload, payloadLen); - break; - case WSop_pong: - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload); - break; - case WSop_close: - { + switch(header->opCode) { + case WSop_text: + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] text: %s\n", client->num, payload); + // no break here! + case WSop_binary: + messageRecived(client, header->opCode, payload, header->payloadLen); + break; + case WSop_ping: + // send pong back + sendFrame(client, WSop_pong, payload, header->payloadLen); + break; + case WSop_pong: + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload); + break; + case WSop_close: { uint16_t reasonCode = 1000; - if(payloadLen >= 2) { + if(header->payloadLen >= 2) { reasonCode = payload[0] << 8 | payload[1]; } DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get ask for close. Code: %d", client->num, reasonCode); - if(payloadLen > 2) { - DEBUG_WEBSOCKETS(" (%s)\n", (payload+2)); + if(header->payloadLen > 2) { + DEBUG_WEBSOCKETS(" (%s)\n", (payload + 2)); } else { DEBUG_WEBSOCKETS("\n"); } clientDisconnect(client, 1000); } - break; - case WSop_continuation: - // continuation is not supported - clientDisconnect(client, 1003); - break; - default: - clientDisconnect(client, 1002); - break; - } + break; + case WSop_continuation: + // continuation is not supported + clientDisconnect(client, 1003); + break; + default: + clientDisconnect(client, 1002); + break; + } + + if(payload) { + free(payload); + } + + // reset input + client->cWsRXsize = 0; +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + //register callback for next message + handleWebsocketWaitFor(client, 2); +#endif - if(payload) { + } else { + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] missing data!\n", client->num); free(payload); + clientDisconnect(client, 1002); } - } /** @@ -417,7 +489,7 @@ String WebSockets::acceptKey(String clientKey) { * @return base64 encoded String */ String WebSockets::base64_encode(uint8_t * data, size_t length) { - size_t size = ((length*1.6f)+1); + size_t size = ((length * 1.6f) + 1); char * buffer = (char *) malloc(size); if(buffer) { base64_encodestate _state; @@ -439,28 +511,46 @@ String WebSockets::base64_encode(uint8_t * data, size_t length) { * @param n size_t byte count * @return true if ok */ -bool WebSockets::readWait(WSclient_t * client, uint8_t *out, size_t n) { +bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWaitCb cb) { +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + + client->tcp->readBytes(out, n, std::bind([](WSclient_t * client, bool ok, WSreadWaitCb cb) { + if(cb) { + cb(client, ok); + } + }, client, std::placeholders::_1, cb)); + +#else unsigned long t = millis(); size_t len; - + DEBUG_WEBSOCKETS("[readCb] n: %d t: %d\n", n, t); while(n > 0) { - if(!client->tcp) { - DEBUG_WEBSOCKETS("[readWait] tcp is null!\n"); + if(client->tcp == NULL) { + DEBUG_WEBSOCKETS("[readCb] tcp is null!\n"); + if(cb) { + cb(client, false); + } return false; } if(!client->tcp->connected()) { - DEBUG_WEBSOCKETS("[readWait] not connected!\n"); + DEBUG_WEBSOCKETS("[readCb] not connected!\n"); + if(cb) { + cb(client, false); + } return false; } if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) { - DEBUG_WEBSOCKETS("[readWait] receive TIMEOUT!\n"); + DEBUG_WEBSOCKETS("[readCb] receive TIMEOUT! %d\n", (millis() - t)); + if(cb) { + cb(client, false); + } return false; } if(!client->tcp->available()) { -#ifdef ESP8266 +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif continue; @@ -475,9 +565,14 @@ bool WebSockets::readWait(WSclient_t * client, uint8_t *out, size_t n) { } else { //DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n); } -#ifdef ESP8266 +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } + if(cb) { + cb(client, true); + } +#endif return true; } + diff --git a/src/WebSockets.h b/src/WebSockets.h index ffccf80..96cf09c 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -27,7 +27,7 @@ #include -//#define DEBUG_WEBSOCKETS(...) Serial1.printf( __VA_ARGS__ ) +//#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) #ifndef DEBUG_WEBSOCKETS #define DEBUG_WEBSOCKETS(...) @@ -44,20 +44,39 @@ #define WEBSOCKETS_TCP_TIMEOUT (1500) -#define NETWORK_ESP8266 (1) -#define NETWORK_W5100 (2) -#define NETWORK_ENC28J60 (3) +#define NETWORK_ESP8266_ASYNC (0) +#define NETWORK_ESP8266 (1) +#define NETWORK_W5100 (2) +#define NETWORK_ENC28J60 (3) +// max size of the WS Message Header +#define WEBSOCKETS_MAX_HEADER_SIZE (14) // select Network type based #ifdef ESP8266 -#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 +//#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 +#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC #else #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 #endif +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +// Note: +// No SSL/WSS support for client in Async mode +// TLS lib need a sync interface! + +#ifndef ESP8266 +#error "network type ESP8266 ASYNC only possible on the ESP mcu!" +#endif + +#include +#include +#include +#define WEBSOCKETS_NETWORK_CLASS AsyncTCPbuffer +#define WEBSOCKETS_NETWORK_SERVER_CLASS AsyncServer + +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) #ifndef ESP8266 #error "network type ESP8266 only possible on the ESP mcu!" @@ -110,6 +129,21 @@ typedef enum { ///< %xB-F are reserved for further control frames } WSopcode_t; +typedef struct { + + bool fin; + bool rsv1; + bool rsv2; + bool rsv3; + + WSopcode_t opCode; + bool mask; + + size_t payloadLen; + + uint8_t * maskKey; +} WSMessageHeader_t; + typedef struct { uint8_t num; ///< connection number @@ -134,10 +168,23 @@ typedef struct { String cExtensions; ///< client Sec-WebSocket-Extensions uint16_t cVersion; ///< client Sec-WebSocket-Version + uint8_t cWsRXsize; ///< State of the RX + uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer + WSMessageHeader_t cWsHeaderDecode; + +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + String cHttpLine; ///< HTTP header lines +#endif + } WSclient_t; + + class WebSockets { protected: + + typedef std::function WSreadWaitCb; + virtual void clientDisconnect(WSclient_t * client); virtual bool clientIsConnected(WSclient_t * client); @@ -146,14 +193,20 @@ class WebSockets { void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0); void sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false, bool fin = true, bool headerToPayload = false); + void headerDone(WSclient_t * client); void handleWebsocket(WSclient_t * client); - bool readWait(WSclient_t * client, uint8_t *out, size_t n); + bool handleWebsocketWaitFor(WSclient_t * client, size_t size); + void handleWebsocketCb(WSclient_t * client); + void handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload); String acceptKey(String clientKey); String base64_encode(uint8_t * data, size_t length); + bool readCb(WSclient_t * client, uint8_t *out, size_t n, WSreadWaitCb cb); + + }; #endif /* WEBSOCKETS_H_ */ diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 3a0a039..0351012 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -40,7 +40,9 @@ WebSocketsClient::~WebSocketsClient() { void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) { _host = host; _port = port; +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) _fingerprint = ""; +#endif _client.num = 0; _client.status = WSC_NOT_CONNECTED; @@ -141,10 +143,12 @@ void WebSocketsClient::loop(void) { } else { DEBUG_WEBSOCKETS("[WS-Client] connection to %s:%u Faild\n", _host.c_str(), _port); - delay(10); //some litle delay to not flood the server + delay(10); //some little delay to not flood the server } } else { +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) handleClientData(); +#endif } } @@ -248,12 +252,15 @@ void WebSocketsClient::messageRecived(WSclient_t * client, WSopcode_t opcode, ui */ void WebSocketsClient::clientDisconnect(WSclient_t * client) { + bool event = false; + #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) if(client->isSSL && client->ssl) { if(client->ssl->connected()) { client->ssl->flush(); client->ssl->stop(); } + event = true; delete client->ssl; client->ssl = NULL; client->tcp = NULL; @@ -265,6 +272,7 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { client->tcp->flush(); client->tcp->stop(); } + event = true; delete client->tcp; client->tcp = NULL; } @@ -280,9 +288,9 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { client->status = WSC_NOT_CONNECTED; DEBUG_WEBSOCKETS("[WS-Client] client disconnected.\n"); - - runCbEvent(WStype_DISCONNECTED, NULL, 0); - + if(event) { + runCbEvent(WStype_DISCONNECTED, NULL, 0); + } } /** @@ -316,7 +324,7 @@ bool WebSocketsClient::clientIsConnected(WSclient_t * client) { return false; } - +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * Handel incomming data from Client */ @@ -325,7 +333,10 @@ void WebSocketsClient::handleClientData(void) { if(len > 0) { switch(_client.status) { case WSC_HEADER: - handleHeader(&_client); + { + String headerLine = _client->tcp->readStringUntil('\n'); + handleHeader(&_client, &headerLine); + } break; case WSC_CONNECTED: WebSockets::handleWebsocket(&_client); @@ -335,10 +346,11 @@ void WebSocketsClient::handleClientData(void) { break; } } -#ifdef ESP8266 +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } +#endif /** * send the WebSocket header to Server @@ -377,6 +389,10 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { client->tcp->write(handshake.c_str(), handshake.length()); +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine))); +#endif + DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header... Done (%uus).\n", (micros() - start)); } @@ -385,20 +401,19 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { * handle the WebSocket header reading * @param client WSclient_t * ptr to the client struct */ -void WebSocketsClient::handleHeader(WSclient_t * client) { +void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { - String headerLine = client->tcp->readStringUntil('\n'); - headerLine.trim(); // remove \r + headerLine->trim(); // remove \r - if(headerLine.length() > 0) { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine.c_str()); + if(headerLine->length() > 0) { + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str()); - if(headerLine.startsWith("HTTP/1.")) { + if(headerLine->startsWith("HTTP/1.")) { // "HTTP/1.1 101 Switching Protocols" - client->cCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt(); - } else if(headerLine.indexOf(':')) { - String headerName = headerLine.substring(0, headerLine.indexOf(':')); - String headerValue = headerLine.substring(headerLine.indexOf(':') + 2); + client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt(); + } else if(headerLine->indexOf(':')) { + String headerName = headerLine->substring(0, headerLine->indexOf(':')); + String headerValue = headerLine->substring(headerLine->indexOf(':') + 2); if(headerName.equalsIgnoreCase("Connection")) { if(headerValue.indexOf("Upgrade") >= 0) { @@ -419,9 +434,14 @@ void WebSocketsClient::handleHeader(WSclient_t * client) { client->cVersion = headerValue.toInt(); } } else { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine.c_str()); + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); } + (*headerLine) = ""; +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine))); +#endif + } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header read fin.\n"); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Client settings:\n"); @@ -456,6 +476,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client) { } if(ok) { + if(client->cAccept.length() == 0) { ok = false; } else { @@ -471,8 +492,8 @@ void WebSocketsClient::handleHeader(WSclient_t * client) { if(ok) { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Websocket connection init done.\n"); + headerDone(client); - client->status = WSC_CONNECTED; runCbEvent(WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length()); diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 589a0d7..719da66 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -75,11 +75,12 @@ class WebSocketsClient: private WebSockets { void clientDisconnect(WSclient_t * client); bool clientIsConnected(WSclient_t * client); - void handleNewClients(void); +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void handleClientData(void); +#endif void sendHeader(WSclient_t * client); - void handleHeader(WSclient_t * client); + void handleHeader(WSclient_t * client, String * headerLine); /** * called for sending a Event to the app diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 1dfcdcd..1d82605 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -32,10 +32,17 @@ WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol _server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port); +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + _server->onClient([](void *s, AsyncClient* c){ + ((WebSocketsServer*)s)->newClient(new AsyncTCPbuffer(c)); + }, this); +#endif + _cbEvent = NULL; } + WebSocketsServer::~WebSocketsServer() { // disconnect all clients disconnect(); @@ -72,6 +79,11 @@ void WebSocketsServer::begin(void) { client->cVersion = 0; client->cIsUpgrade = false; client->cIsWebsocket = false; + + client->cWsRXsize = 0; +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + client->cHttpLine = ""; +#endif } #ifdef ESP8266 @@ -90,8 +102,10 @@ void WebSocketsServer::begin(void) { * called in arduino loop */ void WebSocketsServer::loop(void) { +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) handleNewClients(); handleClientData(); +#endif } /** @@ -155,7 +169,7 @@ void WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool heade if(clientIsConnected(client)) { sendFrame(client, WSop_text, payload, length, false, true, headerToPayload); } -#ifdef ESP8266 +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } @@ -211,7 +225,7 @@ void WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool heade if(clientIsConnected(client)) { sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload); } -#ifdef ESP8266 +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } @@ -248,7 +262,7 @@ void WebSocketsServer::disconnect(uint8_t num) { } } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) /** * get an IP for a client * @param num uint8_t client id @@ -270,6 +284,48 @@ IPAddress WebSocketsServer::remoteIP(uint8_t num) { //################################################################################# //################################################################################# +/** + * handle new client connection + * @param client + */ +bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { + WSclient_t * client; + // search free list entry for client + for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + client = &_clients[i]; + + // state is not connected or tcp connection is lost + if(!clientIsConnected(client)) { + client->tcp = TCPclient; + +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + client->isSSL = false; + client->tcp->setNoDelay(true); +#endif +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) + // set Timeout for readBytesUntil and readStringUntil + client->tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); +#endif + client->status = WSC_HEADER; +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + IPAddress ip = client->tcp->remoteIP(); + DEBUG_WEBSOCKETS("[WS-Server][%d] new client from %d.%d.%d.%d\n", client->num, ip[0], ip[1], ip[2], ip[3]); +#else + DEBUG_WEBSOCKETS("[WS-Server][%d] new client\n", client->num); +#endif + + +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine))); +#endif + + return true; + break; + } + } + return false; +} + /** * * @param client WSclient_t * ptr to the client struct @@ -314,7 +370,9 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { if(client->tcp) { if(client->tcp->connected()) { +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) client->tcp->flush(); +#endif client->tcp->stop(); } delete client->tcp; @@ -328,6 +386,11 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { client->cIsUpgrade = false; client->cIsWebsocket = false; + client->cWsRXsize = 0; +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + client->cHttpLine = ""; +#endif + client->status = WSC_NOT_CONNECTED; DEBUG_WEBSOCKETS("[WS-Server][%d] client disconnected.\n", client->num); @@ -367,71 +430,50 @@ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { return false; } - +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * Handle incomming Connection Request */ void WebSocketsServer::handleNewClients(void) { - WSclient_t * client; + #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) while(_server->hasClient()) { #endif bool ok = false; - // search free list entry for client - for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { - client = &_clients[i]; - // state is not connected or tcp connection is lost - if(!clientIsConnected(client)) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - // store new connection - client->tcp = new WEBSOCKETS_NETWORK_CLASS(_server->available()); + // store new connection + WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); #else - client->tcp = new WEBSOCKETS_NETWORK_CLASS(_server->available()); + WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); #endif - if(!client->tcp) { - DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); - return; - } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - client->isSSL = false; - client->tcp->setNoDelay(true); -#endif - // set Timeout for readBytesUntil and readStringUntil - client->tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); - client->status = WSC_HEADER; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - IPAddress ip = client->tcp->remoteIP(); - DEBUG_WEBSOCKETS("[WS-Server][%d] new client from %d.%d.%d.%d\n", client->num, ip[0], ip[1], ip[2], ip[3]); -#else - DEBUG_WEBSOCKETS("[WS-Server][%d] new client\n", client->num); -#endif - ok = true; - break; - } + if(!tcpClient) { + DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); + return; } + ok = newClient(tcpClient); + if(!ok) { // no free space to handle client - WEBSOCKETS_NETWORK_CLASS tcpClient = _server->available(); #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - IPAddress ip = client->tcp->remoteIP(); + IPAddress ip = tcpClient->remoteIP(); DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); #else DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n"); #endif - tcpClient.stop(); + tcpClient->stop(); } -#ifdef ESP8266 - delay(0); -#endif #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + delay(0); } #endif + } + /** * Handel incomming data from Client */ @@ -443,10 +485,13 @@ void WebSocketsServer::handleClientData(void) { if(clientIsConnected(client)) { int len = client->tcp->available(); if(len > 0) { - + //DEBUG_WEBSOCKETS("[WS-Server][%d][handleClientData] len: %d\n", client->num, len); switch(client->status) { case WSC_HEADER: - handleHeader(client); + { + String headerLine = client->tcp->readStringUntil('\n'); + handleHeader(client, &headerLine); + } break; case WSC_CONNECTED: WebSockets::handleWebsocket(client); @@ -457,31 +502,32 @@ void WebSocketsServer::handleClientData(void) { } } } -#ifdef ESP8266 +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } } +#endif + /** * handle the WebSocket header reading * @param client WSclient_t * ptr to the client struct */ -void WebSocketsServer::handleHeader(WSclient_t * client) { +void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { - String headerLine = client->tcp->readStringUntil('\n'); - headerLine.trim(); // remove \r + headerLine->trim(); // remove \r - if(headerLine.length() > 0) { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine.c_str()); + if(headerLine->length() > 0) { + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine->c_str()); // websocket request starts allways with GET see rfc6455 - if(headerLine.startsWith("GET ")) { + if(headerLine->startsWith("GET ")) { // cut URL out - client->cUrl = headerLine.substring(4, headerLine.indexOf(' ', 4)); - } else if(headerLine.indexOf(':')) { - String headerName = headerLine.substring(0, headerLine.indexOf(':')); - String headerValue = headerLine.substring(headerLine.indexOf(':') + 2); + client->cUrl = headerLine->substring(4, headerLine->indexOf(' ', 4)); + } else if(headerLine->indexOf(':')) { + String headerName = headerLine->substring(0, headerLine->indexOf(':')); + String headerValue = headerLine->substring(headerLine->indexOf(':') + 2); if(headerName.equalsIgnoreCase("Connection")) { if(headerValue.indexOf("Upgrade") >= 0) { @@ -502,9 +548,13 @@ void WebSocketsServer::handleHeader(WSclient_t * client) { client->cExtensions = headerValue; } } else { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine.c_str()); + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); } + (*headerLine) = ""; +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine))); +#endif } else { DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Header read fin.\n", client->num); @@ -532,7 +582,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client) { if(ok) { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incomming.\n", client->num); + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incoming.\n", client->num); // generate Sec-WebSocket-Accept key String sKey = acceptKey(client->cKey); @@ -568,6 +618,8 @@ void WebSocketsServer::handleHeader(WSclient_t * client) { // header end client->tcp->write("\r\n"); + headerDone(client); + // send ping WebSockets::sendFrame(client, WSop_ping); diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index a4155da..f1840cc 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -68,7 +68,7 @@ class WebSocketsServer: private WebSockets { void disconnect(void); void disconnect(uint8_t num); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) IPAddress remoteIP(uint8_t num); #endif @@ -83,15 +83,20 @@ class WebSocketsServer: private WebSockets { WebSocketServerEvent _cbEvent; + bool newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); + void messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); void clientDisconnect(WSclient_t * client); bool clientIsConnected(WSclient_t * client); +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void handleNewClients(void); void handleClientData(void); +#endif + + void handleHeader(WSclient_t * client, String * headerLine); - void handleHeader(WSclient_t * client); /** * called if a non Websocket connection is comming in. diff --git a/tests/webSocket.html b/tests/webSocket.html index 1760886..1dc4f6b 100644 --- a/tests/webSocket.html +++ b/tests/webSocket.html @@ -8,10 +8,11 @@ connection.send('Message from Browser to ESP8266 yay its Working!! ' + new Date()); connection.send('ping'); - setInterval(function() { +/* setInterval(function() { connection.send('Time: ' + new Date()); }, 20); - +*/ +connection.send('Time: ' + new Date()); }; connection.onerror = function (error) { @@ -20,6 +21,7 @@ connection.onmessage = function (e) { console.log('Server: ', e.data); + connection.send('Time: ' + new Date()); }; function sendRGB() { diff --git a/tests/webSocketServer/index.js b/tests/webSocketServer/index.js index 07a3fe9..5fc3606 100644 --- a/tests/webSocketServer/index.js +++ b/tests/webSocketServer/index.js @@ -41,11 +41,11 @@ wsServer.on('request', function(request) { connection.on('message', function(message) { if (message.type === 'utf8') { console.log('Received Message: ' + message.utf8Data); - connection.sendUTF(message.utf8Data); + // connection.sendUTF(message.utf8Data); } else if (message.type === 'binary') { console.log('Received Binary Message of ' + message.binaryData.length + ' bytes'); - connection.sendBytes(message.binaryData); + //connection.sendBytes(message.binaryData); } }); From 5c2c257526ef32214f8dcab7144216fcdd115a7b Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 23 Jan 2016 18:34:30 +0100 Subject: [PATCH 023/347] fix server disconnect problems --- src/WebSockets.cpp | 12 ++++++++++++ src/WebSockets.h | 2 +- src/WebSocketsClient.cpp | 10 ++++++++-- src/WebSocketsServer.cpp | 18 ++++++++++++++++++ 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index d45748e..205b7e7 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -282,6 +282,10 @@ void WebSockets::handleWebsocket(WSclient_t * client) { * @param size */ bool WebSockets::handleWebsocketWaitFor(WSclient_t * client, size_t size) { + if(!client->tcp || !client->tcp->connected()) { + return false; + } + if(size > WEBSOCKETS_MAX_HEADER_SIZE) { DEBUG_WEBSOCKETS("[WS][%d][handleWebsocketWaitFor] size: %d to big!\n", client->num, size); return false; @@ -309,6 +313,10 @@ bool WebSockets::handleWebsocketWaitFor(WSclient_t * client, size_t size) { void WebSockets::handleWebsocketCb(WSclient_t * client) { + if(!client->tcp || !client->tcp->connected()) { + return; + } + uint8_t * buffer = client->cWsHeader; WSMessageHeader_t * header = &client->cWsHeaderDecode; @@ -390,6 +398,7 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) { } void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload) { + WSMessageHeader_t * header = &client->cWsHeaderDecode; if(ok) { if(header->payloadLen > 0) { @@ -513,6 +522,9 @@ String WebSockets::base64_encode(uint8_t * data, size_t length) { */ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWaitCb cb) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + if(!client->tcp || !client->tcp->connected()) { + return false; + } client->tcp->readBytes(out, n, std::bind([](WSclient_t * client, bool ok, WSreadWaitCb cb) { if(cb) { diff --git a/src/WebSockets.h b/src/WebSockets.h index 96cf09c..c203da3 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -27,7 +27,7 @@ #include -//#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) +#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) #ifndef DEBUG_WEBSOCKETS #define DEBUG_WEBSOCKETS(...) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 0351012..987ff85 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -89,6 +89,7 @@ void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String f * called in arduino loop */ void WebSocketsClient::loop(void) { +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) if(!clientIsConnected(&_client)) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) @@ -146,10 +147,9 @@ void WebSocketsClient::loop(void) { delay(10); //some little delay to not flood the server } } else { -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) handleClientData(); -#endif } +#endif } /** @@ -269,11 +269,17 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { if(client->tcp) { if(client->tcp->connected()) { +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) client->tcp->flush(); +#endif client->tcp->stop(); } event = true; +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + client->status = WSC_NOT_CONNECTED; +#else delete client->tcp; +#endif client->tcp = NULL; } diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 1d82605..cddb606 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -296,6 +296,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { // state is not connected or tcp connection is lost if(!clientIsConnected(client)) { + client->tcp = TCPclient; #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) @@ -316,6 +317,18 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + client->tcp->onDisconnect(std::bind([](WebSocketsServer * server, AsyncTCPbuffer * obj, WSclient_t * client) -> bool { + DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num); + + AsyncTCPbuffer ** sl = &server->_clients[client->num].tcp; + if(*sl == obj) { + client->status = WSC_NOT_CONNECTED; + *sl = NULL; + } + return true; + }, this, std::placeholders::_1, client)); + + client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine))); #endif @@ -375,7 +388,11 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { #endif client->tcp->stop(); } +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + client->status = WSC_NOT_CONNECTED; +#else delete client->tcp; +#endif client->tcp = NULL; } @@ -425,6 +442,7 @@ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { if(client->tcp) { // do cleanup + DEBUG_WEBSOCKETS("[WS-Server][%d] client list cleanup.\n", client->num); clientDisconnect(client); } From 790a922d5acb29ee820a32165a1ea00479e4cdf1 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 23 Jan 2016 18:41:45 +0100 Subject: [PATCH 024/347] add deprecated warning for loop in async mode fix sync mode --- src/WebSocketsClient.cpp | 2 +- src/WebSocketsServer.cpp | 4 ++-- src/WebSocketsServer.h | 7 +++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 987ff85..2f703ef 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -340,7 +340,7 @@ void WebSocketsClient::handleClientData(void) { switch(_client.status) { case WSC_HEADER: { - String headerLine = _client->tcp->readStringUntil('\n'); + String headerLine = _client.tcp->readStringUntil('\n'); handleHeader(&_client, &headerLine); } break; diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index cddb606..ebde1bf 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -98,15 +98,15 @@ void WebSocketsServer::begin(void) { DEBUG_WEBSOCKETS("[WS-Server] Server Started.\n"); } +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * called in arduino loop */ void WebSocketsServer::loop(void) { -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) handleNewClients(); handleClientData(); -#endif } +#endif /** * set callback function diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index f1840cc..34036dd 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -42,7 +42,14 @@ class WebSocketsServer: private WebSockets { ~WebSocketsServer(void); void begin(void); +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void loop(void); +#else + // Async interface not need a loop call + void loop(void) __attribute__ ((deprecated)) { + + } +#endif void onEvent(WebSocketServerEvent cbEvent); From 1275914c868d64e0cbf043d2e41826881228e60d Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sun, 24 Jan 2016 00:52:23 +0100 Subject: [PATCH 025/347] first parts of client working --- src/WebSocketsClient.cpp | 118 ++++++++++++++++++++++++++++++--------- src/WebSocketsClient.h | 12 ++++ src/WebSocketsServer.h | 5 +- 3 files changed, 107 insertions(+), 28 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 2f703ef..af74819 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -67,6 +67,8 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) // todo find better seed randomSeed(millis()); #endif + + asyncConnect(); } void WebSocketsClient::begin(String host, uint16_t port, String url) { @@ -85,11 +87,12 @@ void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String f } #endif + +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * called in arduino loop */ void WebSocketsClient::loop(void) { -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) if(!clientIsConnected(&_client)) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) @@ -120,37 +123,16 @@ void WebSocketsClient::loop(void) { } if(_client.tcp->connect(_host.c_str(), _port)) { - DEBUG_WEBSOCKETS("[WS-Client] connected to %s:%u.\n", _host.c_str(), _port); - - _client.status = WSC_HEADER; - - // set Timeout for readBytesUntil and readStringUntil - _client.tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); - -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - _client.tcp->setNoDelay(true); - - if(_client.isSSL && _fingerprint.length()) { - if(!_client.ssl->verify(_fingerprint.c_str(), _host.c_str())) { - DEBUG_WEBSOCKETS("[WS-Client] certificate mismatch\n"); - WebSockets::clientDisconnect(&_client, 1000); - return; - } - } -#endif - - // send Header to Server - sendHeader(&_client); - + connectedCb(); } else { - DEBUG_WEBSOCKETS("[WS-Client] connection to %s:%u Faild\n", _host.c_str(), _port); + connectFailedCb(); delay(10); //some little delay to not flood the server } } else { handleClientData(); } -#endif } +#endif /** * set callback function @@ -511,3 +493,89 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } } +void WebSocketsClient::connectedCb() { + + DEBUG_WEBSOCKETS("[WS-Client] connected to %s:%u.\n", _host.c_str(), _port); + +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + _client.tcp->onDisconnect(std::bind([](WebSocketsClient * c, AsyncTCPbuffer * obj, WSclient_t * client) -> bool { + DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num); + client->status = WSC_NOT_CONNECTED; + client->tcp = NULL; + + // reconnect + // c->asyncConnect(); + + return true; + }, this, std::placeholders::_1, &_client)); +#endif + + _client.status = WSC_HEADER; + +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) + // set Timeout for readBytesUntil and readStringUntil + _client.tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); +#endif + +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + _client.tcp->setNoDelay(true); + + if(_client.isSSL && _fingerprint.length()) { + if(!_client.ssl->verify(_fingerprint.c_str(), _host.c_str())) { + DEBUG_WEBSOCKETS("[WS-Client] certificate mismatch\n"); + WebSockets::clientDisconnect(&_client, 1000); + return; + } + } +#endif + + // send Header to Server + sendHeader(&_client); + +} + + +void WebSocketsClient::connectFailedCb() { + DEBUG_WEBSOCKETS("[WS-Client] connection to %s:%u Faild\n", _host.c_str(), _port); +} + +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + +void WebSocketsClient::asyncConnect() { + + AsyncClient * tcpclient = new AsyncClient(); + + + if(!tcpclient) { + DEBUG_WEBSOCKETS("[WS-Client] creating AsyncClient class failed!"); + return; + } + + tcpclient->onConnect(std::bind([](WebSocketsClient * ws , AsyncClient * tcp) { + ws->_client.tcp = new AsyncTCPbuffer(tcp); + if(!ws->_client.tcp) { + DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); + ws->connectFailedCb(); + return; + } + ws->connectedCb(); + }, this, std::placeholders::_2)); + + tcpclient->onError(std::bind([](WebSocketsClient * ws , AsyncClient * tcp) { + ws->connectFailedCb(); + + // reconnect + ws->asyncConnect(); + }, this, std::placeholders::_2)); + + if(!tcpclient->connect(_host.c_str(), _port)) { + connectFailedCb(); + delete tcpclient; + } + +} + +#endif + + + diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 719da66..cfecf39 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -44,7 +44,12 @@ class WebSocketsClient: private WebSockets { void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = ""); #endif +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void loop(void); +#else + // Async interface not need a loop call + void loop(void) __attribute__ ((deprecated)) {} +#endif void onEvent(WebSocketClientEvent cbEvent); @@ -82,6 +87,13 @@ class WebSocketsClient: private WebSockets { void sendHeader(WSclient_t * client); void handleHeader(WSclient_t * client, String * headerLine); + void connectedCb(); + void connectFailedCb(); + +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + void asyncConnect(); +#endif + /** * called for sending a Event to the app * @param type WStype_t diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 34036dd..3b25373 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -42,13 +42,12 @@ class WebSocketsServer: private WebSockets { ~WebSocketsServer(void); void begin(void); + #if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void loop(void); #else // Async interface not need a loop call - void loop(void) __attribute__ ((deprecated)) { - - } + void loop(void) __attribute__ ((deprecated)) {} #endif void onEvent(WebSocketServerEvent cbEvent); From 358d8c769ea2595cbe489b8507f90d40387a723a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Tib=C3=A9rio?= Date: Sun, 24 Jan 2016 17:08:22 +0000 Subject: [PATCH 026/347] added subprotocol for ssl client also --- src/WebSocketsClient.cpp | 8 ++++---- src/WebSocketsClient.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 05d3755..8f912b3 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -72,14 +72,14 @@ void WebSocketsClient::begin(String host, uint16_t port, String url, String Prot } #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) -void WebSocketsClient::beginSSL(const char *host, uint16_t port, const char * url, const char * fingerprint) { - begin(host, port, url); +void WebSocketsClient::beginSSL(const char *host, uint16_t port, const char * url, const char * fingerprint, const char * Protocol) { + begin(host, port, url, Protocol); _client.isSSL = true; _fingerprint = fingerprint; } -void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String fingerprint) { - beginSSL(host.c_str(), port, url.c_str(), fingerprint.c_str()); +void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String fingerprint, String Protocol) { + beginSSL(host.c_str(), port, url.c_str(), fingerprint.c_str(), Protocol.c_str()); } #endif diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 2ba2e49..c8b23a8 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -40,8 +40,8 @@ class WebSocketsClient: private WebSockets { void begin(String host, uint16_t port, String url = "/", String Protocol = "arduino"); #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - void beginSSL(const char *host, uint16_t port, const char * url = "/", const char * = ""); - void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = ""); + void beginSSL(const char *host, uint16_t port, const char * url = "/", const char * = "", const char * Protocol = "arduino"); + void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String Protocol = "arduino"); #endif void loop(void); From 76853c7a73e3570b059097e9e9d2a27bcef2906d Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Fri, 29 Jan 2016 13:16:02 +0100 Subject: [PATCH 027/347] async client working --- src/WebSockets.h | 4 ++-- src/WebSocketsClient.cpp | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index c203da3..8d4c2db 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -54,8 +54,8 @@ // select Network type based #ifdef ESP8266 -//#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 -#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC +#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 +//#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC #else #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 #endif diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index af74819..4cc9a35 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -67,8 +67,9 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url) // todo find better seed randomSeed(millis()); #endif - +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) asyncConnect(); +#endif } void WebSocketsClient::begin(String host, uint16_t port, String url) { @@ -504,7 +505,7 @@ void WebSocketsClient::connectedCb() { client->tcp = NULL; // reconnect - // c->asyncConnect(); + c->asyncConnect(); return true; }, this, std::placeholders::_1, &_client)); @@ -543,18 +544,24 @@ void WebSocketsClient::connectFailedCb() { void WebSocketsClient::asyncConnect() { - AsyncClient * tcpclient = new AsyncClient(); + DEBUG_WEBSOCKETS("[WS-Client] asyncConnect...\n"); + AsyncClient * tcpclient = new AsyncClient(); if(!tcpclient) { - DEBUG_WEBSOCKETS("[WS-Client] creating AsyncClient class failed!"); + DEBUG_WEBSOCKETS("[WS-Client] creating AsyncClient class failed!\n"); return; } + tcpclient->onDisconnect([](void *obj, AsyncClient* c) { + c->free(); + delete c; + }); + tcpclient->onConnect(std::bind([](WebSocketsClient * ws , AsyncClient * tcp) { ws->_client.tcp = new AsyncTCPbuffer(tcp); if(!ws->_client.tcp) { - DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); + DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!\n"); ws->connectFailedCb(); return; } From b7a694c16a9ea3554f51a691411479310949d267 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Fri, 29 Jan 2016 13:28:05 +0100 Subject: [PATCH 028/347] add note for async mode --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 2cca85f..dbe3cb6 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,13 @@ a WebSocket Server and Client for Arduino based on RFC6455. supported for: - wss client on the ESP8266 +### ESP Async TCP ### + +this libary can run in Async TCP mode on the ESP8266. +the mode can be aktivated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE define). +the ```ESPAsyncTCP``` libary is required. +Note: in this mode wss / SSL is not posible. + ### Issues ### Submit issues to: https://github.com/Links2004/arduinoWebSockets/issues From 63f867581631f5a9cb6403fc5e3b524d99438d54 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Fri, 29 Jan 2016 13:44:18 +0100 Subject: [PATCH 029/347] update README.md --- README.md | 25 +++++++++++++++++-------- library.properties | 4 ++-- src/WebSockets.h | 7 +++++-- src/WebSocketsClient.h | 6 +++++- src/WebSocketsServer.h | 4 ++++ 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index dbe3cb6..887161c 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,16 @@ a WebSocket Server and Client for Arduino based on RFC6455. ##### Supported Hardware ##### - ESP8266 [Arduino for ESP8266](https://github.com/Links2004/Arduino) - - ATmega328 with Ethernet Shield (alpha) - - ATmega328 with enc28j60 (alpha) - - ATmega2560 with Ethernet Shield (alpha) - - ATmega2560 with enc28j60 (alpha) + - ATmega328 with Ethernet Shield (ATmega branch) + - ATmega328 with enc28j60 (ATmega branch) + - ATmega2560 with Ethernet Shield (ATmega branch) + - ATmega2560 with enc28j60 (ATmega branch) + +###### Note: ###### + + version 2.0 is not compatible with AVR/ATmega, check ATmega branch. + + Arduino for AVR not supports std namespace of c++. ### wss / SSL ### supported for: @@ -32,10 +38,13 @@ a WebSocket Server and Client for Arduino based on RFC6455. ### ESP Async TCP ### -this libary can run in Async TCP mode on the ESP8266. -the mode can be aktivated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE define). -the ```ESPAsyncTCP``` libary is required. -Note: in this mode wss / SSL is not posible. +This libary can run in Async TCP mode on the ESP. + +The mode can be aktivated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE define). + +```ESPAsyncTCP``` libary is required. + +Note: in this mode wss / SSL is not possible. ### Issues ### Submit issues to: https://github.com/Links2004/arduinoWebSockets/issues diff --git a/library.properties b/library.properties index 92613b3..9e73afe 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=WebSockets -version=1.3 +version=2.0 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) -paragraph= +paragraph=use 2.0 for ESP and 1.3 for AVR category=Communication url=https://github.com/Links2004/arduinoWebSockets architectures=* diff --git a/src/WebSockets.h b/src/WebSockets.h index 8d4c2db..934c17e 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -27,7 +27,7 @@ #include -#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) +//#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) #ifndef DEBUG_WEBSOCKETS #define DEBUG_WEBSOCKETS(...) @@ -182,8 +182,11 @@ typedef struct { class WebSockets { protected: - +#ifdef __AVR__ + typedef void (*WSreadWaitCb)(WSclient_t * client, bool ok); +#else typedef std::function WSreadWaitCb; +#endif virtual void clientDisconnect(WSclient_t * client); virtual bool clientIsConnected(WSclient_t * client); diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 478aa11..702ebd6 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -30,8 +30,12 @@ class WebSocketsClient: private WebSockets { public: - +#ifdef __AVR__ + typedef void (*WebSocketClientEvent)(WStype_t type, uint8_t * payload, size_t length); +#else typedef std::function WebSocketClientEvent; +#endif + WebSocketsClient(void); ~WebSocketsClient(void); diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 3b25373..bd02038 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -36,7 +36,11 @@ class WebSocketsServer: private WebSockets { public: +#ifdef __AVR__ + typedef void (*WebSocketServerEvent)(uint8_t num, WStype_t type, uint8_t * payload, size_t length); +#else typedef std::function WebSocketServerEvent; +#endif WebSocketsServer(uint16_t port, String origin = "", String protocol = "arduino"); ~WebSocketsServer(void); From 629f524ea4090eda7002d672010992d2fe114d33 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 30 Jan 2016 00:34:00 +0100 Subject: [PATCH 030/347] fix c&p error in handling of more then 125 byte --- src/WebSockets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 205b7e7..2dede69 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -341,7 +341,7 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) { buffer++; if(header->payloadLen == 126) { - headerLen += 4; + headerLen += 2; if(!handleWebsocketWaitFor(client, headerLen)) { return; } From 512e3f6c09591d57591bc3748c4fa9bc39ac46b5 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Sat, 30 Jan 2016 02:24:29 +0200 Subject: [PATCH 031/347] add ESP31B support and fix header size --- src/WebSockets.cpp | 2 +- src/WebSockets.h | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 205b7e7..2dede69 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -341,7 +341,7 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) { buffer++; if(header->payloadLen == 126) { - headerLen += 4; + headerLen += 2; if(!handleWebsocketWaitFor(client, headerLen)) { return; } diff --git a/src/WebSockets.h b/src/WebSockets.h index 934c17e..08cfb1a 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -53,9 +53,9 @@ #define WEBSOCKETS_MAX_HEADER_SIZE (14) // select Network type based -#ifdef ESP8266 -#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 -//#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC +#if defined(ESP8266) || defined(ESP31B) +//#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 +#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC #else #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 #endif @@ -66,11 +66,15 @@ // No SSL/WSS support for client in Async mode // TLS lib need a sync interface! -#ifndef ESP8266 +#if !defined(ESP8266) && !defined(ESP31B) #error "network type ESP8266 ASYNC only possible on the ESP mcu!" #endif +#ifdef ESP8266 #include +#else +#include +#endif #include #include #define WEBSOCKETS_NETWORK_CLASS AsyncTCPbuffer @@ -78,11 +82,15 @@ #elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) -#ifndef ESP8266 +#if !defined(ESP8266) && !defined(ESP31B) #error "network type ESP8266 only possible on the ESP mcu!" #endif +#ifdef ESP8266 #include +#else +#include +#endif #define WEBSOCKETS_NETWORK_CLASS WiFiClient #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer From 16824906c8a0e12865813d24c71d4c68f7748311 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 30 Jan 2016 12:01:09 +0100 Subject: [PATCH 032/347] increase timeout to 2000ms sync TCP is default --- src/WebSockets.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 08cfb1a..36e6b3a 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -42,7 +42,7 @@ #define WEBSOCKETS_MAX_DATA_SIZE (1024) #endif -#define WEBSOCKETS_TCP_TIMEOUT (1500) +#define WEBSOCKETS_TCP_TIMEOUT (2000) #define NETWORK_ESP8266_ASYNC (0) #define NETWORK_ESP8266 (1) @@ -54,8 +54,8 @@ // select Network type based #if defined(ESP8266) || defined(ESP31B) -//#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 -#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC +#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 +//#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC #else #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 #endif From 2b6f1909d7ca742678e33e121a78207817da8a1a Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 30 Jan 2016 12:02:09 +0100 Subject: [PATCH 033/347] add ESP31B to compatible list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 887161c..ddf08c2 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ a WebSocket Server and Client for Arduino based on RFC6455. ##### Supported Hardware ##### - ESP8266 [Arduino for ESP8266](https://github.com/Links2004/Arduino) + - ESP31B - ATmega328 with Ethernet Shield (ATmega branch) - ATmega328 with enc28j60 (ATmega branch) - ATmega2560 with Ethernet Shield (ATmega branch) From 2d87bfa3d60a25a3a95de1d59e95a05cf4288ece Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 6 Feb 2016 19:21:24 +0100 Subject: [PATCH 034/347] less ram usage when using strings --- src/WebSockets.cpp | 2 +- src/WebSockets.h | 2 +- src/WebSocketsClient.cpp | 2 +- src/WebSocketsClient.h | 2 +- src/WebSocketsServer.cpp | 4 ++-- src/WebSocketsServer.h | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 2dede69..4e3aaab 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -473,7 +473,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * @param clientKey String * @return String Accept Key */ -String WebSockets::acceptKey(String clientKey) { +String WebSockets::acceptKey(String & clientKey) { uint8_t sha1HashBin[20] = { 0 }; #ifdef ESP8266 sha1(clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", &sha1HashBin[0]); diff --git a/src/WebSockets.h b/src/WebSockets.h index 36e6b3a..1d46ef1 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -212,7 +212,7 @@ class WebSockets { void handleWebsocketCb(WSclient_t * client); void handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload); - String acceptKey(String clientKey); + String acceptKey(String & clientKey); String base64_encode(uint8_t * data, size_t length); bool readCb(WSclient_t * client, uint8_t *out, size_t n, WSreadWaitCb cb); diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 926fc28..6c38d2a 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -171,7 +171,7 @@ void WebSocketsClient::sendTXT(const char * payload, size_t length) { sendTXT((uint8_t *) payload, length); } -void WebSocketsClient::sendTXT(String payload) { +void WebSocketsClient::sendTXT(String & payload) { sendTXT((uint8_t *) payload.c_str(), payload.length()); } diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 702ebd6..9a66e47 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -61,7 +61,7 @@ class WebSocketsClient: private WebSockets { void sendTXT(const uint8_t * payload, size_t length = 0); void sendTXT(char * payload, size_t length = 0, bool headerToPayload = false); void sendTXT(const char * payload, size_t length = 0); - void sendTXT(String payload); + void sendTXT(String & payload); void sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false); void sendBIN(const uint8_t * payload, size_t length); diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index ebde1bf..a81af57 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -148,7 +148,7 @@ 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()); } @@ -187,7 +187,7 @@ 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()); } diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index bd02038..bf51bfd 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -61,13 +61,13 @@ class WebSocketsServer: private WebSockets { void sendTXT(uint8_t num, const uint8_t * payload, size_t length = 0); void sendTXT(uint8_t num, char * payload, size_t length = 0, bool headerToPayload = false); 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, bool headerToPayload = false); void broadcastTXT(const uint8_t * payload, size_t length = 0); void broadcastTXT(char * payload, size_t length = 0, bool headerToPayload = false); 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, bool headerToPayload = false); void sendBIN(uint8_t num, const uint8_t * payload, size_t length); From c57a4c19abfa91dd0753d4ee99cea5f2fbd2795a Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Wed, 17 Feb 2016 17:56:03 +0100 Subject: [PATCH 035/347] add HTTP Basic Authorization to WS Client and Server see: #55 --- examples/WebSocketClient/WebSocketClient.ino | 1 + src/WebSockets.h | 2 + src/WebSocketsClient.cpp | 30 +++++++++++++ src/WebSocketsClient.h | 3 ++ src/WebSocketsServer.cpp | 45 ++++++++++++++++++++ src/WebSocketsServer.h | 27 +++++++++++- 6 files changed, 106 insertions(+), 2 deletions(-) diff --git a/examples/WebSocketClient/WebSocketClient.ino b/examples/WebSocketClient/WebSocketClient.ino index e68e97c..82a2cc8 100644 --- a/examples/WebSocketClient/WebSocketClient.ino +++ b/examples/WebSocketClient/WebSocketClient.ino @@ -77,6 +77,7 @@ void setup() { } webSocket.begin("192.168.0.123", 81); + //webSocket.setAuthorization("user", "Password"); // HTTP Basic Authorization webSocket.onEvent(webSocketEvent); } diff --git a/src/WebSockets.h b/src/WebSockets.h index 1d46ef1..df1211e 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -180,6 +180,8 @@ typedef struct { uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer WSMessageHeader_t cWsHeaderDecode; + String base64Authorization; ///< Base64 encoded Auth request + #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) String cHttpLine; ///< HTTP header lines #endif diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 6c38d2a..0999f49 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -25,6 +25,7 @@ #include "WebSockets.h" #include "WebSocketsClient.h" + WebSocketsClient::WebSocketsClient() { _cbEvent = NULL; _client.num = 0; @@ -60,6 +61,7 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url, _client.cProtocol = protocol; _client.cExtensions = ""; _client.cVersion = 0; + _client.base64Authorization = ""; #ifdef ESP8266 randomSeed(RANDOM_REG32); @@ -202,6 +204,30 @@ void WebSocketsClient::disconnect(void) { } } +/** + * set the Authorizatio for the http request + * @param user const char * + * @param password const char * + */ +void WebSocketsClient::setAuthorization(const char * user, const char * password) { + if(user && password) { + String auth = user; + auth += ":"; + auth += password; + _client.base64Authorization = base64_encode((uint8_t *)auth.c_str(), auth.length()); + } +} + +/** + * set the Authorizatio for the http request + * @param auth const char * base64 + */ +void WebSocketsClient::setAuthorization(const char * auth) { + if(auth) { + _client.base64Authorization = auth; + } +} + //################################################################################# //################################################################################# //################################################################################# @@ -374,6 +400,10 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { handshake += "Sec-WebSocket-Extensions: " + client->cExtensions + "\r\n"; } + if(client->base64Authorization.length() > 0) { + handshake += "Authorization: Basic " + client->base64Authorization + "\r\n"; + } + handshake += "\r\n"; client->tcp->write(handshake.c_str(), handshake.length()); diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 9a66e47..a263666 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -68,6 +68,9 @@ class WebSocketsClient: private WebSockets { void disconnect(void); + void setAuthorization(const char * user, const char * password); + void setAuthorization(const char * auth); + protected: String _host; uint16_t _port; diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index a81af57..e1448b3 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -80,6 +80,8 @@ void WebSocketsServer::begin(void) { client->cIsUpgrade = false; client->cIsWebsocket = false; + client->base64Authorization = ""; + client->cWsRXsize = 0; #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->cHttpLine = ""; @@ -262,6 +264,32 @@ void WebSocketsServer::disconnect(uint8_t num) { } } + + +/** + * set the Authorizatio for the http request + * @param user const char * + * @param password const char * + */ +void WebSocketsServer::setAuthorization(const char * user, const char * password) { + if(user && password) { + String auth = user; + auth += ":"; + auth += password; + _base64Authorization = base64_encode((uint8_t *)auth.c_str(), auth.length()); + } +} + +/** + * set the Authorizatio for the http request + * @param auth const char * base64 + */ +void WebSocketsServer::setAuthorization(const char * auth) { + if(auth) { + _base64Authorization = auth; + } +} + #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) /** * get an IP for a client @@ -564,6 +592,8 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { client->cProtocol = headerValue; } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Extensions")) { client->cExtensions = headerValue; + } else if(headerName.equalsIgnoreCase("Authorization")) { + client->base64Authorization = headerValue; } } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); @@ -583,6 +613,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cProtocol: %s\n", client->num, client->cProtocol.c_str()); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cExtensions: %s\n", client->num, client->cExtensions.c_str()); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cVersion: %d\n", client->num, client->cVersion); + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - base64Authorization: %s\n", client->num, client->base64Authorization); bool ok = (client->cIsUpgrade && client->cIsWebsocket); @@ -598,6 +629,20 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { } } + if(_base64Authorization.length() > 0) { + if(client->base64Authorization.length() > 0) { + String auth = "Basic "; + auth += _base64Authorization; + if(auth != client->base64Authorization) { + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] HTTP Authorization failed!\n", client->num); + handleAuthorizationFailed(client); + return; + } + } else { + ok = false; + } + } + if(ok) { DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incoming.\n", client->num); diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index bf51bfd..27d7f8b 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -78,6 +78,9 @@ class WebSocketsServer: private WebSockets { void disconnect(void); void disconnect(uint8_t num); + void setAuthorization(const char * user, const char * password); + void setAuthorization(const char * auth); + #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) IPAddress remoteIP(uint8_t num); #endif @@ -86,6 +89,7 @@ class WebSocketsServer: private WebSockets { uint16_t _port; String _origin; String _protocol; + String _base64Authorization; ///< Base64 encoded Auth request WEBSOCKETS_NETWORK_SERVER_CLASS * _server; @@ -109,8 +113,8 @@ class WebSocketsServer: private WebSockets { /** - * called if a non Websocket connection is comming in. - * Note: can be overrided + * called if a non Websocket connection is coming in. + * Note: can be override * @param client WSclient_t * ptr to the client struct */ virtual void handleNonWebsocketConnection(WSclient_t * client) { @@ -126,6 +130,25 @@ class WebSocketsServer: private WebSockets { clientDisconnect(client); } + /** + * called if a non Authorization connection is coming in. + * Note: can be override + * @param client WSclient_t * ptr to the client struct + */ + virtual void handleAuthorizationFailed(WSclient_t *client) { + + client->tcp->write("HTTP/1.1 401 Unauthorized\r\n" + "Server: arduino-WebSocket-Server\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 45\r\n" + "Connection: close\r\n" + "Sec-WebSocket-Version: 13\r\n" + "WWW-Authenticate: Basic realm=\"WebSocket Server\"" + "\r\n" + "This Websocket server requires Authorization!"); + clientDisconnect(client); + } + /** * called for sending a Event to the app * @param num uint8_t From 450ca76a7408a2d8c90256955ba4930df0f82456 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 20 Feb 2016 12:27:19 +0100 Subject: [PATCH 036/347] add return value to all send functions --- src/WebSockets.cpp | 21 ++++++++---- src/WebSockets.h | 2 +- src/WebSocketsClient.cpp | 32 +++++++++-------- src/WebSocketsClient.h | 16 ++++----- src/WebSocketsServer.cpp | 74 ++++++++++++++++++++++++---------------- src/WebSocketsServer.h | 34 +++++++++--------- 6 files changed, 103 insertions(+), 76 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 4e3aaab..3b18344 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -77,17 +77,18 @@ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * rea * @param mask bool add dummy mask to the frame (needed for web browser) * @param fin bool can be used to send data in more then one frame (set fin on the last frame) * @param headerToPayload bool set true if the payload has reserved 14 Byte at the beginning to dynamically add the Header (payload neet to be in RAM!) + * @return true if ok */ -void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool mask, bool fin, bool headerToPayload) { +bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool mask, bool fin, bool headerToPayload) { if(client->tcp && !client->tcp->connected()) { DEBUG_WEBSOCKETS("[WS][%d][sendFrame] not Connected!?\n", client->num); - return; + return false; } if(client->status != WSC_CONNECTED) { DEBUG_WEBSOCKETS("[WS][%d][sendFrame] not in WSC_CONNECTED state!?\n", client->num); - return; + return false; } DEBUG_WEBSOCKETS("[WS][%d][sendFrame] ------- send massage frame -------\n", client->num); @@ -104,6 +105,7 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay uint8_t * headerPtr; uint8_t * payloadPtr = payload; bool useInternBuffer = false; + bool ret = true; // calculate header Size if(length < 126) { @@ -231,14 +233,20 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay // header has be added to payload // payload is forced to reserved 14 Byte but we may not need all based on the length and mask settings // offset in payload is calculatetd 14 - headerSize - client->tcp->write(&payloadPtr[(WEBSOCKETS_MAX_HEADER_SIZE - headerSize)], (length + headerSize)); + if(client->tcp->write(&payloadPtr[(WEBSOCKETS_MAX_HEADER_SIZE - headerSize)], (length + headerSize)) != (length + headerSize)) { + ret = false; + } } else { // send header - client->tcp->write(&buffer[0], headerSize); + if(client->tcp->write(&buffer[0], headerSize) != headerSize) { + ret = false; + } if(payloadPtr && length > 0) { // send payload - client->tcp->write(&payloadPtr[0], length); + if(client->tcp->write(&payloadPtr[0], length) != length) { + ret = false; + } } } @@ -250,6 +258,7 @@ void WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay } #endif + return ret; } /** diff --git a/src/WebSockets.h b/src/WebSockets.h index df1211e..dbca2b3 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -204,7 +204,7 @@ class WebSockets { virtual void messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0); - void sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false, bool fin = true, bool headerToPayload = false); + bool sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false, bool fin = true, bool headerToPayload = false); void headerDone(WSclient_t * client); diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 0999f49..fca918c 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -151,30 +151,32 @@ void WebSocketsClient::onEvent(WebSocketClientEvent cbEvent) { * @param payload uint8_t * * @param length size_t * @param headerToPayload bool (see sendFrame for more details) + * @return true if ok */ -void WebSocketsClient::sendTXT(uint8_t * payload, size_t length, bool headerToPayload) { +bool WebSocketsClient::sendTXT(uint8_t * payload, size_t length, bool headerToPayload) { if(length == 0) { length = strlen((const char *) payload); } if(clientIsConnected(&_client)) { - sendFrame(&_client, WSop_text, payload, length, true, true, headerToPayload); + return sendFrame(&_client, WSop_text, payload, length, true, true, headerToPayload); } + return false; } -void WebSocketsClient::sendTXT(const uint8_t * payload, size_t length) { - sendTXT((uint8_t *) payload, length); +bool WebSocketsClient::sendTXT(const uint8_t * payload, size_t length) { + return sendTXT((uint8_t *) payload, length); } -void WebSocketsClient::sendTXT(char * payload, size_t length, bool headerToPayload) { - sendTXT((uint8_t *) payload, length, headerToPayload); +bool WebSocketsClient::sendTXT(char * payload, size_t length, bool headerToPayload) { + return sendTXT((uint8_t *) payload, length, headerToPayload); } -void WebSocketsClient::sendTXT(const char * payload, size_t length) { - sendTXT((uint8_t *) payload, length); +bool WebSocketsClient::sendTXT(const char * payload, size_t length) { + return sendTXT((uint8_t *) payload, length); } -void WebSocketsClient::sendTXT(String & payload) { - sendTXT((uint8_t *) payload.c_str(), payload.length()); +bool WebSocketsClient::sendTXT(String & payload) { + return sendTXT((uint8_t *) payload.c_str(), payload.length()); } /** @@ -183,15 +185,17 @@ void WebSocketsClient::sendTXT(String & payload) { * @param payload uint8_t * * @param length size_t * @param headerToPayload bool (see sendFrame for more details) + * @return true if ok */ -void WebSocketsClient::sendBIN(uint8_t * payload, size_t length, bool headerToPayload) { +bool WebSocketsClient::sendBIN(uint8_t * payload, size_t length, bool headerToPayload) { if(clientIsConnected(&_client)) { - sendFrame(&_client, WSop_binary, payload, length, true, true, headerToPayload); + return sendFrame(&_client, WSop_binary, payload, length, true, true, headerToPayload); } + return false; } -void WebSocketsClient::sendBIN(const uint8_t * payload, size_t length) { - sendBIN((uint8_t *) payload, length); +bool WebSocketsClient::sendBIN(const uint8_t * payload, size_t length) { + return sendBIN((uint8_t *) payload, length); } /** diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index a263666..b029d07 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -57,14 +57,14 @@ class WebSocketsClient: private WebSockets { void onEvent(WebSocketClientEvent cbEvent); - void sendTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); - void sendTXT(const uint8_t * payload, size_t length = 0); - void sendTXT(char * payload, size_t length = 0, bool headerToPayload = false); - void sendTXT(const char * payload, size_t length = 0); - void sendTXT(String & payload); - - void sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false); - void sendBIN(const uint8_t * payload, size_t length); + bool sendTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); + bool sendTXT(const uint8_t * payload, size_t length = 0); + bool sendTXT(char * payload, size_t length = 0, bool headerToPayload = false); + bool sendTXT(const char * payload, size_t length = 0); + bool sendTXT(String & payload); + + bool sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false); + bool sendBIN(const uint8_t * payload, size_t length); void disconnect(void); diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index e1448b3..f4c9a55 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -124,34 +124,36 @@ void WebSocketsServer::onEvent(WebSocketServerEvent cbEvent) { * @param payload uint8_t * * @param length size_t * @param headerToPayload bool (see sendFrame for more details) + * @return true if ok */ -void WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) { +bool WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) { if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) { - return; + return false; } if(length == 0) { length = strlen((const char *) payload); } WSclient_t * client = &_clients[num]; if(clientIsConnected(client)) { - sendFrame(client, WSop_text, payload, length, false, true, headerToPayload); + return sendFrame(client, WSop_text, payload, length, false, true, headerToPayload); } + return false; } -void WebSocketsServer::sendTXT(uint8_t num, const uint8_t * payload, size_t length) { - sendTXT(num, (uint8_t *) payload, length); +bool WebSocketsServer::sendTXT(uint8_t num, const uint8_t * payload, size_t length) { + return sendTXT(num, (uint8_t *) payload, length); } -void WebSocketsServer::sendTXT(uint8_t num, char * payload, size_t length, bool headerToPayload) { - sendTXT(num, (uint8_t *) payload, length, headerToPayload); +bool WebSocketsServer::sendTXT(uint8_t num, char * payload, size_t length, bool headerToPayload) { + return sendTXT(num, (uint8_t *) payload, length, headerToPayload); } -void WebSocketsServer::sendTXT(uint8_t num, const char * payload, size_t length) { - sendTXT(num, (uint8_t *) payload, length); +bool WebSocketsServer::sendTXT(uint8_t num, const char * payload, size_t length) { + return sendTXT(num, (uint8_t *) payload, length); } -void WebSocketsServer::sendTXT(uint8_t num, String & payload) { - sendTXT(num, (uint8_t *) payload.c_str(), payload.length()); +bool WebSocketsServer::sendTXT(uint8_t num, String & payload) { + return sendTXT(num, (uint8_t *) payload.c_str(), payload.length()); } /** @@ -159,9 +161,11 @@ void WebSocketsServer::sendTXT(uint8_t num, String & payload) { * @param payload uint8_t * * @param length size_t * @param headerToPayload bool (see sendFrame for more details) + * @return true if ok */ -void WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool headerToPayload) { +bool WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool headerToPayload) { WSclient_t * client; + bool ret = true; if(length == 0) { length = strlen((const char *) payload); } @@ -169,28 +173,31 @@ void WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool heade for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { client = &_clients[i]; if(clientIsConnected(client)) { - sendFrame(client, WSop_text, payload, length, false, true, headerToPayload); + if(!sendFrame(client, WSop_text, payload, length, false, true, headerToPayload)) { + ret = false; + } } #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } + return ret; } -void WebSocketsServer::broadcastTXT(const uint8_t * payload, size_t length) { - broadcastTXT((uint8_t *) payload, length); +bool WebSocketsServer::broadcastTXT(const uint8_t * payload, size_t length) { + return broadcastTXT((uint8_t *) payload, length); } -void WebSocketsServer::broadcastTXT(char * payload, size_t length, bool headerToPayload) { - broadcastTXT((uint8_t *) payload, length, headerToPayload); +bool WebSocketsServer::broadcastTXT(char * payload, size_t length, bool headerToPayload) { + return broadcastTXT((uint8_t *) payload, length, headerToPayload); } -void WebSocketsServer::broadcastTXT(const char * payload, size_t length) { - broadcastTXT((uint8_t *) payload, length); +bool WebSocketsServer::broadcastTXT(const char * payload, size_t length) { + return broadcastTXT((uint8_t *) payload, length); } -void WebSocketsServer::broadcastTXT(String & payload) { - broadcastTXT((uint8_t *) payload.c_str(), payload.length()); +bool WebSocketsServer::broadcastTXT(String & payload) { + return broadcastTXT((uint8_t *) payload.c_str(), payload.length()); } /** @@ -199,19 +206,21 @@ void WebSocketsServer::broadcastTXT(String & payload) { * @param payload uint8_t * * @param length size_t * @param headerToPayload bool (see sendFrame for more details) + * @return true if ok */ -void WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) { +bool WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) { if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) { - return; + return false; } WSclient_t * client = &_clients[num]; if(clientIsConnected(client)) { - sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload); + return sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload); } + return false; } -void WebSocketsServer::sendBIN(uint8_t num, const uint8_t * payload, size_t length) { - sendBIN(num, (uint8_t *) payload, length); +bool WebSocketsServer::sendBIN(uint8_t num, const uint8_t * payload, size_t length) { + return sendBIN(num, (uint8_t *) payload, length); } /** @@ -219,22 +228,27 @@ void WebSocketsServer::sendBIN(uint8_t num, const uint8_t * payload, size_t leng * @param payload uint8_t * * @param length size_t * @param headerToPayload bool (see sendFrame for more details) + * @return true if ok */ -void WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload) { +bool WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload) { WSclient_t * client; + bool ret = true; for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { client = &_clients[i]; if(clientIsConnected(client)) { - sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload); + if(!sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload)) { + ret = false; + } } #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } + return ret; } -void WebSocketsServer::broadcastBIN(const uint8_t * payload, size_t length) { - broadcastBIN((uint8_t *) payload, length); +bool WebSocketsServer::broadcastBIN(const uint8_t * payload, size_t length) { + return broadcastBIN((uint8_t *) payload, length); } /** diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 27d7f8b..8b75982 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -57,23 +57,23 @@ class WebSocketsServer: private WebSockets { void onEvent(WebSocketServerEvent cbEvent); - void sendTXT(uint8_t num, uint8_t * payload, size_t length = 0, bool headerToPayload = false); - void sendTXT(uint8_t num, const uint8_t * payload, size_t length = 0); - void sendTXT(uint8_t num, char * payload, size_t length = 0, bool headerToPayload = false); - 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, bool headerToPayload = false); - void broadcastTXT(const uint8_t * payload, size_t length = 0); - void broadcastTXT(char * payload, size_t length = 0, bool headerToPayload = false); - void broadcastTXT(const char * payload, size_t length = 0); - void broadcastTXT(String & payload); - - void sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload = false); - void sendBIN(uint8_t num, const uint8_t * payload, size_t length); - - void broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload = false); - void broadcastBIN(const uint8_t * payload, size_t length); + bool sendTXT(uint8_t num, uint8_t * payload, size_t length = 0, bool headerToPayload = false); + bool sendTXT(uint8_t num, const uint8_t * payload, size_t length = 0); + bool sendTXT(uint8_t num, char * payload, size_t length = 0, bool headerToPayload = false); + bool sendTXT(uint8_t num, const char * payload, size_t length = 0); + bool sendTXT(uint8_t num, String & payload); + + bool broadcastTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); + bool broadcastTXT(const uint8_t * payload, size_t length = 0); + bool broadcastTXT(char * payload, size_t length = 0, bool headerToPayload = false); + bool broadcastTXT(const char * payload, size_t length = 0); + bool broadcastTXT(String & payload); + + bool sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload = false); + bool sendBIN(uint8_t num, const uint8_t * payload, size_t length); + + bool broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload = false); + bool broadcastBIN(const uint8_t * payload, size_t length); void disconnect(void); void disconnect(uint8_t num); From 49a2a9ab4fef2187d01c9812b910868857504117 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 20 Feb 2016 12:30:38 +0100 Subject: [PATCH 037/347] update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ddf08c2..9325238 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ a WebSocket Server and Client for Arduino based on RFC6455. ###### Note: ###### - version 2.0 is not compatible with AVR/ATmega, check ATmega branch. + version 2.0 and up is not compatible with AVR/ATmega, check ATmega branch. Arduino for AVR not supports std namespace of c++. @@ -43,7 +43,7 @@ This libary can run in Async TCP mode on the ESP. The mode can be aktivated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE define). -```ESPAsyncTCP``` libary is required. +[ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP) libary is required. Note: in this mode wss / SSL is not possible. From 1ebae1d3e1f8b72e366410b00fb216f09f618134 Mon Sep 17 00:00:00 2001 From: Nicholas Crumrine Date: Fri, 4 Mar 2016 14:19:19 -0600 Subject: [PATCH 038/347] Add note about delay() limitation. Change concerns issue https://github.com/Links2004/arduinoWebSockets/issues/58 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ddf08c2..52e25ea 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,8 @@ a WebSocket Server and Client for Arduino based on RFC6455. - max input length is limited to the ram size and the ```WEBSOCKETS_MAX_DATA_SIZE``` define - max output length has no limit (the hardware is the limit) - Client send big frames with mask 0x00000000 (on AVR all frames) - + - Functions called from within the context of the websocket loop might not honor `yield()` and/or `delay()`. See [this issue](https://github.com/Links2004/arduinoWebSockets/issues/58#issuecomment-192376395) for more info and a potential workaround. + - ##### Supported Hardware ##### - ESP8266 [Arduino for ESP8266](https://github.com/Links2004/Arduino) - ESP31B From 8988faf5f0dd69ff5c1cab1611b58d577e03c0fc Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 5 Mar 2016 12:13:13 +0100 Subject: [PATCH 039/347] fix #60 os_printf can not handle String direct --- src/WebSocketsServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index f4c9a55..57e61e4 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -627,7 +627,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cProtocol: %s\n", client->num, client->cProtocol.c_str()); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cExtensions: %s\n", client->num, client->cExtensions.c_str()); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cVersion: %d\n", client->num, client->cVersion); - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - base64Authorization: %s\n", client->num, client->base64Authorization); + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - base64Authorization: %s\n", client->num, client->base64Authorization.c_str()); bool ok = (client->cIsUpgrade && client->cIsWebsocket); From 5b4eaa0b11979f83020eb9dcc7ec8923ddcdde41 Mon Sep 17 00:00:00 2001 From: Uri Shaked Date: Wed, 16 Mar 2016 03:28:21 +0200 Subject: [PATCH 040/347] fix typo: lenght -> length --- examples/WebSocketClientSSL/WebSocketClientSSL.ino | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/WebSocketClientSSL/WebSocketClientSSL.ino b/examples/WebSocketClientSSL/WebSocketClientSSL.ino index f4bced1..62e860b 100644 --- a/examples/WebSocketClientSSL/WebSocketClientSSL.ino +++ b/examples/WebSocketClientSSL/WebSocketClientSSL.ino @@ -22,7 +22,7 @@ WebSocketsClient webSocket; #define USE_SERIAL Serial1 -void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch(type) { @@ -44,11 +44,11 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { // webSocket.sendTXT("message here"); break; case WStype_BIN: - USE_SERIAL.printf("[WSc] get binary lenght: %u\n", lenght); - hexdump(payload, lenght); + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); // send data to server - // webSocket.sendBIN(payload, lenght); + // webSocket.sendBIN(payload, length); break; } From 00be8c7833b32a377e3d1f7135abf40697bc7ee0 Mon Sep 17 00:00:00 2001 From: Uri Shaked Date: Wed, 16 Mar 2016 11:55:21 +0200 Subject: [PATCH 041/347] Make the `Sec-WebSocket-Protocol` header optional Some server implementations (e.g. slack bots api) don't accept the connection if `Sec-WebSocket-Protocol` is specified. --- src/WebSocketsClient.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index fca918c..6995272 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -397,9 +397,12 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { "Connection: Upgrade\r\n" "User-Agent: arduino-WebSocket-Client\r\n" "Sec-WebSocket-Version: 13\r\n" - "Sec-WebSocket-Protocol: " + client->cProtocol +"\r\n" "Sec-WebSocket-Key: " + client->cKey + "\r\n"; + if(client->cProtocol.length() > 0) { + handshake += "Sec-WebSocket-Protocol: " + client->cProtocol + "\r\n"; + } + if(client->cExtensions.length() > 0) { handshake += "Sec-WebSocket-Extensions: " + client->cExtensions + "\r\n"; } From ea997cf97761666e9ea102896904fa2a653361f2 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Wed, 16 Mar 2016 16:25:31 +0100 Subject: [PATCH 042/347] update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c174569..c625942 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,11 @@ a WebSocket Server and Client for Arduino based on RFC6455. - max input length is limited to the ram size and the ```WEBSOCKETS_MAX_DATA_SIZE``` define - max output length has no limit (the hardware is the limit) - Client send big frames with mask 0x00000000 (on AVR all frames) - - Functions called from within the context of the websocket loop might not honor `yield()` and/or `delay()`. See [this issue](https://github.com/Links2004/arduinoWebSockets/issues/58#issuecomment-192376395) for more info and a potential workaround. - - + + ##### Limitations for Async ##### + - Functions called from within the context of the websocket event might not honor `yield()` and/or `delay()`. See [this issue](https://github.com/Links2004/arduinoWebSockets/issues/58#issuecomment-192376395) for more info and a potential workaround. + - wss / SSL is not possible. + ##### Supported Hardware ##### - ESP8266 [Arduino for ESP8266](https://github.com/Links2004/Arduino) - ESP31B @@ -46,8 +49,6 @@ The mode can be aktivated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE [ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP) libary is required. -Note: in this mode wss / SSL is not possible. - ### Issues ### Submit issues to: https://github.com/Links2004/arduinoWebSockets/issues From b3efb316ed2148811e235515b724ead45d33120b Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Wed, 16 Mar 2016 16:25:57 +0100 Subject: [PATCH 043/347] bump version --- library.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library.properties b/library.properties index 9e73afe..85f8dff 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=WebSockets -version=2.0 +version=2.0.2 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) -paragraph=use 2.0 for ESP and 1.3 for AVR +paragraph=use 2.x.x for ESP and 1.3 for AVR category=Communication url=https://github.com/Links2004/arduinoWebSockets architectures=* From 4f55c36c80d21a1fb855c6e0161c4ed4a3b6fbe7 Mon Sep 17 00:00:00 2001 From: Wayne May Date: Sat, 30 Apr 2016 15:46:19 -0700 Subject: [PATCH 044/347] RFC requires a port for Host when it is non default. https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.23 --- src/WebSocketsClient.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 6995272..2261f2c 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -392,7 +392,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { #endif String handshake = "GET " + client->cUrl + " HTTP/1.1\r\n" - "Host: " + _host + "\r\n" + "Host: " + _host + ":" + _port + "\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" "User-Agent: arduino-WebSocket-Client\r\n" @@ -620,6 +620,3 @@ void WebSocketsClient::asyncConnect() { } #endif - - - From 10a8d3ca67d85af7cce5967507180947226a4326 Mon Sep 17 00:00:00 2001 From: Wayne May Date: Sat, 30 Apr 2016 20:55:59 -0700 Subject: [PATCH 045/347] Adding Origin, as required by spec. https://tools.ietf.org/html/rfc6455#section-1.6 --- src/WebSocketsClient.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 2261f2c..97d84e8 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -393,8 +393,9 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { String handshake = "GET " + client->cUrl + " HTTP/1.1\r\n" "Host: " + _host + ":" + _port + "\r\n" - "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" + "Upgrade: websocket\r\n" + "Origin: file://\r\n" "User-Agent: arduino-WebSocket-Client\r\n" "Sec-WebSocket-Version: 13\r\n" "Sec-WebSocket-Key: " + client->cKey + "\r\n"; From d36f7bb100bfc2d34d3ac5be6268744eecc1384e Mon Sep 17 00:00:00 2001 From: Thorsten Freitag Date: Mon, 9 May 2016 00:11:42 +1000 Subject: [PATCH 046/347] Changed Header value to lower case upgrade, seems to fix connection issues with SAP HCP IoT services. Changed setAuthorization(const char * auth) to send Auth header as is, without BASIC to enable oAuth tokens in header --- src/WebSockets.h | 1 + src/WebSocketsClient.cpp | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index dbca2b3..fcd85a6 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -181,6 +181,7 @@ typedef struct { WSMessageHeader_t cWsHeaderDecode; String base64Authorization; ///< Base64 encoded Auth request + String plainAuthorization; ///< Base64 encoded Auth request #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) String cHttpLine; ///< HTTP header lines diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 6995272..f8821e5 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -62,6 +62,7 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url, _client.cExtensions = ""; _client.cVersion = 0; _client.base64Authorization = ""; + _client.plainAuthorization = ""; #ifdef ESP8266 randomSeed(RANDOM_REG32); @@ -228,7 +229,8 @@ void WebSocketsClient::setAuthorization(const char * user, const char * password */ void WebSocketsClient::setAuthorization(const char * auth) { if(auth) { - _client.base64Authorization = auth; + //_client.base64Authorization = auth; + _client.plainAuthorization = auth; } } @@ -400,7 +402,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { "Sec-WebSocket-Key: " + client->cKey + "\r\n"; if(client->cProtocol.length() > 0) { - handshake += "Sec-WebSocket-Protocol: " + client->cProtocol + "\r\n"; + handshake += "Sec-WebSocket-Protocol: " + client->cProtocol + "\r\n"; } if(client->cExtensions.length() > 0) { @@ -411,6 +413,10 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { handshake += "Authorization: Basic " + client->base64Authorization + "\r\n"; } + if(client->plainAuthorization.length() > 0) { + handshake += "Authorization: " + client->plainAuthorization + "\r\n"; + } + handshake += "\r\n"; client->tcp->write(handshake.c_str(), handshake.length()); @@ -442,7 +448,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { String headerValue = headerLine->substring(headerLine->indexOf(':') + 2); if(headerName.equalsIgnoreCase("Connection")) { - if(headerValue.indexOf("Upgrade") >= 0) { + if(headerValue.indexOf("upgrade") >= 0) { client->cIsUpgrade = true; } } else if(headerName.equalsIgnoreCase("Upgrade")) { From dd14850bb67cc3ee5d856c86d5d0110494b834f7 Mon Sep 17 00:00:00 2001 From: Thorsten Freitag Date: Tue, 10 May 2016 11:56:01 +1000 Subject: [PATCH 047/347] Used case insensitive recognition for upgrade header. Should work as before, but also with servers that wrongly use lower case upgrade in the header --- src/WebSocketsClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index f8821e5..a0bb6a5 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -448,7 +448,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { String headerValue = headerLine->substring(headerLine->indexOf(':') + 2); if(headerName.equalsIgnoreCase("Connection")) { - if(headerValue.indexOf("upgrade") >= 0) { + if(headerValue.equalsIgnoreCase("upgrade")) { client->cIsUpgrade = true; } } else if(headerName.equalsIgnoreCase("Upgrade")) { From c4e5f5c7e7e9f7468dc247b7a5616ab8835918d3 Mon Sep 17 00:00:00 2001 From: jlippa Date: Sat, 4 Jun 2016 21:31:42 +0100 Subject: [PATCH 048/347] RFC 6455 4.2.1.4 case sensitivity fix This is a case sensitivity fix for the Connection header Upgrade value to make this part meet the requirement of IETF websocket RFC 6455 4.2.1.4: "A |Connection| header field that includes the token "Upgrade", treated as an ASCII case-insensitive value." --- src/WebSocketsServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 57e61e4..dbe0b34 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -590,7 +590,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { String headerValue = headerLine->substring(headerLine->indexOf(':') + 2); if(headerName.equalsIgnoreCase("Connection")) { - if(headerValue.indexOf("Upgrade") >= 0) { + if(headerValue.equalsIgnoreCase("Upgrade")) { client->cIsUpgrade = true; } } else if(headerName.equalsIgnoreCase("Upgrade")) { From 48ee5fc6fbdd43bb9c425ef54df3085b36c7b1c5 Mon Sep 17 00:00:00 2001 From: jlippa Date: Sun, 5 Jun 2016 08:27:39 +0100 Subject: [PATCH 049/347] Firefox fix Overlay fix for Firefox and other clients that send additional data in the Connection header e.g. "Connection: Keep-Alive, Upgrade" --- src/WebSocketsServer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index dbe0b34..ccde0cd 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -590,7 +590,8 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { String headerValue = headerLine->substring(headerLine->indexOf(':') + 2); if(headerName.equalsIgnoreCase("Connection")) { - if(headerValue.equalsIgnoreCase("Upgrade")) { + headerValue.toLowerCase(); + if(headerValue.indexOf("upgrade") >= 0) { client->cIsUpgrade = true; } } else if(headerName.equalsIgnoreCase("Upgrade")) { From 8190e8121c64865f5309ae81ecaa01fb5169612d Mon Sep 17 00:00:00 2001 From: joe Date: Sun, 5 Jun 2016 15:29:11 +0100 Subject: [PATCH 050/347] Added sample ESP8266 nginx SSL reverse proxy configuration file --- examples/Nginx/esp8266.ssl.reverse.proxy.conf | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 examples/Nginx/esp8266.ssl.reverse.proxy.conf diff --git a/examples/Nginx/esp8266.ssl.reverse.proxy.conf b/examples/Nginx/esp8266.ssl.reverse.proxy.conf new file mode 100644 index 0000000..ec5aa89 --- /dev/null +++ b/examples/Nginx/esp8266.ssl.reverse.proxy.conf @@ -0,0 +1,83 @@ +# ESP8266 nginx SSL reverse proxy configuration file (tested and working on nginx v1.10.0) + +# proxy cache location +proxy_cache_path /opt/etc/nginx/cache levels=1:2 keys_zone=ESP8266_cache:10m max_size=10g inactive=5m use_temp_path=off; + +# webserver proxy +server { + + # general server parameters + listen 50080; + server_name myDomain.net; + access_log /opt/var/log/nginx/myDomain.net.access.log; + + # SSL configuration + ssl on; + ssl_certificate /usr/builtin/etc/certificate/lets-encrypt/myDomain.net/fullchain.pem; + ssl_certificate_key /usr/builtin/etc/certificate/lets-encrypt/myDomain.net/privkey.pem; + ssl_session_cache builtin:1000 shared:SSL:10m; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; + ssl_prefer_server_ciphers on; + + location / { + + # proxy caching configuration + proxy_cache ESP8266_cache; + proxy_cache_revalidate on; + proxy_cache_min_uses 1; + proxy_cache_use_stale off; + proxy_cache_lock on; + # proxy_cache_bypass $http_cache_control; + # include the sessionId cookie value as part of the cache key - keeps the cache per user + # proxy_cache_key $proxy_host$request_uri$cookie_sessionId; + + # header pass through configuration + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # ESP8266 custom headers which identify to the device that it's running through an SSL proxy + proxy_set_header X-SSL On; + proxy_set_header X-SSL-WebserverPort 50080; + proxy_set_header X-SSL-WebsocketPort 50081; + + # extra debug headers + add_header X-Proxy-Cache $upstream_cache_status; + add_header X-Forwarded-For $proxy_add_x_forwarded_for; + + # actual proxying configuration + proxy_ssl_session_reuse on; + # target the IP address of the device with proxy_pass + proxy_pass http://192.168.0.20; + proxy_read_timeout 90; + } + } + +# websocket proxy +server { + + # general server parameters + listen 50081; + server_name myDomain.net; + access_log /opt/var/log/nginx/myDomain.net.wss.access.log; + + # SSL configuration + ssl on; + ssl_certificate /usr/builtin/etc/certificate/lets-encrypt/myDomain.net/fullchain.pem; + ssl_certificate_key /usr/builtin/etc/certificate/lets-encrypt/myDomain.net/privkey.pem; + ssl_session_cache builtin:1000 shared:SSL:10m; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; + ssl_prefer_server_ciphers on; + + location / { + + # websocket upgrade tunnel configuration + proxy_pass http://192.168.0.20:81; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_read_timeout 86400; + } + } From f8a5acc9b787480602788d52dfb231433d1ec488 Mon Sep 17 00:00:00 2001 From: Kenta Kusumoto Date: Mon, 6 Jun 2016 15:21:13 +0300 Subject: [PATCH 051/347] Add socket.io client --- .../WebSocketClientSocketIO.ino | 113 ++++++++++++++++++ src/WebSockets.cpp | 7 +- src/WebSockets.h | 3 + src/WebSocketsClient.cpp | 60 +++++++--- src/WebSocketsClient.h | 3 + 5 files changed, 168 insertions(+), 18 deletions(-) create mode 100644 examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino diff --git a/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino b/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino new file mode 100644 index 0000000..8736559 --- /dev/null +++ b/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino @@ -0,0 +1,113 @@ +/* + * WebSocketClientSocketIO.ino + * + * Created on: 06.06.2016 + * + */ + +#include + +#include +#include + +#include + +#include + +ESP8266WiFiMulti WiFiMulti; +WebSocketsClient webSocket; + + +#define USE_SERIAL Serial1 + +#define MESSAGE_INTERVAL 30000 +#define HEARTBEAT_INTERVAL 25000 + +uint64_t messageTimestamp = 0; +uint64_t heartbeatTimestamp = 0; +bool isConnected = false; + +void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { + + + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[WSc] Disconnected!\n"); + isConnected = false; + break; + case WStype_CONNECTED: + { + USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); + isConnected = true; + + // send message to server when Connected + // socket.io upgrade confirmation message (required) + webSocket.sendTXT("5"); + } + break; + case WStype_TEXT: + USE_SERIAL.printf("[WSc] get text: %s\n", payload); + + // send message to server + // webSocket.sendTXT("message here"); + break; + case WStype_BIN: + USE_SERIAL.printf("[WSc] get binary lenght: %u\n", lenght); + hexdump(payload, lenght); + + // send data to server + // webSocket.sendBIN(payload, lenght); + break; + } + +} + +void setup() { + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + //Serial.setDebugOutput(true); + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFiMulti.addAP("SSID", "passpasspass"); + + //WiFi.disconnect(); + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + webSocket.begin("192.168.0.123", 81); + //webSocket.setAuthorization("user", "Password"); // HTTP Basic Authorization + webSocket.onEvent(webSocketEvent); + +} + +void loop() { + webSocket.loop(); + + if(isConnected) { + + uint64_t now = millis(); + + if(now - messageTimestamp > INTERVAL) { + messageTimestamp = now; + // example socket.io message with type "messageType" and JSON payload + webSocket.sendTXT("42[\"messageType\",{\"greeting\":\"hello\"}]"); + } + if((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) { + heartbeatTimestamp = now; + // socket.io heartbeat message + webSocket.sendTXT("2"); + } + } +} diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 3b18344..2da0d90 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -296,7 +296,7 @@ bool WebSockets::handleWebsocketWaitFor(WSclient_t * client, size_t size) { } if(size > WEBSOCKETS_MAX_HEADER_SIZE) { - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocketWaitFor] size: %d to big!\n", client->num, size); + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocketWaitFor] size: %d too big!\n", client->num, size); return false; } @@ -364,7 +364,7 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) { } if(buffer[0] != 0 || buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0) { - // really to big! + // really too big! header->payloadLen = 0xFFFFFFFF; } else { header->payloadLen = buffer[4] << 24 | buffer[5] << 16 | buffer[6] << 8 | buffer[7]; @@ -377,7 +377,7 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) { DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] mask: %u payloadLen: %u\n", client->num, header->mask, header->payloadLen); if(header->payloadLen > WEBSOCKETS_MAX_DATA_SIZE) { - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] payload to big! (%u)\n", client->num, header->payloadLen); + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] payload too big! (%u)\n", client->num, header->payloadLen); clientDisconnect(client, 1009); return; } @@ -596,4 +596,3 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait #endif return true; } - diff --git a/src/WebSockets.h b/src/WebSockets.h index fcd85a6..ac062f4 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -159,6 +159,8 @@ typedef struct { WEBSOCKETS_NETWORK_CLASS * tcp; + bool isSocketIO; ///< client for socket.io server + #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) bool isSSL; ///< run in ssl mode WiFiClientSecure * ssl; @@ -170,6 +172,7 @@ typedef struct { bool cIsUpgrade; ///< Connection == Upgrade bool cIsWebsocket; ///< Upgrade == websocket + String cSessionId; ///< client Set-Cookie (session id) String cKey; ///< client Sec-WebSocket-Key String cAccept; ///< client Sec-WebSocket-Accept String cProtocol; ///< client Sec-WebSocket-Protocol diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 31a169a..aefb743 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -91,6 +91,14 @@ void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String f } #endif +void WebSocketsClient::beginSocketIO(const char *host, uint16_t port, const char * url, const char * protocol) { + begin(host, port, url, protocol); + _client.isSocketIO = true; +} + +void WebSocketsClient::beginSocketIO(String host, uint16_t port, String url, String protocol) { + beginSocketIO(host.c_str(), port, url.c_str(), protocol.c_str()); +} #if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** @@ -393,23 +401,38 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { unsigned long start = micros(); #endif - String handshake = "GET " + client->cUrl + " HTTP/1.1\r\n" - "Host: " + _host + ":" + _port + "\r\n" - "Connection: Upgrade\r\n" - "Upgrade: websocket\r\n" - "Origin: file://\r\n" - "User-Agent: arduino-WebSocket-Client\r\n" - "Sec-WebSocket-Version: 13\r\n" - "Sec-WebSocket-Key: " + client->cKey + "\r\n"; - - if(client->cProtocol.length() > 0) { - handshake += "Sec-WebSocket-Protocol: " + client->cProtocol + "\r\n"; - } + String transport; + String handshake; + if(!client->isSocketIO || (client->isSocketIO && client->cSessionId.length() > 0)) { + if(client->isSocketIO) { + transport = "&transport=websocket&sid=" + client->cSessionId; + } + handshake = "GET " + client->cUrl + transport + " HTTP/1.1\r\n" + "Host: " + _host + ":" + _port + "\r\n" + "Connection: Upgrade\r\n" + "Upgrade: websocket\r\n" + "Origin: file://\r\n" + "User-Agent: arduino-WebSocket-Client\r\n" + "Sec-WebSocket-Version: 13\r\n" + "Sec-WebSocket-Key: " + client->cKey + "\r\n"; + + if(client->cProtocol.length() > 0) { + handshake += "Sec-WebSocket-Protocol: " + client->cProtocol + "\r\n"; + } + + if(client->cExtensions.length() > 0) { + handshake += "Sec-WebSocket-Extensions: " + client->cExtensions + "\r\n"; + } - if(client->cExtensions.length() > 0) { - handshake += "Sec-WebSocket-Extensions: " + client->cExtensions + "\r\n"; + } else { + handshake = "GET " + client->cUrl + "&transport=polling HTTP/1.1\r\n" + "Connection: keep-alive\r\n"; } + handshake += "Host: " + _host + ":" + _port + "\r\n" + "Origin: file://\r\n" + "User-Agent: arduino-WebSocket-Client\r\n"; + if(client->base64Authorization.length() > 0) { handshake += "Authorization: Basic " + client->base64Authorization + "\r\n"; } @@ -465,6 +488,8 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { client->cExtensions = headerValue; } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Version")) { client->cVersion = headerValue.toInt(); + } else if(headerName.equalsIgnoreCase("Set-Cookie")) { + client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1); } } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); @@ -490,6 +515,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cProtocol: %s\n", client->cProtocol.c_str()); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cExtensions: %s\n", client->cExtensions.c_str()); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cVersion: %d\n", client->cVersion); + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cSessionId: %s\n", client->cSessionId.c_str()); bool ok = (client->cIsUpgrade && client->cIsWebsocket); @@ -498,6 +524,10 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { case 101: ///< Switching Protocols break; + case 200: + if(client->isSocketIO) { + break; + } case 403: ///< Forbidden // todo handle login default: ///< Server dont unterstand requrst @@ -530,6 +560,8 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { runCbEvent(WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length()); + } else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) { + sendHeader(client); } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); client->tcp->write("This is a webSocket client!"); diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index b029d07..97cf560 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -48,6 +48,9 @@ class WebSocketsClient: private WebSockets { void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino"); #endif + void beginSocketIO(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); + void beginSocketIO(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); + #if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void loop(void); #else From bf3cfa623748795dc7421efdb0d546e9f273aa9a Mon Sep 17 00:00:00 2001 From: Kenta Kusumoto Date: Mon, 6 Jun 2016 17:50:31 +0300 Subject: [PATCH 052/347] Fix reference to INTERVAL --- examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino b/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino index 8736559..6d08b02 100644 --- a/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino +++ b/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino @@ -99,7 +99,7 @@ void loop() { uint64_t now = millis(); - if(now - messageTimestamp > INTERVAL) { + if(now - messageTimestamp > MESSAGE_INTERVAL) { messageTimestamp = now; // example socket.io message with type "messageType" and JSON payload webSocket.sendTXT("42[\"messageType\",{\"greeting\":\"hello\"}]"); From e589b40b2582cc8a0b4ef0cfd2ce1d1ed5b9357d Mon Sep 17 00:00:00 2001 From: joe Date: Wed, 8 Jun 2016 23:04:18 +0100 Subject: [PATCH 053/347] custom http header validation implementation --- .../WebSocketServerHttpHeaderValidation.ino | 85 ++++++++++++++++++ src/WebSockets.cpp | 2 +- src/WebSockets.h | 5 +- src/WebSocketsServer.cpp | 87 ++++++++++++++++--- src/WebSocketsServer.h | 33 ++++++- 5 files changed, 196 insertions(+), 16 deletions(-) create mode 100644 examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino diff --git a/examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino b/examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino new file mode 100644 index 0000000..5323b84 --- /dev/null +++ b/examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino @@ -0,0 +1,85 @@ +/* + * WebSocketServer.ino + * + * Created on: 22.05.2015 + * + */ + +#include + +#include +#include +#include +#include + +ESP8266WiFiMulti WiFiMulti; + +WebSocketsServer webSocket = WebSocketsServer(81); + +#define USE_SERIAL Serial1 + +const unsigned long int validSessionId = 12345; //some arbitrary value to act as a valid sessionId + +/* + * Returns a bool value as an indicator to describe whether a user is allowed to initiate a websocket upgrade + * based on the value of a cookie. This function expects the rawCookieHeaderValue to look like this "sessionId=|" + */ +bool isCookieValid(String rawCookieHeaderValue) { + + if (rawCookieHeaderValue.indexOf("sessionId") != -1) { + String sessionIdStr = rawCookieHeaderValue.substring(rawCookieHeaderValue.indexOf("sessionId=") + 10, rawCookieHeaderValue.indexOf("|")); + unsigned long int sessionId = strtoul(sessionIdStr.c_str(), NULL, 10); + return sessionId == validSessionId; + } + return false; +} + +/* + * The WebSocketServerHttpHeaderValFunc delegate passed to webSocket.onValidateHttpHeader + */ +bool validateHttpHeader(String headerName, String headerValue) { + + //assume a true response for any headers not handled by this validator + bool valid = true; + + if(headerName.equalsIgnoreCase("Cookie")) { + //if the header passed is the Cookie header, validate it according to the rules in 'isCookieValid' function + valid = isCookieValid(headerValue); + } + + return valid; +} + +void setup() { + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + //Serial.setDebugOutput(true); + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFiMulti.addAP("SSID", "passpasspass"); + + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + //connecting clients must supply a valid session cookie at websocket upgrade handshake negotiation time + const char * headerkeys[] = { "Cookie" }; + webSocket.onValidateHttpHeader(validateHttpHeader, headerkeys); + webSocket.begin(); +} + +void loop() { + webSocket.loop(); +} + diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 3b18344..3c89b9d 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -426,7 +426,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] text: %s\n", client->num, payload); // no break here! case WSop_binary: - messageRecived(client, header->opCode, payload, header->payloadLen); + messageReceived(client, header->opCode, payload, header->payloadLen); break; case WSop_ping: // send pong back diff --git a/src/WebSockets.h b/src/WebSockets.h index fcd85a6..b78199f 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -183,6 +183,9 @@ typedef struct { String base64Authorization; ///< Base64 encoded Auth request String plainAuthorization; ///< Base64 encoded Auth request + bool cHttpHeadersValid; ///< non-websocket http header validity indicator + size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count + #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) String cHttpLine; ///< HTTP header lines #endif @@ -202,7 +205,7 @@ class WebSockets { virtual void clientDisconnect(WSclient_t * client); virtual bool clientIsConnected(WSclient_t * client); - virtual void messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); + virtual void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0); bool sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false, bool fin = true, bool headerToPayload = false); diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index ccde0cd..eaaf731 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -40,6 +40,9 @@ WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol _cbEvent = NULL; + _httpHeaderValidationFunc = NULL; + _mandatoryHttpHeaders = NULL; + _mandatoryHttpHeaderCount = 0; } @@ -53,10 +56,14 @@ WebSocketsServer::~WebSocketsServer() { // TODO how to close server? #endif + if (_mandatoryHttpHeaders) + delete[] _mandatoryHttpHeaders; + + _mandatoryHttpHeaderCount = 0; } /** - * calles to init the Websockets server + * called to initialize the Websocket server */ void WebSocketsServer::begin(void) { WSclient_t * client; @@ -83,6 +90,7 @@ void WebSocketsServer::begin(void) { client->base64Authorization = ""; client->cWsRXsize = 0; + #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->cHttpLine = ""; #endif @@ -118,7 +126,30 @@ void WebSocketsServer::onEvent(WebSocketServerEvent cbEvent) { _cbEvent = cbEvent; } -/** +/* + * Sets the custom http header validator function + * If this functionality is being used, call this function prior to calling WebSocketsServer::begin + * @param httpHeaderValidationFunc WebSocketServerHttpHeaderValFunc ///< pointer to the custom http header validation function + * @param mandatoryHttpHeaders const char* ///< the array of named http headers considered to be mandatory / must be present in order for websocket upgrade to succeed + */ +void WebSocketsServer::onValidateHttpHeader( + WebSocketServerHttpHeaderValFunc validationFunc, + const char* mandatoryHttpHeaders[]) +{ + _httpHeaderValidationFunc = validationFunc; + + if (_mandatoryHttpHeaders) + delete[] _mandatoryHttpHeaders; + + _mandatoryHttpHeaderCount = (sizeof(mandatoryHttpHeaders) / sizeof(char*)); + _mandatoryHttpHeaders = new String[_mandatoryHttpHeaderCount]; + + for (size_t i = 0; i < _mandatoryHttpHeaderCount; i++) { + _mandatoryHttpHeaders[i] = mandatoryHttpHeaders[i]; + } +} + +/* * send text data to client * @param num uint8_t client id * @param payload uint8_t * @@ -279,9 +310,8 @@ void WebSocketsServer::disconnect(uint8_t num) { } - -/** - * set the Authorizatio for the http request +/* + * set the Authorization for the http request * @param user const char * * @param password const char * */ @@ -388,7 +418,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { * @param payload uint8_t * * @param lenght size_t */ -void WebSocketsServer::messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t lenght) { +void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t lenght) { WStype_t type = WStype_ERROR; switch(opcode) { @@ -446,6 +476,7 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { client->cIsWebsocket = false; client->cWsRXsize = 0; + #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->cHttpLine = ""; #endif @@ -461,7 +492,7 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { /** * get client state * @param client WSclient_t * ptr to the client struct - * @return true = conneted + * @return true = connected */ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { @@ -492,7 +523,7 @@ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { } #if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** - * Handle incomming Connection Request + * Handle incoming Connection Request */ void WebSocketsServer::handleNewClients(void) { @@ -569,10 +600,22 @@ void WebSocketsServer::handleClientData(void) { } #endif +/* + * returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection + * @param headerName String ///< the name of the header being checked + */ +bool WebSocketsServer::hasMandatoryHeader(String headerName) { + for (size_t i = 0; i < _mandatoryHttpHeaderCount; i++) { + if (_mandatoryHttpHeaders[i].equalsIgnoreCase(headerName)) + return true; + } + return false; +} /** - * handle the WebSocket header reading - * @param client WSclient_t * ptr to the client struct + * handles http header reading for WebSocket upgrade + * @param client WSclient_t * ///< pointer to the client struct + * @param headerLine String ///< the header being read / processed */ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { @@ -581,10 +624,16 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { if(headerLine->length() > 0) { DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine->c_str()); - // websocket request starts allways with GET see rfc6455 + // websocket requests always start with GET see rfc6455 if(headerLine->startsWith("GET ")) { + // cut URL out client->cUrl = headerLine->substring(4, headerLine->indexOf(' ', 4)); + + //reset non-websocket http header validation state for this client + client->cHttpHeadersValid = true; + client->cMandatoryHeadersCount = 0; + } else if(headerLine->indexOf(':')) { String headerName = headerLine->substring(0, headerLine->indexOf(':')); String headerValue = headerLine->substring(headerLine->indexOf(':') + 2); @@ -609,7 +658,13 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { client->cExtensions = headerValue; } else if(headerName.equalsIgnoreCase("Authorization")) { client->base64Authorization = headerValue; + } else { + client->cHttpHeadersValid &= execHttpHeaderValidation(headerName, headerValue); + if (_mandatoryHttpHeaderCount > 0 && hasMandatoryHeader(headerName)) { + client->cMandatoryHeadersCount++; + } } + } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); } @@ -619,8 +674,8 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine))); #endif } else { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Header read fin.\n", client->num); + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Header read fin.\n", client->num); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cURL: %s\n", client->num, client->cUrl.c_str()); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cIsUpgrade: %d\n", client->num, client->cIsUpgrade); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cIsWebsocket: %d\n", client->num, client->cIsWebsocket); @@ -629,6 +684,8 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cExtensions: %s\n", client->num, client->cExtensions.c_str()); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cVersion: %d\n", client->num, client->cVersion); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - base64Authorization: %s\n", client->num, client->base64Authorization.c_str()); + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cHttpHeadersValid: %d\n", client->num, client->cHttpHeadersValid); + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cMandatoryHeadersCount: %d\n", client->num, client->cMandatoryHeadersCount); bool ok = (client->cIsUpgrade && client->cIsWebsocket); @@ -642,6 +699,12 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { if(client->cVersion != 13) { ok = false; } + if(!client->cHttpHeadersValid) { + ok = false; + } + if (client->cMandatoryHeadersCount != _mandatoryHttpHeaderCount) { + ok = false; + } } if(_base64Authorization.length() > 0) { diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 8b75982..d03f840 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -38,8 +38,10 @@ class WebSocketsServer: private WebSockets { #ifdef __AVR__ typedef void (*WebSocketServerEvent)(uint8_t num, WStype_t type, uint8_t * payload, size_t length); + typedef bool (*WebSocketServerHttpHeaderValFunc)(String headerName, String headerValue); #else typedef std::function WebSocketServerEvent; + typedef std::function WebSocketServerHttpHeaderValFunc; #endif WebSocketsServer(uint16_t port, String origin = "", String protocol = "arduino"); @@ -55,6 +57,7 @@ class WebSocketsServer: private WebSockets { #endif void onEvent(WebSocketServerEvent cbEvent); + void onValidateHttpHeader(WebSocketServerHttpHeaderValFunc validationFunc, const char* mandatoryHttpHeaders[]); bool sendTXT(uint8_t num, uint8_t * payload, size_t length = 0, bool headerToPayload = false); @@ -90,16 +93,19 @@ class WebSocketsServer: private WebSockets { String _origin; String _protocol; String _base64Authorization; ///< Base64 encoded Auth request + String * _mandatoryHttpHeaders; + size_t _mandatoryHttpHeaderCount; WEBSOCKETS_NETWORK_SERVER_CLASS * _server; WSclient_t _clients[WEBSOCKETS_SERVER_CLIENT_MAX]; WebSocketServerEvent _cbEvent; + WebSocketServerHttpHeaderValFunc _httpHeaderValidationFunc; bool newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); - void messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); + void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); void clientDisconnect(WSclient_t * client); bool clientIsConnected(WSclient_t * client); @@ -111,7 +117,6 @@ class WebSocketsServer: private WebSockets { void handleHeader(WSclient_t * client, String * headerLine); - /** * called if a non Websocket connection is coming in. * Note: can be override @@ -162,6 +167,30 @@ class WebSocketsServer: private WebSockets { } } + /* + * Called at client socket connect handshake negotiation time for each http header that is not + * a websocket specific http header (not Connection, Upgrade, Sec-WebSocket-*) + * If the custom httpHeaderValidationFunc returns false for any headerName / headerValue passed, the + * socket negotiation is considered invalid and the upgrade to websockets request is denied / rejected + * This mechanism can be used to enable custom authentication schemes e.g. test the value + * of a session cookie to determine if a user is logged on / authenticated + */ + virtual bool execHttpHeaderValidation(String headerName, String headerValue) { + if(_httpHeaderValidationFunc) { + //return the value of the custom http header validation function + return _httpHeaderValidationFunc(headerName, headerValue); + } + //no custom http header validation so just assume all is good + return true; + } + +private: + /* + * returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection + * @param headerName String ///< the name of the header being checked + */ + bool hasMandatoryHeader(String headerName); + }; From 97443ae7774a3f5ec0de2a6a8f9ad034d2c9fe1f Mon Sep 17 00:00:00 2001 From: joe Date: Wed, 8 Jun 2016 23:11:21 +0100 Subject: [PATCH 054/347] custom http header validation implementation; minor comment fixes --- .../WebSocketServer/WebSocketServerHttpHeaderValidation.ino | 4 ++-- src/WebSocketsServer.cpp | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino b/examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino index 5323b84..ecbc739 100644 --- a/examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino +++ b/examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino @@ -1,7 +1,7 @@ /* - * WebSocketServer.ino + * WebSocketServerHttpHeaderValidation.ino * - * Created on: 22.05.2015 + * Created on: 08.06.2016 * */ diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index eaaf731..c2457bf 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -128,7 +128,6 @@ void WebSocketsServer::onEvent(WebSocketServerEvent cbEvent) { /* * Sets the custom http header validator function - * If this functionality is being used, call this function prior to calling WebSocketsServer::begin * @param httpHeaderValidationFunc WebSocketServerHttpHeaderValFunc ///< pointer to the custom http header validation function * @param mandatoryHttpHeaders const char* ///< the array of named http headers considered to be mandatory / must be present in order for websocket upgrade to succeed */ From 7e5c64a5735b107e9d0a0c50d0399dccfa253f8d Mon Sep 17 00:00:00 2001 From: joe Date: Thu, 9 Jun 2016 19:48:38 +0100 Subject: [PATCH 055/347] mandatoryHttpHeaderCount fix --- .../WebSocketServerHttpHeaderValidation.ino | 3 ++- src/WebSocketsServer.cpp | 8 +++++--- src/WebSocketsServer.h | 5 ++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino b/examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino index ecbc739..da58fa3 100644 --- a/examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino +++ b/examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino @@ -75,7 +75,8 @@ void setup() { //connecting clients must supply a valid session cookie at websocket upgrade handshake negotiation time const char * headerkeys[] = { "Cookie" }; - webSocket.onValidateHttpHeader(validateHttpHeader, headerkeys); + size_t headerKeyCount = sizeof(headerkeys) / sizeof(char*); + webSocket.onValidateHttpHeader(validateHttpHeader, headerkeys, headerKeyCount); webSocket.begin(); } diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index c2457bf..53641d2 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -129,18 +129,20 @@ void WebSocketsServer::onEvent(WebSocketServerEvent cbEvent) { /* * Sets the custom http header validator function * @param httpHeaderValidationFunc WebSocketServerHttpHeaderValFunc ///< pointer to the custom http header validation function - * @param mandatoryHttpHeaders const char* ///< the array of named http headers considered to be mandatory / must be present in order for websocket upgrade to succeed + * @param mandatoryHttpHeaders[] const char* ///< the array of named http headers considered to be mandatory / must be present in order for websocket upgrade to succeed + * @param mandatoryHttpHeaderCount size_t ///< the number of items in the mandatoryHttpHeaders array */ void WebSocketsServer::onValidateHttpHeader( WebSocketServerHttpHeaderValFunc validationFunc, - const char* mandatoryHttpHeaders[]) + const char* mandatoryHttpHeaders[], + size_t mandatoryHttpHeaderCount) { _httpHeaderValidationFunc = validationFunc; if (_mandatoryHttpHeaders) delete[] _mandatoryHttpHeaders; - _mandatoryHttpHeaderCount = (sizeof(mandatoryHttpHeaders) / sizeof(char*)); + _mandatoryHttpHeaderCount = mandatoryHttpHeaderCount; _mandatoryHttpHeaders = new String[_mandatoryHttpHeaderCount]; for (size_t i = 0; i < _mandatoryHttpHeaderCount; i++) { diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index d03f840..7a93c0e 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -57,7 +57,10 @@ class WebSocketsServer: private WebSockets { #endif void onEvent(WebSocketServerEvent cbEvent); - void onValidateHttpHeader(WebSocketServerHttpHeaderValFunc validationFunc, const char* mandatoryHttpHeaders[]); + void onValidateHttpHeader( + WebSocketServerHttpHeaderValFunc validationFunc, + const char* mandatoryHttpHeaders[], + size_t mandatoryHttpHeaderCount); bool sendTXT(uint8_t num, uint8_t * payload, size_t length = 0, bool headerToPayload = false); From 815093a123588c8c3bed0b0f96f9c0754367d7ac Mon Sep 17 00:00:00 2001 From: joe Date: Sat, 11 Jun 2016 10:17:13 +0100 Subject: [PATCH 056/347] wss / SSL README.md documentation update --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index c625942..0394d98 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,9 @@ a WebSocket Server and Client for Arduino based on RFC6455. ### wss / SSL ### supported for: - wss client on the ESP8266 + - wss / SSL is not natively supported in WebSocketsServer however it is possible to achieve secure websockets + by running the device behind an SSL proxy. See [Nginx](examples/Nginx/esp8266.ssl.reverse.proxy.conf) for a + sample Nginx server configuration file to enable this. ### ESP Async TCP ### From b3d4367d10fff53aa47b9fdcd0e156f2a84f9e86 Mon Sep 17 00:00:00 2001 From: cella Date: Fri, 17 Jun 2016 15:37:07 +0100 Subject: [PATCH 057/347] fix spellings --- src/WebSocketsClient.cpp | 2 +- src/WebSocketsClient.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 31a169a..af29c97 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -245,7 +245,7 @@ void WebSocketsClient::setAuthorization(const char * auth) { * @param payload uint8_t * * @param lenght size_t */ -void WebSocketsClient::messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t lenght) { +void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t lenght) { WStype_t type = WStype_ERROR; switch(opcode) { diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index b029d07..9fa43bd 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -82,7 +82,7 @@ class WebSocketsClient: private WebSockets { WebSocketClientEvent _cbEvent; - void messageRecived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); + void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); void clientDisconnect(WSclient_t * client); bool clientIsConnected(WSclient_t * client); From cdee9fec058869f77e1c0c19c09bed132fe3e9a4 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 11 Jul 2016 17:29:29 +0200 Subject: [PATCH 058/347] release version 2.0.4 --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 85f8dff..0a8fa91 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.0.2 +version=2.0.4 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From 1961ddc1593dc8b184d3f3f65e9afa8460a928b9 Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Mon, 11 Jul 2016 17:30:08 +0200 Subject: [PATCH 059/347] bump git version --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 0a8fa91..0c5c9bd 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.0.4 +version=2.0.5 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From 7361e2b1b66b9bbd9cdb0beeac06676cb78647f2 Mon Sep 17 00:00:00 2001 From: Sergey Anisimov Date: Fri, 15 Jul 2016 20:29:13 +0100 Subject: [PATCH 060/347] WEBSOCKETS_NETWORK_TYPE exteral definition Making possible to define WEBSOCKETS_NETWORK_TYPE as a compile parameter. --- src/WebSockets.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/WebSockets.h b/src/WebSockets.h index b78199f..22b1e28 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -52,6 +52,7 @@ // max size of the WS Message Header #define WEBSOCKETS_MAX_HEADER_SIZE (14) +#if !defined(WEBSOCKETS_NETWORK_TYPE) // select Network type based #if defined(ESP8266) || defined(ESP31B) #define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 @@ -59,6 +60,7 @@ #else #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 #endif +#endif #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) From d036dcd8e23389c7e04cf8caf406dd19cfbc9f43 Mon Sep 17 00:00:00 2001 From: Roman3349 Date: Tue, 27 Sep 2016 11:25:56 +0200 Subject: [PATCH 061/347] Add information about examples, license and version to @PlatformIO Library Registry manifest file Signed-off-by: Roman3349 --- library.json | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/library.json b/library.json index 14bae5d..c8a3b09 100644 --- a/library.json +++ b/library.json @@ -1,19 +1,28 @@ { - "name": "WebSockets", - "keywords": "wifi, http, web, server, client, websocket", - "description": "WebSocket Server and Client for Arduino based on RFC6455", - "repository": - { - "type": "git", - "url": "https://github.com/Links2004/arduinoWebSockets.git" - }, - "exclude": "tests", - "frameworks": "arduino", - "platforms": "*", - "authors": - { - "name": "Markus Sattler", - "url": "https://github.com/Links2004", - "maintainer": true - } + "name": "WebSockets", + "description": "WebSocket Server and Client for Arduino based on RFC6455", + "keywords": "wifi, http, web, server, client, websocket", + "authors": [ + { + "name": "Markus Sattler", + "url": "https://github.com/Links2004", + "maintainer": true + } + ], + "repository": { + "type": "git", + "url": "https://github.com/Links2004/arduinoWebSockets.git" + }, + "version": "2.0.5", + "license": "LGPL-2.1", + "export": { + "exclude": [ + "tests" + ] + }, + "frameworks": "arduino", + "platforms": "*", + "examples": [ + "examples/*/*.ino" + ] } From 7810d0d0b3cf07012bd6c67735713bbcd0af6485 Mon Sep 17 00:00:00 2001 From: CAOU123 Date: Thu, 20 Oct 2016 15:46:44 -0400 Subject: [PATCH 062/347] Make library compatible with Particle devices --- README.md | 4 ++ .../ParticleWebSocketClient/application.cpp | 46 +++++++++++++++++++ src/WebSockets.cpp | 2 +- src/WebSockets.h | 17 +++++++ src/WebSocketsClient.cpp | 2 +- src/WebSocketsClient.h | 1 - src/WebSocketsServer.cpp | 6 +-- src/WebSocketsServer.h | 1 - 8 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 examples/ParticleWebSocketClient/application.cpp diff --git a/README.md b/README.md index 0394d98..6a6ebb8 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,10 @@ The mode can be aktivated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE [ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP) libary is required. +### Support for Particle devices ### +- ESP.getFreeHeap() replaced by macro GET_FREE_HEAP, defined by the type of device (currently only for ESP and STM32-based/Particle devices). +- Use Particle's TCPClient and TCPServer classes instead of Arduino's. + ### Issues ### Submit issues to: https://github.com/Links2004/arduinoWebSockets/issues diff --git a/examples/ParticleWebSocketClient/application.cpp b/examples/ParticleWebSocketClient/application.cpp new file mode 100644 index 0000000..461228f --- /dev/null +++ b/examples/ParticleWebSocketClient/application.cpp @@ -0,0 +1,46 @@ +/* To compile using make CLI, create a folder under \firmware\user\applications and copy application.cpp there. +* Then, copy src files under particleWebSocket folder. +*/ + +#include "application.h" +#include "particleWebSocket/WebSocketsClient.h" + +WebSocketsClient webSocket; + +void webSocketEvent(WStype_t type, uint8_t* payload, size_t length) +{ + switch (type) + { + case WStype_DISCONNECTED: + Serial.printlnf("[WSc] Disconnected!"); + break; + case WStype_CONNECTED: + Serial.printlnf("[WSc] Connected to URL: %s", payload); + webSocket.sendTXT("Connected\r\n"); + break; + case WStype_TEXT: + Serial.printlnf("[WSc] get text: %s", payload); + break; + case WStype_BIN: + Serial.printlnf("[WSc] get binary length: %u", length); + break; + } +} + +void setup() +{ + Serial.begin(9600); + + WiFi.setCredentials("[SSID]", "[PASSWORD]", WPA2, WLAN_CIPHER_AES_TKIP); + WiFi.connect(); + + webSocket.begin("192.168.1.153", 85, "/ClientService/?variable=Test1212"); + webSocket.onEvent(webSocketEvent); +} + +void loop() +{ + webSocket.sendTXT("Hello world!"); + delay(500); + webSocket.loop(); +} diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 6e9c2af..79d3dfc 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -123,7 +123,7 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay #ifdef WEBSOCKETS_USE_BIG_MEM // only for ESP since AVR has less HEAP // try to send data in one TCP package (only if some free Heap is there) - if(!headerToPayload && ((length > 0) && (length < 1400)) && (ESP.getFreeHeap() > 6000)) { + if(!headerToPayload && ((length > 0) && (length < 1400)) && (GET_FREE_HEAP > 6000)) { DEBUG_WEBSOCKETS("[WS][%d][sendFrame] pack to one TCP package...\n", client->num); uint8_t * dataPtr = (uint8_t *) malloc(length + WEBSOCKETS_MAX_HEADER_SIZE); if(dataPtr) { diff --git a/src/WebSockets.h b/src/WebSockets.h index c43f4d9..272eeca 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -25,7 +25,12 @@ #ifndef WEBSOCKETS_H_ #define WEBSOCKETS_H_ +#ifdef STM32_DEVICE +#include +#define bit(b) (1UL << (b)) // Taken directly from Arduino.h +#else #include +#endif //#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) @@ -37,10 +42,17 @@ #ifdef ESP8266 #define WEBSOCKETS_MAX_DATA_SIZE (15*1024) #define WEBSOCKETS_USE_BIG_MEM +#define GET_FREE_HEAP ESP.getFreeHeap() +#else +#ifdef STM32_DEVICE +#define WEBSOCKETS_MAX_DATA_SIZE (15*1024) +#define WEBSOCKETS_USE_BIG_MEM +#define GET_FREE_HEAP System.freeMemory() #else //atmega328p has only 2KB ram! #define WEBSOCKETS_MAX_DATA_SIZE (1024) #endif +#endif #define WEBSOCKETS_TCP_TIMEOUT (2000) @@ -98,10 +110,15 @@ #elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_W5100) +#ifdef STM32_DEVICE +#define WEBSOCKETS_NETWORK_CLASS TCPClient +#define WEBSOCKETS_NETWORK_SERVER_CLASS TCPServer +#else #include #include #define WEBSOCKETS_NETWORK_CLASS EthernetClient #define WEBSOCKETS_NETWORK_SERVER_CLASS EthernetServer +#endif #elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ENC28J60) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 3b93a14..384d5a9 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -443,7 +443,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { handshake += "\r\n"; - client->tcp->write(handshake.c_str(), handshake.length()); + client->tcp->write((uint8_t*)handshake.c_str(), handshake.length()); #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine))); diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 2a8bc3e..f1db64f 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -25,7 +25,6 @@ #ifndef WEBSOCKETSCLIENT_H_ #define WEBSOCKETSCLIENT_H_ -#include #include "WebSockets.h" class WebSocketsClient: private WebSockets { diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 53641d2..34ccf61 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -739,20 +739,20 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { "Connection: Upgrade\r\n" "Sec-WebSocket-Version: 13\r\n" "Sec-WebSocket-Accept: "); - client->tcp->write(sKey.c_str(), sKey.length()); + client->tcp->write((uint8_t*)sKey.c_str(), sKey.length()); if(_origin.length() > 0) { String origin = "\r\nAccess-Control-Allow-Origin: "; origin += _origin; origin += "\r\n"; - client->tcp->write(origin.c_str(), origin.length()); + client->tcp->write((uint8_t*)origin.c_str(), origin.length()); } if(client->cProtocol.length() > 0) { String protocol = "\r\nSec-WebSocket-Protocol: "; protocol += _protocol; protocol += "\r\n"; - client->tcp->write(protocol.c_str(), protocol.length()); + client->tcp->write((uint8_t*)protocol.c_str(), protocol.length()); } else { client->tcp->write("\r\n"); } diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 7a93c0e..8bf9496 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -25,7 +25,6 @@ #ifndef WEBSOCKETSSERVER_H_ #define WEBSOCKETSSERVER_H_ -#include #include "WebSockets.h" #define WEBSOCKETS_SERVER_CLIENT_MAX (5) From 0d9aa043f004352711509a5e684edba195b17b57 Mon Sep 17 00:00:00 2001 From: Markus Date: Sat, 22 Oct 2016 20:36:36 +0200 Subject: [PATCH 063/347] fix WebSocketClientSocketIO example --- examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino b/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino index 6d08b02..9f54361 100644 --- a/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino +++ b/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino @@ -86,7 +86,7 @@ void setup() { delay(100); } - webSocket.begin("192.168.0.123", 81); + webSocket.beginSocketIO("192.168.0.123", 81); //webSocket.setAuthorization("user", "Password"); // HTTP Basic Authorization webSocket.onEvent(webSocketEvent); From d2719573d44a67872bbf9bb2886f42fcd67ebfba Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 22 Oct 2016 19:47:44 +0200 Subject: [PATCH 064/347] add function to send WS ping sendPing(); #130 --- src/WebSocketsClient.cpp | 18 ++++++++++++++ src/WebSocketsClient.h | 3 +++ src/WebSocketsServer.cpp | 51 ++++++++++++++++++++++++++++++++++++++++ src/WebSocketsServer.h | 6 +++++ 4 files changed, 78 insertions(+) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 3b93a14..9b4aad0 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -207,6 +207,24 @@ bool WebSocketsClient::sendBIN(const uint8_t * payload, size_t length) { return sendBIN((uint8_t *) payload, length); } +/** + * sends a WS ping to Server + * @param payload uint8_t * + * @param length size_t + * @return true if ping is send out + */ +bool WebSocketsClient::sendPing(uint8_t * payload, size_t length) { + if(clientIsConnected(&_client)) { + return sendFrame(&_client, WSop_ping, payload, length); + } + return false; +} + +bool WebSocketsClient::sendPing(String & payload) { + return sendPing((uint8_t *) payload.c_str(), payload.length()); +} + + /** * disconnect one client * @param num uint8_t client id diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 2a8bc3e..bae1777 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -69,6 +69,9 @@ class WebSocketsClient: private WebSockets { bool sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false); bool sendBIN(const uint8_t * payload, size_t length); + bool sendPing(uint8_t * payload = NULL, size_t length = 0); + bool sendPing(String & payload); + void disconnect(void); void setAuthorization(const char * user, const char * password); diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 53641d2..c2262f6 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -283,6 +283,57 @@ bool WebSocketsServer::broadcastBIN(const uint8_t * payload, size_t length) { return broadcastBIN((uint8_t *) payload, length); } + +/** + * sends a WS ping to Client + * @param num uint8_t client id + * @param payload uint8_t * + * @param length size_t + * @return true if ping is send out + */ +bool WebSocketsServer::sendPing(uint8_t num, uint8_t * payload, size_t length) { + if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) { + return false; + } + WSclient_t * client = &_clients[num]; + if(clientIsConnected(client)) { + return sendFrame(client, WSop_ping, payload, length); + } + return false; +} + +bool WebSocketsServer::sendPing(uint8_t num, String & payload) { + return sendPing(num, (uint8_t *) payload.c_str(), payload.length()); +} + +/** + * sends a WS ping to all Client + * @param payload uint8_t * + * @param length size_t + * @return true if ping is send out + */ +bool WebSocketsServer::broadcastPing(uint8_t * payload, size_t length) { + WSclient_t * client; + bool ret = true; + for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + client = &_clients[i]; + if(clientIsConnected(client)) { + if(!sendFrame(client, WSop_ping, payload, length)) { + ret = false; + } + } +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + delay(0); +#endif + } + return ret; +} + +bool WebSocketsServer::broadcastPing(String & payload) { + return broadcastPing((uint8_t *) payload.c_str(), payload.length()); +} + + /** * disconnect all clients */ diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 7a93c0e..f6acee5 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -81,6 +81,12 @@ class WebSocketsServer: private WebSockets { bool broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload = false); bool broadcastBIN(const uint8_t * payload, size_t length); + bool sendPing(uint8_t num, uint8_t * payload = NULL, size_t length = 0); + bool sendPing(uint8_t num, String & payload); + + bool broadcastPing(uint8_t * payload = NULL, size_t length = 0); + bool broadcastPing(String & payload); + void disconnect(void); void disconnect(uint8_t num); From 75133dfa6d6c0f4d52fbb61b37b371d4ecb4512c Mon Sep 17 00:00:00 2001 From: Markus Sattler Date: Sat, 22 Oct 2016 19:48:16 +0200 Subject: [PATCH 065/347] version bumb --- library.json | 2 +- library.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index c8a3b09..46de566 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.0.5", + "version": "2.0.6", "license": "LGPL-2.1", "export": { "exclude": [ diff --git a/library.properties b/library.properties index 0c5c9bd..0725e3f 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.0.5 +version=2.0.6 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From 689e3ef92116eb8e70605f067d6f60aa3624c7c1 Mon Sep 17 00:00:00 2001 From: Ugo Riboni Date: Tue, 8 Nov 2016 01:48:01 +0100 Subject: [PATCH 066/347] Change inheritance of WebSocketServer to allow classes inheriting from it to call sendFrame with custom arguments. --- src/WebSocketsServer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index f6acee5..654bd41 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -33,7 +33,7 @@ -class WebSocketsServer: private WebSockets { +class WebSocketsServer: public WebSockets { public: #ifdef __AVR__ From a097f0defdf5b30fef54ee0e128ea319dbf88bb6 Mon Sep 17 00:00:00 2001 From: Ugo Riboni Date: Tue, 8 Nov 2016 22:52:00 +0100 Subject: [PATCH 067/347] protected inheritance is enough --- src/WebSocketsServer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 654bd41..b50effa 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -33,7 +33,7 @@ -class WebSocketsServer: public WebSockets { +class WebSocketsServer: protected WebSockets { public: #ifdef __AVR__ From 5cd68c5304f142c730e0d565411c202a393ae244 Mon Sep 17 00:00:00 2001 From: quantumlicht Date: Wed, 16 Nov 2016 18:31:39 -0500 Subject: [PATCH 068/347] - Remove duplicate handshake headers - Add debug log for displaying handshake headers Host, Origin, and User-Agent were duplicated in the case the client was not socketIO or if it was and has a sessionId --- src/WebSocketsClient.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 9b4aad0..3e2e49d 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -426,11 +426,8 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { transport = "&transport=websocket&sid=" + client->cSessionId; } handshake = "GET " + client->cUrl + transport + " HTTP/1.1\r\n" - "Host: " + _host + ":" + _port + "\r\n" "Connection: Upgrade\r\n" "Upgrade: websocket\r\n" - "Origin: file://\r\n" - "User-Agent: arduino-WebSocket-Client\r\n" "Sec-WebSocket-Version: 13\r\n" "Sec-WebSocket-Key: " + client->cKey + "\r\n"; @@ -460,7 +457,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { } handshake += "\r\n"; - + DEBUG_WEBSOCKETS("[WS-Client][sendHeader] handshake %s", handshake.c_str()); client->tcp->write(handshake.c_str(), handshake.length()); #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) From 45bb7dbe238408ff55cd32228f174515632297dd Mon Sep 17 00:00:00 2001 From: Markus Date: Wed, 23 Nov 2016 17:39:48 +0100 Subject: [PATCH 069/347] Update WebSocketsClient.cpp fix #140 Socket.io client doesn't reconnect to server --- src/WebSocketsClient.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 3e2e49d..8866327 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -331,6 +331,7 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { client->cVersion = 0; client->cIsUpgrade = false; client->cIsWebsocket = false; + client->SessionId = ""; client->status = WSC_NOT_CONNECTED; From ab3b5bae4656bac77bc645b18260eac39e27220b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Toledo?= Date: Thu, 24 Nov 2016 02:25:01 -0200 Subject: [PATCH 070/347] Update WebSocketsClient.cpp fix typo that was breaking the build --- src/WebSocketsClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 8866327..0cb1f38 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -331,7 +331,7 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { client->cVersion = 0; client->cIsUpgrade = false; client->cIsWebsocket = false; - client->SessionId = ""; + client->cSessionId = ""; client->status = WSC_NOT_CONNECTED; From 0aaf50f87f46ff6a4011ea83dd91e12d053d7bcf Mon Sep 17 00:00:00 2001 From: Markus Date: Fri, 6 Jan 2017 10:44:25 +0100 Subject: [PATCH 071/347] mask ping for client fix #34 --- src/WebSocketsClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 0cb1f38..fbcb3a1 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -215,7 +215,7 @@ bool WebSocketsClient::sendBIN(const uint8_t * payload, size_t length) { */ bool WebSocketsClient::sendPing(uint8_t * payload, size_t length) { if(clientIsConnected(&_client)) { - return sendFrame(&_client, WSop_ping, payload, length); + return sendFrame(&_client, WSop_ping, payload, length, true); } return false; } From 60903a2fa5807ea38b26b33a82daeed8880b8e6d Mon Sep 17 00:00:00 2001 From: Markus Date: Fri, 6 Jan 2017 10:48:30 +0100 Subject: [PATCH 072/347] mask pong #34 --- src/WebSockets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 6e9c2af..18eb019 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -430,7 +430,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t break; case WSop_ping: // send pong back - sendFrame(client, WSop_pong, payload, header->payloadLen); + sendFrame(client, WSop_pong, payload, header->payloadLen, true); break; case WSop_pong: DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload); From dac71c4c238b770b6beec816ae494c61bb3c4eb5 Mon Sep 17 00:00:00 2001 From: Markus Date: Sun, 8 Jan 2017 09:55:28 +0100 Subject: [PATCH 073/347] moving host header try to fix #159 --- src/WebSocketsClient.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index fbcb3a1..91fee1d 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -427,6 +427,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { transport = "&transport=websocket&sid=" + client->cSessionId; } handshake = "GET " + client->cUrl + transport + " HTTP/1.1\r\n" + "Host: " + _host + ":" + _port + "\r\n" "Connection: Upgrade\r\n" "Upgrade: websocket\r\n" "Sec-WebSocket-Version: 13\r\n" @@ -442,11 +443,11 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { } else { handshake = "GET " + client->cUrl + "&transport=polling HTTP/1.1\r\n" + "Host: " + _host + ":" + _port + "\r\n" "Connection: keep-alive\r\n"; } - handshake += "Host: " + _host + ":" + _port + "\r\n" - "Origin: file://\r\n" + handshake += "Origin: file://\r\n" "User-Agent: arduino-WebSocket-Client\r\n"; if(client->base64Authorization.length() > 0) { From bef2541ede696f512b5efd0d31adb47700f43223 Mon Sep 17 00:00:00 2001 From: Markus Date: Sat, 21 Jan 2017 12:28:56 +0100 Subject: [PATCH 074/347] fix #162 missing isSocketIO init --- src/WebSocketsClient.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 91fee1d..e0019fd 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -63,6 +63,7 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url, _client.cVersion = 0; _client.base64Authorization = ""; _client.plainAuthorization = ""; + _client.isSocketIO = false; #ifdef ESP8266 randomSeed(RANDOM_REG32); From 6757b8b74c4f136fa6c760eab480f671506d5c1d Mon Sep 17 00:00:00 2001 From: nguyenhunga5 Date: Fri, 3 Feb 2017 13:30:20 +0700 Subject: [PATCH 075/347] Fix socket.io issue Fix socket.io issue reference from https://github.com/Links2004/arduinoWebSockets/issues/167#issuecomment-276724057 --- src/WebSocketsClient.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index e0019fd..c526d96 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -507,7 +507,11 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Version")) { client->cVersion = headerValue.toInt(); } else if(headerName.equalsIgnoreCase("Set-Cookie")) { - client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1); + if (headerValue.indexOf("HttpOnly") > -1) { + client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1, headerValue.indexOf(";")); + } else { + client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1); + } } } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); From f52d718cf23bae41c1f6cd6e7215f6879e0dede9 Mon Sep 17 00:00:00 2001 From: tzapu Date: Fri, 3 Feb 2017 13:53:46 +0200 Subject: [PATCH 076/347] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0394d98..6f2e5a4 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ a WebSocket Server and Client for Arduino based on RFC6455. This libary can run in Async TCP mode on the ESP. -The mode can be aktivated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE define). +The mode can be activated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE define). [ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP) libary is required. From ae2ba7effe08993a6a2d0429d10a9c97b3b82e02 Mon Sep 17 00:00:00 2001 From: Markus Date: Wed, 8 Feb 2017 19:05:27 +0100 Subject: [PATCH 077/347] bump version to 2.0.7 --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 0725e3f..983024e 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.0.6 +version=2.0.7 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From 6da0bc97e8745fa828ae5d8b806ccdd300e68cdf Mon Sep 17 00:00:00 2001 From: Markus Date: Wed, 8 Feb 2017 19:06:06 +0100 Subject: [PATCH 078/347] bump version to 2.0.7 --- library.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.json b/library.json index 46de566..60e02a4 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.0.6", + "version": "2.0.7", "license": "LGPL-2.1", "export": { "exclude": [ From e93a323e565ad7af9e00d54b3548a40ea9161b5c Mon Sep 17 00:00:00 2001 From: Links Date: Wed, 22 Feb 2017 14:29:26 +0100 Subject: [PATCH 079/347] add support for Fragmentation / continuation opcode Receive --- README.md | 33 +++---- .../WebSocketServerFragmentation.ino | 94 +++++++++++++++++++ src/WebSockets.cpp | 11 +-- src/WebSockets.h | 12 ++- src/WebSocketsClient.cpp | 9 +- src/WebSocketsClient.h | 2 +- src/WebSocketsServer.cpp | 9 +- src/WebSocketsServer.h | 2 +- 8 files changed, 137 insertions(+), 35 deletions(-) create mode 100644 examples/WebSocketServer/WebSocketServerFragmentation.ino diff --git a/README.md b/README.md index 5041cbf..c829ef4 100644 --- a/README.md +++ b/README.md @@ -3,47 +3,47 @@ WebSocket Server and Client for Arduino a WebSocket Server and Client for Arduino based on RFC6455. - + ##### Supported features of RFC6455 ##### - text frame - binary frame - connection close - ping - pong - -##### Not supported features of RFC6455 ##### - continuation frame - + ##### Limitations ##### - max input length is limited to the ram size and the ```WEBSOCKETS_MAX_DATA_SIZE``` define - max output length has no limit (the hardware is the limit) - Client send big frames with mask 0x00000000 (on AVR all frames) - + - continuation frame reassembly need to be handled in the application code + ##### Limitations for Async ##### - Functions called from within the context of the websocket event might not honor `yield()` and/or `delay()`. See [this issue](https://github.com/Links2004/arduinoWebSockets/issues/58#issuecomment-192376395) for more info and a potential workaround. - wss / SSL is not possible. - + ##### Supported Hardware ##### - ESP8266 [Arduino for ESP8266](https://github.com/Links2004/Arduino) - ESP31B - - ATmega328 with Ethernet Shield (ATmega branch) - - ATmega328 with enc28j60 (ATmega branch) - - ATmega2560 with Ethernet Shield (ATmega branch) - - ATmega2560 with enc28j60 (ATmega branch) - + - Particle with STM32 ARM Cortex M3 + - ATmega328 with Ethernet Shield (ATmega branch) + - ATmega328 with enc28j60 (ATmega branch) + - ATmega2560 with Ethernet Shield (ATmega branch) + - ATmega2560 with enc28j60 (ATmega branch) + ###### Note: ###### version 2.0 and up is not compatible with AVR/ATmega, check ATmega branch. - + Arduino for AVR not supports std namespace of c++. - + ### wss / SSL ### supported for: - wss client on the ESP8266 - wss / SSL is not natively supported in WebSocketsServer however it is possible to achieve secure websockets by running the device behind an SSL proxy. See [Nginx](examples/Nginx/esp8266.ssl.reverse.proxy.conf) for a - sample Nginx server configuration file to enable this. - + sample Nginx server configuration file to enable this. + ### ESP Async TCP ### This libary can run in Async TCP mode on the ESP. @@ -52,9 +52,6 @@ The mode can be activated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE [ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP) libary is required. -### Support for Particle devices ### -- ESP.getFreeHeap() replaced by macro GET_FREE_HEAP, defined by the type of device (currently only for ESP and STM32-based/Particle devices). -- Use Particle's TCPClient and TCPServer classes instead of Arduino's. ### Issues ### Submit issues to: https://github.com/Links2004/arduinoWebSockets/issues diff --git a/examples/WebSocketServer/WebSocketServerFragmentation.ino b/examples/WebSocketServer/WebSocketServerFragmentation.ino new file mode 100644 index 0000000..e51f2ac --- /dev/null +++ b/examples/WebSocketServer/WebSocketServerFragmentation.ino @@ -0,0 +1,94 @@ +/* + * WebSocketServer.ino + * + * Created on: 22.05.2015 + * + */ + +#include + +#include +#include +#include +#include + +ESP8266WiFiMulti WiFiMulti; + +WebSocketsServer webSocket = WebSocketsServer(81); + +#define USE_SERIAL Serial + +String fragmentBuffer = ""; + +void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) { + + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[%u] Disconnected!\n", num); + break; + case WStype_CONNECTED: { + IPAddress ip = webSocket.remoteIP(num); + USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); + + // send message to client + webSocket.sendTXT(num, "Connected"); + } + break; + case WStype_TEXT: + USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); + break; + case WStype_BIN: + USE_SERIAL.printf("[%u] get binary lenght: %u\n", num, lenght); + hexdump(payload, lenght); + break; + + // Fragmentation / continuation opcode handling + // case WStype_FRAGMENT_BIN_START: + case WStype_FRAGMENT_TEXT_START: + fragmentBuffer = (char*)payload; + USE_SERIAL.printf("[%u] get start start of Textfragment: %s\n", num, payload); + break; + case WStype_FRAGMENT: + fragmentBuffer += (char*)payload; + USE_SERIAL.printf("[%u] get Textfragment : %s\n", num, payload); + break; + case WStype_FRAGMENT_FIN: + fragmentBuffer += (char*)payload; + USE_SERIAL.printf("[%u] get end of Textfragment: %s\n", num, payload); + USE_SERIAL.printf("[%u] full frame: %s\n", num, fragmentBuffer.c_str()); + break; + } + +} + +void setup() { + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + //Serial.setDebugOutput(true); + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFiMulti.addAP("SSID", "passpasspass"); + + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + webSocket.begin(); + webSocket.onEvent(webSocketEvent); +} + +void loop() { + webSocket.loop(); +} + diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 3c3d69d..118ebb7 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -426,14 +426,15 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] text: %s\n", client->num, payload); // no break here! case WSop_binary: - messageReceived(client, header->opCode, payload, header->payloadLen); + case WSop_continuation: + messageReceived(client, header->opCode, payload, header->payloadLen, header->fin); break; case WSop_ping: // send pong back sendFrame(client, WSop_pong, payload, header->payloadLen, true); break; case WSop_pong: - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload); + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload ? (const char*)payload : ""); break; case WSop_close: { uint16_t reasonCode = 1000; @@ -449,11 +450,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t } clientDisconnect(client, 1000); } - break; - case WSop_continuation: - // continuation is not supported - clientDisconnect(client, 1003); - break; + break; default: clientDisconnect(client, 1002); break; diff --git a/src/WebSockets.h b/src/WebSockets.h index 272eeca..a3419bc 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -32,7 +32,11 @@ #include #endif +#ifdef DEBUG_ESP_PORT +#define DEBUG_WEBSOCKETS(...) DEBUG_ESP_PORT.printf( __VA_ARGS__ ) +#else //#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) +#endif #ifndef DEBUG_WEBSOCKETS #define DEBUG_WEBSOCKETS(...) @@ -142,7 +146,11 @@ typedef enum { WStype_DISCONNECTED, WStype_CONNECTED, WStype_TEXT, - WStype_BIN + WStype_BIN, + WStype_FRAGMENT_TEXT_START, + WStype_FRAGMENT_BIN_START, + WStype_FRAGMENT, + WStype_FRAGMENT_FIN, } WStype_t; typedef enum { @@ -227,7 +235,7 @@ class WebSockets { virtual void clientDisconnect(WSclient_t * client); virtual bool clientIsConnected(WSclient_t * client); - virtual void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); + virtual void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0); bool sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false, bool fin = true, bool headerToPayload = false); diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 18c9f6c..76e354c 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -272,16 +272,19 @@ void WebSocketsClient::setAuthorization(const char * auth) { * @param payload uint8_t * * @param lenght size_t */ -void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t lenght) { +void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t lenght, bool fin) { WStype_t type = WStype_ERROR; switch(opcode) { case WSop_text: - type = WStype_TEXT; + type = fin ? WStype_TEXT : WStype_FRAGMENT_TEXT_START; break; case WSop_binary: - type = WStype_BIN; + type = fin ? WStype_BIN : WStype_FRAGMENT_BIN_START; break; + case WSop_continuation: + type = fin ? WStype_FRAGMENT_FIN : WStype_FRAGMENT; + break; } runCbEvent(type, payload, lenght); diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index bdbbb3b..83913dc 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -87,7 +87,7 @@ class WebSocketsClient: private WebSockets { WebSocketClientEvent _cbEvent; - void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); + void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); void clientDisconnect(WSclient_t * client); bool clientIsConnected(WSclient_t * client); diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 9e6037e..a7d3dc3 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -470,15 +470,18 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { * @param payload uint8_t * * @param lenght size_t */ -void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t lenght) { +void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t lenght, bool fin) { WStype_t type = WStype_ERROR; switch(opcode) { case WSop_text: - type = WStype_TEXT; + type = fin ? WStype_TEXT : WStype_FRAGMENT_TEXT_START; break; case WSop_binary: - type = WStype_BIN; + type = fin ? WStype_BIN : WStype_FRAGMENT_BIN_START; + break; + case WSop_continuation: + type = fin ? WStype_FRAGMENT_FIN : WStype_FRAGMENT; break; } diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 33037ed..6185e92 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -113,7 +113,7 @@ class WebSocketsServer: protected WebSockets { bool newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); - void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length); + void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); void clientDisconnect(WSclient_t * client); bool clientIsConnected(WSclient_t * client); From 34a2d282e4f8425142395fdfb52c29b020389429 Mon Sep 17 00:00:00 2001 From: Links Date: Wed, 22 Feb 2017 15:30:58 +0100 Subject: [PATCH 080/347] allow to moves all Header strings to Flash (~300 Byte) #152 --- src/WebSockets.h | 10 ++++ src/WebSocketsClient.cpp | 111 ++++++++++++++++++++++----------------- src/WebSocketsServer.cpp | 47 +++++++++-------- src/WebSocketsServer.h | 3 +- 4 files changed, 99 insertions(+), 72 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index a3419bc..7bb4303 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -47,6 +47,8 @@ #define WEBSOCKETS_MAX_DATA_SIZE (15*1024) #define WEBSOCKETS_USE_BIG_MEM #define GET_FREE_HEAP ESP.getFreeHeap() +// moves all Header strings to Flash (~300 Byte) +//#define WEBSOCKETS_SAVE_RAM #else #ifdef STM32_DEVICE #define WEBSOCKETS_MAX_DATA_SIZE (15*1024) @@ -55,6 +57,8 @@ #else //atmega328p has only 2KB ram! #define WEBSOCKETS_MAX_DATA_SIZE (1024) +// moves all Header strings to Flash +#define WEBSOCKETS_SAVE_RAM #endif #endif @@ -134,6 +138,12 @@ #error "no network type selected!" #endif +// moves all Header strings to Flash (~300 Byte) +#ifdef WEBSOCKETS_SAVE_RAM +#define WEBSOCKETS_STRING(var) F(var) +#else +#define WEBSOCKETS_STRING(var) var +#endif typedef enum { WSC_NOT_CONNECTED, diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 76e354c..c4a8206 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -404,12 +404,15 @@ void WebSocketsClient::handleClientData(void) { } #endif + /** * send the WebSocket header to Server * @param client WSclient_t * ptr to the client struct */ void WebSocketsClient::sendHeader(WSclient_t * client) { + static const char * NEW_LINE = "\r\n"; + DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header...\n"); uint8_t randomKey[16] = { 0 }; @@ -424,45 +427,59 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { unsigned long start = micros(); #endif - String transport; String handshake; - if(!client->isSocketIO || (client->isSocketIO && client->cSessionId.length() > 0)) { - if(client->isSocketIO) { - transport = "&transport=websocket&sid=" + client->cSessionId; - } - handshake = "GET " + client->cUrl + transport + " HTTP/1.1\r\n" - "Host: " + _host + ":" + _port + "\r\n" - "Connection: Upgrade\r\n" - "Upgrade: websocket\r\n" - "Sec-WebSocket-Version: 13\r\n" - "Sec-WebSocket-Key: " + client->cKey + "\r\n"; - - if(client->cProtocol.length() > 0) { - handshake += "Sec-WebSocket-Protocol: " + client->cProtocol + "\r\n"; - } - - if(client->cExtensions.length() > 0) { - handshake += "Sec-WebSocket-Extensions: " + client->cExtensions + "\r\n"; - } - - } else { - handshake = "GET " + client->cUrl + "&transport=polling HTTP/1.1\r\n" - "Host: " + _host + ":" + _port + "\r\n" - "Connection: keep-alive\r\n"; - } - - handshake += "Origin: file://\r\n" - "User-Agent: arduino-WebSocket-Client\r\n"; - - if(client->base64Authorization.length() > 0) { - handshake += "Authorization: Basic " + client->base64Authorization + "\r\n"; - } - - if(client->plainAuthorization.length() > 0) { - handshake += "Authorization: " + client->plainAuthorization + "\r\n"; + bool ws_header = true; + String url = client->cUrl; + + if(client->isSocketIO) { + if(client->cSessionId.length() == 0) { + url += WEBSOCKETS_STRING("&transport=polling"); + ws_header = false; + } else { + url += WEBSOCKETS_STRING("&transport=websocket&sid="); + url += client->cSessionId; + } } - handshake += "\r\n"; + handshake = WEBSOCKETS_STRING("GET "); + handshake += url + WEBSOCKETS_STRING(" HTTP/1.1\r\n" + "Host: "); + handshake += _host + ":" + _port + NEW_LINE; + + if(ws_header) { + handshake += WEBSOCKETS_STRING("Connection: Upgrade\r\n" + "Upgrade: websocket\r\n" + "Sec-WebSocket-Version: 13\r\n" + "Sec-WebSocket-Key: "); + handshake += client->cKey + NEW_LINE; + + if(client->cProtocol.length() > 0) { + handshake += WEBSOCKETS_STRING("Sec-WebSocket-Protocol: "); + handshake +=client->cProtocol + NEW_LINE; + } + + if(client->cExtensions.length() > 0) { + handshake += WEBSOCKETS_STRING("Sec-WebSocket-Extensions: "); + handshake +=client->cExtensions + NEW_LINE; + } + } else { + handshake += WEBSOCKETS_STRING("Connection: keep-alive\r\n"); + } + + handshake += WEBSOCKETS_STRING("Origin: file://\r\n" + "User-Agent: arduino-WebSocket-Client\r\n"); + + if(client->base64Authorization.length() > 0) { + handshake += WEBSOCKETS_STRING("Authorization: Basic "); + handshake += client->base64Authorization + NEW_LINE; + } + + if(client->plainAuthorization.length() > 0) { + handshake += WEBSOCKETS_STRING("Authorization: "); + handshake += client->plainAuthorization + NEW_LINE; + } + + handshake += NEW_LINE; DEBUG_WEBSOCKETS("[WS-Client][sendHeader] handshake %s", (uint8_t*)handshake.c_str()); client->tcp->write((uint8_t*)handshake.c_str(), handshake.length()); @@ -486,32 +503,32 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { if(headerLine->length() > 0) { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str()); - if(headerLine->startsWith("HTTP/1.")) { + if(headerLine->startsWith(WEBSOCKETS_STRING("HTTP/1."))) { // "HTTP/1.1 101 Switching Protocols" client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt(); } else if(headerLine->indexOf(':')) { String headerName = headerLine->substring(0, headerLine->indexOf(':')); String headerValue = headerLine->substring(headerLine->indexOf(':') + 2); - if(headerName.equalsIgnoreCase("Connection")) { - if(headerValue.equalsIgnoreCase("upgrade")) { + if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) { + if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("upgrade"))) { client->cIsUpgrade = true; } - } else if(headerName.equalsIgnoreCase("Upgrade")) { - if(headerValue.equalsIgnoreCase("websocket")) { + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) { + if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) { client->cIsWebsocket = true; } - } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Accept")) { + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Accept"))) { client->cAccept = headerValue; client->cAccept.trim(); // see rfc6455 - } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Protocol")) { + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) { client->cProtocol = headerValue; - } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Extensions")) { + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) { client->cExtensions = headerValue; - } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Version")) { + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) { client->cVersion = headerValue.toInt(); - } else if(headerName.equalsIgnoreCase("Set-Cookie")) { - if (headerValue.indexOf("HttpOnly") > -1) { + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Set-Cookie"))) { + if (headerValue.indexOf(WEBSOCKETS_STRING("HttpOnly")) > -1) { client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1, headerValue.indexOf(";")); } else { client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1); diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index a7d3dc3..adc40ae 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -667,6 +667,7 @@ bool WebSocketsServer::hasMandatoryHeader(String headerName) { return false; } + /** * handles http header reading for WebSocket upgrade * @param client WSclient_t * ///< pointer to the client struct @@ -674,6 +675,8 @@ bool WebSocketsServer::hasMandatoryHeader(String headerName) { */ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { + static const char * NEW_LINE = "\r\n"; + headerLine->trim(); // remove \r if(headerLine->length() > 0) { @@ -693,25 +696,25 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { String headerName = headerLine->substring(0, headerLine->indexOf(':')); String headerValue = headerLine->substring(headerLine->indexOf(':') + 2); - if(headerName.equalsIgnoreCase("Connection")) { + if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) { headerValue.toLowerCase(); - if(headerValue.indexOf("upgrade") >= 0) { + if(headerValue.indexOf(WEBSOCKETS_STRING("upgrade")) >= 0) { client->cIsUpgrade = true; } - } else if(headerName.equalsIgnoreCase("Upgrade")) { - if(headerValue.equalsIgnoreCase("websocket")) { + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) { + if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) { client->cIsWebsocket = true; } - } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Version")) { + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) { client->cVersion = headerValue.toInt(); - } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Key")) { + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Key"))) { client->cKey = headerValue; client->cKey.trim(); // see rfc6455 - } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Protocol")) { + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) { client->cProtocol = headerValue; - } else if(headerName.equalsIgnoreCase("Sec-WebSocket-Extensions")) { + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) { client->cExtensions = headerValue; - } else if(headerName.equalsIgnoreCase("Authorization")) { + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Authorization"))) { client->base64Authorization = headerValue; } else { client->cHttpHeadersValid &= execHttpHeaderValidation(headerName, headerValue); @@ -764,7 +767,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { if(_base64Authorization.length() > 0) { if(client->base64Authorization.length() > 0) { - String auth = "Basic "; + String auth = WEBSOCKETS_STRING("Basic "); auth += _base64Authorization; if(auth != client->base64Authorization) { DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] HTTP Authorization failed!\n", client->num); @@ -787,32 +790,30 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { client->status = WSC_CONNECTED; - client->tcp->write("HTTP/1.1 101 Switching Protocols\r\n" + String handshake = WEBSOCKETS_STRING("HTTP/1.1 101 Switching Protocols\r\n" "Server: arduino-WebSocketsServer\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Version: 13\r\n" "Sec-WebSocket-Accept: "); - client->tcp->write((uint8_t*)sKey.c_str(), sKey.length()); + handshake += sKey + NEW_LINE; if(_origin.length() > 0) { - String origin = "\r\nAccess-Control-Allow-Origin: "; - origin += _origin; - origin += "\r\n"; - client->tcp->write((uint8_t*)origin.c_str(), origin.length()); + handshake += WEBSOCKETS_STRING("Access-Control-Allow-Origin: "); + handshake +=_origin + NEW_LINE; } if(client->cProtocol.length() > 0) { - String protocol = "\r\nSec-WebSocket-Protocol: "; - protocol += _protocol; - protocol += "\r\n"; - client->tcp->write((uint8_t*)protocol.c_str(), protocol.length()); - } else { - client->tcp->write("\r\n"); + handshake += WEBSOCKETS_STRING("Sec-WebSocket-Protocol: "); + handshake +=_protocol + NEW_LINE; } // header end - client->tcp->write("\r\n"); + handshake += NEW_LINE; + + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] handshake %s", client->num, (uint8_t*)handshake.c_str()); + + client->tcp->write((uint8_t*)handshake.c_str(), handshake.length()); headerDone(client); diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 6185e92..3550c6a 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -149,8 +149,7 @@ class WebSocketsServer: protected WebSockets { * @param client WSclient_t * ptr to the client struct */ virtual void handleAuthorizationFailed(WSclient_t *client) { - - client->tcp->write("HTTP/1.1 401 Unauthorized\r\n" + client->tcp->write("HTTP/1.1 401 Unauthorized\r\n" "Server: arduino-WebSocket-Server\r\n" "Content-Type: text/plain\r\n" "Content-Length: 45\r\n" From 210f2e8fa181b155130591844989f2e0a7d31760 Mon Sep 17 00:00:00 2001 From: Philippe Guay Date: Mon, 6 Mar 2017 11:03:43 -0500 Subject: [PATCH 081/347] Add documentation for top level API in README --- README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/README.md b/README.md index c829ef4..18acacb 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,39 @@ a WebSocket Server and Client for Arduino based on RFC6455. - ATmega2560 with Ethernet Shield (ATmega branch) - ATmega2560 with enc28j60 (ATmega branch) +##### High Level API ##### + + - `begin` : Initiate connection sequence to the websocket host. +``` +void begin(const char *host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); +void begin(String host, uint16_t port, String url = "/", String protocol = "arduino"); + ``` + - `onEvent`: Callback to handle for websocket events + + ``` + void onEvent(WebSocketClientEvent cbEvent); + ``` + + - `WebSocketClientEvent`: Handler for websocket events + ``` + void (*WebSocketClientEvent)(WStype_t type, uint8_t * payload, size_t length) + ``` +Where `WStype_t type` is defined as: + ``` + typedef enum { + WStype_ERROR, + WStype_DISCONNECTED, + WStype_CONNECTED, + WStype_TEXT, + WStype_BIN, + WStype_FRAGMENT_TEXT_START, + WStype_FRAGMENT_BIN_START, + WStype_FRAGMENT, + WStype_FRAGMENT_FIN, + } WStype_t; + ``` + + ###### Note: ###### version 2.0 and up is not compatible with AVR/ATmega, check ATmega branch. From 55bc7db7ad915833e2ce3e0fb6efe29942462fa3 Mon Sep 17 00:00:00 2001 From: Markus Date: Mon, 6 Mar 2017 19:16:26 +0100 Subject: [PATCH 082/347] move API docs --- README.md | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 18acacb..8936f6e 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,29 @@ a WebSocket Server and Client for Arduino based on RFC6455. - ATmega2560 with Ethernet Shield (ATmega branch) - ATmega2560 with enc28j60 (ATmega branch) -##### High Level API ##### +###### Note: ###### + + version 2.0 and up is not compatible with AVR/ATmega, check ATmega branch. + + Arduino for AVR not supports std namespace of c++. + +### wss / SSL ### + supported for: + - wss client on the ESP8266 + - wss / SSL is not natively supported in WebSocketsServer however it is possible to achieve secure websockets + by running the device behind an SSL proxy. See [Nginx](examples/Nginx/esp8266.ssl.reverse.proxy.conf) for a + sample Nginx server configuration file to enable this. + +### ESP Async TCP ### + +This libary can run in Async TCP mode on the ESP. + +The mode can be activated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE define). + +[ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP) libary is required. + + +### High Level Client API ### - `begin` : Initiate connection sequence to the websocket host. ``` @@ -63,29 +85,6 @@ Where `WStype_t type` is defined as: } WStype_t; ``` - -###### Note: ###### - - version 2.0 and up is not compatible with AVR/ATmega, check ATmega branch. - - Arduino for AVR not supports std namespace of c++. - -### wss / SSL ### - supported for: - - wss client on the ESP8266 - - wss / SSL is not natively supported in WebSocketsServer however it is possible to achieve secure websockets - by running the device behind an SSL proxy. See [Nginx](examples/Nginx/esp8266.ssl.reverse.proxy.conf) for a - sample Nginx server configuration file to enable this. - -### ESP Async TCP ### - -This libary can run in Async TCP mode on the ESP. - -The mode can be activated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE define). - -[ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP) libary is required. - - ### Issues ### Submit issues to: https://github.com/Links2004/arduinoWebSockets/issues From 3b1dabbe1e68b2e5e5bc8c3f524c4f6c83b206de Mon Sep 17 00:00:00 2001 From: Philippe Guay Date: Mon, 6 Mar 2017 15:07:20 -0500 Subject: [PATCH 083/347] fix typo lenght -> length --- examples/WebSocketClient/WebSocketClient.ino | 8 ++++---- .../WebSocketClientSocketIO/WebSocketClientSocketIO.ino | 8 ++++---- examples/WebSocketServer/WebSocketServer.ino | 8 ++++---- examples/WebSocketServer/WebSocketServerFragmentation.ino | 6 +++--- .../WebSocketServer_LEDcontrol.ino | 2 +- src/WebSocketsClient.cpp | 6 +++--- src/WebSocketsServer.cpp | 6 +++--- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/examples/WebSocketClient/WebSocketClient.ino b/examples/WebSocketClient/WebSocketClient.ino index 82a2cc8..5a344fd 100644 --- a/examples/WebSocketClient/WebSocketClient.ino +++ b/examples/WebSocketClient/WebSocketClient.ino @@ -20,7 +20,7 @@ WebSocketsClient webSocket; #define USE_SERIAL Serial1 -void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch(type) { @@ -42,11 +42,11 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { // webSocket.sendTXT("message here"); break; case WStype_BIN: - USE_SERIAL.printf("[WSc] get binary lenght: %u\n", lenght); - hexdump(payload, lenght); + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); // send data to server - // webSocket.sendBIN(payload, lenght); + // webSocket.sendBIN(payload, length); break; } diff --git a/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino b/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino index 9f54361..39dce87 100644 --- a/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino +++ b/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino @@ -27,7 +27,7 @@ uint64_t messageTimestamp = 0; uint64_t heartbeatTimestamp = 0; bool isConnected = false; -void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch(type) { @@ -52,11 +52,11 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { // webSocket.sendTXT("message here"); break; case WStype_BIN: - USE_SERIAL.printf("[WSc] get binary lenght: %u\n", lenght); - hexdump(payload, lenght); + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); // send data to server - // webSocket.sendBIN(payload, lenght); + // webSocket.sendBIN(payload, length); break; } diff --git a/examples/WebSocketServer/WebSocketServer.ino b/examples/WebSocketServer/WebSocketServer.ino index 795d9a6..5e266a2 100644 --- a/examples/WebSocketServer/WebSocketServer.ino +++ b/examples/WebSocketServer/WebSocketServer.ino @@ -18,7 +18,7 @@ WebSocketsServer webSocket = WebSocketsServer(81); #define USE_SERIAL Serial1 -void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) { +void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { switch(type) { case WStype_DISCONNECTED: @@ -43,11 +43,11 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght // webSocket.broadcastTXT("message here"); break; case WStype_BIN: - USE_SERIAL.printf("[%u] get binary lenght: %u\n", num, lenght); - hexdump(payload, lenght); + USE_SERIAL.printf("[%u] get binary length: %u\n", num, length); + hexdump(payload, length); // send message to client - // webSocket.sendBIN(num, payload, lenght); + // webSocket.sendBIN(num, payload, length); break; } diff --git a/examples/WebSocketServer/WebSocketServerFragmentation.ino b/examples/WebSocketServer/WebSocketServerFragmentation.ino index e51f2ac..62bef31 100644 --- a/examples/WebSocketServer/WebSocketServerFragmentation.ino +++ b/examples/WebSocketServer/WebSocketServerFragmentation.ino @@ -20,7 +20,7 @@ WebSocketsServer webSocket = WebSocketsServer(81); String fragmentBuffer = ""; -void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) { +void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { switch(type) { case WStype_DISCONNECTED: @@ -38,8 +38,8 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); break; case WStype_BIN: - USE_SERIAL.printf("[%u] get binary lenght: %u\n", num, lenght); - hexdump(payload, lenght); + USE_SERIAL.printf("[%u] get binary length: %u\n", num, length); + hexdump(payload, length); break; // Fragmentation / continuation opcode handling diff --git a/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino b/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino index 96a74ac..152771d 100644 --- a/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino +++ b/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino @@ -26,7 +26,7 @@ ESP8266WiFiMulti WiFiMulti; ESP8266WebServer server = ESP8266WebServer(80); WebSocketsServer webSocket = WebSocketsServer(81); -void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) { +void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { switch(type) { case WStype_DISCONNECTED: diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index c4a8206..0d39cb1 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -270,9 +270,9 @@ void WebSocketsClient::setAuthorization(const char * auth) { * @param client WSclient_t * ptr to the client struct * @param opcode WSopcode_t * @param payload uint8_t * - * @param lenght size_t + * @param length size_t */ -void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t lenght, bool fin) { +void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) { WStype_t type = WStype_ERROR; switch(opcode) { @@ -287,7 +287,7 @@ void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, u break; } - runCbEvent(type, payload, lenght); + runCbEvent(type, payload, length); } diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index adc40ae..c10b2d4 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -468,9 +468,9 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { * @param client WSclient_t * ptr to the client struct * @param opcode WSopcode_t * @param payload uint8_t * - * @param lenght size_t + * @param length size_t */ -void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t lenght, bool fin) { +void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) { WStype_t type = WStype_ERROR; switch(opcode) { @@ -485,7 +485,7 @@ void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, u break; } - runCbEvent(client->num, type, payload, lenght); + runCbEvent(client->num, type, payload, length); } From 26140be6c91afb0baf7ad157c9e1248ec83627f2 Mon Sep 17 00:00:00 2001 From: Philippe Guay Date: Mon, 6 Mar 2017 15:07:20 -0500 Subject: [PATCH 084/347] fix #150 typo lenght -> length --- examples/WebSocketClient/WebSocketClient.ino | 8 ++++---- .../WebSocketClientSocketIO/WebSocketClientSocketIO.ino | 8 ++++---- examples/WebSocketServer/WebSocketServer.ino | 8 ++++---- examples/WebSocketServer/WebSocketServerFragmentation.ino | 6 +++--- .../WebSocketServer_LEDcontrol.ino | 2 +- src/WebSocketsClient.cpp | 6 +++--- src/WebSocketsServer.cpp | 6 +++--- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/examples/WebSocketClient/WebSocketClient.ino b/examples/WebSocketClient/WebSocketClient.ino index 82a2cc8..5a344fd 100644 --- a/examples/WebSocketClient/WebSocketClient.ino +++ b/examples/WebSocketClient/WebSocketClient.ino @@ -20,7 +20,7 @@ WebSocketsClient webSocket; #define USE_SERIAL Serial1 -void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch(type) { @@ -42,11 +42,11 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { // webSocket.sendTXT("message here"); break; case WStype_BIN: - USE_SERIAL.printf("[WSc] get binary lenght: %u\n", lenght); - hexdump(payload, lenght); + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); // send data to server - // webSocket.sendBIN(payload, lenght); + // webSocket.sendBIN(payload, length); break; } diff --git a/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino b/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino index 9f54361..39dce87 100644 --- a/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino +++ b/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino @@ -27,7 +27,7 @@ uint64_t messageTimestamp = 0; uint64_t heartbeatTimestamp = 0; bool isConnected = false; -void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch(type) { @@ -52,11 +52,11 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t lenght) { // webSocket.sendTXT("message here"); break; case WStype_BIN: - USE_SERIAL.printf("[WSc] get binary lenght: %u\n", lenght); - hexdump(payload, lenght); + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); // send data to server - // webSocket.sendBIN(payload, lenght); + // webSocket.sendBIN(payload, length); break; } diff --git a/examples/WebSocketServer/WebSocketServer.ino b/examples/WebSocketServer/WebSocketServer.ino index 795d9a6..5e266a2 100644 --- a/examples/WebSocketServer/WebSocketServer.ino +++ b/examples/WebSocketServer/WebSocketServer.ino @@ -18,7 +18,7 @@ WebSocketsServer webSocket = WebSocketsServer(81); #define USE_SERIAL Serial1 -void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) { +void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { switch(type) { case WStype_DISCONNECTED: @@ -43,11 +43,11 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght // webSocket.broadcastTXT("message here"); break; case WStype_BIN: - USE_SERIAL.printf("[%u] get binary lenght: %u\n", num, lenght); - hexdump(payload, lenght); + USE_SERIAL.printf("[%u] get binary length: %u\n", num, length); + hexdump(payload, length); // send message to client - // webSocket.sendBIN(num, payload, lenght); + // webSocket.sendBIN(num, payload, length); break; } diff --git a/examples/WebSocketServer/WebSocketServerFragmentation.ino b/examples/WebSocketServer/WebSocketServerFragmentation.ino index e51f2ac..62bef31 100644 --- a/examples/WebSocketServer/WebSocketServerFragmentation.ino +++ b/examples/WebSocketServer/WebSocketServerFragmentation.ino @@ -20,7 +20,7 @@ WebSocketsServer webSocket = WebSocketsServer(81); String fragmentBuffer = ""; -void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) { +void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { switch(type) { case WStype_DISCONNECTED: @@ -38,8 +38,8 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); break; case WStype_BIN: - USE_SERIAL.printf("[%u] get binary lenght: %u\n", num, lenght); - hexdump(payload, lenght); + USE_SERIAL.printf("[%u] get binary length: %u\n", num, length); + hexdump(payload, length); break; // Fragmentation / continuation opcode handling diff --git a/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino b/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino index 96a74ac..152771d 100644 --- a/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino +++ b/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino @@ -26,7 +26,7 @@ ESP8266WiFiMulti WiFiMulti; ESP8266WebServer server = ESP8266WebServer(80); WebSocketsServer webSocket = WebSocketsServer(81); -void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) { +void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { switch(type) { case WStype_DISCONNECTED: diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index c4a8206..0d39cb1 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -270,9 +270,9 @@ void WebSocketsClient::setAuthorization(const char * auth) { * @param client WSclient_t * ptr to the client struct * @param opcode WSopcode_t * @param payload uint8_t * - * @param lenght size_t + * @param length size_t */ -void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t lenght, bool fin) { +void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) { WStype_t type = WStype_ERROR; switch(opcode) { @@ -287,7 +287,7 @@ void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, u break; } - runCbEvent(type, payload, lenght); + runCbEvent(type, payload, length); } diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index adc40ae..c10b2d4 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -468,9 +468,9 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { * @param client WSclient_t * ptr to the client struct * @param opcode WSopcode_t * @param payload uint8_t * - * @param lenght size_t + * @param length size_t */ -void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t lenght, bool fin) { +void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) { WStype_t type = WStype_ERROR; switch(opcode) { @@ -485,7 +485,7 @@ void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, u break; } - runCbEvent(client->num, type, payload, lenght); + runCbEvent(client->num, type, payload, length); } From e675c7590e18e752d7b0223c08572c1fc8f8ce8d Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 9 Mar 2017 18:43:23 +0100 Subject: [PATCH 085/347] add missing include for ESP with W5100 #177 --- src/WebSockets.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/WebSockets.h b/src/WebSockets.h index 7bb4303..1e62469 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -32,6 +32,8 @@ #include #endif +#include + #ifdef DEBUG_ESP_PORT #define DEBUG_WEBSOCKETS(...) DEBUG_ESP_PORT.printf( __VA_ARGS__ ) #else @@ -77,6 +79,7 @@ #if defined(ESP8266) || defined(ESP31B) #define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 //#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC +//#define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 #else #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 #endif From 1afe317c7d8e734bd7e307255fd30198b789782e Mon Sep 17 00:00:00 2001 From: Markus Date: Mon, 13 Mar 2017 17:25:10 +0100 Subject: [PATCH 086/347] improve LED example onchange to oninput #178 --- .../WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino b/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino index 152771d..f737d7f 100644 --- a/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino +++ b/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino @@ -100,7 +100,7 @@ void setup() { // handle index server.on("/", []() { // send index.html - server.send(200, "text/html", "LED Control:

R:
G:
B:
"); + server.send(200, "text/html", "LED Control:

R:
G:
B:
"); }); server.begin(); From 81e567b24822fb95c122a994eedc55fb87e5a1d9 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 18 Mar 2017 10:32:37 +0100 Subject: [PATCH 087/347] send 401 header too if auth string is empty #116 --- src/WebSocketsServer.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index c10b2d4..9b8cfe7 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -766,17 +766,13 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { } if(_base64Authorization.length() > 0) { - if(client->base64Authorization.length() > 0) { - String auth = WEBSOCKETS_STRING("Basic "); - auth += _base64Authorization; - if(auth != client->base64Authorization) { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] HTTP Authorization failed!\n", client->num); - handleAuthorizationFailed(client); - return; - } - } else { - ok = false; - } + String auth = WEBSOCKETS_STRING("Basic "); + auth += _base64Authorization; + if(auth != client->base64Authorization) { + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] HTTP Authorization failed!\n", client->num); + handleAuthorizationFailed(client); + return; + } } if(ok) { From adb52b11e9123c8fab10683ca044f290f72cd1e5 Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 9 Apr 2017 17:58:23 +0200 Subject: [PATCH 088/347] handle cases when not all data can be written to TCP stack #187 --- src/WebSockets.cpp | 59 ++++++++++++++++++++++++++++++++++++++-- src/WebSockets.h | 2 ++ src/WebSocketsClient.cpp | 4 +-- src/WebSocketsServer.cpp | 2 +- 4 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 118ebb7..af8c9d5 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -233,18 +233,18 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay // header has be added to payload // payload is forced to reserved 14 Byte but we may not need all based on the length and mask settings // offset in payload is calculatetd 14 - headerSize - if(client->tcp->write(&payloadPtr[(WEBSOCKETS_MAX_HEADER_SIZE - headerSize)], (length + headerSize)) != (length + headerSize)) { + if(write(client, &payloadPtr[(WEBSOCKETS_MAX_HEADER_SIZE - headerSize)], (length + headerSize)) != (length + headerSize)) { ret = false; } } else { // send header - if(client->tcp->write(&buffer[0], headerSize) != headerSize) { + if(write(client, &buffer[0], headerSize) != headerSize) { ret = false; } if(payloadPtr && length > 0) { // send payload - if(client->tcp->write(&payloadPtr[0], length) != length) { + if(write(client, &payloadPtr[0], length) != length) { ret = false; } } @@ -593,3 +593,56 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait #endif return true; } + +/** + * write x byte to tcp or get timeout + * @param client WSclient_t * + * @param out uint8_t * data buffer + * @param n size_t byte count + * @return true if ok + */ +size_t WebSockets::write(WSclient_t * client, uint8_t *out, size_t n) { + if(out == NULL) return 0; + if(client == NULL) return 0; + unsigned long t = millis(); + size_t len = 0; + size_t total = 0; + DEBUG_WEBSOCKETS("[size_t] n: %d t: %d\n", n, t); + while(n > 0) { + if(client->tcp == NULL) { + DEBUG_WEBSOCKETS("[write] tcp is null!\n"); + break; + } + + if(!client->tcp->connected()) { + DEBUG_WEBSOCKETS("[write] not connected!\n"); + break; + } + + if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) { + DEBUG_WEBSOCKETS("[write] write TIMEOUT! %d\n", (millis() - t)); + break; + } + + len = client->tcp->write(out, n); + if(len) { + t = millis(); + out += len; + n -= len; + total += len; + //DEBUG_WEBSOCKETS("write %d left %d!\n", len, n); + } else { + //DEBUG_WEBSOCKETS("write %d failed left %d!\n", len, n); + } +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + delay(0); +#endif + } + return total; +} + +size_t WebSockets::write(WSclient_t * client, const char *out) { + if(client == NULL) return 0; + if(out == NULL) return 0; + return write(client, (uint8_t*)out, strlen(out)); +} diff --git a/src/WebSockets.h b/src/WebSockets.h index 1e62469..46a26df 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -265,6 +265,8 @@ class WebSockets { String base64_encode(uint8_t * data, size_t length); bool readCb(WSclient_t * client, uint8_t *out, size_t n, WSreadWaitCb cb); + size_t write(WSclient_t * client, uint8_t *out, size_t n); + size_t write(WSclient_t * client, const char *out); }; diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 0d39cb1..adc4335 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -482,7 +482,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { handshake += NEW_LINE; DEBUG_WEBSOCKETS("[WS-Client][sendHeader] handshake %s", (uint8_t*)handshake.c_str()); - client->tcp->write((uint8_t*)handshake.c_str(), handshake.length()); + write(client, (uint8_t*)handshake.c_str(), handshake.length()); #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine))); @@ -607,7 +607,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { sendHeader(client); } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); - client->tcp->write("This is a webSocket client!"); + write(client, "This is a webSocket client!"); clientDisconnect(client); } } diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 9b8cfe7..f860298 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -809,7 +809,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] handshake %s", client->num, (uint8_t*)handshake.c_str()); - client->tcp->write((uint8_t*)handshake.c_str(), handshake.length()); + write(client, (uint8_t*)handshake.c_str(), handshake.length()); headerDone(client); From c911776860bc563312d3b2870d0306be4214f0b3 Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 10 Apr 2017 17:49:42 +0200 Subject: [PATCH 089/347] add virtual to write fix some naming --- src/WebSockets.cpp | 4 ++-- src/WebSockets.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index af8c9d5..434e1e7 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -599,7 +599,7 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait * @param client WSclient_t * * @param out uint8_t * data buffer * @param n size_t byte count - * @return true if ok + * @return bytes send */ size_t WebSockets::write(WSclient_t * client, uint8_t *out, size_t n) { if(out == NULL) return 0; @@ -607,7 +607,7 @@ size_t WebSockets::write(WSclient_t * client, uint8_t *out, size_t n) { unsigned long t = millis(); size_t len = 0; size_t total = 0; - DEBUG_WEBSOCKETS("[size_t] n: %d t: %d\n", n, t); + DEBUG_WEBSOCKETS("[write] n: %d t: %d\n", n, t); while(n > 0) { if(client->tcp == NULL) { DEBUG_WEBSOCKETS("[write] tcp is null!\n"); diff --git a/src/WebSockets.h b/src/WebSockets.h index 46a26df..30ec910 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -265,7 +265,7 @@ class WebSockets { String base64_encode(uint8_t * data, size_t length); bool readCb(WSclient_t * client, uint8_t *out, size_t n, WSreadWaitCb cb); - size_t write(WSclient_t * client, uint8_t *out, size_t n); + virtual size_t write(WSclient_t * client, uint8_t *out, size_t n); size_t write(WSclient_t * client, const char *out); From f68d9d8030c108058d56c7a9475d1ae3925b1cf1 Mon Sep 17 00:00:00 2001 From: jesben Date: Sun, 18 Jun 2017 12:50:07 +0200 Subject: [PATCH 090/347] Adding method for beginSocketIOSSL --- src/WebSocketsClient.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 0d39cb1..c0ff360 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -101,6 +101,19 @@ void WebSocketsClient::beginSocketIO(String host, uint16_t port, String url, Str beginSocketIO(host.c_str(), port, url.c_str(), protocol.c_str()); } +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +void WebSocketsClient::beginSocketIOSSL(const char *host, uint16_t port, const char * url, const char * protocol) { + begin(host, port, url, protocol); + _client.isSocketIO = true; + _client.isSSL = true; + _fingerprint = ""; +} + +void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url, String protocol) { + beginSocketIOSSL(host.c_str(), port, url.c_str(), protocol.c_str()); +} +#endif + #if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * called in arduino loop From 40f84c19f4476496cc8a9b91186eaae607d929a7 Mon Sep 17 00:00:00 2001 From: jesben Date: Sun, 18 Jun 2017 12:51:34 +0200 Subject: [PATCH 091/347] Adding beginSocketIOSSL --- src/WebSocketsClient.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 83913dc..d8b6814 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -50,6 +50,11 @@ class WebSocketsClient: private WebSockets { void beginSocketIO(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); void beginSocketIO(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + void beginSocketIOSSL(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); + void beginSocketIOSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); +#endif + #if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void loop(void); #else From a4533a028c70c7aac7c1c9636e5c0e4043378ef6 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 8 Jul 2017 08:38:05 +0200 Subject: [PATCH 092/347] fix NULL ptr when server abort the connection (#207) --- src/WebSocketsClient.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index c0ff360..819af0e 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -616,14 +616,16 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { runCbEvent(WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length()); - } else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) { - sendHeader(client); - } else { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); - client->tcp->write("This is a webSocket client!"); - clientDisconnect(client); - } - } + } else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) { + sendHeader(client); + } else { + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); + if(clientIsConnected(client)) { + client->tcp->write("This is a webSocket client!"); + } + clientDisconnect(client); + } + } } void WebSocketsClient::connectedCb() { From ad07f3c66510696849bcbc77831e138978c942f8 Mon Sep 17 00:00:00 2001 From: Martin Becker Date: Tue, 18 Jul 2017 12:37:04 +0200 Subject: [PATCH 093/347] Allow to disable "Origin" header The origin header often makes trouble with current WebSocket implementations. Thus, we introduce the WEBSOCKET_HEADERS_NO_ORIGIN macro which disables this header it if defined. --- src/WebSocketsClient.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 819af0e..1dfcfba 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -479,8 +479,12 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { handshake += WEBSOCKETS_STRING("Connection: keep-alive\r\n"); } - handshake += WEBSOCKETS_STRING("Origin: file://\r\n" - "User-Agent: arduino-WebSocket-Client\r\n"); +#ifndef WEBSOCKET_HEADERS_NO_ORIGIN + // add origin header if requested + handshake += WEBSOCKETS_STRING("Origin: file://\r\n"); +#endif + + handshake += WEBSOCKETS_STRING("User-Agent: arduino-WebSocket-Client\r\n"); if(client->base64Authorization.length() > 0) { handshake += WEBSOCKETS_STRING("Authorization: Basic "); From 86d2e2400a10c88fa06e62490d54b2e355f1e04b Mon Sep 17 00:00:00 2001 From: Martin Becker Date: Tue, 18 Jul 2017 13:33:13 +0200 Subject: [PATCH 094/347] Add SockJS+Stomp example --- .../WebSocketClientSockJsAndStomp.ino | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino diff --git a/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino b/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino new file mode 100644 index 0000000..fb5d7bf --- /dev/null +++ b/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino @@ -0,0 +1,155 @@ +/* + * WebSocketClientSockJsAndStomp.ino + * + * Example for connecting and maintining a connection with a SockJS+STOMP websocket connection. + * In this example we connect to a Spring application (see https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html). + * + * Created on: 18.07.2017 + * Author: Martin Becker , contact: becker@informatik.uni-wuerzburg.de + */ + +// CONSTANTS AND MACROS + +#define DEBUG_WEBSOCKETS +#define DEBUG_WEBSOCKETS(...) Serial.printf( __VA_ARGS__ ) + +#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 +#define WEBSOCKETS_HEADERS_NO_ORIGIN + +#define USE_SERIAL Serial + + +// LIBRARIES + +#include +#include + + +// SETTINGS + +const char* wlan_ssid = "yourssid"; +const char* wlan_password = "password"; + +const char* ws_host = "the.host.com"; +const int ws_port = 80; + +// base URL for SockJS (websocket) connection +// The complete URL will look something like this(cf. http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-36): +// ws://://<3digits>//websocket +// For the default config of Spring's SockJS/STOMP support the default base URL is "/socketentry/". +const char* ws_baseurl = "/socketentry/"; // don't forget leading and trailing "/" !!! + + +// VARIABLES + +WebSocketsClient webSocket; + + +// FUNCTIONS + +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { + + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[WSc] Disconnected!\n"); + break; + case WStype_CONNECTED: + { + USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); + } + break; + case WStype_TEXT: { + + // ##################### + // handle STOMP protocol + // ##################### + + String text = (char*) payload; + + USE_SERIAL.printf("[WSc] get text: %s\n", payload); + + if (payload[0] == 'h') { + + USE_SERIAL.println("Heartbeat!"); + + } else if (payload[0] == 'o') { + + // on open connection + char *msg = "[\"CONNECT\\naccept-version:1.1,1.0\\nheart-beat:10000,10000\\n\\n\\u0000\"]"; + webSocket.sendTXT(msg); + + } else if (text.startsWith("a[\"CONNECTED")) { + + // subscribe to some channels + + char *msg = "[\"SUBSCRIBE\\nid:sub-0\\ndestination:/user/queue/messages\\n\\n\\u0000\"]"; + webSocket.sendTXT(msg); + delay(1000); + + // and send a message + + msg = "[\"SEND\\ndestination:/app/message\\ncontent-length:33\\n\\n{\\\"user\\\":\\\"esp\\\",\\\"message\\\":\\\"Hello!\\\"}\\u0000\"]"; + webSocket.sendTXT(msg); + delay(1000); + } + + break; + } + case WStype_BIN: + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); + + // send data to server + // webSocket.sendBIN(payload, length); + break; + } + +} + +void setup() { + + // setup serial + + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + +// USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + // connect to WiFi + + USE_SERIAL.print("Logging into WLAN: "); Serial.print(wlan_ssid); Serial.print(" ..."); + WiFi.mode(WIFI_STA); + WiFi.begin(wlan_ssid, wlan_password); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + USE_SERIAL.print("."); + } + USE_SERIAL.println(" success."); + USE_SERIAL.print("IP: "); USE_SERIAL.println(WiFi.localIP()); + + // ##################### + // create socket url according to SockJS protocol (cf. http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-36) + // ##################### + String socketUrl = ws_baseurl; + socketUrl += random(0,999); + socketUrl += "/"; + socketUrl += random(0,999999); // should be a random string, but this works (see ) + socketUrl += "/websocket"; + + // connect to websocket + webSocket.begin(ws_host, ws_port, socketUrl); + webSocket.onEvent(webSocketEvent); +} + +void loop() { + webSocket.loop(); +} From 42ab3168c5eabbc407354dc2477c7ad7482891df Mon Sep 17 00:00:00 2001 From: Martin Becker Date: Wed, 19 Jul 2017 09:59:34 +0200 Subject: [PATCH 095/347] Switch to setting extra headers via function --- src/WebSockets.h | 2 ++ src/WebSocketsClient.cpp | 16 ++++++++++++---- src/WebSocketsClient.h | 3 +++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 1e62469..41cbe7d 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -226,6 +226,8 @@ typedef struct { String base64Authorization; ///< Base64 encoded Auth request String plainAuthorization; ///< Base64 encoded Auth request + String extraHeaders; + bool cHttpHeadersValid; ///< non-websocket http header validity indicator size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 1dfcfba..787b7a5 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -29,6 +29,7 @@ WebSocketsClient::WebSocketsClient() { _cbEvent = NULL; _client.num = 0; + _client.extraHeaders = "Origin: file://"; } WebSocketsClient::~WebSocketsClient() { @@ -274,6 +275,15 @@ void WebSocketsClient::setAuthorization(const char * auth) { } } +/** + * set extra headers for the http request; + * separate headers by "\r\n" + * @param extraHeaders const char * extraHeaders + */ +void WebSocketsClient::setExtraHeaders(const char * extraHeaders) { + _client.extraHeaders = extraHeaders; +} + //################################################################################# //################################################################################# //################################################################################# @@ -479,10 +489,8 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { handshake += WEBSOCKETS_STRING("Connection: keep-alive\r\n"); } -#ifndef WEBSOCKET_HEADERS_NO_ORIGIN - // add origin header if requested - handshake += WEBSOCKETS_STRING("Origin: file://\r\n"); -#endif + // add extra headers; by default this includes "Origin: file://" + handshake += client->extraHeaders + NEW_LINE; handshake += WEBSOCKETS_STRING("User-Agent: arduino-WebSocket-Client\r\n"); diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index d8b6814..df9bbef 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -80,6 +80,9 @@ class WebSocketsClient: private WebSockets { void setAuthorization(const char * user, const char * password); void setAuthorization(const char * auth); + + void setExtraHeaders(char * extraHeaders); + void setExtraHeaders(const char * extraHeaders); protected: String _host; From 32cb052f23a0eb56f7e8cc885a175de4f4ce779c Mon Sep 17 00:00:00 2001 From: Martin Becker Date: Wed, 19 Jul 2017 10:19:32 +0200 Subject: [PATCH 096/347] Update SockJS+STOMP example --- .../WebSocketClientSockJsAndStomp.ino | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino b/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino index fb5d7bf..c8d990f 100644 --- a/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino +++ b/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino @@ -5,16 +5,10 @@ * In this example we connect to a Spring application (see https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html). * * Created on: 18.07.2017 - * Author: Martin Becker , contact: becker@informatik.uni-wuerzburg.de + * Author: Martin Becker , Contact: becker@informatik.uni-wuerzburg.de */ -// CONSTANTS AND MACROS - -#define DEBUG_WEBSOCKETS -#define DEBUG_WEBSOCKETS(...) Serial.printf( __VA_ARGS__ ) - -#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 -#define WEBSOCKETS_HEADERS_NO_ORIGIN +// PRE #define USE_SERIAL Serial @@ -28,9 +22,9 @@ // SETTINGS const char* wlan_ssid = "yourssid"; -const char* wlan_password = "password"; +const char* wlan_password = "somepassword"; -const char* ws_host = "the.host.com"; +const char* ws_host = "the.host.net"; const int ws_port = 80; // base URL for SockJS (websocket) connection @@ -117,11 +111,6 @@ void setup() { USE_SERIAL.println(); - for(uint8_t t = 4; t > 0; t--) { - USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); - USE_SERIAL.flush(); - delay(1000); - } // connect to WiFi @@ -135,6 +124,7 @@ void setup() { } USE_SERIAL.println(" success."); USE_SERIAL.print("IP: "); USE_SERIAL.println(WiFi.localIP()); + // ##################### // create socket url according to SockJS protocol (cf. http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-36) @@ -147,6 +137,8 @@ void setup() { // connect to websocket webSocket.begin(ws_host, ws_port, socketUrl); + webSocket.setExtraHeaders(""); // remove "Origin: file://" header because it breaks the connection with Spring's default websocket config +// webSocket.setExtraHeaders("foo: I am so funny\r\nbar: not"); // some headers, in case you feel funny webSocket.onEvent(webSocketEvent); } From 669f0b489efc393307353ac2a4134e3638b52d1a Mon Sep 17 00:00:00 2001 From: Martin Becker Date: Wed, 19 Jul 2017 11:12:00 +0200 Subject: [PATCH 097/347] Fix empty header issue --- .../WebSocketClientSockJsAndStomp.ino | 2 +- src/WebSocketsClient.cpp | 8 +++++--- src/WebSocketsClient.h | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino b/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino index c8d990f..96ce679 100644 --- a/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino +++ b/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino @@ -137,7 +137,7 @@ void setup() { // connect to websocket webSocket.begin(ws_host, ws_port, socketUrl); - webSocket.setExtraHeaders(""); // remove "Origin: file://" header because it breaks the connection with Spring's default websocket config + webSocket.setExtraHeaders(); // remove "Origin: file://" header because it breaks the connection with Spring's default websocket config // webSocket.setExtraHeaders("foo: I am so funny\r\nbar: not"); // some headers, in case you feel funny webSocket.onEvent(webSocketEvent); } diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 787b7a5..3faae99 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -29,7 +29,7 @@ WebSocketsClient::WebSocketsClient() { _cbEvent = NULL; _client.num = 0; - _client.extraHeaders = "Origin: file://"; + _client.extraHeaders = WEBSOCKETS_STRING("Origin: file://"); } WebSocketsClient::~WebSocketsClient() { @@ -490,8 +490,10 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { } // add extra headers; by default this includes "Origin: file://" - handshake += client->extraHeaders + NEW_LINE; - + if (client->extraHeaders) { + handshake += client->extraHeaders + NEW_LINE; + } + handshake += WEBSOCKETS_STRING("User-Agent: arduino-WebSocket-Client\r\n"); if(client->base64Authorization.length() > 0) { diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index df9bbef..b097b68 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -81,8 +81,8 @@ class WebSocketsClient: private WebSockets { void setAuthorization(const char * user, const char * password); void setAuthorization(const char * auth); + void setExtraHeaders(const char * extraHeaders = NULL); void setExtraHeaders(char * extraHeaders); - void setExtraHeaders(const char * extraHeaders); protected: String _host; From fcb623ce9167f1e6a380b359d94f500fecffce94 Mon Sep 17 00:00:00 2001 From: Martin Becker Date: Wed, 19 Jul 2017 15:50:25 +0200 Subject: [PATCH 098/347] Simplified example --- .../WebSocketClientSockJsAndStomp.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino b/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino index 96ce679..f5397db 100644 --- a/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino +++ b/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino @@ -82,7 +82,7 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { // and send a message - msg = "[\"SEND\\ndestination:/app/message\\ncontent-length:33\\n\\n{\\\"user\\\":\\\"esp\\\",\\\"message\\\":\\\"Hello!\\\"}\\u0000\"]"; + msg = "[\"SEND\\ndestination:/app/message\\n\\n{\\\"user\\\":\\\"esp\\\",\\\"message\\\":\\\"Hello!\\\"}\\u0000\"]"; webSocket.sendTXT(msg); delay(1000); } From d0ab6c4fd1e26f97ab5e8857d33edee96526c923 Mon Sep 17 00:00:00 2001 From: Martin Becker Date: Thu, 20 Jul 2017 08:21:29 +0200 Subject: [PATCH 099/347] Remove redundant method header and fix indent --- .../WebSocketClientSockJsAndStomp.ino | 108 +++++++++--------- src/WebSocketsClient.h | 1 - 2 files changed, 54 insertions(+), 55 deletions(-) diff --git a/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino b/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino index f5397db..078b547 100644 --- a/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino +++ b/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino @@ -1,12 +1,12 @@ /* - * WebSocketClientSockJsAndStomp.ino - * - * Example for connecting and maintining a connection with a SockJS+STOMP websocket connection. - * In this example we connect to a Spring application (see https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html). - * - * Created on: 18.07.2017 - * Author: Martin Becker , Contact: becker@informatik.uni-wuerzburg.de - */ + WebSocketClientSockJsAndStomp.ino + + Example for connecting and maintining a connection with a SockJS+STOMP websocket connection. + In this example we connect to a Spring application (see https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html). + + Created on: 18.07.2017 + Author: Martin Becker , Contact: becker@informatik.uni-wuerzburg.de +*/ // PRE @@ -28,7 +28,7 @@ const char* ws_host = "the.host.net"; const int ws_port = 80; // base URL for SockJS (websocket) connection -// The complete URL will look something like this(cf. http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-36): +// The complete URL will look something like this(cf. http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-36): // ws://://<3digits>//websocket // For the default config of Spring's SockJS/STOMP support the default base URL is "/socketentry/". const char* ws_baseurl = "/socketentry/"; // don't forget leading and trailing "/" !!! @@ -43,7 +43,7 @@ WebSocketsClient webSocket; void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { - switch(type) { + switch (type) { case WStype_DISCONNECTED: USE_SERIAL.printf("[WSc] Disconnected!\n"); break; @@ -52,43 +52,43 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); } break; - case WStype_TEXT: { - - // ##################### - // handle STOMP protocol - // ##################### - - String text = (char*) payload; - - USE_SERIAL.printf("[WSc] get text: %s\n", payload); - - if (payload[0] == 'h') { - - USE_SERIAL.println("Heartbeat!"); - - } else if (payload[0] == 'o') { - - // on open connection - char *msg = "[\"CONNECT\\naccept-version:1.1,1.0\\nheart-beat:10000,10000\\n\\n\\u0000\"]"; - webSocket.sendTXT(msg); - - } else if (text.startsWith("a[\"CONNECTED")) { - - // subscribe to some channels - - char *msg = "[\"SUBSCRIBE\\nid:sub-0\\ndestination:/user/queue/messages\\n\\n\\u0000\"]"; - webSocket.sendTXT(msg); - delay(1000); - - // and send a message - - msg = "[\"SEND\\ndestination:/app/message\\n\\n{\\\"user\\\":\\\"esp\\\",\\\"message\\\":\\\"Hello!\\\"}\\u0000\"]"; - webSocket.sendTXT(msg); - delay(1000); - } + case WStype_TEXT: + { + // ##################### + // handle STOMP protocol + // ##################### - break; - } + String text = (char*) payload; + + USE_SERIAL.printf("[WSc] get text: %s\n", payload); + + if (payload[0] == 'h') { + + USE_SERIAL.println("Heartbeat!"); + + } else if (payload[0] == 'o') { + + // on open connection + char *msg = "[\"CONNECT\\naccept-version:1.1,1.0\\nheart-beat:10000,10000\\n\\n\\u0000\"]"; + webSocket.sendTXT(msg); + + } else if (text.startsWith("a[\"CONNECTED")) { + + // subscribe to some channels + + char *msg = "[\"SUBSCRIBE\\nid:sub-0\\ndestination:/user/queue/messages\\n\\n\\u0000\"]"; + webSocket.sendTXT(msg); + delay(1000); + + // and send a message + + msg = "[\"SEND\\ndestination:/app/message\\n\\n{\\\"user\\\":\\\"esp\\\",\\\"message\\\":\\\"Hello!\\\"}\\u0000\"]"; + webSocket.sendTXT(msg); + delay(1000); + } + + break; + } case WStype_BIN: USE_SERIAL.printf("[WSc] get binary length: %u\n", length); hexdump(payload, length); @@ -107,7 +107,7 @@ void setup() { // USE_SERIAL.begin(921600); USE_SERIAL.begin(115200); -// USE_SERIAL.setDebugOutput(true); + // USE_SERIAL.setDebugOutput(true); USE_SERIAL.println(); @@ -117,28 +117,28 @@ void setup() { USE_SERIAL.print("Logging into WLAN: "); Serial.print(wlan_ssid); Serial.print(" ..."); WiFi.mode(WIFI_STA); WiFi.begin(wlan_ssid, wlan_password); - + while (WiFi.status() != WL_CONNECTED) { - delay(500); - USE_SERIAL.print("."); + delay(500); + USE_SERIAL.print("."); } USE_SERIAL.println(" success."); USE_SERIAL.print("IP: "); USE_SERIAL.println(WiFi.localIP()); - + // ##################### // create socket url according to SockJS protocol (cf. http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-36) // ##################### String socketUrl = ws_baseurl; - socketUrl += random(0,999); + socketUrl += random(0, 999); socketUrl += "/"; - socketUrl += random(0,999999); // should be a random string, but this works (see ) + socketUrl += random(0, 999999); // should be a random string, but this works (see ) socketUrl += "/websocket"; // connect to websocket webSocket.begin(ws_host, ws_port, socketUrl); webSocket.setExtraHeaders(); // remove "Origin: file://" header because it breaks the connection with Spring's default websocket config -// webSocket.setExtraHeaders("foo: I am so funny\r\nbar: not"); // some headers, in case you feel funny + // webSocket.setExtraHeaders("foo: I am so funny\r\nbar: not"); // some headers, in case you feel funny webSocket.onEvent(webSocketEvent); } diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index b097b68..7390a76 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -82,7 +82,6 @@ class WebSocketsClient: private WebSockets { void setAuthorization(const char * auth); void setExtraHeaders(const char * extraHeaders = NULL); - void setExtraHeaders(char * extraHeaders); protected: String _host; From 87c6c80c67014ab640e34678d31a11b5f8e007c4 Mon Sep 17 00:00:00 2001 From: Markus Date: Thu, 20 Jul 2017 18:18:35 +0200 Subject: [PATCH 100/347] setup travis --- .travis.yml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..881c97f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,37 @@ +sudo: false +language: bash +os: + - linux + +script: + - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 + - sleep 3 + - export DISPLAY=:1.0 + - wget http://downloads.arduino.cc/arduino-1.6.5-linux64.tar.xz + - tar xf arduino-1.6.5-linux64.tar.xz + - mv arduino-1.6.5 $HOME/arduino_ide + - export PATH="$HOME/arduino_ide:$PATH" + - which arduino + - mkdir -p $HOME/Arduino/libraries + - cp -r $TRAVIS_BUILD_DIR $HOME/Arduino/libraries/arduinoWebSockets + - cd $HOME/arduino_ide/hardware + - mkdir esp8266com + - cd esp8266com + - git clone https://github.com/esp8266/Arduino.git esp8266 + - cd esp8266/tools + - python get.py + - source $TRAVIS_BUILD_DIR/travis/common.sh + - arduino --board esp8266com:esp8266:generic --save-prefs + - arduino --get-pref sketchbook.path + - build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets esp8266 + +notifications: + email: + on_success: change + on_failure: change + webhooks: + urls: + - https://webhooks.gitter.im/e/1aa78fbe15080b0c2e37 + on_success: change # options: [always|never|change] default: always + on_failure: always # options: [always|never|change] default: always + on_start: false # default: false From 64c8908b058c88a34744077b1e34e05e7db0d1d3 Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 20 Jul 2017 18:26:04 +0200 Subject: [PATCH 101/347] add script for travis --- .../ParticleWebSocketClient/.esp8266.skip | 0 examples/WebSocketClientAVR/.esp8266.skip | 0 travis/common.sh | 24 +++++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 examples/ParticleWebSocketClient/.esp8266.skip create mode 100644 examples/WebSocketClientAVR/.esp8266.skip create mode 100644 travis/common.sh diff --git a/examples/ParticleWebSocketClient/.esp8266.skip b/examples/ParticleWebSocketClient/.esp8266.skip new file mode 100644 index 0000000..e69de29 diff --git a/examples/WebSocketClientAVR/.esp8266.skip b/examples/WebSocketClientAVR/.esp8266.skip new file mode 100644 index 0000000..e69de29 diff --git a/travis/common.sh b/travis/common.sh new file mode 100644 index 0000000..4bcd81b --- /dev/null +++ b/travis/common.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +function build_sketches() +{ + local arduino=$1 + local srcpath=$2 + local platform=$3 + local sketches=$(find $srcpath -name *.ino) + for sketch in $sketches; do + local sketchdir=$(dirname $sketch) + if [[ -f "$sketchdir/.$platform.skip" ]]; then + echo -e "\n\n ------------ Skipping $sketch ------------ \n\n"; + continue + fi + echo -e "\n\n ------------ Building $sketch ------------ \n\n"; + $arduino --verify $sketch; + local result=$? + if [ $result -ne 0 ]; then + echo "Build failed ($1)" + return $result + fi + done +} + From 96c266101ee0e83541bd48e11842ad7d2cd6cffb Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 20 Jul 2017 18:32:25 +0200 Subject: [PATCH 102/347] add needed includes --- .../WebSocketClientSockJsAndStomp.ino | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino b/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino index 078b547..493a949 100644 --- a/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino +++ b/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino @@ -15,6 +15,9 @@ // LIBRARIES +#include +#include + #include #include @@ -52,7 +55,7 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); } break; - case WStype_TEXT: + case WStype_TEXT: { // ##################### // handle STOMP protocol From cc3ce02c670563d039a769dd72703a0976887862 Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 20 Jul 2017 18:40:38 +0200 Subject: [PATCH 103/347] move files to get travis working --- .../WebSocketServerFragmentation.ino | 0 .../WebSocketServerHttpHeaderValidation.ino | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename examples/{WebSocketServer => WebSocketServerFragmentation}/WebSocketServerFragmentation.ino (100%) rename examples/{WebSocketServer => WebSocketServerHttpHeaderValidation}/WebSocketServerHttpHeaderValidation.ino (100%) diff --git a/examples/WebSocketServer/WebSocketServerFragmentation.ino b/examples/WebSocketServerFragmentation/WebSocketServerFragmentation.ino similarity index 100% rename from examples/WebSocketServer/WebSocketServerFragmentation.ino rename to examples/WebSocketServerFragmentation/WebSocketServerFragmentation.ino diff --git a/examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino b/examples/WebSocketServerHttpHeaderValidation/WebSocketServerHttpHeaderValidation.ino similarity index 100% rename from examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino rename to examples/WebSocketServerHttpHeaderValidation/WebSocketServerHttpHeaderValidation.ino From 0ca020bbd2d408a65453087c9b8f176cb498c7c7 Mon Sep 17 00:00:00 2001 From: Markus Date: Thu, 20 Jul 2017 18:47:36 +0200 Subject: [PATCH 104/347] add build status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8936f6e..0c49b48 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -WebSocket Server and Client for Arduino +WebSocket Server and Client for Arduino [![Build Status](https://travis-ci.org/Links2004/arduinoWebSockets.svg?branch=master)](https://travis-ci.org/Links2004/arduinoWebSockets) =========================================== a WebSocket Server and Client for Arduino based on RFC6455. From 4fc80871a605694bf09f3c0503fabd43e3bd2150 Mon Sep 17 00:00:00 2001 From: Silver Kuusik Date: Sun, 30 Jul 2017 00:18:37 +0200 Subject: [PATCH 105/347] Update WebSockets.h --- src/WebSockets.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 41cbe7d..3c08deb 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -70,6 +70,7 @@ #define NETWORK_ESP8266 (1) #define NETWORK_W5100 (2) #define NETWORK_ENC28J60 (3) +#define NETWORK_ESP32 (4) // max size of the WS Message Header #define WEBSOCKETS_MAX_HEADER_SIZE (14) @@ -80,6 +81,8 @@ #define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 //#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC //#define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 +#elif defined(ESP32) +#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP32 #else #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 #endif @@ -137,6 +140,13 @@ #define WEBSOCKETS_NETWORK_CLASS UIPClient #define WEBSOCKETS_NETWORK_SERVER_CLASS UIPServer +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) + +#include +#include +#define WEBSOCKETS_NETWORK_CLASS WiFiClient +#define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer + #else #error "no network type selected!" #endif @@ -201,7 +211,7 @@ typedef struct { bool isSocketIO; ///< client for socket.io server -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) bool isSSL; ///< run in ssl mode WiFiClientSecure * ssl; #endif From 8c19d7ba48e90280868c4146616a15b6e29e760a Mon Sep 17 00:00:00 2001 From: Silver Kuusik Date: Sun, 30 Jul 2017 00:21:13 +0200 Subject: [PATCH 106/347] Update WebSockets.cpp added esp32 hwcrypto for sha1 --- src/WebSockets.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 118ebb7..a713625 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -38,6 +38,8 @@ extern "C" { #ifdef ESP8266 #include +#elif defined(ESP32) +#include #else extern "C" { @@ -483,6 +485,9 @@ String WebSockets::acceptKey(String & clientKey) { uint8_t sha1HashBin[20] = { 0 }; #ifdef ESP8266 sha1(clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", &sha1HashBin[0]); +#elif defined(ESP32) + String data = clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + esp_sha(SHA1, (unsigned char*)data.c_str(), data.length(), &sha1HashBin[0]); #else clientKey += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; SHA1_CTX ctx; From a388676b40040be56f61db1d9ca86a839441c539 Mon Sep 17 00:00:00 2001 From: Silver Kuusik Date: Sun, 30 Jul 2017 00:22:23 +0200 Subject: [PATCH 107/347] added remoteIP for esp32 --- src/WebSocketsServer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 3550c6a..72169df 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -92,7 +92,7 @@ class WebSocketsServer: protected WebSockets { void setAuthorization(const char * user, const char * password); void setAuthorization(const char * auth); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) IPAddress remoteIP(uint8_t num); #endif From 1d40160d99e5987ae745fa62c328679ffbbdc632 Mon Sep 17 00:00:00 2001 From: Silver Kuusik Date: Sun, 30 Jul 2017 00:54:17 +0200 Subject: [PATCH 108/347] added esp32 support --- src/WebSocketsServer.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 9b8cfe7..d8017e6 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -52,6 +52,8 @@ WebSocketsServer::~WebSocketsServer() { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) _server->close(); +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) + _server->end(); #else // TODO how to close server? #endif @@ -75,7 +77,7 @@ void WebSocketsServer::begin(void) { client->num = i; client->status = WSC_NOT_CONNECTED; client->tcp = NULL; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) client->isSSL = false; client->ssl = NULL; #endif @@ -98,6 +100,9 @@ void WebSocketsServer::begin(void) { #ifdef ESP8266 randomSeed(RANDOM_REG32); +#elif defined(ESP32) + #define DR_REG_RNG_BASE 0x3ff75144 + randomSeed(READ_PERI_REG(DR_REG_RNG_BASE)); #else // TODO find better seed randomSeed(millis()); @@ -386,7 +391,7 @@ void WebSocketsServer::setAuthorization(const char * auth) { } } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) /** * get an IP for a client * @param num uint8_t client id @@ -423,7 +428,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { client->tcp = TCPclient; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) client->isSSL = false; client->tcp->setNoDelay(true); #endif @@ -432,7 +437,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { client->tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); #endif client->status = WSC_HEADER; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) IPAddress ip = client->tcp->remoteIP(); DEBUG_WEBSOCKETS("[WS-Server][%d] new client from %d.%d.%d.%d\n", client->num, ip[0], ip[1], ip[2], ip[3]); #else @@ -496,7 +501,7 @@ void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, u void WebSocketsServer::clientDisconnect(WSclient_t * client) { -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) if(client->isSSL && client->ssl) { if(client->ssl->connected()) { client->ssl->flush(); @@ -584,10 +589,12 @@ void WebSocketsServer::handleNewClients(void) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) while(_server->hasClient()) { +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) + while(_server->available()) { #endif bool ok = false; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) // store new connection WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); #else @@ -603,7 +610,7 @@ void WebSocketsServer::handleNewClients(void) { if(!ok) { // no free space to handle client -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) IPAddress ip = tcpClient->remoteIP(); DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); #else @@ -612,11 +619,10 @@ void WebSocketsServer::handleNewClients(void) { tcpClient->stop(); } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) delay(0); - } #endif - + } } From dbabc1025bc2d942a801965e1f67d45b79b90148 Mon Sep 17 00:00:00 2001 From: Silver Kuusik Date: Sun, 30 Jul 2017 00:58:15 +0200 Subject: [PATCH 109/347] added esp32 support --- src/WebSocketsClient.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 7390a76..3ca2698 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -42,7 +42,7 @@ class WebSocketsClient: private WebSockets { void begin(const char *host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); void begin(String host, uint16_t port, String url = "/", String protocol = "arduino"); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) void beginSSL(const char *host, uint16_t port, const char * url = "/", const char * = "", const char * protocol = "arduino"); void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino"); #endif @@ -50,7 +50,7 @@ class WebSocketsClient: private WebSockets { void beginSocketIO(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); void beginSocketIO(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) void beginSocketIOSSL(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); void beginSocketIOSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); #endif @@ -87,7 +87,7 @@ class WebSocketsClient: private WebSockets { String _host; uint16_t _port; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) String _fingerprint; #endif WSclient_t _client; From 4c1c5378cb84838ae590f7dd7a138ef5d848cc3f Mon Sep 17 00:00:00 2001 From: Silver Kuusik Date: Sun, 30 Jul 2017 01:40:36 +0200 Subject: [PATCH 110/347] esp32 no hasClient function --- src/WebSocketsServer.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index d8017e6..4f6400e 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -589,8 +589,6 @@ void WebSocketsServer::handleNewClients(void) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) while(_server->hasClient()) { -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) - while(_server->available()) { #endif bool ok = false; @@ -621,8 +619,9 @@ void WebSocketsServer::handleNewClients(void) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) delay(0); -#endif } +#endif + } From 29df9c30f708ac21c7604132a86ffdd4b69d1cdb Mon Sep 17 00:00:00 2001 From: Links Date: Fri, 18 Aug 2017 17:16:51 +0200 Subject: [PATCH 111/347] bump version to 2.0.8 --- library.json | 2 +- library.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library.json b/library.json index 60e02a4..733c40b 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.0.7", + "version": "2.0.8", "license": "LGPL-2.1", "export": { "exclude": [ diff --git a/library.properties b/library.properties index 983024e..5c319c0 100644 --- a/library.properties +++ b/library.properties @@ -1,7 +1,7 @@ name=WebSockets -version=2.0.7 +version=2.0.8 author=Markus Sattler -maintainer=Markus Sattler +maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) paragraph=use 2.x.x for ESP and 1.3 for AVR category=Communication From 522a67bc1b4ec0e56cb7e86d4d0bd780ccfa3dff Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 19 Aug 2017 21:16:07 +0200 Subject: [PATCH 112/347] add setReconnectInterval for the Client --- examples/WebSocketClient/WebSocketClient.ino | 93 +++++++++++--------- src/WebSockets.h | 3 + src/WebSocketsClient.cpp | 23 ++++- src/WebSocketsClient.h | 5 ++ 4 files changed, 79 insertions(+), 45 deletions(-) diff --git a/examples/WebSocketClient/WebSocketClient.ino b/examples/WebSocketClient/WebSocketClient.ino index 5a344fd..3ce8498 100644 --- a/examples/WebSocketClient/WebSocketClient.ino +++ b/examples/WebSocketClient/WebSocketClient.ino @@ -17,71 +17,76 @@ ESP8266WiFiMulti WiFiMulti; WebSocketsClient webSocket; - #define USE_SERIAL Serial1 void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[WSc] Disconnected!\n"); + break; + case WStype_CONNECTED: { + USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); - switch(type) { - case WStype_DISCONNECTED: - USE_SERIAL.printf("[WSc] Disconnected!\n"); - break; - case WStype_CONNECTED: - { - USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); - - // send message to server when Connected - webSocket.sendTXT("Connected"); - } - break; - case WStype_TEXT: - USE_SERIAL.printf("[WSc] get text: %s\n", payload); + // send message to server when Connected + webSocket.sendTXT("Connected"); + } + break; + case WStype_TEXT: + USE_SERIAL.printf("[WSc] get text: %s\n", payload); // send message to server // webSocket.sendTXT("message here"); - break; - case WStype_BIN: - USE_SERIAL.printf("[WSc] get binary length: %u\n", length); - hexdump(payload, length); + break; + case WStype_BIN: + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); - // send data to server - // webSocket.sendBIN(payload, length); - break; - } + // send data to server + // webSocket.sendBIN(payload, length); + break; + } } void setup() { - // USE_SERIAL.begin(921600); - USE_SERIAL.begin(115200); + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + //Serial.setDebugOutput(true); + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } - //Serial.setDebugOutput(true); - USE_SERIAL.setDebugOutput(true); + WiFiMulti.addAP("SSID", "passpasspass"); - USE_SERIAL.println(); - USE_SERIAL.println(); - USE_SERIAL.println(); + //WiFi.disconnect(); + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } - for(uint8_t t = 4; t > 0; t--) { - USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); - USE_SERIAL.flush(); - delay(1000); - } + // server address, port and URL + webSocket.begin("192.168.0.123", 81, "/"); - WiFiMulti.addAP("SSID", "passpasspass"); + // event handler + webSocket.onEvent(webSocketEvent); - //WiFi.disconnect(); - while(WiFiMulti.run() != WL_CONNECTED) { - delay(100); - } + // use HTTP Basic Authorization this is optional remove if not needed + webSocket.setAuthorization("user", "Password"); - webSocket.begin("192.168.0.123", 81); - //webSocket.setAuthorization("user", "Password"); // HTTP Basic Authorization - webSocket.onEvent(webSocketEvent); + // try ever 5000 again if connection has failed + webSocket.setReconnectInterval(5000); } void loop() { - webSocket.loop(); + webSocket.loop(); } diff --git a/src/WebSockets.h b/src/WebSockets.h index 41cbe7d..cca3ae1 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -34,11 +34,14 @@ #include +#ifndef NODEBUG_WEBSOCKETS #ifdef DEBUG_ESP_PORT #define DEBUG_WEBSOCKETS(...) DEBUG_ESP_PORT.printf( __VA_ARGS__ ) #else //#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) #endif +#endif + #ifndef DEBUG_WEBSOCKETS #define DEBUG_WEBSOCKETS(...) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 3faae99..ab1bf66 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -75,6 +75,9 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url, #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) asyncConnect(); #endif + + _lastConnectionFail = 0; + _reconnectInterval = 500; } void WebSocketsClient::begin(String host, uint16_t port, String url, String protocol) { @@ -121,6 +124,10 @@ void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url, */ void WebSocketsClient::loop(void) { if(!clientIsConnected(&_client)) { + // do not flood the server + if((millis() - _lastConnectionFail) < _reconnectInterval) { + return; + } #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) if(_client.isSSL) { @@ -151,9 +158,11 @@ void WebSocketsClient::loop(void) { if(_client.tcp->connect(_host.c_str(), _port)) { connectedCb(); + _lastConnectionFail = 0; } else { connectFailedCb(); - delay(10); //some little delay to not flood the server + _lastConnectionFail = millis(); + } } else { handleClientData(); @@ -284,6 +293,16 @@ void WebSocketsClient::setExtraHeaders(const char * extraHeaders) { _client.extraHeaders = extraHeaders; } + +/** + * set the reconnect Interval + * how long to wait after a connection initiate failed + * @param time in ms + */ +void WebSocketsClient::setReconnectInterval(unsigned long time) { + _reconnectInterval = time; +} + //################################################################################# //################################################################################# //################################################################################# @@ -604,6 +623,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { ok = false; DEBUG_WEBSOCKETS("[WS-Client][handleHeader] serverCode is not 101 (%d)\n", client->cCode); clientDisconnect(client); + _lastConnectionFail = millis(); break; } } @@ -634,6 +654,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { sendHeader(client); } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); + _lastConnectionFail = millis(); if(clientIsConnected(client)) { client->tcp->write("This is a webSocket client!"); } diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 7390a76..c1f5b0c 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -83,6 +83,8 @@ class WebSocketsClient: private WebSockets { void setExtraHeaders(const char * extraHeaders = NULL); + void setReconnectInterval(unsigned long time); + protected: String _host; uint16_t _port; @@ -94,6 +96,9 @@ class WebSocketsClient: private WebSockets { WebSocketClientEvent _cbEvent; + unsigned long _lastConnectionFail; + unsigned long _reconnectInterval; + void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); void clientDisconnect(WSclient_t * client); From b6c27f74cd0ec136b97cf50d124ac209ca1557d1 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 19 Aug 2017 22:05:33 +0200 Subject: [PATCH 113/347] bump version to 2.0.9 --- library.json | 2 +- library.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index 733c40b..881ef54 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.0.8", + "version": "2.0.9", "license": "LGPL-2.1", "export": { "exclude": [ diff --git a/library.properties b/library.properties index 5c319c0..c166487 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.0.8 +version=2.0.9 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From f40a390ab158e42e8e2190335f43650ab2e831c9 Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 21 Aug 2017 21:39:14 +0200 Subject: [PATCH 114/347] workaround windows gcc Template issue (#228, #229) --- src/WebSockets.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 434e1e7..1320e3e 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -624,7 +624,7 @@ size_t WebSockets::write(WSclient_t * client, uint8_t *out, size_t n) { break; } - len = client->tcp->write(out, n); + len = client->tcp->write((const uint8_t*)out, n); if(len) { t = millis(); out += len; From 1bd4638621c750571c4c61c46380e15a8d8a68bc Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 21 Aug 2017 21:44:30 +0200 Subject: [PATCH 115/347] bump version to 2.0.10 --- library.json | 2 +- library.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index 881ef54..35289fc 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.0.9", + "version": "2.0.10", "license": "LGPL-2.1", "export": { "exclude": [ diff --git a/library.properties b/library.properties index c166487..6ae767e 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.0.9 +version=2.0.10 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From 83a1539e1e583323ba07cf03df4540cdcf73b0c7 Mon Sep 17 00:00:00 2001 From: Silver Kuusik Date: Sun, 3 Sep 2017 09:55:15 +0200 Subject: [PATCH 116/347] fix: ESP32 new client connection --- src/WebSocketsServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 4f6400e..72bca56 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -587,7 +587,7 @@ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { */ void WebSocketsServer::handleNewClients(void) { -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) while(_server->hasClient()) { #endif bool ok = false; From a93a8457805816abe178382ce907655ae4f9a3f5 Mon Sep 17 00:00:00 2001 From: Silver Kuusik Date: Sun, 3 Sep 2017 10:06:00 +0200 Subject: [PATCH 117/347] add: ESP32 support --- src/WebSocketsClient.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 3faae99..541e30f 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -42,14 +42,14 @@ WebSocketsClient::~WebSocketsClient() { void WebSocketsClient::begin(const char *host, uint16_t port, const char * url, const char * protocol) { _host = host; _port = port; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) _fingerprint = ""; #endif _client.num = 0; _client.status = WSC_NOT_CONNECTED; _client.tcp = NULL; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) _client.isSSL = false; _client.ssl = NULL; #endif @@ -81,7 +81,7 @@ void WebSocketsClient::begin(String host, uint16_t port, String url, String prot begin(host.c_str(), port, url.c_str(), protocol.c_str()); } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) void WebSocketsClient::beginSSL(const char *host, uint16_t port, const char * url, const char * fingerprint, const char * protocol) { begin(host, port, url, protocol); _client.isSSL = true; @@ -102,7 +102,7 @@ void WebSocketsClient::beginSocketIO(String host, uint16_t port, String url, Str beginSocketIO(host.c_str(), port, url.c_str(), protocol.c_str()); } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) void WebSocketsClient::beginSocketIOSSL(const char *host, uint16_t port, const char * url, const char * protocol) { begin(host, port, url, protocol); _client.isSocketIO = true; @@ -122,7 +122,7 @@ void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url, void WebSocketsClient::loop(void) { if(!clientIsConnected(&_client)) { -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) if(_client.isSSL) { DEBUG_WEBSOCKETS("[WS-Client] connect wss...\n"); if(_client.ssl) { @@ -322,7 +322,7 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { bool event = false; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) if(client->isSSL && client->ssl) { if(client->ssl->connected()) { client->ssl->flush(); @@ -421,7 +421,7 @@ void WebSocketsClient::handleClientData(void) { break; } } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) delay(0); #endif } From 4fd2e9d99366f7483ccef00004bd35501803fa19 Mon Sep 17 00:00:00 2001 From: Martin Becker Date: Mon, 25 Sep 2017 15:04:56 +0200 Subject: [PATCH 118/347] Add example for plain STOMP connection --- .../WebSocketClientStomp.ino | 148 ++++++++++++++++++ .../WebSocketClientStompOverSockJs.ino} | 8 +- 2 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 examples/WebSocketClientStomp/WebSocketClientStomp.ino rename examples/{WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino => WebSocketClientStompOverSockJs/WebSocketClientStompOverSockJs.ino} (92%) diff --git a/examples/WebSocketClientStomp/WebSocketClientStomp.ino b/examples/WebSocketClientStomp/WebSocketClientStomp.ino new file mode 100644 index 0000000..bb77c44 --- /dev/null +++ b/examples/WebSocketClientStomp/WebSocketClientStomp.ino @@ -0,0 +1,148 @@ +/* + WebSocketClientStomp.ino + + Example for connecting and maintining a connection with a STOMP websocket connection. + In this example, we connect to a Spring application (see https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html). + + Created on: 25.09.2017 + Author: Martin Becker , Contact: becker@informatik.uni-wuerzburg.de +*/ + +// PRE + +#define USE_SERIAL Serial + + +// LIBRARIES + +#include + +#include +#include + + +// SETTINGS + +const char* wlan_ssid = "yourssid"; +const char* wlan_password = "somepassword"; + +const char* ws_host = "the.host.net"; +const int ws_port = 80; + +// URL for STOMP endpoint. +// For the default config of Spring's STOMP support, the default URL is "/socketentry/websocket". +const char* stompUrl = "/socketentry/websocket"; // don't forget the leading "/" !!! + + +// VARIABLES + +WebSocketsClient webSocket; + + +// FUNCTIONS + +/** + * STOMP messages need to be NULL-terminated (i.e., \0 or \u0000). + * However, when we send a String or a char[] array without specifying + * a length, the size of the message payload is derived by strlen() internally, + * thus dropping any NULL values appended to the "msg"-String. + * + * To solve this, we first convert the String to a NULL terminated char[] array + * via "c_str" and set the length of the payload to include the NULL value. + */ +void sendMessage(String & msg) { + webSocket.sendTXT(msg.c_str(), msg.length() + 1); +} + +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { + + switch (type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[WSc] Disconnected!\n"); + break; + case WStype_CONNECTED: + { + USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); + + String msg = "CONNECT\r\naccept-version:1.1,1.0\r\nheart-beat:10000,10000\r\n\r\n"; + sendMessage(msg); + } + break; + case WStype_TEXT: + { + // ##################### + // handle STOMP protocol + // ##################### + + String text = (char*) payload; + USE_SERIAL.printf("[WSc] get text: %s\n", payload); + + if (text.startsWith("CONNECTED")) { + + // subscribe to some channels + + String msg = "SUBSCRIBE\nid:sub-0\ndestination:/user/queue/messages\n\n"; + sendMessage(msg); + delay(1000); + + // and send a message + + msg = "SEND\ndestination:/app/message\n\n{\"user\":\"esp\",\"message\":\"Hello!\"}"; + sendMessage(msg); + delay(1000); + + } else { + + // do something with messages + + } + + break; + } + case WStype_BIN: + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); + + // send data to server + // webSocket.sendBIN(payload, length); + break; + } + +} + +void setup() { + + // setup serial + + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + // USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + + + // connect to WiFi + + USE_SERIAL.print("Logging into WLAN: "); Serial.print(wlan_ssid); Serial.print(" ..."); + WiFi.mode(WIFI_STA); + WiFi.begin(wlan_ssid, wlan_password); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + USE_SERIAL.print("."); + } + USE_SERIAL.println(" success."); + USE_SERIAL.print("IP: "); USE_SERIAL.println(WiFi.localIP()); + + + // connect to websocket + webSocket.begin(ws_host, ws_port, stompUrl); + webSocket.setExtraHeaders(); // remove "Origin: file://" header because it breaks the connection with Spring's default websocket config + // webSocket.setExtraHeaders("foo: I am so funny\r\nbar: not"); // some headers, in case you feel funny + webSocket.onEvent(webSocketEvent); +} + +void loop() { + webSocket.loop(); +} diff --git a/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino b/examples/WebSocketClientStompOverSockJs/WebSocketClientStompOverSockJs.ino similarity index 92% rename from examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino rename to examples/WebSocketClientStompOverSockJs/WebSocketClientStompOverSockJs.ino index 493a949..cb0c45b 100644 --- a/examples/WebSocketClientSockJsAndStomp/WebSocketClientSockJsAndStomp.ino +++ b/examples/WebSocketClientStompOverSockJs/WebSocketClientStompOverSockJs.ino @@ -1,8 +1,8 @@ /* - WebSocketClientSockJsAndStomp.ino + WebSocketClientStompOverSockJs.ino Example for connecting and maintining a connection with a SockJS+STOMP websocket connection. - In this example we connect to a Spring application (see https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html). + In this example, we connect to a Spring application (see https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html). Created on: 18.07.2017 Author: Martin Becker , Contact: becker@informatik.uni-wuerzburg.de @@ -33,7 +33,7 @@ const int ws_port = 80; // base URL for SockJS (websocket) connection // The complete URL will look something like this(cf. http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-36): // ws://://<3digits>//websocket -// For the default config of Spring's SockJS/STOMP support the default base URL is "/socketentry/". +// For the default config of Spring's SockJS/STOMP support, the default base URL is "/socketentry/". const char* ws_baseurl = "/socketentry/"; // don't forget leading and trailing "/" !!! @@ -58,7 +58,7 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { case WStype_TEXT: { // ##################### - // handle STOMP protocol + // handle SockJs+STOMP protocol // ##################### String text = (char*) payload; From 4baf4896cc5aaaf21cc0164171da7dfb1eb16508 Mon Sep 17 00:00:00 2001 From: Martin Becker Date: Mon, 25 Sep 2017 17:20:07 +0200 Subject: [PATCH 119/347] Add missing Hash.h library --- examples/WebSocketClientStomp/WebSocketClientStomp.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/WebSocketClientStomp/WebSocketClientStomp.ino b/examples/WebSocketClientStomp/WebSocketClientStomp.ino index bb77c44..a0eb011 100644 --- a/examples/WebSocketClientStomp/WebSocketClientStomp.ino +++ b/examples/WebSocketClientStomp/WebSocketClientStomp.ino @@ -16,6 +16,7 @@ // LIBRARIES #include +#include #include #include From b87bce4466ca1bfa03d5c7fce91fcaa1e12418b0 Mon Sep 17 00:00:00 2001 From: Links Date: Wed, 4 Oct 2017 19:17:21 +0200 Subject: [PATCH 120/347] add virtual to destructor #243 --- src/WebSockets.cpp | 1 + src/WebSocketsClient.cpp | 1 - src/WebSocketsClient.h | 2 +- src/WebSocketsServer.h | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 1320e3e..9512324 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -46,6 +46,7 @@ extern "C" { #endif + /** * * @param client WSclient_t * ptr to the client struct diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index b359e6d..ea31db7 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -373,7 +373,6 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { client->cCode = 0; client->cKey = ""; client->cAccept = ""; - client->cProtocol = ""; client->cVersion = 0; client->cIsUpgrade = false; client->cIsWebsocket = false; diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index c1f5b0c..ab82e98 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -37,7 +37,7 @@ class WebSocketsClient: private WebSockets { WebSocketsClient(void); - ~WebSocketsClient(void); + virtual ~WebSocketsClient(void); void begin(const char *host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); void begin(String host, uint16_t port, String url = "/", String protocol = "arduino"); diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 3550c6a..7d5a7cd 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -44,7 +44,7 @@ class WebSocketsServer: protected WebSockets { #endif WebSocketsServer(uint16_t port, String origin = "", String protocol = "arduino"); - ~WebSocketsServer(void); + virtual ~WebSocketsServer(void); void begin(void); From c5461d5779100c2b93764c8200f30ad70aec2e02 Mon Sep 17 00:00:00 2001 From: Markus Date: Fri, 6 Oct 2017 18:30:05 +0200 Subject: [PATCH 121/347] memset zero _clients struct for server fixes #244 --- src/WebSocketsServer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index f860298..0e5795f 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -43,6 +43,8 @@ WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol _httpHeaderValidationFunc = NULL; _mandatoryHttpHeaders = NULL; _mandatoryHttpHeaderCount = 0; + + memset(&_clients[0], 0x00, (sizeof(WSclient_t) * WEBSOCKETS_SERVER_CLIENT_MAX)); } From a0c714bf1043d9d86353793c3e77a86aa5304eba Mon Sep 17 00:00:00 2001 From: PeterEmbedded Date: Mon, 16 Oct 2017 13:01:00 +0200 Subject: [PATCH 122/347] Update WebSockets.cpp Added some missing comments --- src/WebSockets.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 9512324..cd7c9cc 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -51,8 +51,8 @@ extern "C" { * * @param client WSclient_t * ptr to the client struct * @param code uint16_t see RFC - * @param reason - * @param reasonLen + * @param reason ptr to the disconnect reason message + * @param reasonLen length of the disconnect reason message */ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * reason, size_t reasonLen) { DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] clientDisconnect code: %u\n", client->num, code); @@ -73,8 +73,8 @@ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * rea * * @param client WSclient_t * ptr to the client struct * @param opcode WSopcode_t - * @param payload uint8_t * - * @param length size_t + * @param payload uint8_t * ptr to the payload + * @param length size_t length of the payload * @param mask bool add dummy mask to the frame (needed for web browser) * @param fin bool can be used to send data in more then one frame (set fin on the last frame) * @param headerToPayload bool set true if the payload has reserved 14 Byte at the beginning to dynamically add the Header (payload neet to be in RAM!) @@ -92,7 +92,7 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay return false; } - DEBUG_WEBSOCKETS("[WS][%d][sendFrame] ------- send massage frame -------\n", client->num); + DEBUG_WEBSOCKETS("[WS][%d][sendFrame] ------- send message frame -------\n", client->num); DEBUG_WEBSOCKETS("[WS][%d][sendFrame] fin: %u opCode: %u mask: %u length: %u headerToPayload: %u\n", client->num, fin, opcode, mask, length, headerToPayload); if(opcode == WSop_text) { From 1d300084e0bdcdb74fc32c7c7b01a9d94fdb69ea Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 6 Feb 2018 09:57:04 +0100 Subject: [PATCH 123/347] fix --- .../WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino b/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino index f737d7f..913b799 100644 --- a/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino +++ b/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino @@ -23,7 +23,7 @@ ESP8266WiFiMulti WiFiMulti; -ESP8266WebServer server = ESP8266WebServer(80); +ESP8266WebServer server(80); WebSocketsServer webSocket = WebSocketsServer(81); void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { From 0b102995495bc07b67163fd1d5b98c6b6eda1f7e Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 6 Feb 2018 20:22:29 +0100 Subject: [PATCH 124/347] travis builds for ESP32 --- .travis.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.travis.yml b/.travis.yml index 881c97f..b731a64 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,10 +20,20 @@ script: - git clone https://github.com/esp8266/Arduino.git esp8266 - cd esp8266/tools - python get.py + - cd $HOME/arduino_ide/hardware + - mkdir espressif + - cd espressif + - git clone https://github.com/espressif/arduino-esp32.git esp32 + - cd esp32/tools + - python get.py + - cd $TRAVIS_BUILD_DIR - source $TRAVIS_BUILD_DIR/travis/common.sh - arduino --board esp8266com:esp8266:generic --save-prefs - arduino --get-pref sketchbook.path - build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets esp8266 + - arduino --board espressif:esp32:esp32:FlashFreq=80 --save-prefs + - arduino --get-pref sketchbook.path + - build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets esp32 notifications: email: From 30b6deedd272f156350dbcfb3ef76536598f1556 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 6 Feb 2018 20:41:36 +0100 Subject: [PATCH 125/347] use travis matrix --- .travis.yml | 34 +++++++++++++--------------------- travis/common.sh | 22 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index b731a64..29f1cbe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,38 +2,30 @@ sudo: false language: bash os: - linux +env: + global: + - IDE_VERSION=1.6.5 + matrix: + CPU="esp8266" BOARD="esp8266com:esp8266:generic" + CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" script: - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 - sleep 3 - export DISPLAY=:1.0 - - wget http://downloads.arduino.cc/arduino-1.6.5-linux64.tar.xz - - tar xf arduino-1.6.5-linux64.tar.xz - - mv arduino-1.6.5 $HOME/arduino_ide + - wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz + - tar xf arduino-$IDE_VERSION-linux64.tar.xz + - mv arduino-$IDE_VERSION $HOME/arduino_ide - export PATH="$HOME/arduino_ide:$PATH" - which arduino - mkdir -p $HOME/Arduino/libraries - cp -r $TRAVIS_BUILD_DIR $HOME/Arduino/libraries/arduinoWebSockets - - cd $HOME/arduino_ide/hardware - - mkdir esp8266com - - cd esp8266com - - git clone https://github.com/esp8266/Arduino.git esp8266 - - cd esp8266/tools - - python get.py - - cd $HOME/arduino_ide/hardware - - mkdir espressif - - cd espressif - - git clone https://github.com/espressif/arduino-esp32.git esp32 - - cd esp32/tools - - python get.py - - cd $TRAVIS_BUILD_DIR - source $TRAVIS_BUILD_DIR/travis/common.sh - - arduino --board esp8266com:esp8266:generic --save-prefs - - arduino --get-pref sketchbook.path - - build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets esp8266 - - arduino --board espressif:esp32:esp32:FlashFreq=80 --save-prefs + - get_core $CPU + - cd $TRAVIS_BUILD_DIR + - arduino --board $BOARD --save-prefs - arduino --get-pref sketchbook.path - - build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets esp32 + - build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets $CPU notifications: email: diff --git a/travis/common.sh b/travis/common.sh index 4bcd81b..1cf8bff 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -22,3 +22,25 @@ function build_sketches() done } + +function get_core() +{ + cd $HOME/arduino_ide/hardware + + if [ "$1" = "esp8266" ] ; then + mkdir esp8266com + cd esp8266com + git clone https://github.com/esp8266/Arduino.git esp8266 + cd esp8266/tools + python get.py + fi + + if [ "$1" = "esp32" ] ; then + mkdir espressif + cd espressif + git clone https://github.com/espressif/arduino-esp32.git esp32 + cd esp32/tools + python get.py + fi + +} From 5e1f9b1c267ce0b780e597f620496c53183ff27e Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 6 Feb 2018 20:44:10 +0100 Subject: [PATCH 126/347] CORE_HAS_LIBB64 for ESP32 --- src/libb64/cdecode.c | 8 ++++++-- src/libb64/cencode.c | 14 +++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/libb64/cdecode.c b/src/libb64/cdecode.c index 0d86d0e..e135da2 100644 --- a/src/libb64/cdecode.c +++ b/src/libb64/cdecode.c @@ -9,6 +9,10 @@ For details, see http://sourceforge.net/projects/libb64 #include #endif +#if defined(ESP32) +#define CORE_HAS_LIBB64 +#endif + #ifndef CORE_HAS_LIBB64 #include "cdecode_inc.h" @@ -32,9 +36,9 @@ int base64_decode_block(const char* code_in, const int length_in, char* plaintex const char* codechar = code_in; char* plainchar = plaintext_out; char fragment; - + *plainchar = state_in->plainchar; - + switch (state_in->step) { while (1) diff --git a/src/libb64/cencode.c b/src/libb64/cencode.c index 7367135..afe1463 100644 --- a/src/libb64/cencode.c +++ b/src/libb64/cencode.c @@ -9,6 +9,10 @@ For details, see http://sourceforge.net/projects/libb64 #include #endif +#if defined(ESP32) +#define CORE_HAS_LIBB64 +#endif + #ifndef CORE_HAS_LIBB64 #include "cencode_inc.h" @@ -35,9 +39,9 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, char* codechar = code_out; char result; char fragment; - + result = state_in->result; - + switch (state_in->step) { while (1) @@ -76,7 +80,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, *codechar++ = base64_encode_value(result); result = (fragment & 0x03f) >> 0; *codechar++ = base64_encode_value(result); - + ++(state_in->stepcount); if (state_in->stepcount == CHARS_PER_LINE/4) { @@ -92,7 +96,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, int base64_encode_blockend(char* code_out, base64_encodestate* state_in) { char* codechar = code_out; - + switch (state_in->step) { case step_B: @@ -108,7 +112,7 @@ int base64_encode_blockend(char* code_out, base64_encodestate* state_in) break; } *codechar++ = 0x00; - + return codechar - code_out; } From 255f40eaa700ec5dd5fd61a8957d8313e818c0b9 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 6 Feb 2018 20:46:17 +0100 Subject: [PATCH 127/347] travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 29f1cbe..f24935f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,8 @@ env: global: - IDE_VERSION=1.6.5 matrix: - CPU="esp8266" BOARD="esp8266com:esp8266:generic" - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" + - CPU="esp8266" BOARD="esp8266com:esp8266:generic" + - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" script: - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 From 0b35e32b2a1d59041a87dc1216ad04eb616b50f7 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 6 Feb 2018 21:10:29 +0100 Subject: [PATCH 128/347] examples for ESP32 --- examples/WebSocketClient/WebSocketClient.ino | 34 ++++++++++++++++++- examples/WebSocketServer/WebSocketServer.ino | 35 ++++++++++++++++++-- travis/common.sh | 4 ++- 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/examples/WebSocketClient/WebSocketClient.ino b/examples/WebSocketClient/WebSocketClient.ino index 3ce8498..689dada 100644 --- a/examples/WebSocketClient/WebSocketClient.ino +++ b/examples/WebSocketClient/WebSocketClient.ino @@ -10,15 +10,30 @@ #include #include +#if defined(ESP8266) + #include #include + #include #include + ESP8266WiFiMulti WiFiMulti; +#elif defined(ESP32) + #include + #include + WiFiMulti WiFiMulti; + + HardwareSerial Serial1(2); +#endif + #include #include -ESP8266WiFiMulti WiFiMulti; WebSocketsClient webSocket; #define USE_SERIAL Serial1 +#ifndef ESP8266 +void hexdump(const void *mem, uint32_t len, uint8_t cols = 16); +#endif + void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch(type) { @@ -90,3 +105,20 @@ void setup() { void loop() { webSocket.loop(); } + + + +#ifndef ESP8266 +void hexdump(const void *mem, uint32_t len, uint8_t cols) { + const uint8_t* src = (const uint8_t*) mem; + USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); + for(uint32_t i = 0; i < len; i++) { + if(i % cols == 0) { + USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); + } + USE_SERIAL.printf("%02X ", *src); + src++; + } + USE_SERIAL.printf("\n"); +} +#endif diff --git a/examples/WebSocketServer/WebSocketServer.ino b/examples/WebSocketServer/WebSocketServer.ino index 5e266a2..de9c63e 100644 --- a/examples/WebSocketServer/WebSocketServer.ino +++ b/examples/WebSocketServer/WebSocketServer.ino @@ -7,8 +7,18 @@ #include -#include -#include +#if defined(ESP8266) + #include #include + #include #include + ESP8266WiFiMulti WiFiMulti; +#elif defined(ESP32) + #include + #include + WiFiMulti WiFiMulti; + + HardwareSerial Serial1(2); +#endif + #include #include @@ -18,6 +28,11 @@ WebSocketsServer webSocket = WebSocketsServer(81); #define USE_SERIAL Serial1 + +#ifndef ESP8266 +void hexdump(const void *mem, uint32_t len, uint8_t cols = 16); +#endif + void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { switch(type) { @@ -28,7 +43,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length { IPAddress ip = webSocket.remoteIP(num); USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); - + // send message to client webSocket.sendTXT(num, "Connected"); } @@ -84,3 +99,17 @@ void loop() { webSocket.loop(); } +#ifndef ESP8266 +void hexdump(const void *mem, uint32_t len, uint8_t cols) { + const uint8_t* src = (const uint8_t*) mem; + USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); + for(uint32_t i = 0; i < len; i++) { + if(i % cols == 0) { + USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); + } + USE_SERIAL.printf("%02X ", *src); + src++; + } + USE_SERIAL.printf("\n"); +} +#endif diff --git a/travis/common.sh b/travis/common.sh index 1cf8bff..10237bb 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -25,6 +25,8 @@ function build_sketches() function get_core() { + echo Setup core for $1 + cd $HOME/arduino_ide/hardware if [ "$1" = "esp8266" ] ; then @@ -42,5 +44,5 @@ function get_core() cd esp32/tools python get.py fi - + } From 46cff38287eda8594e20c5d03cb4b9d741840ca4 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 6 Feb 2018 21:12:39 +0100 Subject: [PATCH 129/347] fix ESP32 sha1 problem --- src/libsha1/libsha1.c | 2 +- src/libsha1/libsha1.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libsha1/libsha1.c b/src/libsha1/libsha1.c index 7ff3846..fcf01c5 100644 --- a/src/libsha1/libsha1.c +++ b/src/libsha1/libsha1.c @@ -18,7 +18,7 @@ A million repetitions of "a" /* #define LITTLE_ENDIAN * This should be #define'd already, if true. */ /* #define SHA1HANDSOFF * Copies data before messing with it. */ -#ifndef ESP8266 +#if !defined(ESP8266) && !defined(ESP32) #define SHA1HANDSOFF diff --git a/src/libsha1/libsha1.h b/src/libsha1/libsha1.h index 1f08d0e..40afa61 100644 --- a/src/libsha1/libsha1.h +++ b/src/libsha1/libsha1.h @@ -5,7 +5,7 @@ By Steve Reid 100% Public Domain */ -#ifndef ESP8266 +#if !defined(ESP8266) && !defined(ESP32) typedef struct { uint32_t state[5]; @@ -18,4 +18,4 @@ void SHA1Init(SHA1_CTX* context); void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); void SHA1Final(unsigned char digest[20], SHA1_CTX* context); -#endif \ No newline at end of file +#endif From 05f4cfd7bf01143d22cf29c5e1bbd6458a717f1c Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 6 Feb 2018 21:17:14 +0100 Subject: [PATCH 130/347] fix includes for WebSocketClient.ino --- examples/WebSocketClient/WebSocketClient.ino | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/WebSocketClient/WebSocketClient.ino b/examples/WebSocketClient/WebSocketClient.ino index 689dada..baac0f0 100644 --- a/examples/WebSocketClient/WebSocketClient.ino +++ b/examples/WebSocketClient/WebSocketClient.ino @@ -7,9 +7,6 @@ #include -#include -#include - #if defined(ESP8266) #include #include #include #include From d340c89b097e6f5b03db5410f0513fd5479426e4 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 6 Feb 2018 21:26:06 +0100 Subject: [PATCH 131/347] ... --- examples/WebSocketClient/WebSocketClient.ino | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/WebSocketClient/WebSocketClient.ino b/examples/WebSocketClient/WebSocketClient.ino index baac0f0..4dad8e5 100644 --- a/examples/WebSocketClient/WebSocketClient.ino +++ b/examples/WebSocketClient/WebSocketClient.ino @@ -8,8 +8,8 @@ #include #if defined(ESP8266) - #include #include - #include #include + #include + #include ESP8266WiFiMulti WiFiMulti; #elif defined(ESP32) #include @@ -20,7 +20,6 @@ #endif #include - #include WebSocketsClient webSocket; From f62aa6478d8b329945746310421b54ddf84b40b7 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 6 Feb 2018 21:36:44 +0100 Subject: [PATCH 132/347] more ESP32 stuff --- examples/WebSocketClient/WebSocketClient.ino | 7 ++----- src/WebSockets.h | 6 +++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/examples/WebSocketClient/WebSocketClient.ino b/examples/WebSocketClient/WebSocketClient.ino index 4dad8e5..fe602aa 100644 --- a/examples/WebSocketClient/WebSocketClient.ino +++ b/examples/WebSocketClient/WebSocketClient.ino @@ -14,22 +14,20 @@ #elif defined(ESP32) #include #include + #include WiFiMulti WiFiMulti; HardwareSerial Serial1(2); #endif #include + #include WebSocketsClient webSocket; #define USE_SERIAL Serial1 -#ifndef ESP8266 -void hexdump(const void *mem, uint32_t len, uint8_t cols = 16); -#endif - void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch(type) { @@ -103,7 +101,6 @@ void loop() { } - #ifndef ESP8266 void hexdump(const void *mem, uint32_t len, uint8_t cols) { const uint8_t* src = (const uint8_t*) mem; diff --git a/src/WebSockets.h b/src/WebSockets.h index a10aab9..c63bb5e 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -48,7 +48,7 @@ #define NODEBUG_WEBSOCKETS #endif -#ifdef ESP8266 +#if defined(ESP8266) || defined(ESP32) #define WEBSOCKETS_MAX_DATA_SIZE (15*1024) #define WEBSOCKETS_USE_BIG_MEM #define GET_FREE_HEAP ESP.getFreeHeap() @@ -78,7 +78,7 @@ // max size of the WS Message Header #define WEBSOCKETS_MAX_HEADER_SIZE (14) -#if !defined(WEBSOCKETS_NETWORK_TYPE) +#if !defined(WEBSOCKETS_NETWORK_TYPE) // select Network type based #if defined(ESP8266) || defined(ESP31B) #define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 @@ -97,7 +97,7 @@ // No SSL/WSS support for client in Async mode // TLS lib need a sync interface! -#if !defined(ESP8266) && !defined(ESP31B) +#if !defined(ESP8266) && !defined(ESP31B) && !defined(ESP32) #error "network type ESP8266 ASYNC only possible on the ESP mcu!" #endif From d73e3ecc9c4f2a1c121703c488dbe5f40ec74930 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 6 Feb 2018 21:37:24 +0100 Subject: [PATCH 133/347] skip some test for ESP32 --- examples/ParticleWebSocketClient/.esp32.skip | 0 examples/WebSocketClientAVR/.esp32.skip | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 examples/ParticleWebSocketClient/.esp32.skip create mode 100644 examples/WebSocketClientAVR/.esp32.skip diff --git a/examples/ParticleWebSocketClient/.esp32.skip b/examples/ParticleWebSocketClient/.esp32.skip new file mode 100644 index 0000000..e69de29 diff --git a/examples/WebSocketClientAVR/.esp32.skip b/examples/WebSocketClientAVR/.esp32.skip new file mode 100644 index 0000000..e69de29 From 86074c90aea6c5b9a6e8728a9240f876fbbff02a Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 6 Feb 2018 21:41:47 +0100 Subject: [PATCH 134/347] update IDE test --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index f24935f..9ccd59e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ os: env: global: - IDE_VERSION=1.6.5 + - IDE_VERSION=1.8.5 matrix: - CPU="esp8266" BOARD="esp8266com:esp8266:generic" - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" From 2df62558f1bc0dcef29ea79fa7ad78cd4797a065 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 6 Feb 2018 21:48:49 +0100 Subject: [PATCH 135/347] more verbose verify step --- travis/common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/travis/common.sh b/travis/common.sh index 10237bb..062ba05 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -13,7 +13,7 @@ function build_sketches() continue fi echo -e "\n\n ------------ Building $sketch ------------ \n\n"; - $arduino --verify $sketch; + $arduino --verify --verbose $sketch; local result=$? if [ $result -ne 0 ]; then echo "Build failed ($1)" From 94eb4b12e5de0f803b350e883001c200667c3a57 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 6 Feb 2018 21:52:13 +0100 Subject: [PATCH 136/347] IDE version --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9ccd59e..a555767 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,7 @@ os: - linux env: global: - - IDE_VERSION=1.6.5 - - IDE_VERSION=1.8.5 + - IDE_VERSION=1.8.2 matrix: - CPU="esp8266" BOARD="esp8266com:esp8266:generic" - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" From a09b8c48ee465b317cff93ff9514154247025837 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 6 Feb 2018 21:58:26 +0100 Subject: [PATCH 137/347] ide version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a555767..f24935f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ os: - linux env: global: - - IDE_VERSION=1.8.2 + - IDE_VERSION=1.6.5 matrix: - CPU="esp8266" BOARD="esp8266com:esp8266:generic" - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" From b059d0711c5771e0fbfa24cd2e736ffb7888599b Mon Sep 17 00:00:00 2001 From: Links Date: Wed, 7 Feb 2018 17:28:17 +0100 Subject: [PATCH 138/347] sort examples by platform rework the travis tests create ESP32 examples --- .travis.yml | 11 +- examples/ParticleWebSocketClient/.esp32.skip | 0 .../ParticleWebSocketClient/.esp8266.skip | 0 examples/WebSocketClientAVR/.esp32.skip | 0 examples/WebSocketClientAVR/.esp8266.skip | 0 .../WebSocketClientAVR/WebSocketClientAVR.ino | 0 .../WebSocketClient/WebSocketClient.ino | 51 ++++----- .../WebSocketClientSSL/WebSocketClientSSL.ino | 102 ++++++++++++++++++ .../WebSocketServer/WebSocketServer.ino | 51 ++++----- .../WebSocketClient/WebSocketClient.ino | 92 ++++++++++++++++ .../WebSocketClientSSL/WebSocketClientSSL.ino | 0 .../WebSocketClientSocketIO.ino | 0 .../WebSocketClientStomp.ino | 0 .../WebSocketClientStompOverSockJs.ino | 0 .../WebSocketServer/WebSocketServer.ino | 86 +++++++++++++++ .../WebSocketServerFragmentation.ino | 0 .../WebSocketServerHttpHeaderValidation.ino | 0 .../WebSocketServer_LEDcontrol.ino | 1 - .../ParticleWebSocketClient/application.cpp | 0 src/WebSockets.h | 28 +++-- travis/common.sh | 9 +- 21 files changed, 351 insertions(+), 80 deletions(-) delete mode 100644 examples/ParticleWebSocketClient/.esp32.skip delete mode 100644 examples/ParticleWebSocketClient/.esp8266.skip delete mode 100644 examples/WebSocketClientAVR/.esp32.skip delete mode 100644 examples/WebSocketClientAVR/.esp8266.skip rename examples/{ => avr}/WebSocketClientAVR/WebSocketClientAVR.ino (100%) rename examples/{ => esp32}/WebSocketClient/WebSocketClient.ino (80%) create mode 100644 examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino rename examples/{ => esp32}/WebSocketServer/WebSocketServer.ino (78%) create mode 100644 examples/esp8266/WebSocketClient/WebSocketClient.ino rename examples/{ => esp8266}/WebSocketClientSSL/WebSocketClientSSL.ino (100%) rename examples/{ => esp8266}/WebSocketClientSocketIO/WebSocketClientSocketIO.ino (100%) rename examples/{ => esp8266}/WebSocketClientStomp/WebSocketClientStomp.ino (100%) rename examples/{ => esp8266}/WebSocketClientStompOverSockJs/WebSocketClientStompOverSockJs.ino (100%) create mode 100644 examples/esp8266/WebSocketServer/WebSocketServer.ino rename examples/{ => esp8266}/WebSocketServerFragmentation/WebSocketServerFragmentation.ino (100%) rename examples/{ => esp8266}/WebSocketServerHttpHeaderValidation/WebSocketServerHttpHeaderValidation.ino (100%) rename examples/{ => esp8266}/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino (96%) rename examples/{ => particle}/ParticleWebSocketClient/application.cpp (100%) diff --git a/.travis.yml b/.travis.yml index f24935f..b15fc0d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,12 @@ language: bash os: - linux env: - global: - - IDE_VERSION=1.6.5 matrix: - - CPU="esp8266" BOARD="esp8266com:esp8266:generic" - - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80" IDE_VERSION=1.6.5 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80" IDE_VERSION=1.8.5 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80,Debug=Serial1" IDE_VERSION=1.6.5 + - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.6.5 + - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.5 script: - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 @@ -25,7 +26,7 @@ script: - cd $TRAVIS_BUILD_DIR - arduino --board $BOARD --save-prefs - arduino --get-pref sketchbook.path - - build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets $CPU + - build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets/examples/$CPU $CPU notifications: email: diff --git a/examples/ParticleWebSocketClient/.esp32.skip b/examples/ParticleWebSocketClient/.esp32.skip deleted file mode 100644 index e69de29..0000000 diff --git a/examples/ParticleWebSocketClient/.esp8266.skip b/examples/ParticleWebSocketClient/.esp8266.skip deleted file mode 100644 index e69de29..0000000 diff --git a/examples/WebSocketClientAVR/.esp32.skip b/examples/WebSocketClientAVR/.esp32.skip deleted file mode 100644 index e69de29..0000000 diff --git a/examples/WebSocketClientAVR/.esp8266.skip b/examples/WebSocketClientAVR/.esp8266.skip deleted file mode 100644 index e69de29..0000000 diff --git a/examples/WebSocketClientAVR/WebSocketClientAVR.ino b/examples/avr/WebSocketClientAVR/WebSocketClientAVR.ino similarity index 100% rename from examples/WebSocketClientAVR/WebSocketClientAVR.ino rename to examples/avr/WebSocketClientAVR/WebSocketClientAVR.ino diff --git a/examples/WebSocketClient/WebSocketClient.ino b/examples/esp32/WebSocketClient/WebSocketClient.ino similarity index 80% rename from examples/WebSocketClient/WebSocketClient.ino rename to examples/esp32/WebSocketClient/WebSocketClient.ino index fe602aa..7483b6b 100644 --- a/examples/WebSocketClient/WebSocketClient.ino +++ b/examples/esp32/WebSocketClient/WebSocketClient.ino @@ -7,39 +7,44 @@ #include -#if defined(ESP8266) - #include - #include - ESP8266WiFiMulti WiFiMulti; -#elif defined(ESP32) - #include - #include - #include - WiFiMulti WiFiMulti; - - HardwareSerial Serial1(2); -#endif +#include +#include +#include #include -#include +WiFiMulti WiFiMulti; WebSocketsClient webSocket; +HardwareSerial Serial1(2); + #define USE_SERIAL Serial1 +void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) { + const uint8_t* src = (const uint8_t*) mem; + USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); + for(uint32_t i = 0; i < len; i++) { + if(i % cols == 0) { + USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); + } + USE_SERIAL.printf("%02X ", *src); + src++; + } + USE_SERIAL.printf("\n"); +} + void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch(type) { case WStype_DISCONNECTED: USE_SERIAL.printf("[WSc] Disconnected!\n"); break; - case WStype_CONNECTED: { + case WStype_CONNECTED: USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); // send message to server when Connected webSocket.sendTXT("Connected"); - } break; case WStype_TEXT: USE_SERIAL.printf("[WSc] get text: %s\n", payload); @@ -99,19 +104,3 @@ void setup() { void loop() { webSocket.loop(); } - - -#ifndef ESP8266 -void hexdump(const void *mem, uint32_t len, uint8_t cols) { - const uint8_t* src = (const uint8_t*) mem; - USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); - for(uint32_t i = 0; i < len; i++) { - if(i % cols == 0) { - USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); - } - USE_SERIAL.printf("%02X ", *src); - src++; - } - USE_SERIAL.printf("\n"); -} -#endif diff --git a/examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino b/examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino new file mode 100644 index 0000000..5b4f3a5 --- /dev/null +++ b/examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino @@ -0,0 +1,102 @@ +/* + * WebSocketClientSSL.ino + * + * Created on: 10.12.2015 + * + * note SSL is only possible with the ESP8266 + * + */ + +#include + +#include +#include +#include + +#include + + +WiFiMulti WiFiMulti; +WebSocketsClient webSocket; + +HardwareSerial Serial1(2); + +#define USE_SERIAL Serial1 + +void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) { + const uint8_t* src = (const uint8_t*) mem; + USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); + for(uint32_t i = 0; i < len; i++) { + if(i % cols == 0) { + USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); + } + USE_SERIAL.printf("%02X ", *src); + src++; + } + USE_SERIAL.printf("\n"); +} + +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { + + + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[WSc] Disconnected!\n"); + break; + case WStype_CONNECTED: + { + USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); + + // send message to server when Connected + webSocket.sendTXT("Connected"); + } + break; + case WStype_TEXT: + USE_SERIAL.printf("[WSc] get text: %s\n", payload); + + // send message to server + // webSocket.sendTXT("message here"); + break; + case WStype_BIN: + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); + + // send data to server + // webSocket.sendBIN(payload, length); + break; + } + +} + +void setup() { + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + //Serial.setDebugOutput(true); + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFiMulti.addAP("SSID", "passpasspass"); + + //WiFi.disconnect(); + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + webSocket.beginSSL("192.168.0.123", 81); + webSocket.onEvent(webSocketEvent); + +} + +void loop() { + webSocket.loop(); +} diff --git a/examples/WebSocketServer/WebSocketServer.ino b/examples/esp32/WebSocketServer/WebSocketServer.ino similarity index 78% rename from examples/WebSocketServer/WebSocketServer.ino rename to examples/esp32/WebSocketServer/WebSocketServer.ino index de9c63e..da7d38f 100644 --- a/examples/WebSocketServer/WebSocketServer.ino +++ b/examples/esp32/WebSocketServer/WebSocketServer.ino @@ -7,31 +7,31 @@ #include -#if defined(ESP8266) - #include #include - #include #include - ESP8266WiFiMulti WiFiMulti; -#elif defined(ESP32) - #include - #include - WiFiMulti WiFiMulti; - - HardwareSerial Serial1(2); -#endif +#include +#include +#include #include -#include - -ESP8266WiFiMulti WiFiMulti; +WiFiMulti WiFiMulti; WebSocketsServer webSocket = WebSocketsServer(81); -#define USE_SERIAL Serial1 +HardwareSerial Serial1(2); +#define USE_SERIAL Serial1 -#ifndef ESP8266 -void hexdump(const void *mem, uint32_t len, uint8_t cols = 16); -#endif +void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) { + const uint8_t* src = (const uint8_t*) mem; + USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); + for(uint32_t i = 0; i < len; i++) { + if(i % cols == 0) { + USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); + } + USE_SERIAL.printf("%02X ", *src); + src++; + } + USE_SERIAL.printf("\n"); +} void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { @@ -98,18 +98,3 @@ void setup() { void loop() { webSocket.loop(); } - -#ifndef ESP8266 -void hexdump(const void *mem, uint32_t len, uint8_t cols) { - const uint8_t* src = (const uint8_t*) mem; - USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); - for(uint32_t i = 0; i < len; i++) { - if(i % cols == 0) { - USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); - } - USE_SERIAL.printf("%02X ", *src); - src++; - } - USE_SERIAL.printf("\n"); -} -#endif diff --git a/examples/esp8266/WebSocketClient/WebSocketClient.ino b/examples/esp8266/WebSocketClient/WebSocketClient.ino new file mode 100644 index 0000000..3ce8498 --- /dev/null +++ b/examples/esp8266/WebSocketClient/WebSocketClient.ino @@ -0,0 +1,92 @@ +/* + * WebSocketClient.ino + * + * Created on: 24.05.2015 + * + */ + +#include + +#include +#include + +#include + +#include + +ESP8266WiFiMulti WiFiMulti; +WebSocketsClient webSocket; + +#define USE_SERIAL Serial1 + +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { + + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[WSc] Disconnected!\n"); + break; + case WStype_CONNECTED: { + USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); + + // send message to server when Connected + webSocket.sendTXT("Connected"); + } + break; + case WStype_TEXT: + USE_SERIAL.printf("[WSc] get text: %s\n", payload); + + // send message to server + // webSocket.sendTXT("message here"); + break; + case WStype_BIN: + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); + + // send data to server + // webSocket.sendBIN(payload, length); + break; + } + +} + +void setup() { + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + //Serial.setDebugOutput(true); + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFiMulti.addAP("SSID", "passpasspass"); + + //WiFi.disconnect(); + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + // server address, port and URL + webSocket.begin("192.168.0.123", 81, "/"); + + // event handler + webSocket.onEvent(webSocketEvent); + + // use HTTP Basic Authorization this is optional remove if not needed + webSocket.setAuthorization("user", "Password"); + + // try ever 5000 again if connection has failed + webSocket.setReconnectInterval(5000); + +} + +void loop() { + webSocket.loop(); +} diff --git a/examples/WebSocketClientSSL/WebSocketClientSSL.ino b/examples/esp8266/WebSocketClientSSL/WebSocketClientSSL.ino similarity index 100% rename from examples/WebSocketClientSSL/WebSocketClientSSL.ino rename to examples/esp8266/WebSocketClientSSL/WebSocketClientSSL.ino diff --git a/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino b/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino similarity index 100% rename from examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino rename to examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino diff --git a/examples/WebSocketClientStomp/WebSocketClientStomp.ino b/examples/esp8266/WebSocketClientStomp/WebSocketClientStomp.ino similarity index 100% rename from examples/WebSocketClientStomp/WebSocketClientStomp.ino rename to examples/esp8266/WebSocketClientStomp/WebSocketClientStomp.ino diff --git a/examples/WebSocketClientStompOverSockJs/WebSocketClientStompOverSockJs.ino b/examples/esp8266/WebSocketClientStompOverSockJs/WebSocketClientStompOverSockJs.ino similarity index 100% rename from examples/WebSocketClientStompOverSockJs/WebSocketClientStompOverSockJs.ino rename to examples/esp8266/WebSocketClientStompOverSockJs/WebSocketClientStompOverSockJs.ino diff --git a/examples/esp8266/WebSocketServer/WebSocketServer.ino b/examples/esp8266/WebSocketServer/WebSocketServer.ino new file mode 100644 index 0000000..5e266a2 --- /dev/null +++ b/examples/esp8266/WebSocketServer/WebSocketServer.ino @@ -0,0 +1,86 @@ +/* + * WebSocketServer.ino + * + * Created on: 22.05.2015 + * + */ + +#include + +#include +#include +#include +#include + +ESP8266WiFiMulti WiFiMulti; + +WebSocketsServer webSocket = WebSocketsServer(81); + +#define USE_SERIAL Serial1 + +void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { + + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[%u] Disconnected!\n", num); + break; + case WStype_CONNECTED: + { + IPAddress ip = webSocket.remoteIP(num); + USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); + + // send message to client + webSocket.sendTXT(num, "Connected"); + } + break; + case WStype_TEXT: + USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); + + // send message to client + // webSocket.sendTXT(num, "message here"); + + // send data to all connected clients + // webSocket.broadcastTXT("message here"); + break; + case WStype_BIN: + USE_SERIAL.printf("[%u] get binary length: %u\n", num, length); + hexdump(payload, length); + + // send message to client + // webSocket.sendBIN(num, payload, length); + break; + } + +} + +void setup() { + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + //Serial.setDebugOutput(true); + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFiMulti.addAP("SSID", "passpasspass"); + + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + webSocket.begin(); + webSocket.onEvent(webSocketEvent); +} + +void loop() { + webSocket.loop(); +} + diff --git a/examples/WebSocketServerFragmentation/WebSocketServerFragmentation.ino b/examples/esp8266/WebSocketServerFragmentation/WebSocketServerFragmentation.ino similarity index 100% rename from examples/WebSocketServerFragmentation/WebSocketServerFragmentation.ino rename to examples/esp8266/WebSocketServerFragmentation/WebSocketServerFragmentation.ino diff --git a/examples/WebSocketServerHttpHeaderValidation/WebSocketServerHttpHeaderValidation.ino b/examples/esp8266/WebSocketServerHttpHeaderValidation/WebSocketServerHttpHeaderValidation.ino similarity index 100% rename from examples/WebSocketServerHttpHeaderValidation/WebSocketServerHttpHeaderValidation.ino rename to examples/esp8266/WebSocketServerHttpHeaderValidation/WebSocketServerHttpHeaderValidation.ino diff --git a/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino b/examples/esp8266/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino similarity index 96% rename from examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino rename to examples/esp8266/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino index 913b799..7915409 100644 --- a/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino +++ b/examples/esp8266/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino @@ -119,4 +119,3 @@ void loop() { webSocket.loop(); server.handleClient(); } - diff --git a/examples/ParticleWebSocketClient/application.cpp b/examples/particle/ParticleWebSocketClient/application.cpp similarity index 100% rename from examples/ParticleWebSocketClient/application.cpp rename to examples/particle/ParticleWebSocketClient/application.cpp diff --git a/src/WebSockets.h b/src/WebSockets.h index c63bb5e..0d930f7 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -49,24 +49,29 @@ #endif #if defined(ESP8266) || defined(ESP32) + #define WEBSOCKETS_MAX_DATA_SIZE (15*1024) #define WEBSOCKETS_USE_BIG_MEM #define GET_FREE_HEAP ESP.getFreeHeap() // moves all Header strings to Flash (~300 Byte) //#define WEBSOCKETS_SAVE_RAM -#else -#ifdef STM32_DEVICE + +#elif defined(STM32_DEVICE) + #define WEBSOCKETS_MAX_DATA_SIZE (15*1024) #define WEBSOCKETS_USE_BIG_MEM #define GET_FREE_HEAP System.freeMemory() + #else + //atmega328p has only 2KB ram! #define WEBSOCKETS_MAX_DATA_SIZE (1024) // moves all Header strings to Flash #define WEBSOCKETS_SAVE_RAM -#endif + #endif + #define WEBSOCKETS_TCP_TIMEOUT (2000) #define NETWORK_ESP8266_ASYNC (0) @@ -84,28 +89,35 @@ #define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 //#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC //#define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 + #elif defined(ESP32) #define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP32 + #else #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 + #endif #endif +// Includes and defined based on Network Type #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) // Note: // No SSL/WSS support for client in Async mode // TLS lib need a sync interface! -#if !defined(ESP8266) && !defined(ESP31B) && !defined(ESP32) -#error "network type ESP8266 ASYNC only possible on the ESP mcu!" -#endif -#ifdef ESP8266 +#if defined(ESP8266) #include -#else +#elif defined(ESP32) +#include +#include +#elif defined(ESP31B) #include +#else +#error "network type ESP8266 ASYNC only possible on the ESP mcu!" #endif + #include #include #define WEBSOCKETS_NETWORK_CLASS AsyncTCPbuffer diff --git a/travis/common.sh b/travis/common.sh index 062ba05..be959fa 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -13,10 +13,15 @@ function build_sketches() continue fi echo -e "\n\n ------------ Building $sketch ------------ \n\n"; - $arduino --verify --verbose $sketch; + $arduino --verify $sketch; local result=$? if [ $result -ne 0 ]; then - echo "Build failed ($1)" + echo "Build failed ($sketch) build verbose..." + $arduino --verify --verbose --preserve-temp-files $sketch + result=$? + fi + if [ $result -ne 0 ]; then + echo "Build failed ($1) $sketch" return $result fi done From 48e690a42af2a94aaeb47fa000a37578765db628 Mon Sep 17 00:00:00 2001 From: Links Date: Wed, 7 Feb 2018 18:11:08 +0100 Subject: [PATCH 139/347] bump version to 2.1.0 travis arduino 1.8.5 --- .travis.yml | 2 +- README.md | 3 ++- library.json | 2 +- library.properties | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b15fc0d..8e4397d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ os: env: matrix: - CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80" IDE_VERSION=1.6.5 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80" IDE_VERSION=1.8.5 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80,FlashSize=1M0" IDE_VERSION=1.8.5 - CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80,Debug=Serial1" IDE_VERSION=1.6.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.6.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.5 diff --git a/README.md b/README.md index 0c49b48..81b4107 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,8 @@ a WebSocket Server and Client for Arduino based on RFC6455. - wss / SSL is not possible. ##### Supported Hardware ##### - - ESP8266 [Arduino for ESP8266](https://github.com/Links2004/Arduino) + - ESP8266 [Arduino for ESP8266](https://github.com/esp8266/Arduino/) + - ESP32 [Arduino for ESP32](https://github.com/espressif/arduino-esp32) - ESP31B - Particle with STM32 ARM Cortex M3 - ATmega328 with Ethernet Shield (ATmega branch) diff --git a/library.json b/library.json index 35289fc..a019efb 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.0.10", + "version": "2.1.0", "license": "LGPL-2.1", "export": { "exclude": [ diff --git a/library.properties b/library.properties index 6ae767e..14e1fe9 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.0.10 +version=2.1.0 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From 4759a66a62f86911b2eb0d19080d0cea54aadbad Mon Sep 17 00:00:00 2001 From: Links Date: Wed, 7 Feb 2018 18:15:50 +0100 Subject: [PATCH 140/347] Arduino 1.8.5 is very peaky with the board parameters --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8e4397d..14693dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ os: env: matrix: - CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80" IDE_VERSION=1.6.5 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80,FlashSize=1M0" IDE_VERSION=1.8.5 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80,FlashSize=1M0,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.5 - CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80,Debug=Serial1" IDE_VERSION=1.6.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.6.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.5 From 4b04f6fa532229940ddd0f11bce418da8c63daef Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 7 Mar 2018 10:33:33 +0200 Subject: [PATCH 141/347] Update supported platforms, allow PIO to detect examples automatically --- library.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/library.json b/library.json index a019efb..0dbd62d 100644 --- a/library.json +++ b/library.json @@ -21,8 +21,5 @@ ] }, "frameworks": "arduino", - "platforms": "*", - "examples": [ - "examples/*/*.ino" - ] + "platforms": "atmelavr, espressif8266, espressif32" } From 50d9a8d6e5d9a869df57fd3b40cd2a36ec89d04c Mon Sep 17 00:00:00 2001 From: getbyte Date: Sun, 18 Mar 2018 01:25:49 +0300 Subject: [PATCH 142/347] fix undefined virtual methods --- src/WebSockets.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 0d930f7..b81161a 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -272,10 +272,10 @@ class WebSockets { typedef std::function WSreadWaitCb; #endif - virtual void clientDisconnect(WSclient_t * client); - virtual bool clientIsConnected(WSclient_t * client); + virtual void clientDisconnect(WSclient_t * client) = 0; + virtual bool clientIsConnected(WSclient_t * client) = 0; - virtual void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); + virtual void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) = 0; void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0); bool sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false, bool fin = true, bool headerToPayload = false); From d02932ef21fa930fb1f4a810ac5e2aa9bbce6b15 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Mon, 2 Apr 2018 22:17:34 -0700 Subject: [PATCH 143/347] Allow custom WEBSOCKETS_SERVER_CLIENT_MAX definition --- src/WebSocketsServer.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index cd38fd6..538b585 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -27,7 +27,9 @@ #include "WebSockets.h" +#ifndef WEBSOCKETS_SERVER_CLIENT_MAX #define WEBSOCKETS_SERVER_CLIENT_MAX (5) +#endif From 02e01288025b7b28bc7db3d0b4e78ee610dedc54 Mon Sep 17 00:00:00 2001 From: Markus Date: Tue, 17 Apr 2018 19:42:47 +0200 Subject: [PATCH 144/347] Update index.js fix port --- tests/webSocketServer/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/webSocketServer/index.js b/tests/webSocketServer/index.js index 5fc3606..389e193 100644 --- a/tests/webSocketServer/index.js +++ b/tests/webSocketServer/index.js @@ -7,7 +7,7 @@ var server = http.createServer(function(request, response) { response.writeHead(404); response.end(); }); -server.listen(81, function() { +server.listen(8011, function() { console.log((new Date()) + ' Server is listening on port 8011'); }); @@ -54,4 +54,4 @@ wsServer.on('request', function(request) { }); connection.sendUTF("Hallo Client!"); -}); \ No newline at end of file +}); From ac8d806085d75e6e54d99d84b3ee0fdaa722213b Mon Sep 17 00:00:00 2001 From: chemicstry Date: Thu, 10 May 2018 01:16:39 +0300 Subject: [PATCH 145/347] Fix format specifiers --- src/WebSockets.cpp | 12 ++++++------ src/WebSocketsClient.cpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 44ddbb1..86ba98f 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -253,7 +253,7 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay } } - DEBUG_WEBSOCKETS("[WS][%d][sendFrame] sending Frame Done (%uus).\n", client->num, (micros() - start)); + DEBUG_WEBSOCKETS("[WS][%d][sendFrame] sending Frame Done (%luus).\n", client->num, (micros() - start)); #ifdef WEBSOCKETS_USE_BIG_MEM if(useInternBuffer && payloadPtr) { @@ -271,7 +271,7 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay void WebSockets::headerDone(WSclient_t * client) { client->status = WSC_CONNECTED; client->cWsRXsize = 0; - DEBUG_WEBSOCKETS("[WS][%d][headerDone] Header Handling Done (%uus).\n", client->num); + DEBUG_WEBSOCKETS("[WS][%d][headerDone] Header Handling Done.\n", client->num); #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->cHttpLine = ""; handleWebsocket(client); @@ -547,7 +547,7 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait #else unsigned long t = millis(); size_t len; - DEBUG_WEBSOCKETS("[readCb] n: %d t: %d\n", n, t); + DEBUG_WEBSOCKETS("[readCb] n: %zu t: %lu\n", n, t); while(n > 0) { if(client->tcp == NULL) { DEBUG_WEBSOCKETS("[readCb] tcp is null!\n"); @@ -566,7 +566,7 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait } if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) { - DEBUG_WEBSOCKETS("[readCb] receive TIMEOUT! %d\n", (millis() - t)); + DEBUG_WEBSOCKETS("[readCb] receive TIMEOUT! %lu\n", (millis() - t)); if(cb) { cb(client, false); } @@ -613,7 +613,7 @@ size_t WebSockets::write(WSclient_t * client, uint8_t *out, size_t n) { unsigned long t = millis(); size_t len = 0; size_t total = 0; - DEBUG_WEBSOCKETS("[write] n: %d t: %d\n", n, t); + DEBUG_WEBSOCKETS("[write] n: %zu t: %lu\n", n, t); while(n > 0) { if(client->tcp == NULL) { DEBUG_WEBSOCKETS("[write] tcp is null!\n"); @@ -626,7 +626,7 @@ size_t WebSockets::write(WSclient_t * client, uint8_t *out, size_t n) { } if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) { - DEBUG_WEBSOCKETS("[write] write TIMEOUT! %d\n", (millis() - t)); + DEBUG_WEBSOCKETS("[write] write TIMEOUT! %lu\n", (millis() - t)); break; } diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 68e24fa..7ee2eb5 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -533,7 +533,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine))); #endif - DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header... Done (%uus).\n", (micros() - start)); + DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header... Done (%luus).\n", (micros() - start)); } From ea8e81c6ced4d44679c6c1ad39a0ea2f9d3e2197 Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 10 May 2018 18:55:23 +0200 Subject: [PATCH 146/347] add close #322 --- src/WebSocketsServer.cpp | 32 +++++++++++++++++++++----------- src/WebSocketsServer.h | 3 +++ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 1e60f97..4a841c2 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -29,6 +29,7 @@ WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol _port = port; _origin = origin; _protocol = protocol; + _runnning = false; _server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port); @@ -50,15 +51,7 @@ WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol WebSocketsServer::~WebSocketsServer() { // disconnect all clients - disconnect(); - -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - _server->close(); -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) - _server->end(); -#else - // TODO how to close server? -#endif + close(); if (_mandatoryHttpHeaders) delete[] _mandatoryHttpHeaders; @@ -110,18 +103,35 @@ void WebSocketsServer::begin(void) { randomSeed(millis()); #endif + _runnning = true; _server->begin(); DEBUG_WEBSOCKETS("[WS-Server] Server Started.\n"); } +void WebSocketsServer::close(void) { + _runnning = false; + disconnect(); + +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + _server->close(); +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) + _server->end(); +#else + // TODO how to close server? +#endif + +} + #if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * called in arduino loop */ void WebSocketsServer::loop(void) { - handleNewClients(); - handleClientData(); + if(_runnning) { + handleNewClients(); + handleClientData(); + } } #endif diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 538b585..a8dcf6e 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -49,6 +49,7 @@ class WebSocketsServer: protected WebSockets { virtual ~WebSocketsServer(void); void begin(void); + void close(void); #if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void loop(void); @@ -113,6 +114,8 @@ class WebSocketsServer: protected WebSockets { WebSocketServerEvent _cbEvent; WebSocketServerHttpHeaderValFunc _httpHeaderValidationFunc; + bool _runnning; + bool newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); From 486a612693621a2197743f54c5866990405888c9 Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 10 May 2018 20:12:48 +0200 Subject: [PATCH 147/347] allow usage of IPAddress #230 --- src/WebSockets.h | 1 + src/WebSocketsClient.cpp | 4 ++++ src/WebSocketsClient.h | 1 + 3 files changed, 6 insertions(+) diff --git a/src/WebSockets.h b/src/WebSockets.h index b81161a..c3901f5 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -30,6 +30,7 @@ #define bit(b) (1UL << (b)) // Taken directly from Arduino.h #else #include +#include #endif #include diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 7ee2eb5..57cce6c 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -84,6 +84,10 @@ void WebSocketsClient::begin(String host, uint16_t port, String url, String prot begin(host.c_str(), port, url.c_str(), protocol.c_str()); } +void WebSocketsClient::begin(IPAddress host, uint16_t port, const char * url, const char * protocol) { + return begin(host.toString().c_str(), port, url, protocol); +} + #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) void WebSocketsClient::beginSSL(const char *host, uint16_t port, const char * url, const char * fingerprint, const char * protocol) { begin(host, port, url, protocol); diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index b56cff8..8e6305e 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -41,6 +41,7 @@ class WebSocketsClient: private WebSockets { void begin(const char *host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); void begin(String host, uint16_t port, String url = "/", String protocol = "arduino"); + void begin(IPAddress host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) void beginSSL(const char *host, uint16_t port, const char * url = "/", const char * = "", const char * protocol = "arduino"); From 4b33575af1ecfd173f14307654c4567f8665d8d0 Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 10 May 2018 20:42:03 +0200 Subject: [PATCH 148/347] add connectedClients see #242 --- src/WebSocketsServer.cpp | 18 ++++++++++++++++++ src/WebSocketsServer.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 4a841c2..6c76af7 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -403,6 +403,24 @@ void WebSocketsServer::setAuthorization(const char * auth) { } } +/** + * count the connected clients (optional ping them) + * @param ping bool ping the connected clients + */ +int WebSocketsServer::connectedClients(bool ping) { + WSclient_t * client; + int count = 0; + for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + client = &_clients[i]; + if(client->status == WSC_CONNECTED) { + if(ping != true || sendPing(i)) { + count++; + } + } + } + return count; +} + #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) /** * get an IP for a client diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index a8dcf6e..e010488 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -95,6 +95,8 @@ class WebSocketsServer: protected WebSockets { void setAuthorization(const char * user, const char * password); void setAuthorization(const char * auth); + int connectedClients(bool ping = false); + #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) IPAddress remoteIP(uint8_t num); #endif From 5636b02b467c1cd1718dddb38980ba8dcb8cd936 Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 10 May 2018 20:47:05 +0200 Subject: [PATCH 149/347] add WebSocketServerAllFunctionsDemo (WIP) --- .../WebSocketServerAllFunctionsDemo.ino | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 examples/esp8266/WebSocketServerAllFunctionsDemo/WebSocketServerAllFunctionsDemo.ino diff --git a/examples/esp8266/WebSocketServerAllFunctionsDemo/WebSocketServerAllFunctionsDemo.ino b/examples/esp8266/WebSocketServerAllFunctionsDemo/WebSocketServerAllFunctionsDemo.ino new file mode 100644 index 0000000..3e2c145 --- /dev/null +++ b/examples/esp8266/WebSocketServerAllFunctionsDemo/WebSocketServerAllFunctionsDemo.ino @@ -0,0 +1,133 @@ +/* + * WebSocketServerAllFunctionsDemo.ino + * + * Created on: 10.05.2018 + * + */ + +#include + +#include +#include +#include +#include +#include +#include + +#define LED_RED 15 +#define LED_GREEN 12 +#define LED_BLUE 13 + +#define USE_SERIAL Serial + + +ESP8266WiFiMulti WiFiMulti; + +ESP8266WebServer server(80); +WebSocketsServer webSocket = WebSocketsServer(81); + +void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { + + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[%u] Disconnected!\n", num); + break; + case WStype_CONNECTED: { + IPAddress ip = webSocket.remoteIP(num); + USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); + + // send message to client + webSocket.sendTXT(num, "Connected"); + } + break; + case WStype_TEXT: + USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); + + if(payload[0] == '#') { + // we get RGB data + + // decode rgb data + uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16); + + analogWrite(LED_RED, ((rgb >> 16) & 0xFF)); + analogWrite(LED_GREEN, ((rgb >> 8) & 0xFF)); + analogWrite(LED_BLUE, ((rgb >> 0) & 0xFF)); + } + + break; + } + +} + +void setup() { + //USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + //USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + pinMode(LED_RED, OUTPUT); + pinMode(LED_GREEN, OUTPUT); + pinMode(LED_BLUE, OUTPUT); + + digitalWrite(LED_RED, 1); + digitalWrite(LED_GREEN, 1); + digitalWrite(LED_BLUE, 1); + + WiFiMulti.addAP("SSID", "passpasspass"); + + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + // start webSocket server + webSocket.begin(); + webSocket.onEvent(webSocketEvent); + + if(MDNS.begin("esp8266")) { + USE_SERIAL.println("MDNS responder started"); + } + + // handle index + server.on("/", []() { + // send index.html + server.send(200, "text/html", "LED Control:

R:
G:
B:
"); + }); + + server.begin(); + + // Add service to MDNS + MDNS.addService("http", "tcp", 80); + MDNS.addService("ws", "tcp", 81); + + digitalWrite(LED_RED, 0); + digitalWrite(LED_GREEN, 0); + digitalWrite(LED_BLUE, 0); + +} + +unsigned long last_10sec = 0; +unsigned int counter = 0; + +void loop() { + unsigned long t = millis(); + webSocket.loop(); + server.handleClient(); + + if((t - last_10sec) > 10 * 1000) { + counter++; + bool ping = (counter % 2); + int i = webSocket.connectedClients(ping); + USE_SERIAL.printf("%d Connected websocket clients ping: %d", i, ping); + last_10sec = millis(); + } +} From e8c0d775fba32ff641a33eac69ac9a479cacc159 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 12 May 2018 11:22:16 +0200 Subject: [PATCH 150/347] fix #146 HTTP Header handler --- src/WebSocketsClient.cpp | 77 +++++++++++++++++++++------------------- src/WebSocketsServer.cpp | 7 +++- 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 57cce6c..22a1acd 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -547,45 +547,50 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { */ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { - headerLine->trim(); // remove \r + headerLine->trim(); // remove \r - if(headerLine->length() > 0) { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str()); + if(headerLine->length() > 0) { + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str()); - if(headerLine->startsWith(WEBSOCKETS_STRING("HTTP/1."))) { - // "HTTP/1.1 101 Switching Protocols" - client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt(); - } else if(headerLine->indexOf(':')) { - String headerName = headerLine->substring(0, headerLine->indexOf(':')); - String headerValue = headerLine->substring(headerLine->indexOf(':') + 2); + if(headerLine->startsWith(WEBSOCKETS_STRING("HTTP/1."))) { + // "HTTP/1.1 101 Switching Protocols" + client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt(); + } else if(headerLine->indexOf(':')) { + String headerName = headerLine->substring(0, headerLine->indexOf(':')); + String headerValue = headerLine->substring(headerLine->indexOf(':') + 1); - if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) { - if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("upgrade"))) { - client->cIsUpgrade = true; - } - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) { - if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) { - client->cIsWebsocket = true; - } - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Accept"))) { - client->cAccept = headerValue; - client->cAccept.trim(); // see rfc6455 - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) { - client->cProtocol = headerValue; - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) { - client->cExtensions = headerValue; - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) { - client->cVersion = headerValue.toInt(); - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Set-Cookie"))) { - if (headerValue.indexOf(WEBSOCKETS_STRING("HttpOnly")) > -1) { - client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1, headerValue.indexOf(";")); - } else { - client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1); - } - } - } else { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); - } + // remove space in the beginning (RFC2616) + if(headerValue[0] == ' ') { + headerValue.remove(0, 1); + } + + if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) { + if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("upgrade"))) { + client->cIsUpgrade = true; + } + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) { + if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) { + client->cIsWebsocket = true; + } + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Accept"))) { + client->cAccept = headerValue; + client->cAccept.trim(); // see rfc6455 + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) { + client->cProtocol = headerValue; + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) { + client->cExtensions = headerValue; + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) { + client->cVersion = headerValue.toInt(); + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Set-Cookie"))) { + if(headerValue.indexOf(WEBSOCKETS_STRING("HttpOnly")) > -1) { + client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1, headerValue.indexOf(";")); + } else { + client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1); + } + } + } else { + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); + } (*headerLine) = ""; #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 6c76af7..6013dce 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -729,7 +729,12 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { } else if(headerLine->indexOf(':')) { String headerName = headerLine->substring(0, headerLine->indexOf(':')); - String headerValue = headerLine->substring(headerLine->indexOf(':') + 2); + String headerValue = headerLine->substring(headerLine->indexOf(':') + 1); + + // remove space in the beginning (RFC2616) + if(headerValue[0] == ' ') { + headerValue.remove(0, 1); + } if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) { headerValue.toLowerCase(); From a796079b0c3236337a14e34e721c639f49577490 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 12 May 2018 11:27:03 +0200 Subject: [PATCH 151/347] fix code style --- src/WebSocketsClient.cpp | 292 +++++++++++++++++++-------------------- src/WebSocketsServer.cpp | 90 ++++++------ 2 files changed, 188 insertions(+), 194 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 22a1acd..17f888d 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -25,7 +25,6 @@ #include "WebSockets.h" #include "WebSocketsClient.h" - WebSocketsClient::WebSocketsClient() { _cbEvent = NULL; _client.num = 0; @@ -85,7 +84,7 @@ void WebSocketsClient::begin(String host, uint16_t port, String url, String prot } void WebSocketsClient::begin(IPAddress host, uint16_t port, const char * url, const char * protocol) { - return begin(host.toString().c_str(), port, url, protocol); + return begin(host.toString().c_str(), port, url, protocol); } #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) @@ -128,10 +127,10 @@ void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url, */ void WebSocketsClient::loop(void) { if(!clientIsConnected(&_client)) { - // do not flood the server - if((millis() - _lastConnectionFail) < _reconnectInterval) { - return; - } + // do not flood the server + if((millis() - _lastConnectionFail) < _reconnectInterval) { + return; + } #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) if(_client.isSSL) { @@ -252,7 +251,6 @@ bool WebSocketsClient::sendPing(String & payload) { return sendPing((uint8_t *) payload.c_str(), payload.length()); } - /** * disconnect one client * @param num uint8_t client id @@ -273,7 +271,7 @@ void WebSocketsClient::setAuthorization(const char * user, const char * password String auth = user; auth += ":"; auth += password; - _client.base64Authorization = base64_encode((uint8_t *)auth.c_str(), auth.length()); + _client.base64Authorization = base64_encode((uint8_t *) auth.c_str(), auth.length()); } } @@ -297,14 +295,13 @@ void WebSocketsClient::setExtraHeaders(const char * extraHeaders) { _client.extraHeaders = extraHeaders; } - /** * set the reconnect Interval * how long to wait after a connection initiate failed * @param time in ms */ void WebSocketsClient::setReconnectInterval(unsigned long time) { - _reconnectInterval = time; + _reconnectInterval = time; } //################################################################################# @@ -328,9 +325,9 @@ void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, u case WSop_binary: type = fin ? WStype_BIN : WStype_FRAGMENT_BIN_START; break; - case WSop_continuation: - type = fin ? WStype_FRAGMENT_FIN : WStype_FRAGMENT; - break; + case WSop_continuation: + type = fin ? WStype_FRAGMENT_FIN : WStype_FRAGMENT; + break; } runCbEvent(type, payload, length); @@ -429,8 +426,7 @@ void WebSocketsClient::handleClientData(void) { int len = _client.tcp->available(); if(len > 0) { switch(_client.status) { - case WSC_HEADER: - { + case WSC_HEADER: { String headerLine = _client.tcp->readStringUntil('\n'); handleHeader(&_client, &headerLine); } @@ -449,14 +445,13 @@ void WebSocketsClient::handleClientData(void) { } #endif - /** * send the WebSocket header to Server * @param client WSclient_t * ptr to the client struct */ void WebSocketsClient::sendHeader(WSclient_t * client) { - static const char * NEW_LINE = "\r\n"; + static const char * NEW_LINE = "\r\n"; DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header...\n"); @@ -477,64 +472,64 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { String url = client->cUrl; if(client->isSocketIO) { - if(client->cSessionId.length() == 0) { - url += WEBSOCKETS_STRING("&transport=polling"); - ws_header = false; - } else { - url += WEBSOCKETS_STRING("&transport=websocket&sid="); - url += client->cSessionId; - } + if(client->cSessionId.length() == 0) { + url += WEBSOCKETS_STRING("&transport=polling"); + ws_header = false; + } else { + url += WEBSOCKETS_STRING("&transport=websocket&sid="); + url += client->cSessionId; + } } - handshake = WEBSOCKETS_STRING("GET "); - handshake += url + WEBSOCKETS_STRING(" HTTP/1.1\r\n" - "Host: "); - handshake += _host + ":" + _port + NEW_LINE; - - if(ws_header) { - handshake += WEBSOCKETS_STRING("Connection: Upgrade\r\n" - "Upgrade: websocket\r\n" - "Sec-WebSocket-Version: 13\r\n" - "Sec-WebSocket-Key: "); - handshake += client->cKey + NEW_LINE; - - if(client->cProtocol.length() > 0) { - handshake += WEBSOCKETS_STRING("Sec-WebSocket-Protocol: "); - handshake +=client->cProtocol + NEW_LINE; - } - - if(client->cExtensions.length() > 0) { - handshake += WEBSOCKETS_STRING("Sec-WebSocket-Extensions: "); - handshake +=client->cExtensions + NEW_LINE; - } - } else { - handshake += WEBSOCKETS_STRING("Connection: keep-alive\r\n"); - } - - // add extra headers; by default this includes "Origin: file://" - if (client->extraHeaders) { - handshake += client->extraHeaders + NEW_LINE; - } - - handshake += WEBSOCKETS_STRING("User-Agent: arduino-WebSocket-Client\r\n"); - - if(client->base64Authorization.length() > 0) { - handshake += WEBSOCKETS_STRING("Authorization: Basic "); - handshake += client->base64Authorization + NEW_LINE; - } - - if(client->plainAuthorization.length() > 0) { - handshake += WEBSOCKETS_STRING("Authorization: "); - handshake += client->plainAuthorization + NEW_LINE; - } - - handshake += NEW_LINE; - - DEBUG_WEBSOCKETS("[WS-Client][sendHeader] handshake %s", (uint8_t*)handshake.c_str()); - write(client, (uint8_t*)handshake.c_str(), handshake.length()); + handshake = WEBSOCKETS_STRING("GET "); + handshake += url + WEBSOCKETS_STRING(" HTTP/1.1\r\n" + "Host: "); + handshake += _host + ":" + _port + NEW_LINE; + + if(ws_header) { + handshake += WEBSOCKETS_STRING("Connection: Upgrade\r\n" + "Upgrade: websocket\r\n" + "Sec-WebSocket-Version: 13\r\n" + "Sec-WebSocket-Key: "); + handshake += client->cKey + NEW_LINE; + + if(client->cProtocol.length() > 0) { + handshake += WEBSOCKETS_STRING("Sec-WebSocket-Protocol: "); + handshake += client->cProtocol + NEW_LINE; + } + + if(client->cExtensions.length() > 0) { + handshake += WEBSOCKETS_STRING("Sec-WebSocket-Extensions: "); + handshake += client->cExtensions + NEW_LINE; + } + } else { + handshake += WEBSOCKETS_STRING("Connection: keep-alive\r\n"); + } + + // add extra headers; by default this includes "Origin: file://" + if(client->extraHeaders) { + handshake += client->extraHeaders + NEW_LINE; + } + + handshake += WEBSOCKETS_STRING("User-Agent: arduino-WebSocket-Client\r\n"); + + if(client->base64Authorization.length() > 0) { + handshake += WEBSOCKETS_STRING("Authorization: Basic "); + handshake += client->base64Authorization + NEW_LINE; + } + + if(client->plainAuthorization.length() > 0) { + handshake += WEBSOCKETS_STRING("Authorization: "); + handshake += client->plainAuthorization + NEW_LINE; + } + + handshake += NEW_LINE; + + DEBUG_WEBSOCKETS("[WS-Client][sendHeader] handshake %s", (uint8_t* )handshake.c_str()); + write(client, (uint8_t*) handshake.c_str(), handshake.length()); #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) - client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine))); + client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine))); #endif DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header... Done (%luus).\n", (micros() - start)); @@ -547,50 +542,50 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { */ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { - headerLine->trim(); // remove \r - - if(headerLine->length() > 0) { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str()); - - if(headerLine->startsWith(WEBSOCKETS_STRING("HTTP/1."))) { - // "HTTP/1.1 101 Switching Protocols" - client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt(); - } else if(headerLine->indexOf(':')) { - String headerName = headerLine->substring(0, headerLine->indexOf(':')); - String headerValue = headerLine->substring(headerLine->indexOf(':') + 1); - - // remove space in the beginning (RFC2616) - if(headerValue[0] == ' ') { - headerValue.remove(0, 1); - } - - if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) { - if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("upgrade"))) { - client->cIsUpgrade = true; - } - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) { - if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) { - client->cIsWebsocket = true; - } - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Accept"))) { - client->cAccept = headerValue; - client->cAccept.trim(); // see rfc6455 - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) { - client->cProtocol = headerValue; - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) { - client->cExtensions = headerValue; - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) { - client->cVersion = headerValue.toInt(); - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Set-Cookie"))) { - if(headerValue.indexOf(WEBSOCKETS_STRING("HttpOnly")) > -1) { - client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1, headerValue.indexOf(";")); - } else { - client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1); - } - } - } else { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); - } + headerLine->trim(); // remove \r + + if(headerLine->length() > 0) { + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str()); + + if(headerLine->startsWith(WEBSOCKETS_STRING("HTTP/1."))) { + // "HTTP/1.1 101 Switching Protocols" + client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt(); + } else if(headerLine->indexOf(':')) { + String headerName = headerLine->substring(0, headerLine->indexOf(':')); + String headerValue = headerLine->substring(headerLine->indexOf(':') + 1); + + // remove space in the beginning (RFC2616) + if(headerValue[0] == ' ') { + headerValue.remove(0, 1); + } + + if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) { + if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("upgrade"))) { + client->cIsUpgrade = true; + } + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) { + if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) { + client->cIsWebsocket = true; + } + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Accept"))) { + client->cAccept = headerValue; + client->cAccept.trim(); // see rfc6455 + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) { + client->cProtocol = headerValue; + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) { + client->cExtensions = headerValue; + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) { + client->cVersion = headerValue.toInt(); + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Set-Cookie"))) { + if(headerValue.indexOf(WEBSOCKETS_STRING("HttpOnly")) > -1) { + client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1, headerValue.indexOf(";")); + } else { + client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1); + } + } + } else { + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); + } (*headerLine) = ""; #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) @@ -657,17 +652,17 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { runCbEvent(WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length()); - } else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) { - sendHeader(client); - } else { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); - _lastConnectionFail = millis(); - if(clientIsConnected(client)) { - write(client, "This is a webSocket client!"); - } - clientDisconnect(client); - } - } + } else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) { + sendHeader(client); + } else { + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); + _lastConnectionFail = millis(); + if(clientIsConnected(client)) { + write(client, "This is a webSocket client!"); + } + clientDisconnect(client); + } + } } void WebSocketsClient::connectedCb() { @@ -676,15 +671,15 @@ void WebSocketsClient::connectedCb() { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) _client.tcp->onDisconnect(std::bind([](WebSocketsClient * c, AsyncTCPbuffer * obj, WSclient_t * client) -> bool { - DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num); - client->status = WSC_NOT_CONNECTED; - client->tcp = NULL; + DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num); + client->status = WSC_NOT_CONNECTED; + client->tcp = NULL; - // reconnect - c->asyncConnect(); + // reconnect + c->asyncConnect(); - return true; - }, this, std::placeholders::_1, &_client)); + return true; + }, this, std::placeholders::_1, &_client)); #endif _client.status = WSC_HEADER; @@ -711,7 +706,6 @@ void WebSocketsClient::connectedCb() { } - void WebSocketsClient::connectFailedCb() { DEBUG_WEBSOCKETS("[WS-Client] connection to %s:%u Faild\n", _host.c_str(), _port); } @@ -730,26 +724,26 @@ void WebSocketsClient::asyncConnect() { } tcpclient->onDisconnect([](void *obj, AsyncClient* c) { - c->free(); - delete c; - }); + c->free(); + delete c; + }); tcpclient->onConnect(std::bind([](WebSocketsClient * ws , AsyncClient * tcp) { - ws->_client.tcp = new AsyncTCPbuffer(tcp); - if(!ws->_client.tcp) { - DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!\n"); - ws->connectFailedCb(); - return; - } - ws->connectedCb(); - }, this, std::placeholders::_2)); + ws->_client.tcp = new AsyncTCPbuffer(tcp); + if(!ws->_client.tcp) { + DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!\n"); + ws->connectFailedCb(); + return; + } + ws->connectedCb(); + }, this, std::placeholders::_2)); tcpclient->onError(std::bind([](WebSocketsClient * ws , AsyncClient * tcp) { - ws->connectFailedCb(); + ws->connectFailedCb(); - // reconnect - ws->asyncConnect(); - }, this, std::placeholders::_2)); + // reconnect + ws->asyncConnect(); + }, this, std::placeholders::_2)); if(!tcpclient->connect(_host.c_str(), _port)) { connectFailedCb(); diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 6013dce..b036371 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -712,60 +712,60 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { static const char * NEW_LINE = "\r\n"; - headerLine->trim(); // remove \r + headerLine->trim(); // remove \r - if(headerLine->length() > 0) { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine->c_str()); + if(headerLine->length() > 0) { + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine->c_str()); - // websocket requests always start with GET see rfc6455 - if(headerLine->startsWith("GET ")) { + // websocket requests always start with GET see rfc6455 + if(headerLine->startsWith("GET ")) { - // cut URL out - client->cUrl = headerLine->substring(4, headerLine->indexOf(' ', 4)); + // cut URL out + client->cUrl = headerLine->substring(4, headerLine->indexOf(' ', 4)); - //reset non-websocket http header validation state for this client + //reset non-websocket http header validation state for this client client->cHttpHeadersValid = true; client->cMandatoryHeadersCount = 0; - } else if(headerLine->indexOf(':')) { - String headerName = headerLine->substring(0, headerLine->indexOf(':')); - String headerValue = headerLine->substring(headerLine->indexOf(':') + 1); + } else if(headerLine->indexOf(':')) { + String headerName = headerLine->substring(0, headerLine->indexOf(':')); + String headerValue = headerLine->substring(headerLine->indexOf(':') + 1); // remove space in the beginning (RFC2616) if(headerValue[0] == ' ') { headerValue.remove(0, 1); } - if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) { - headerValue.toLowerCase(); - if(headerValue.indexOf(WEBSOCKETS_STRING("upgrade")) >= 0) { - client->cIsUpgrade = true; - } - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) { - if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) { - client->cIsWebsocket = true; - } - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) { - client->cVersion = headerValue.toInt(); - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Key"))) { - client->cKey = headerValue; - client->cKey.trim(); // see rfc6455 - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) { - client->cProtocol = headerValue; - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) { - client->cExtensions = headerValue; - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Authorization"))) { - client->base64Authorization = headerValue; - } else { - client->cHttpHeadersValid &= execHttpHeaderValidation(headerName, headerValue); - if (_mandatoryHttpHeaderCount > 0 && hasMandatoryHeader(headerName)) { - client->cMandatoryHeadersCount++; - } - } + if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) { + headerValue.toLowerCase(); + if(headerValue.indexOf(WEBSOCKETS_STRING("upgrade")) >= 0) { + client->cIsUpgrade = true; + } + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) { + if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) { + client->cIsWebsocket = true; + } + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) { + client->cVersion = headerValue.toInt(); + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Key"))) { + client->cKey = headerValue; + client->cKey.trim(); // see rfc6455 + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) { + client->cProtocol = headerValue; + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) { + client->cExtensions = headerValue; + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Authorization"))) { + client->base64Authorization = headerValue; + } else { + client->cHttpHeadersValid &= execHttpHeaderValidation(headerName, headerValue); + if(_mandatoryHttpHeaderCount > 0 && hasMandatoryHeader(headerName)) { + client->cMandatoryHeadersCount++; + } + } - } else { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); - } + } else { + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); + } (*headerLine) = ""; #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) @@ -787,11 +787,11 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { bool ok = (client->cIsUpgrade && client->cIsWebsocket); - if(ok) { - if(client->cUrl.length() == 0) { - ok = false; - } - if(client->cKey.length() == 0) { + if(ok) { + if(client->cUrl.length() == 0) { + ok = false; + } + if(client->cKey.length() == 0) { ok = false; } if(client->cVersion != 13) { From 9ce044e550f1cce05ca9a93705b8a9e953960ee7 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 12 May 2018 11:34:12 +0200 Subject: [PATCH 152/347] code style --- .../WebSocketServerAllFunctionsDemo.ino | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/examples/esp8266/WebSocketServerAllFunctionsDemo/WebSocketServerAllFunctionsDemo.ino b/examples/esp8266/WebSocketServerAllFunctionsDemo/WebSocketServerAllFunctionsDemo.ino index 3e2c145..5fed1a9 100644 --- a/examples/esp8266/WebSocketServerAllFunctionsDemo/WebSocketServerAllFunctionsDemo.ino +++ b/examples/esp8266/WebSocketServerAllFunctionsDemo/WebSocketServerAllFunctionsDemo.ino @@ -20,7 +20,6 @@ #define USE_SERIAL Serial - ESP8266WiFiMulti WiFiMulti; ESP8266WebServer server(80); @@ -49,9 +48,9 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length // decode rgb data uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16); - analogWrite(LED_RED, ((rgb >> 16) & 0xFF)); - analogWrite(LED_GREEN, ((rgb >> 8) & 0xFF)); - analogWrite(LED_BLUE, ((rgb >> 0) & 0xFF)); + analogWrite(LED_RED, ((rgb >> 16) & 0xFF)); + analogWrite(LED_GREEN, ((rgb >> 8) & 0xFF)); + analogWrite(LED_BLUE, ((rgb >> 0) & 0xFF)); } break; @@ -119,15 +118,15 @@ unsigned long last_10sec = 0; unsigned int counter = 0; void loop() { - unsigned long t = millis(); - webSocket.loop(); - server.handleClient(); - - if((t - last_10sec) > 10 * 1000) { - counter++; - bool ping = (counter % 2); - int i = webSocket.connectedClients(ping); - USE_SERIAL.printf("%d Connected websocket clients ping: %d", i, ping); - last_10sec = millis(); - } + unsigned long t = millis(); + webSocket.loop(); + server.handleClient(); + + if((t - last_10sec) > 10 * 1000) { + counter++; + bool ping = (counter % 2); + int i = webSocket.connectedClients(ping); + USE_SERIAL.printf("%d Connected websocket clients ping: %d\n", i, ping); + last_10sec = millis(); + } } From bde97179bf9f8d3c39235d751816ae9358984c2c Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 12 May 2018 11:39:59 +0200 Subject: [PATCH 153/347] fix unused parameter warnings fix switch warinings part of #319 --- src/WebSockets.h | 3 +++ src/WebSocketsClient.cpp | 7 +++++++ src/WebSocketsServer.cpp | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/src/WebSockets.h b/src/WebSockets.h index c3901f5..989d9b9 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -299,4 +299,7 @@ class WebSockets { }; +#ifndef UNUSED +#define UNUSED(var) (void)(var) +#endif #endif /* WEBSOCKETS_H_ */ diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 17f888d..b211df2 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -318,6 +318,8 @@ void WebSocketsClient::setReconnectInterval(unsigned long time) { void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) { WStype_t type = WStype_ERROR; + UNUSED(client); + switch(opcode) { case WSop_text: type = fin ? WStype_TEXT : WStype_FRAGMENT_TEXT_START; @@ -328,6 +330,11 @@ void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, u case WSop_continuation: type = fin ? WStype_FRAGMENT_FIN : WStype_FRAGMENT; break; + case WSop_close: + case WSop_ping: + case WSop_pong: + default: + break; } runCbEvent(type, payload, length); diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index b036371..4ff0c0f 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -518,6 +518,11 @@ void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, u case WSop_continuation: type = fin ? WStype_FRAGMENT_FIN : WStype_FRAGMENT; break; + case WSop_close: + case WSop_ping: + case WSop_pong: + default: + break; } runCbEvent(client->num, type, payload, length); From 7ddcdc2bd31cbe963e42419344ea18c2952ae76e Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 12 May 2018 12:40:56 +0200 Subject: [PATCH 154/347] add info for AVR usage with version 2.x.x --- src/WebSockets.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/WebSockets.h b/src/WebSockets.h index 989d9b9..4063b5f 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -33,7 +33,13 @@ #include #endif +#ifdef ARDUINO_ARCH_AVR +#error Version 2.x.x currently does not support Arduino with AVR since there is no support for std namespace of c++. +#error Use Version 1.x.x. (ATmega branch) +#else #include +#endif + #ifndef NODEBUG_WEBSOCKETS #ifdef DEBUG_ESP_PORT From d2043bf8ef35257efc8f1477bc9fe57c334f0c85 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 12 May 2018 15:13:50 +0200 Subject: [PATCH 155/347] start work for socket.IO basic Engine.IO implementation --- src/SocketIOclient.cpp | 88 ++++++++++++++++++++++++++++++++++++++++ src/SocketIOclient.h | 58 ++++++++++++++++++++++++++ src/WebSocketsClient.cpp | 4 ++ src/WebSocketsClient.h | 1 + 4 files changed, 151 insertions(+) create mode 100644 src/SocketIOclient.cpp create mode 100644 src/SocketIOclient.h diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp new file mode 100644 index 0000000..b2e35e3 --- /dev/null +++ b/src/SocketIOclient.cpp @@ -0,0 +1,88 @@ +/* + * SocketIOclient.cpp + * + * Created on: May 12, 2018 + * Author: links + */ + +#include "WebSockets.h" +#include "WebSocketsClient.h" +#include "SocketIOclient.h" + +SocketIOclient::SocketIOclient() { + +} + +SocketIOclient::~SocketIOclient() { + +} + +void SocketIOclient::begin(const char *host, uint16_t port, const char * url, const char * protocol) { + WebSocketsClient::beginSocketIO(host, port, url, protocol); +} + +void SocketIOclient::begin(String host, uint16_t port, String url, String protocol) { + WebSocketsClient::beginSocketIO(host, port, url, protocol); +} + +void SocketIOclient::loop(void) { + WebSocketsClient::loop(); + unsigned long t = millis(); + if((t - _lastConnectionFail) > EIO_HEARTBEAT_INTERVAL) { + _lastConnectionFail = t; + sendTXT(eIOtype_PING); + } +} + +void SocketIOclient::runCbEvent(WStype_t type, uint8_t * payload, size_t length) { + switch(type) { + case WStype_DISCONNECTED: + DEBUG_WEBSOCKETS("[wsIOc] Disconnected!\n"); + break; + case WStype_CONNECTED: { + DEBUG_WEBSOCKETS("[wsIOc] Connected to url: %s\n", payload); + // send message to server when Connected + // socket.io upgrade confirmation message (required) + sendTXT(eIOtype_UPGRADE); + } + break; + case WStype_TEXT: { + + if(length < 1) { + break; + } + + engineIOmessageType_t eType = (engineIOmessageType_t) payload[0]; + switch(eType) { + case eIOtype_PING: + payload[0] = eIOtype_PONG; + DEBUG_WEBSOCKETS("[wsIOc] get ping send pong (%s)\n", payload); + sendTXT(payload, length); + break; + case eIOtype_PONG: + DEBUG_WEBSOCKETS("[wsIOc] get pong\n"); + break; + case eIOtype_OPEN: + case eIOtype_CLOSE: + case eIOtype_MESSAGE: + case eIOtype_UPGRADE: + case eIOtype_NOOP: + default: + DEBUG_WEBSOCKETS("[wsIOc] Engine.IO Message Type %c (%02X) is not implemented\n", eType, eType); + DEBUG_WEBSOCKETS("[wsIOc] get text: %s\n", payload); + break; + } + + // send message to server + // webSocket.sendTXT("message here"); + } + break; + case WStype_BIN: + DEBUG_WEBSOCKETS("[wsIOc] get binary length: %u\n", length); + // hexdump(payload, length); + + // send data to server + // webSocket.sendBIN(payload, length); + break; + } +} diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h new file mode 100644 index 0000000..df53278 --- /dev/null +++ b/src/SocketIOclient.h @@ -0,0 +1,58 @@ +/* + * SocketIOclient.h + * + * Created on: May 12, 2018 + * Author: links + */ + +#ifndef SOCKETIOCLIENT_H_ +#define SOCKETIOCLIENT_H_ + +#include "WebSockets.h" + +#define EIO_HEARTBEAT_INTERVAL 10000 + +typedef enum { + eIOtype_OPEN = '0', ///< Sent from the server when a new transport is opened (recheck) + eIOtype_CLOSE = '1', ///< Request the close of this transport but does not shutdown the connection itself. + eIOtype_PING = '2', ///< Sent by the client. Server should answer with a pong packet containing the same data + eIOtype_PONG = '3', ///< Sent by the server to respond to ping packets. + eIOtype_MESSAGE = '4', ///< actual message, client and server should call their callbacks with the data + eIOtype_UPGRADE = '5', ///< Before engine.io switches a transport, it tests, if server and client can communicate over this transport. If this test succeed, the client sends an upgrade packets which requests the server to flush its cache on the old transport and switch to the new transport. + eIOtype_NOOP = '6', ///< A noop packet. Used primarily to force a poll cycle when an incoming websocket connection is received. +} engineIOmessageType_t; + + +typedef enum { + sIOtype_CONNECT = '0', + sIOtype_DISCONNECT = '1', + sIOtype_EVENT = '2', + sIOtype_ACK = '3', + sIOtype_ERROR = '4', + sIOtype_BINARY_EVENT = '5', + sIOtype_BINARY_ACK = '6', +} socketIOmessageType_t; + +class SocketIOclient: private WebSocketsClient { + + public: +#ifdef __AVR__ + typedef void (*SocketIOclientEvent)(WStype_t type, uint8_t * payload, size_t length); +#else + typedef std::function SocketIOclientEvent; +#endif + + SocketIOclient(void); + virtual ~SocketIOclient(void); + + void begin(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); + void begin(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); + + + void loop(void); + private: + void runCbEvent(WStype_t type, uint8_t * payload, size_t length); + uint64_t _lastHeartbeat = 0; +}; + +#endif /* SOCKETIOCLIENT_H_ */ diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index b211df2..79184db 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -215,6 +215,10 @@ bool WebSocketsClient::sendTXT(String & payload) { return sendTXT((uint8_t *) payload.c_str(), payload.length()); } +bool WebSocketsClient::sendTXT(char payload) { + return sendTXT((uint8_t *) &payload, 1); +} + /** * send binary data to client * @param num uint8_t client id diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 8e6305e..db02300 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -70,6 +70,7 @@ class WebSocketsClient: private WebSockets { bool sendTXT(char * payload, size_t length = 0, bool headerToPayload = false); bool sendTXT(const char * payload, size_t length = 0); bool sendTXT(String & payload); + bool sendTXT(char payload); bool sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false); bool sendBIN(const uint8_t * payload, size_t length); From 8967356af3fb925b43b6f2405a78045942e01bca Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 12 May 2018 15:27:08 +0200 Subject: [PATCH 156/347] improve ram usage on one char send --- src/SocketIOclient.cpp | 2 +- src/WebSocketsClient.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index b2e35e3..619cf7d 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -42,7 +42,7 @@ void SocketIOclient::runCbEvent(WStype_t type, uint8_t * payload, size_t length) case WStype_CONNECTED: { DEBUG_WEBSOCKETS("[wsIOc] Connected to url: %s\n", payload); // send message to server when Connected - // socket.io upgrade confirmation message (required) + // Engine.io upgrade confirmation message (required) sendTXT(eIOtype_UPGRADE); } break; diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 79184db..d5e6f47 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -216,7 +216,9 @@ bool WebSocketsClient::sendTXT(String & payload) { } bool WebSocketsClient::sendTXT(char payload) { - return sendTXT((uint8_t *) &payload, 1); + uint8_t buf[WEBSOCKETS_MAX_HEADER_SIZE + 2] = {0x00}; + buf[WEBSOCKETS_MAX_HEADER_SIZE] = payload; + return sendTXT(buf, 1, true); } /** From f95c0143424995d4b16e7d3ea6e2b07554eae890 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 12 May 2018 16:53:34 +0200 Subject: [PATCH 157/347] basic event sending works --- src/SocketIOclient.cpp | 62 +++++++++++++- src/SocketIOclient.h | 15 +++- src/WebSockets.cpp | 169 +++++++++++++++++++++++++-------------- src/WebSockets.h | 3 + src/WebSocketsClient.cpp | 11 +++ src/WebSocketsClient.h | 4 +- 6 files changed, 199 insertions(+), 65 deletions(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index 619cf7d..d2b2f28 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -25,12 +25,68 @@ void SocketIOclient::begin(String host, uint16_t port, String url, String protoc WebSocketsClient::beginSocketIO(host, port, url, protocol); } +bool SocketIOclient::isConnected(void) { + return WebSocketsClient::isConnected(); +} + +/** + * send text data to client + * @param num uint8_t client id + * @param payload uint8_t * + * @param length size_t + * @param headerToPayload bool (see sendFrame for more details) + * @return true if ok + */ +bool SocketIOclient::sendEVENT(uint8_t * payload, size_t length, bool headerToPayload) { + bool ret = false; + if(length == 0) { + length = strlen((const char *) payload); + } + if(clientIsConnected(&_client)) { + + if(!headerToPayload) { + // webSocket Header + ret = WebSocketsClient::sendFrameHeader(&_client, WSop_text, length + 2, true, true); + // Engine.IO / Socket.IO Header + if(ret) { + uint8_t buf[3] = { eIOtype_MESSAGE, sIOtype_EVENT, 0x00 }; + ret = WebSocketsClient::write(&_client, buf, 2); + } + if(ret) { + ret = WebSocketsClient::write(&_client, payload, length ); + } + return ret; + } else { + // TODO implement + } + + // return WebSocketsClient::sendFrame(&_client, WSop_text, payload, length, true, true, headerToPayload); + } + return false; +} + +bool SocketIOclient::sendEVENT(const uint8_t * payload, size_t length) { + return sendEVENT((uint8_t *) payload, length); +} + +bool SocketIOclient::sendEVENT(char * payload, size_t length, bool headerToPayload) { + return sendEVENT((uint8_t *) payload, length, headerToPayload); +} + +bool SocketIOclient::sendEVENT(const char * payload, size_t length) { + return sendEVENT((uint8_t *) payload, length); +} + +bool SocketIOclient::sendEVENT(String & payload) { + return sendEVENT((uint8_t *) payload.c_str(), payload.length()); +} + void SocketIOclient::loop(void) { WebSocketsClient::loop(); unsigned long t = millis(); if((t - _lastConnectionFail) > EIO_HEARTBEAT_INTERVAL) { _lastConnectionFail = t; - sendTXT(eIOtype_PING); + //WebSocketsClient::sendTXT(eIOtype_PING); } } @@ -43,7 +99,7 @@ void SocketIOclient::runCbEvent(WStype_t type, uint8_t * payload, size_t length) DEBUG_WEBSOCKETS("[wsIOc] Connected to url: %s\n", payload); // send message to server when Connected // Engine.io upgrade confirmation message (required) - sendTXT(eIOtype_UPGRADE); + WebSocketsClient::sendTXT(eIOtype_UPGRADE); } break; case WStype_TEXT: { @@ -57,7 +113,7 @@ void SocketIOclient::runCbEvent(WStype_t type, uint8_t * payload, size_t length) case eIOtype_PING: payload[0] = eIOtype_PONG; DEBUG_WEBSOCKETS("[wsIOc] get ping send pong (%s)\n", payload); - sendTXT(payload, length); + WebSocketsClient::sendTXT(payload, length, false); break; case eIOtype_PONG: DEBUG_WEBSOCKETS("[wsIOc] get pong\n"); diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index df53278..b179954 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -12,6 +12,9 @@ #define EIO_HEARTBEAT_INTERVAL 10000 +#define EIO_MAX_HEADER_SIZE (WEBSOCKETS_MAX_HEADER_SIZE + 1) +#define SIO_MAX_HEADER_SIZE (EIO_MAX_HEADER_SIZE + 1) + typedef enum { eIOtype_OPEN = '0', ///< Sent from the server when a new transport is opened (recheck) eIOtype_CLOSE = '1', ///< Request the close of this transport but does not shutdown the connection itself. @@ -33,7 +36,7 @@ typedef enum { sIOtype_BINARY_ACK = '6', } socketIOmessageType_t; -class SocketIOclient: private WebSocketsClient { +class SocketIOclient: protected WebSocketsClient { public: #ifdef __AVR__ @@ -48,9 +51,17 @@ class SocketIOclient: private WebSocketsClient { void begin(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); void begin(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); + bool isConnected(void); + + bool sendEVENT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); + bool sendEVENT(const uint8_t * payload, size_t length = 0); + bool sendEVENT(char * payload, size_t length = 0, bool headerToPayload = false); + bool sendEVENT(const char * payload, size_t length = 0); + bool sendEVENT(String & payload); void loop(void); - private: + + protected: void runCbEvent(WStype_t type, uint8_t * payload, size_t length); uint64_t _lastHeartbeat = 0; }; diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 86ba98f..95cd902 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -71,6 +71,115 @@ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * rea clientDisconnect(client); } +/** + * + * @param buf uint8_t * ptr to the buffer for writing + * @param opcode WSopcode_t + * @param length size_t length of the payload + * @param mask bool add dummy mask to the frame (needed for web browser) + * @param maskkey uint8_t[4] key used for payload + * @param fin bool can be used to send data in more then one frame (set fin on the last frame) + */ +uint8_t WebSockets::createHeader(uint8_t * headerPtr, WSopcode_t opcode, size_t length, bool mask, uint8_t maskKey[4], bool fin) { + uint8_t headerSize; + // calculate header Size + if(length < 126) { + headerSize = 2; + } else if(length < 0xFFFF) { + headerSize = 4; + } else { + headerSize = 10; + } + + if(mask) { + headerSize += 4; + } + + // create header + + // byte 0 + *headerPtr = 0x00; + if(fin) { + *headerPtr |= bit(7); ///< set Fin + } + *headerPtr |= opcode; ///< set opcode + headerPtr++; + + // byte 1 + *headerPtr = 0x00; + if(mask) { + *headerPtr |= bit(7); ///< set mask + } + + if(length < 126) { + *headerPtr |= length; + headerPtr++; + } else if(length < 0xFFFF) { + *headerPtr |= 126; + headerPtr++; + *headerPtr = ((length >> 8) & 0xFF); + headerPtr++; + *headerPtr = (length & 0xFF); + headerPtr++; + } else { + // Normally we never get here (to less memory) + *headerPtr |= 127; + headerPtr++; + *headerPtr = 0x00; + headerPtr++; + *headerPtr = 0x00; + headerPtr++; + *headerPtr = 0x00; + headerPtr++; + *headerPtr = 0x00; + headerPtr++; + *headerPtr = ((length >> 24) & 0xFF); + headerPtr++; + *headerPtr = ((length >> 16) & 0xFF); + headerPtr++; + *headerPtr = ((length >> 8) & 0xFF); + headerPtr++; + *headerPtr = (length & 0xFF); + headerPtr++; + } + + if(mask) { + *headerPtr = maskKey[0]; + headerPtr++; + *headerPtr = maskKey[1]; + headerPtr++; + *headerPtr = maskKey[2]; + headerPtr++; + *headerPtr = maskKey[3]; + headerPtr++; + } + return headerSize; +} + +/** + * + * @param client WSclient_t * ptr to the client struct + * @param opcode WSopcode_t + * @param length size_t length of the payload + * @param mask bool add dummy mask to the frame (needed for web browser) + * @param fin bool can be used to send data in more then one frame (set fin on the last frame) + * @return true if ok + */ +bool WebSockets::sendFrameHeader(WSclient_t * client, WSopcode_t opcode, size_t length, bool mask, bool fin) { + uint8_t maskKey[4] = { 0x00, 0x00, 0x00, 0x00 }; + uint8_t buffer[WEBSOCKETS_MAX_HEADER_SIZE] = { 0 }; + + uint8_t headerSize = createHeader(&buffer[0], opcode, length, mask, maskKey, fin); + + if(write(client, &buffer[0], headerSize) != headerSize) { + return false; + } + + return true; +} + + + /** * * @param client WSclient_t * ptr to the client struct @@ -146,53 +255,7 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay headerPtr = &buffer[0]; } - // create header - - // byte 0 - *headerPtr = 0x00; - if(fin) { - *headerPtr |= bit(7); ///< set Fin - } - *headerPtr |= opcode; ///< set opcode - headerPtr++; - - // byte 1 - *headerPtr = 0x00; - if(mask) { - *headerPtr |= bit(7); ///< set mask - } - - if(length < 126) { - *headerPtr |= length; - headerPtr++; - } else if(length < 0xFFFF) { - *headerPtr |= 126; - headerPtr++; - *headerPtr = ((length >> 8) & 0xFF); - headerPtr++; - *headerPtr = (length & 0xFF); - headerPtr++; - } else { - // Normally we never get here (to less memory) - *headerPtr |= 127; - headerPtr++; - *headerPtr = 0x00; - headerPtr++; - *headerPtr = 0x00; - headerPtr++; - *headerPtr = 0x00; - headerPtr++; - *headerPtr = 0x00; - headerPtr++; - *headerPtr = ((length >> 24) & 0xFF); - headerPtr++; - *headerPtr = ((length >> 16) & 0xFF); - headerPtr++; - *headerPtr = ((length >> 8) & 0xFF); - headerPtr++; - *headerPtr = (length & 0xFF); - headerPtr++; - } + createHeader(headerPtr, opcode, length, mask, maskKey, fin); if(mask) { if(useInternBuffer) { @@ -200,8 +263,6 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay // by this fact its possible the do the masking for(uint8_t x = 0; x < sizeof(maskKey); x++) { maskKey[x] = random(0xFF); - *headerPtr = maskKey[x]; - headerPtr++; } uint8_t * dataMaskPtr; @@ -215,16 +276,6 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay for(size_t x = 0; x < length; x++) { dataMaskPtr[x] = (dataMaskPtr[x] ^ maskKey[x % 4]); } - - } else { - *headerPtr = maskKey[0]; - headerPtr++; - *headerPtr = maskKey[1]; - headerPtr++; - *headerPtr = maskKey[2]; - headerPtr++; - *headerPtr = maskKey[3]; - headerPtr++; } } diff --git a/src/WebSockets.h b/src/WebSockets.h index 4063b5f..ebcf612 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -285,6 +285,9 @@ class WebSockets { virtual void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) = 0; void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0); + + uint8_t createHeader(uint8_t * buf, WSopcode_t opcode, size_t length, bool mask, uint8_t maskKey[4], bool fin); + bool sendFrameHeader(WSclient_t * client, WSopcode_t opcode, size_t length = 0, bool mask = false, bool fin = true); bool sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false, bool fin = true, bool headerToPayload = false); void headerDone(WSclient_t * client); diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index d5e6f47..2e2faf3 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -310,6 +310,10 @@ void WebSocketsClient::setReconnectInterval(unsigned long time) { _reconnectInterval = time; } +bool WebSocketsClient::isConnected(void) { + return (_client.status == WSC_CONNECTED); +} + //################################################################################# //################################################################################# //################################################################################# @@ -666,6 +670,13 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { runCbEvent(WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length()); } else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) { + if(_client.tcp->available()) { + // read not needed data + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] still data in buffer (%d), clean up.\n", _client.tcp->available()); + while(_client.tcp->available() > 0) { + _client.tcp->read(); + } + } sendHeader(client); } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index db02300..711ce92 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -27,7 +27,7 @@ #include "WebSockets.h" -class WebSocketsClient: private WebSockets { +class WebSocketsClient: protected WebSockets { public: #ifdef __AVR__ typedef void (*WebSocketClientEvent)(WStype_t type, uint8_t * payload, size_t length); @@ -87,6 +87,8 @@ class WebSocketsClient: private WebSockets { void setReconnectInterval(unsigned long time); + bool isConnected(void); + protected: String _host; uint16_t _port; From 50903cd410832ba5cd482b72651a7edebdbc4dc2 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 12 May 2018 17:10:17 +0200 Subject: [PATCH 158/347] basic event RX working --- src/SocketIOclient.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index d2b2f28..845afb3 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -118,9 +118,33 @@ void SocketIOclient::runCbEvent(WStype_t type, uint8_t * payload, size_t length) case eIOtype_PONG: DEBUG_WEBSOCKETS("[wsIOc] get pong\n"); break; + case eIOtype_MESSAGE: { + if(length < 2) { + break; + } + socketIOmessageType_t ioType = (socketIOmessageType_t) payload[1]; + uint8_t * data = &payload[2]; + size_t lData = length - 2; + switch(ioType) { + case sIOtype_EVENT: + DEBUG_WEBSOCKETS("[wsIOc] get event (%d): %s\n", lData, data); + break; + case sIOtype_CONNECT: + case sIOtype_DISCONNECT: + case sIOtype_ACK: + case sIOtype_ERROR: + case sIOtype_BINARY_EVENT: + case sIOtype_BINARY_ACK: + default: + DEBUG_WEBSOCKETS("[wsIOc] Socket.IO Message Type %c (%02X) is not implemented\n", ioType, ioType); + DEBUG_WEBSOCKETS("[wsIOc] get text: %s\n", payload); + break; + } + + } + break; case eIOtype_OPEN: case eIOtype_CLOSE: - case eIOtype_MESSAGE: case eIOtype_UPGRADE: case eIOtype_NOOP: default: From bdee8b97446fabac85239ee3a4e6e8afbcc864ed Mon Sep 17 00:00:00 2001 From: Markus Date: Thu, 21 Jun 2018 09:30:11 +0200 Subject: [PATCH 159/347] call end for ESP8266_ASYNC TCP Server --- src/WebSocketsServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 4ff0c0f..4bd8536 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -115,7 +115,7 @@ void WebSocketsServer::close(void) { #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) _server->close(); -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) _server->end(); #else // TODO how to close server? From f7a7ab6ab4364942aea4a23a26d2798f56f147d3 Mon Sep 17 00:00:00 2001 From: Markus Date: Wed, 4 Jul 2018 16:29:28 +0200 Subject: [PATCH 160/347] wrap reasonCode in define see #343 --- src/WebSockets.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 86ba98f..60baf2f 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -440,11 +440,12 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload ? (const char*)payload : ""); break; case WSop_close: { - uint16_t reasonCode = 1000; - if(header->payloadLen >= 2) { - reasonCode = payload[0] << 8 | payload[1]; - } - + #ifndef NODEBUG_WEBSOCKETS + uint16_t reasonCode = 1000; + if(header->payloadLen >= 2) { + reasonCode = payload[0] << 8 | payload[1]; + } + #endif DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get ask for close. Code: %d", client->num, reasonCode); if(header->payloadLen > 2) { DEBUG_WEBSOCKETS(" (%s)\n", (payload + 2)); From 38c401b8afc0721d4c178193105830d354371b06 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 7 Aug 2018 18:06:32 +0200 Subject: [PATCH 161/347] adapt to ESP32 repo changes https://github.com/espressif/arduino-esp32/commit/4e5cbdaa7f4ae6d4f76a378e010d8979da9532bf --- examples/esp32/WebSocketClient/WebSocketClient.ino | 2 -- examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino | 2 -- examples/esp32/WebSocketServer/WebSocketServer.ino | 2 -- 3 files changed, 6 deletions(-) diff --git a/examples/esp32/WebSocketClient/WebSocketClient.ino b/examples/esp32/WebSocketClient/WebSocketClient.ino index 7483b6b..ae3b1d0 100644 --- a/examples/esp32/WebSocketClient/WebSocketClient.ino +++ b/examples/esp32/WebSocketClient/WebSocketClient.ino @@ -17,8 +17,6 @@ WiFiMulti WiFiMulti; WebSocketsClient webSocket; -HardwareSerial Serial1(2); - #define USE_SERIAL Serial1 void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) { diff --git a/examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino b/examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino index 5b4f3a5..8761d19 100644 --- a/examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino +++ b/examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino @@ -19,8 +19,6 @@ WiFiMulti WiFiMulti; WebSocketsClient webSocket; -HardwareSerial Serial1(2); - #define USE_SERIAL Serial1 void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) { diff --git a/examples/esp32/WebSocketServer/WebSocketServer.ino b/examples/esp32/WebSocketServer/WebSocketServer.ino index da7d38f..2174ebe 100644 --- a/examples/esp32/WebSocketServer/WebSocketServer.ino +++ b/examples/esp32/WebSocketServer/WebSocketServer.ino @@ -16,8 +16,6 @@ WiFiMulti WiFiMulti; WebSocketsServer webSocket = WebSocketsServer(81); -HardwareSerial Serial1(2); - #define USE_SERIAL Serial1 void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) { From 388683d4cd5cfff2e740bb45ba027b8ff96d792f Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 7 Aug 2018 18:10:48 +0200 Subject: [PATCH 162/347] fix compiler warnings for ESP32 - #319 --- examples/esp32/WebSocketClient/WebSocketClient.ino | 6 ++++++ examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino | 6 ++++++ examples/esp32/WebSocketServer/WebSocketServer.ino | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/examples/esp32/WebSocketClient/WebSocketClient.ino b/examples/esp32/WebSocketClient/WebSocketClient.ino index ae3b1d0..00c70e1 100644 --- a/examples/esp32/WebSocketClient/WebSocketClient.ino +++ b/examples/esp32/WebSocketClient/WebSocketClient.ino @@ -57,6 +57,12 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { // send data to server // webSocket.sendBIN(payload, length); break; + case WStype_ERROR: + case WStype_FRAGMENT_TEXT_START: + case WStype_FRAGMENT_BIN_START: + case WStype_FRAGMENT: + case WStype_FRAGMENT_FIN: + break; } } diff --git a/examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino b/examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino index 8761d19..7d59f63 100644 --- a/examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino +++ b/examples/esp32/WebSocketClientSSL/WebSocketClientSSL.ino @@ -62,6 +62,12 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { // send data to server // webSocket.sendBIN(payload, length); break; + case WStype_ERROR: + case WStype_FRAGMENT_TEXT_START: + case WStype_FRAGMENT_BIN_START: + case WStype_FRAGMENT: + case WStype_FRAGMENT_FIN: + break; } } diff --git a/examples/esp32/WebSocketServer/WebSocketServer.ino b/examples/esp32/WebSocketServer/WebSocketServer.ino index 2174ebe..87866ed 100644 --- a/examples/esp32/WebSocketServer/WebSocketServer.ino +++ b/examples/esp32/WebSocketServer/WebSocketServer.ino @@ -62,6 +62,12 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length // send message to client // webSocket.sendBIN(num, payload, length); break; + case WStype_ERROR: + case WStype_FRAGMENT_TEXT_START: + case WStype_FRAGMENT_BIN_START: + case WStype_FRAGMENT: + case WStype_FRAGMENT_FIN: + break; } } From 32dd01b91bbae7f10b0b77ac200e69ea064ed44f Mon Sep 17 00:00:00 2001 From: Links Date: Wed, 8 Aug 2018 18:11:18 +0200 Subject: [PATCH 163/347] bump version to 2.1.1 --- library.json | 2 +- library.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index 0dbd62d..36461eb 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.1.0", + "version": "2.1.1", "license": "LGPL-2.1", "export": { "exclude": [ diff --git a/library.properties b/library.properties index 14e1fe9..31c2334 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.1.0 +version=2.1.1 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From 38a881a86a35c2cbf755f9c8da33178b70bd4f82 Mon Sep 17 00:00:00 2001 From: Links Date: Wed, 8 Aug 2018 18:12:02 +0200 Subject: [PATCH 164/347] bump version to 2.1.2 --- library.json | 2 +- library.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index 36461eb..f1a5892 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.1.1", + "version": "2.1.2", "license": "LGPL-2.1", "export": { "exclude": [ diff --git a/library.properties b/library.properties index 31c2334..00d0945 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.1.1 +version=2.1.2 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From a70d644f5d69837228a8f6c3067cf4689487d6a2 Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 23 Sep 2018 11:56:33 +0200 Subject: [PATCH 165/347] adapt travis config to match esp8266 changes --- .travis.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 14693dd..d887f0b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,11 +4,13 @@ os: - linux env: matrix: - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80" IDE_VERSION=1.6.5 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80,FlashSize=1M0,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.5 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:CpuFrequency=80,Debug=Serial1" IDE_VERSION=1.6.5 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80" IDE_VERSION=1.6.5 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M0,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.5 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M0,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.7 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,Debug=Serial1" IDE_VERSION=1.6.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.6.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.5 + - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.7 script: - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 From e8249f76e6c0b4a377056dd259785a50902e52fe Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 23 Sep 2018 12:02:06 +0200 Subject: [PATCH 166/347] travis config second fix --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d887f0b..a10b098 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,8 @@ os: env: matrix: - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80" IDE_VERSION=1.6.5 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M0,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.5 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M0,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.7 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.5 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.7 - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,Debug=Serial1" IDE_VERSION=1.6.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.6.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.5 From 50e2e366cc54a8bcdcb5ee3fa7e8f3f5f41a867a Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 23 Sep 2018 12:07:42 +0200 Subject: [PATCH 167/347] fix travis debug test build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a10b098..3493a8c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ env: - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80" IDE_VERSION=1.6.5 - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.5 - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.7 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,Debug=Serial1" IDE_VERSION=1.6.5 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,dbg=Serial1" IDE_VERSION=1.6.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.6.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.7 From 4db22fe5e416d65e0524b66160ce73030263e863 Mon Sep 17 00:00:00 2001 From: Sanket Patel Date: Fri, 21 Sep 2018 23:58:48 +0530 Subject: [PATCH 168/347] make masking RFC complaint and fix #208 --- src/WebSockets.cpp | 13 ++++++------- src/WebSockets.h | 3 ++- src/WebSocketsClient.cpp | 7 ++++--- src/WebSocketsServer.cpp | 8 ++++---- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 60baf2f..5e32a93 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -77,12 +77,11 @@ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * rea * @param opcode WSopcode_t * @param payload uint8_t * ptr to the payload * @param length size_t length of the payload - * @param mask bool add dummy mask to the frame (needed for web browser) * @param fin bool can be used to send data in more then one frame (set fin on the last frame) * @param headerToPayload bool set true if the payload has reserved 14 Byte at the beginning to dynamically add the Header (payload neet to be in RAM!) * @return true if ok */ -bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool mask, bool fin, bool headerToPayload) { +bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin, bool headerToPayload) { if(client->tcp && !client->tcp->connected()) { DEBUG_WEBSOCKETS("[WS][%d][sendFrame] not Connected!?\n", client->num); @@ -95,7 +94,7 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay } DEBUG_WEBSOCKETS("[WS][%d][sendFrame] ------- send message frame -------\n", client->num); - DEBUG_WEBSOCKETS("[WS][%d][sendFrame] fin: %u opCode: %u mask: %u length: %u headerToPayload: %u\n", client->num, fin, opcode, mask, length, headerToPayload); + DEBUG_WEBSOCKETS("[WS][%d][sendFrame] fin: %u opCode: %u mask: %u length: %u headerToPayload: %u\n", client->num, fin, opcode, client->cIsClient, length, headerToPayload); if(opcode == WSop_text) { DEBUG_WEBSOCKETS("[WS][%d][sendFrame] text: %s\n", client->num, (payload + (headerToPayload ? 14 : 0))); @@ -119,7 +118,7 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay headerSize = 10; } - if(mask) { + if(client->cIsClient) { headerSize += 4; } @@ -158,7 +157,7 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay // byte 1 *headerPtr = 0x00; - if(mask) { + if(client->cIsClient) { *headerPtr |= bit(7); ///< set mask } @@ -194,7 +193,7 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay headerPtr++; } - if(mask) { + if(client->cIsClient) { if(useInternBuffer) { // if we use a Intern Buffer we can modify the data // by this fact its possible the do the masking @@ -434,7 +433,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t break; case WSop_ping: // send pong back - sendFrame(client, WSop_pong, payload, header->payloadLen, true); + sendFrame(client, WSop_pong, payload, header->payloadLen); break; case WSop_pong: DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload ? (const char*)payload : ""); diff --git a/src/WebSockets.h b/src/WebSockets.h index 4063b5f..da88f08 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -241,6 +241,7 @@ typedef struct { String cUrl; ///< http url uint16_t cCode; ///< http code + bool cIsClient = false; ///< will be used for masking bool cIsUpgrade; ///< Connection == Upgrade bool cIsWebsocket; ///< Upgrade == websocket @@ -285,7 +286,7 @@ class WebSockets { virtual void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) = 0; void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0); - bool sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool mask = false, bool fin = true, bool headerToPayload = false); + bool sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool fin = true, bool headerToPayload = false); void headerDone(WSclient_t * client); diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index b211df2..94ca434 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -28,6 +28,7 @@ WebSocketsClient::WebSocketsClient() { _cbEvent = NULL; _client.num = 0; + _client.cIsClient = true; _client.extraHeaders = WEBSOCKETS_STRING("Origin: file://"); } @@ -194,7 +195,7 @@ bool WebSocketsClient::sendTXT(uint8_t * payload, size_t length, bool headerToPa length = strlen((const char *) payload); } if(clientIsConnected(&_client)) { - return sendFrame(&_client, WSop_text, payload, length, true, true, headerToPayload); + return sendFrame(&_client, WSop_text, payload, length, true, headerToPayload); } return false; } @@ -225,7 +226,7 @@ bool WebSocketsClient::sendTXT(String & payload) { */ bool WebSocketsClient::sendBIN(uint8_t * payload, size_t length, bool headerToPayload) { if(clientIsConnected(&_client)) { - return sendFrame(&_client, WSop_binary, payload, length, true, true, headerToPayload); + return sendFrame(&_client, WSop_binary, payload, length, true, headerToPayload); } return false; } @@ -242,7 +243,7 @@ bool WebSocketsClient::sendBIN(const uint8_t * payload, size_t length) { */ bool WebSocketsClient::sendPing(uint8_t * payload, size_t length) { if(clientIsConnected(&_client)) { - return sendFrame(&_client, WSop_ping, payload, length, true); + return sendFrame(&_client, WSop_ping, payload, length); } return false; } diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 4bd8536..e1752f2 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -184,7 +184,7 @@ bool WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bo } WSclient_t * client = &_clients[num]; if(clientIsConnected(client)) { - return sendFrame(client, WSop_text, payload, length, false, true, headerToPayload); + return sendFrame(client, WSop_text, payload, length, true, headerToPayload); } return false; } @@ -222,7 +222,7 @@ bool WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool heade for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { client = &_clients[i]; if(clientIsConnected(client)) { - if(!sendFrame(client, WSop_text, payload, length, false, true, headerToPayload)) { + if(!sendFrame(client, WSop_text, payload, length, true, headerToPayload)) { ret = false; } } @@ -263,7 +263,7 @@ bool WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length, bo } WSclient_t * client = &_clients[num]; if(clientIsConnected(client)) { - return sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload); + return sendFrame(client, WSop_binary, payload, length, true, headerToPayload); } return false; } @@ -285,7 +285,7 @@ bool WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool heade for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { client = &_clients[i]; if(clientIsConnected(client)) { - if(!sendFrame(client, WSop_binary, payload, length, false, true, headerToPayload)) { + if(!sendFrame(client, WSop_binary, payload, length, true, headerToPayload)) { ret = false; } } From 68800e2e7a152a1b359a3f192635c6805926fe60 Mon Sep 17 00:00:00 2001 From: Jozef Sovcik Date: Tue, 23 Oct 2018 18:01:33 +0200 Subject: [PATCH 169/347] implementing heartbeat --- src/WebSockets.cpp | 46 ++++++++++++++++++++++++++++++++++++++++ src/WebSockets.h | 10 +++++++++ src/WebSocketsClient.cpp | 46 +++++++++++++++++++++++++++++++++++++++- src/WebSocketsClient.h | 5 +++++ 4 files changed, 106 insertions(+), 1 deletion(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 5e32a93..f0e39b9 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -433,10 +433,12 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t break; case WSop_ping: // send pong back + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] ping received (%s)\n", client->num, payload ? (const char*)payload : ""); sendFrame(client, WSop_pong, payload, header->payloadLen); break; case WSop_pong: DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload ? (const char*)payload : ""); + client->pongReceived = true; break; case WSop_close: { #ifndef NODEBUG_WEBSOCKETS @@ -652,3 +654,47 @@ size_t WebSockets::write(WSclient_t * client, const char *out) { if(out == NULL) return 0; return write(client, (uint8_t*)out, strlen(out)); } + +/** + * enable ping/pong heartbeat process + * @param client WSclient_t * + * @param pingInterval uint32_t how often ping will be sent + * @param pongTimeout uint32_t millis after which pong should timout if not received + * @param disconnectTimeoutCount uint8_t how many timeouts before disconnect, 0=> do not disconnect + */ +void WebSockets::enableHeartbeat(WSclient_t * client, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount){ + if(client == NULL) return; + client->pingInterval = pingInterval; + client->pongTimeout = pongTimeout; + client->disconnectTimeoutCount = disconnectTimeoutCount; + +} + +/** + * handle ping/pong heartbeat timeout process + * @param client WSclient_t * + */ +void WebSockets::handleHBTimeout(WSclient_t * client){ + if (client->pingInterval) { // if heartbeat is enabled + uint32_t pi = millis() - client->lastPing; + + if (client->pongReceived) { + client->pongTimeoutCount = 0; + } else { + if (pi > client->pongTimeout){ // pong not received in time + client->pongTimeoutCount++; + client->lastPing = millis() - client->pingInterval - 500; // force ping on the next run + + DEBUG_WEBSOCKETS("[HBtimeout] pong TIMEOUT! lp=%d millis=%d pi=%d count=%d\n", client->lastPing, millis(), pi, client->pongTimeoutCount); + + if (client->disconnectTimeoutCount && client->pongTimeoutCount >= client->disconnectTimeoutCount){ + DEBUG_WEBSOCKETS("[HBtimeout] count=%d, DISCONNECTING\n", client->pongTimeoutCount); + client->status = WSC_NOT_CONNECTED; + //clientDisconnect(client); + } + } + } + + } + +} \ No newline at end of file diff --git a/src/WebSockets.h b/src/WebSockets.h index da88f08..39a1e0b 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -264,6 +264,13 @@ typedef struct { bool cHttpHeadersValid; ///< non-websocket http header validity indicator size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count + bool pongReceived; + uint32_t pingInterval; // how often ping will be sent, 0 means "heartbeat is not active" + uint32_t lastPing; // millis when last pong has been received + uint32_t pongTimeout; // interval in millis after which pong is considered to timeout + uint8_t disconnectTimeoutCount; // after how many subsequent pong timeouts discconnect will happen, 0 means "do not disconnect" + uint8_t pongTimeoutCount; // current pong timeout count + #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) String cHttpLine; ///< HTTP header lines #endif @@ -303,6 +310,9 @@ class WebSockets { virtual size_t write(WSclient_t * client, uint8_t *out, size_t n); size_t write(WSclient_t * client, const char *out); + void enableHeartbeat(WSclient_t * client, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); + void handleHBTimeout(WSclient_t * client); + }; diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 94ca434..9bfb274 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -66,6 +66,10 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url, _client.plainAuthorization = ""; _client.isSocketIO = false; + _client.lastPing = 0; + _client.pongReceived = false; + _client.pongTimeoutCount = 0; + #ifdef ESP8266 randomSeed(RANDOM_REG32); #else @@ -169,6 +173,10 @@ void WebSocketsClient::loop(void) { } } else { + if (_client.status == WSC_CONNECTED){ + handleHBPing(); + handleHBTimeout(&_client); + } handleClientData(); } } @@ -243,7 +251,10 @@ bool WebSocketsClient::sendBIN(const uint8_t * payload, size_t length) { */ bool WebSocketsClient::sendPing(uint8_t * payload, size_t length) { if(clientIsConnected(&_client)) { - return sendFrame(&_client, WSop_ping, payload, length); + bool sent = sendFrame(&_client, WSop_ping, payload, length); + if (sent) + _client.lastPing = millis(); + return sent; } return false; } @@ -761,3 +772,36 @@ void WebSocketsClient::asyncConnect() { } #endif + +/** + * send heartbeat ping to server in set intervals + */ +void WebSocketsClient::handleHBPing(){ + if (_client.pingInterval == 0) return; + uint32_t pi = millis() - _client.lastPing; + if (pi > _client.pingInterval){ + DEBUG_WEBSOCKETS("[WS-Client] sending HB ping\n"); + if (sendPing()) { + _client.lastPing = millis(); + _client.pongReceived = false; + } + } + +} + +/** + * enable ping/pong heartbeat process + * @param pingInterval uint32_t how often ping will be sent + * @param pongTimeout uint32_t millis after which pong should timout if not received + * @param disconnectTimeoutCount uint8_t how many timeouts before disconnect, 0=> do not disconnect + */ +void WebSocketsClient::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount){ + WebSockets::enableHeartbeat(&_client, pingInterval, pongTimeout, disconnectTimeoutCount); +} + +/** + * disable ping/pong heartbeat process + */ +void WebSocketsClient::disableHeartbeat(){ + _client.pingInterval = 0; +} \ No newline at end of file diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 8e6305e..47fe8c8 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -86,6 +86,9 @@ class WebSocketsClient: private WebSockets { void setReconnectInterval(unsigned long time); + void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); + void disableHeartbeat(); + protected: String _host; uint16_t _port; @@ -115,6 +118,8 @@ class WebSocketsClient: private WebSockets { void connectedCb(); void connectFailedCb(); + void handleHBPing(); // send ping in specified intervals + #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) void asyncConnect(); #endif From 9b6ce7563a2d8876f71ce113f402b61a24e8cdc6 Mon Sep 17 00:00:00 2001 From: Jozef Sovcik Date: Wed, 24 Oct 2018 08:17:37 +0200 Subject: [PATCH 170/347] added example for heartbeat --- examples/esp8266/WebSocketClient/WebSocketClient.ino | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/esp8266/WebSocketClient/WebSocketClient.ino b/examples/esp8266/WebSocketClient/WebSocketClient.ino index 3ce8498..86fc241 100644 --- a/examples/esp8266/WebSocketClient/WebSocketClient.ino +++ b/examples/esp8266/WebSocketClient/WebSocketClient.ino @@ -84,6 +84,12 @@ void setup() { // try ever 5000 again if connection has failed webSocket.setReconnectInterval(5000); + + // start heartbeat (optional) + // ping server every 15000 ms + // expect pong from server within 3000 ms + // consider connection disconnected if pong is not received 2 times + webSocket.enableHeartbeat(15000, 3000, 2); } From d6934379087bbce9dee177bf635e69736599ea90 Mon Sep 17 00:00:00 2001 From: Jozef Sovcik Date: Wed, 24 Oct 2018 08:19:02 +0200 Subject: [PATCH 171/347] version bump --- library.json | 2 +- library.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index f1a5892..978e584 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.1.2", + "version": "2.1.3", "license": "LGPL-2.1", "export": { "exclude": [ diff --git a/library.properties b/library.properties index 00d0945..a30fdbf 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.1.2 +version=2.1.3 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From d6dd7be9879bca9bfe36d7f6eead77a98bce7555 Mon Sep 17 00:00:00 2001 From: Jozef Sovcik Date: Sat, 3 Nov 2018 13:15:14 +0100 Subject: [PATCH 172/347] disconnecting after pong not received --- src/WebSockets.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index f0e39b9..fc4a6ba 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -689,8 +689,7 @@ void WebSockets::handleHBTimeout(WSclient_t * client){ if (client->disconnectTimeoutCount && client->pongTimeoutCount >= client->disconnectTimeoutCount){ DEBUG_WEBSOCKETS("[HBtimeout] count=%d, DISCONNECTING\n", client->pongTimeoutCount); - client->status = WSC_NOT_CONNECTED; - //clientDisconnect(client); + clientDisconnect(client); } } } From 1b6b42b877c201be6a01788713386e2bcd26bcc6 Mon Sep 17 00:00:00 2001 From: Jozef Sovcik Date: Sat, 3 Nov 2018 13:16:12 +0100 Subject: [PATCH 173/347] processing client data before potential disconnect --- src/WebSocketsClient.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 9bfb274..2d96358 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -173,11 +173,13 @@ void WebSocketsClient::loop(void) { } } else { + handleClientData(); + if (_client.status == WSC_CONNECTED){ handleHBPing(); handleHBTimeout(&_client); } - handleClientData(); + } } #endif @@ -726,7 +728,7 @@ void WebSocketsClient::connectedCb() { } void WebSocketsClient::connectFailedCb() { - DEBUG_WEBSOCKETS("[WS-Client] connection to %s:%u Faild\n", _host.c_str(), _port); + DEBUG_WEBSOCKETS("[WS-Client] connection to %s:%u Failed\n", _host.c_str(), _port); } #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) From 4223a9e41f7f7752b6b8e82697a8b51e58912f13 Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 30 May 2019 14:24:57 +0200 Subject: [PATCH 174/347] fix Travis --- .travis.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3493a8c..e478035 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,10 @@ sudo: false +dist: + - xenial +addons: + apt: + packages: + - xvfb language: bash os: - linux @@ -14,8 +20,8 @@ env: script: - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 - - sleep 3 - export DISPLAY=:1.0 + - sleep 3 - wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz - tar xf arduino-$IDE_VERSION-linux64.tar.xz - mv arduino-$IDE_VERSION $HOME/arduino_ide @@ -28,6 +34,7 @@ script: - cd $TRAVIS_BUILD_DIR - arduino --board $BOARD --save-prefs - arduino --get-pref sketchbook.path + - arduino --pref update.check=false - build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets/examples/$CPU $CPU notifications: From 31bade1530169508e6aa553eef76430cb147122d Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 30 May 2019 14:33:44 +0200 Subject: [PATCH 175/347] test with newer arduino IDE (1.8.9) --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e478035..9d3f31b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,11 +12,11 @@ env: matrix: - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80" IDE_VERSION=1.6.5 - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.5 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.7 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.9 - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,dbg=Serial1" IDE_VERSION=1.6.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.6.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.5 - - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.7 + - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.9 script: - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 From c361895a4bdb26bda3bbc48042890318e8f5014f Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 30 May 2019 16:32:30 +0200 Subject: [PATCH 176/347] add setCACert based on #434 --- src/WebSockets.h | 1 + src/WebSocketsClient.cpp | 41 ++++++++++++++++++++++++++++++++++------ src/WebSocketsClient.h | 9 ++++++--- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 39a1e0b..5951023 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -57,6 +57,7 @@ #if defined(ESP8266) || defined(ESP32) +#define HAS_SSL #define WEBSOCKETS_MAX_DATA_SIZE (15*1024) #define WEBSOCKETS_USE_BIG_MEM #define GET_FREE_HEAP ESP.getFreeHeap() diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 2d96358..eb46c12 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -42,14 +42,15 @@ WebSocketsClient::~WebSocketsClient() { void WebSocketsClient::begin(const char *host, uint16_t port, const char * url, const char * protocol) { _host = host; _port = port; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if defined(HAS_SSL) _fingerprint = ""; + _CA_cert = NULL; #endif _client.num = 0; _client.status = WSC_NOT_CONNECTED; _client.tcp = NULL; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if defined(HAS_SSL) _client.isSSL = false; _client.ssl = NULL; #endif @@ -92,16 +93,24 @@ void WebSocketsClient::begin(IPAddress host, uint16_t port, const char * url, co return begin(host.toString().c_str(), port, url, protocol); } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if defined(HAS_SSL) void WebSocketsClient::beginSSL(const char *host, uint16_t port, const char * url, const char * fingerprint, const char * protocol) { begin(host, port, url, protocol); _client.isSSL = true; _fingerprint = fingerprint; + _CA_cert = NULL; } void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String fingerprint, String protocol) { beginSSL(host.c_str(), port, url.c_str(), fingerprint.c_str(), protocol.c_str()); } + +void WebSocketsClient::beginSslWithCA(const char *host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { + begin(host, port, url, protocol); + _client.isSSL = true; + _fingerprint = ""; + _CA_cert = CA_cert; +} #endif void WebSocketsClient::beginSocketIO(const char *host, uint16_t port, const char * url, const char * protocol) { @@ -113,7 +122,7 @@ void WebSocketsClient::beginSocketIO(String host, uint16_t port, String url, Str beginSocketIO(host.c_str(), port, url.c_str(), protocol.c_str()); } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if defined(HAS_SSL) void WebSocketsClient::beginSocketIOSSL(const char *host, uint16_t port, const char * url, const char * protocol) { begin(host, port, url, protocol); _client.isSocketIO = true; @@ -124,6 +133,14 @@ void WebSocketsClient::beginSocketIOSSL(const char *host, uint16_t port, const c void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url, String protocol) { beginSocketIOSSL(host.c_str(), port, url.c_str(), protocol.c_str()); } + +void WebSocketsClient::beginSocketIOSSLWithCA(const char *host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { + begin(host, port, url, protocol); + _client.isSocketIO = true; + _client.isSSL = true; + _fingerprint = ""; + _CA_cert = CA_cert; +} #endif #if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) @@ -147,6 +164,16 @@ void WebSocketsClient::loop(void) { } _client.ssl = new WiFiClientSecure(); _client.tcp = _client.ssl; + if(_CA_cert) { + DEBUG_WEBSOCKETS("[WS-Client] setting CA certificate"); +#if defined(ESP32) + _client.ssl->setCACert(_CA_cert); +#elif defined(ESP8266) + _client.ssl->setCACert((const uint8_t *)_CA_cert, strlen(_CA_cert) + 1); +#else +#error setCACert not implemented +#endif + } } else { DEBUG_WEBSOCKETS("[WS-Client] connect ws...\n"); if(_client.tcp) { @@ -710,9 +737,11 @@ void WebSocketsClient::connectedCb() { _client.tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); #endif -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32 _client.tcp->setNoDelay(true); +#endif +#if defined(HAS_SSL) if(_client.isSSL && _fingerprint.length()) { if(!_client.ssl->verify(_fingerprint.c_str(), _host.c_str())) { DEBUG_WEBSOCKETS("[WS-Client] certificate mismatch\n"); @@ -806,4 +835,4 @@ void WebSocketsClient::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeo */ void WebSocketsClient::disableHeartbeat(){ _client.pingInterval = 0; -} \ No newline at end of file +} diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 47fe8c8..07c82d1 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -43,17 +43,19 @@ class WebSocketsClient: private WebSockets { void begin(String host, uint16_t port, String url = "/", String protocol = "arduino"); void begin(IPAddress host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if defined(HAS_SSL) void beginSSL(const char *host, uint16_t port, const char * url = "/", const char * = "", const char * protocol = "arduino"); void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino"); + void beginSslWithCA(const char *host, uint16_t port, const char * url = "/", const char * CA_cert = NULL, const char * protocol = "arduino"); #endif void beginSocketIO(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); void beginSocketIO(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if defined(HAS_SSL) void beginSocketIOSSL(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); void beginSocketIOSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); + void beginSocketIOSSLWithCA(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino"); #endif #if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) @@ -93,8 +95,9 @@ class WebSocketsClient: private WebSockets { String _host; uint16_t _port; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if defined(HAS_SSL) String _fingerprint; + const char *_CA_cert; #endif WSclient_t _client; From 8ec27b0468615eb86f8b2df0c03a28e4caa96332 Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 30 May 2019 16:52:20 +0200 Subject: [PATCH 177/347] fix indexOf #430 --- src/WebSocketsClient.cpp | 2 +- src/WebSocketsServer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index eb46c12..345db8b 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -598,7 +598,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { if(headerLine->startsWith(WEBSOCKETS_STRING("HTTP/1."))) { // "HTTP/1.1 101 Switching Protocols" client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt(); - } else if(headerLine->indexOf(':')) { + } else if(headerLine->indexOf(':') >= 0) { String headerName = headerLine->substring(0, headerLine->indexOf(':')); String headerValue = headerLine->substring(headerLine->indexOf(':') + 1); diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index e1752f2..2918fe4 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -732,7 +732,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { client->cHttpHeadersValid = true; client->cMandatoryHeadersCount = 0; - } else if(headerLine->indexOf(':')) { + } else if(headerLine->indexOf(':') >= 0) { String headerName = headerLine->substring(0, headerLine->indexOf(':')); String headerValue = headerLine->substring(headerLine->indexOf(':') + 1); From df3ef524b6b481939c184f2a044dcbaf00b83a6f Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 30 May 2019 18:24:28 +0200 Subject: [PATCH 178/347] fix #428 by setting Insecure if we do not have a CA or fingerprint --- src/WebSocketsClient.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 345db8b..4fe5b1b 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -748,6 +748,10 @@ void WebSocketsClient::connectedCb() { WebSockets::clientDisconnect(&_client, 1000); return; } + } else if(_client.isSSL && !_CA_cert) { +#if defined(wificlientbearssl_h) && !defined(USING_AXTLS) + _client.ssl->setInsecure(); +#endif } #endif From 0aa07421a6e25e49a0eecea968d91770eb88fceb Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 30 May 2019 20:15:03 +0200 Subject: [PATCH 179/347] add events for ping / pong rx #382 --- examples/esp8266/WebSocketClient/WebSocketClient.ino | 10 +++++++++- src/WebSockets.cpp | 8 ++++---- src/WebSockets.h | 2 ++ src/WebSocketsClient.cpp | 6 +++++- src/WebSocketsServer.cpp | 6 +++++- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/examples/esp8266/WebSocketClient/WebSocketClient.ino b/examples/esp8266/WebSocketClient/WebSocketClient.ino index 86fc241..67aa383 100644 --- a/examples/esp8266/WebSocketClient/WebSocketClient.ino +++ b/examples/esp8266/WebSocketClient/WebSocketClient.ino @@ -45,7 +45,15 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { // send data to server // webSocket.sendBIN(payload, length); break; - } + case WStype_PING: + // pong will be send automatically + USE_SERIAL.printf("[WSc] get ping\n"); + break; + case WStype_PONG: + // answer to a ping we send + USE_SERIAL.printf("[WSc] get pong\n"); + break; + } } diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index fc4a6ba..0f57922 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -435,10 +435,12 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t // send pong back DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] ping received (%s)\n", client->num, payload ? (const char*)payload : ""); sendFrame(client, WSop_pong, payload, header->payloadLen); + messageReceived(client, header->opCode, payload, header->payloadLen, header->fin); break; case WSop_pong: DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload ? (const char*)payload : ""); client->pongReceived = true; + messageReceived(client, header->opCode, payload, header->payloadLen, header->fin); break; case WSop_close: { #ifndef NODEBUG_WEBSOCKETS @@ -667,7 +669,7 @@ void WebSockets::enableHeartbeat(WSclient_t * client, uint32_t pingInterval, uin client->pingInterval = pingInterval; client->pongTimeout = pongTimeout; client->disconnectTimeoutCount = disconnectTimeoutCount; - + client->pongReceived = false; } /** @@ -693,7 +695,5 @@ void WebSockets::handleHBTimeout(WSclient_t * client){ } } } - } - -} \ No newline at end of file +} diff --git a/src/WebSockets.h b/src/WebSockets.h index 5951023..65a9484 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -197,6 +197,8 @@ typedef enum { WStype_FRAGMENT_BIN_START, WStype_FRAGMENT, WStype_FRAGMENT_FIN, + WStype_PING, + WStype_PONG, } WStype_t; typedef enum { diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 4fe5b1b..6887641 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -371,9 +371,13 @@ void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, u case WSop_continuation: type = fin ? WStype_FRAGMENT_FIN : WStype_FRAGMENT; break; - case WSop_close: case WSop_ping: + type = WStype_PING; + break; case WSop_pong: + type = WStype_PONG; + break; + case WSop_close: default: break; } diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 2918fe4..a6492c0 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -518,9 +518,13 @@ void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, u case WSop_continuation: type = fin ? WStype_FRAGMENT_FIN : WStype_FRAGMENT; break; - case WSop_close: case WSop_ping: + type = WStype_PING; + break; case WSop_pong: + type = WStype_PONG; + break; + case WSop_close: default: break; } From e8df841b7f96927a418b508205816eb3b7d7740b Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 10 Jun 2019 09:29:58 +0200 Subject: [PATCH 180/347] add support for ESP32 ETH.h see #443 --- src/WebSockets.h | 21 +++++++++++++++++---- src/WebSocketsClient.cpp | 6 +++--- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 65a9484..f9c2a94 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -57,7 +57,6 @@ #if defined(ESP8266) || defined(ESP32) -#define HAS_SSL #define WEBSOCKETS_MAX_DATA_SIZE (15*1024) #define WEBSOCKETS_USE_BIG_MEM #define GET_FREE_HEAP ESP.getFreeHeap() @@ -87,6 +86,7 @@ #define NETWORK_W5100 (2) #define NETWORK_ENC28J60 (3) #define NETWORK_ESP32 (4) +#define NETWORK_ESP32_ETH (5) // max size of the WS Message Header #define WEBSOCKETS_MAX_HEADER_SIZE (14) @@ -100,7 +100,7 @@ #elif defined(ESP32) #define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP32 - +//#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP32_ETH #else #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 @@ -143,6 +143,7 @@ #include #endif #define WEBSOCKETS_NETWORK_CLASS WiFiClient +#define WEBSOCKETS_NETWORK_SSL_CLASS WiFiClientSecure #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer #elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_W5100) @@ -168,12 +169,24 @@ #include #include #define WEBSOCKETS_NETWORK_CLASS WiFiClient +#define WEBSOCKETS_NETWORK_SSL_CLASS WiFiClientSecure +#define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer + +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32_ETH) + +#include +#define WEBSOCKETS_NETWORK_CLASS WiFiClient #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer #else #error "no network type selected!" #endif + +#ifdef WEBSOCKETS_NETWORK_SSL_CLASS +#define HAS_SSL +#endif + // moves all Header strings to Flash (~300 Byte) #ifdef WEBSOCKETS_SAVE_RAM #define WEBSOCKETS_STRING(var) F(var) @@ -236,9 +249,9 @@ typedef struct { bool isSocketIO; ///< client for socket.io server -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if defined(HAS_SSL) bool isSSL; ///< run in ssl mode - WiFiClientSecure * ssl; + WEBSOCKETS_NETWORK_SSL_CLASS * ssl; #endif String cUrl; ///< http url diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 6887641..0002561 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -154,7 +154,7 @@ void WebSocketsClient::loop(void) { return; } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if defined(HAS_SSL) if(_client.isSSL) { DEBUG_WEBSOCKETS("[WS-Client] connect wss...\n"); if(_client.ssl) { @@ -162,7 +162,7 @@ void WebSocketsClient::loop(void) { _client.ssl = NULL; _client.tcp = NULL; } - _client.ssl = new WiFiClientSecure(); + _client.ssl = new WEBSOCKETS_NETWORK_SSL_CLASS(); _client.tcp = _client.ssl; if(_CA_cert) { DEBUG_WEBSOCKETS("[WS-Client] setting CA certificate"); @@ -180,7 +180,7 @@ void WebSocketsClient::loop(void) { delete _client.tcp; _client.tcp = NULL; } - _client.tcp = new WiFiClient(); + _client.tcp = new WEBSOCKETS_NETWORK_CLASS(); } #else _client.tcp = new WEBSOCKETS_NETWORK_CLASS(); From 3063ad27ae047e67aff292230152587206cc490b Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 10 Jun 2019 12:57:49 +0200 Subject: [PATCH 181/347] clang-format --- .clang-format | 63 +++++++ src/WebSockets.cpp | 198 ++++++++++---------- src/WebSockets.h | 202 ++++++++++---------- src/WebSocketsClient.cpp | 258 ++++++++++++-------------- src/WebSocketsClient.h | 132 +++++++------ src/WebSocketsServer.cpp | 391 ++++++++++++++++++--------------------- src/WebSocketsServer.h | 228 +++++++++++------------ 7 files changed, 741 insertions(+), 731 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..e72c54b --- /dev/null +++ b/.clang-format @@ -0,0 +1,63 @@ +--- +BasedOnStyle: Google +AccessModifierOffset: '-2' +AlignAfterOpenBracket: DontAlign +AlignConsecutiveAssignments: 'true' +AlignConsecutiveDeclarations: 'false' +AlignEscapedNewlines: Left +AlignTrailingComments: 'true' +AllowAllParametersOfDeclarationOnNextLine: 'false' +AllowShortBlocksOnASingleLine: 'false' +AllowShortCaseLabelsOnASingleLine: 'false' +AllowShortFunctionsOnASingleLine: InlineOnly +AllowShortIfStatementsOnASingleLine: 'true' +AllowShortLoopsOnASingleLine: 'true' +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: 'true' +AlwaysBreakTemplateDeclarations: 'false' +BinPackParameters: 'true' +BreakAfterJavaFieldAnnotations: 'false' +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: 'false' +BreakBeforeTernaryOperators: 'false' +BreakConstructorInitializers: BeforeColon +BreakStringLiterals: 'false' +ColumnLimit: '0' +CompactNamespaces: 'true' +ConstructorInitializerAllOnOneLineOrOnePerLine: 'true' +ConstructorInitializerIndentWidth: '4' +ContinuationIndentWidth: '4' +Cpp11BracedListStyle: 'false' +DerivePointerAlignment: 'false' +FixNamespaceComments: 'true' +IndentCaseLabels: 'true' +IndentWidth: '4' +IndentWrappedFunctionNames: 'false' +JavaScriptQuotes: Single +JavaScriptWrapImports: 'false' +KeepEmptyLinesAtTheStartOfBlocks: 'false' +MaxEmptyLinesToKeep: '1' +NamespaceIndentation: All +ObjCBlockIndentWidth: '4' +ObjCSpaceAfterProperty: 'false' +ObjCSpaceBeforeProtocolList: 'false' +PointerAlignment: Middle +SortIncludes: 'false' +SortUsingDeclarations: 'true' +SpaceAfterCStyleCast: 'false' +SpaceAfterTemplateKeyword: 'false' +SpaceBeforeAssignmentOperators: 'true' +SpaceBeforeParens: Never +SpaceInEmptyParentheses: 'false' +SpacesBeforeTrailingComments: '4' +SpacesInAngles: 'false' +SpacesInCStyleCastParentheses: 'false' +SpacesInContainerLiterals: 'false' +SpacesInParentheses: 'false' +SpacesInSquareBrackets: 'false' +TabWidth: '4' +UseTab: Never + +... diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 0f57922..608c045 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -48,7 +48,6 @@ extern "C" { #endif - /** * * @param client WSclient_t * ptr to the client struct @@ -60,7 +59,7 @@ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * rea DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] clientDisconnect code: %u\n", client->num, code); if(client->status == WSC_CONNECTED && code) { if(reason) { - sendFrame(client, WSop_close, (uint8_t *) reason, reasonLen); + sendFrame(client, WSop_close, (uint8_t *)reason, reasonLen); } else { uint8_t buffer[2]; buffer[0] = ((code >> 8) & 0xFF); @@ -82,7 +81,6 @@ void WebSockets::clientDisconnect(WSclient_t * client, uint16_t code, char * rea * @return true if ok */ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin, bool headerToPayload) { - if(client->tcp && !client->tcp->connected()) { DEBUG_WEBSOCKETS("[WS][%d][sendFrame] not Connected!?\n", client->num); return false; @@ -100,14 +98,14 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay DEBUG_WEBSOCKETS("[WS][%d][sendFrame] text: %s\n", client->num, (payload + (headerToPayload ? 14 : 0))); } - uint8_t maskKey[4] = { 0x00, 0x00, 0x00, 0x00 }; + uint8_t maskKey[4] = { 0x00, 0x00, 0x00, 0x00 }; uint8_t buffer[WEBSOCKETS_MAX_HEADER_SIZE] = { 0 }; uint8_t headerSize; uint8_t * headerPtr; uint8_t * payloadPtr = payload; bool useInternBuffer = false; - bool ret = true; + bool ret = true; // calculate header Size if(length < 126) { @@ -127,12 +125,12 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay // try to send data in one TCP package (only if some free Heap is there) if(!headerToPayload && ((length > 0) && (length < 1400)) && (GET_FREE_HEAP > 6000)) { DEBUG_WEBSOCKETS("[WS][%d][sendFrame] pack to one TCP package...\n", client->num); - uint8_t * dataPtr = (uint8_t *) malloc(length + WEBSOCKETS_MAX_HEADER_SIZE); + uint8_t * dataPtr = (uint8_t *)malloc(length + WEBSOCKETS_MAX_HEADER_SIZE); if(dataPtr) { memcpy((dataPtr + WEBSOCKETS_MAX_HEADER_SIZE), payload, length); headerToPayload = true; useInternBuffer = true; - payloadPtr = dataPtr; + payloadPtr = dataPtr; } } #endif @@ -152,7 +150,7 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay if(fin) { *headerPtr |= bit(7); ///< set Fin } - *headerPtr |= opcode; ///< set opcode + *headerPtr |= opcode; ///< set opcode headerPtr++; // byte 1 @@ -268,10 +266,10 @@ bool WebSockets::sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * pay * @param client WSclient_t * ptr to the client struct */ void WebSockets::headerDone(WSclient_t * client) { - client->status = WSC_CONNECTED; + client->status = WSC_CONNECTED; client->cWsRXsize = 0; DEBUG_WEBSOCKETS("[WS][%d][headerDone] Header Handling Done.\n", client->num); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->cHttpLine = ""; handleWebsocket(client); #endif @@ -318,12 +316,12 @@ bool WebSockets::handleWebsocketWaitFor(WSclient_t * client, size_t size) { // timeout or error server->clientDisconnect(client, 1002); } - }, this, size, std::placeholders::_1, std::placeholders::_2)); + }, + this, size, std::placeholders::_1, std::placeholders::_2)); return false; } void WebSockets::handleWebsocketCb(WSclient_t * client) { - if(!client->tcp || !client->tcp->connected()) { return; } @@ -331,7 +329,7 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) { uint8_t * buffer = client->cWsHeader; WSMessageHeader_t * header = &client->cWsHeaderDecode; - uint8_t * payload = NULL; + uint8_t * payload = NULL; uint8_t headerLen = 2; @@ -340,15 +338,15 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) { } // split first 2 bytes in the data - header->fin = ((*buffer >> 7) & 0x01); - header->rsv1 = ((*buffer >> 6) & 0x01); - header->rsv2 = ((*buffer >> 5) & 0x01); - header->rsv3 = ((*buffer >> 4) & 0x01); - header->opCode = (WSopcode_t) (*buffer & 0x0F); + header->fin = ((*buffer >> 7) & 0x01); + header->rsv1 = ((*buffer >> 6) & 0x01); + header->rsv2 = ((*buffer >> 5) & 0x01); + header->rsv3 = ((*buffer >> 4) & 0x01); + header->opCode = (WSopcode_t)(*buffer & 0x0F); buffer++; - header->mask = ((*buffer >> 7) & 0x01); - header->payloadLen = (WSopcode_t) (*buffer & 0x7F); + header->mask = ((*buffer >> 7) & 0x01); + header->payloadLen = (WSopcode_t)(*buffer & 0x7F); buffer++; if(header->payloadLen == 126) { @@ -395,7 +393,7 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) { if(header->payloadLen > 0) { // if text data we need one more - payload = (uint8_t *) malloc(header->payloadLen + 1); + payload = (uint8_t *)malloc(header->payloadLen + 1); if(!payload) { DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] to less memory to handle payload %d!\n", client->num, header->payloadLen); @@ -409,7 +407,6 @@ void WebSockets::handleWebsocketCb(WSclient_t * client) { } void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload) { - WSMessageHeader_t * header = &client->cWsHeaderDecode; if(ok) { if(header->payloadLen > 0) { @@ -433,22 +430,22 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t break; case WSop_ping: // send pong back - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] ping received (%s)\n", client->num, payload ? (const char*)payload : ""); + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] ping received (%s)\n", client->num, payload ? (const char *)payload : ""); sendFrame(client, WSop_pong, payload, header->payloadLen); messageReceived(client, header->opCode, payload, header->payloadLen, header->fin); break; case WSop_pong: - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload ? (const char*)payload : ""); + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get pong (%s)\n", client->num, payload ? (const char *)payload : ""); client->pongReceived = true; messageReceived(client, header->opCode, payload, header->payloadLen, header->fin); break; case WSop_close: { - #ifndef NODEBUG_WEBSOCKETS - uint16_t reasonCode = 1000; - if(header->payloadLen >= 2) { - reasonCode = payload[0] << 8 | payload[1]; - } - #endif +#ifndef NODEBUG_WEBSOCKETS + uint16_t reasonCode = 1000; + if(header->payloadLen >= 2) { + reasonCode = payload[0] << 8 | payload[1]; + } +#endif DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get ask for close. Code: %d", client->num, reasonCode); if(header->payloadLen > 2) { DEBUG_WEBSOCKETS(" (%s)\n", (payload + 2)); @@ -456,8 +453,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t DEBUG_WEBSOCKETS("\n"); } clientDisconnect(client, 1000); - } - break; + } break; default: clientDisconnect(client, 1002); break; @@ -469,7 +465,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t // reset input client->cWsRXsize = 0; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) //register callback for next message handleWebsocketWaitFor(client, 2); #endif @@ -492,12 +488,12 @@ String WebSockets::acceptKey(String & clientKey) { sha1(clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", &sha1HashBin[0]); #elif defined(ESP32) String data = clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - esp_sha(SHA1, (unsigned char*)data.c_str(), data.length(), &sha1HashBin[0]); + esp_sha(SHA1, (unsigned char *)data.c_str(), data.length(), &sha1HashBin[0]); #else clientKey += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; SHA1_CTX ctx; SHA1Init(&ctx); - SHA1Update(&ctx, (const unsigned char*)clientKey.c_str(), clientKey.length()); + SHA1Update(&ctx, (const unsigned char *)clientKey.c_str(), clientKey.length()); SHA1Final(&sha1HashBin[0], &ctx); #endif @@ -514,13 +510,13 @@ String WebSockets::acceptKey(String & clientKey) { * @return base64 encoded String */ String WebSockets::base64_encode(uint8_t * data, size_t length) { - size_t size = ((length * 1.6f) + 1); - char * buffer = (char *) malloc(size); + size_t size = ((length * 1.6f) + 1); + char * buffer = (char *)malloc(size); 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); + 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); @@ -537,7 +533,7 @@ String WebSockets::base64_encode(uint8_t * data, size_t length) { * @return true if ok */ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWaitCb cb) { -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) if(!client->tcp || !client->tcp->connected()) { return false; } @@ -546,7 +542,8 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait if(cb) { cb(client, ok); } - }, client, std::placeholders::_1, cb)); + }, + client, std::placeholders::_1, cb)); #else unsigned long t = millis(); @@ -578,13 +575,13 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait } if(!client->tcp->available()) { -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif continue; } - len = client->tcp->read((uint8_t*) out, n); + len = client->tcp->read((uint8_t *)out, n); if(len) { t = millis(); out += len; @@ -593,7 +590,7 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait } else { //DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n); } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } @@ -611,50 +608,54 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait * @param n size_t byte count * @return bytes send */ -size_t WebSockets::write(WSclient_t * client, uint8_t *out, size_t n) { - if(out == NULL) return 0; - if(client == NULL) return 0; - unsigned long t = millis(); - size_t len = 0; - size_t total = 0; - DEBUG_WEBSOCKETS("[write] n: %zu t: %lu\n", n, t); - while(n > 0) { - if(client->tcp == NULL) { - DEBUG_WEBSOCKETS("[write] tcp is null!\n"); - break; - } - - if(!client->tcp->connected()) { - DEBUG_WEBSOCKETS("[write] not connected!\n"); - break; - } - - if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) { - DEBUG_WEBSOCKETS("[write] write TIMEOUT! %lu\n", (millis() - t)); - break; - } - - len = client->tcp->write((const uint8_t*)out, n); - if(len) { - t = millis(); - out += len; - n -= len; - total += len; - //DEBUG_WEBSOCKETS("write %d left %d!\n", len, n); - } else { - //DEBUG_WEBSOCKETS("write %d failed left %d!\n", len, n); - } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - delay(0); +size_t WebSockets::write(WSclient_t * client, uint8_t * out, size_t n) { + if(out == NULL) + return 0; + if(client == NULL) + return 0; + unsigned long t = millis(); + size_t len = 0; + size_t total = 0; + DEBUG_WEBSOCKETS("[write] n: %zu t: %lu\n", n, t); + while(n > 0) { + if(client->tcp == NULL) { + DEBUG_WEBSOCKETS("[write] tcp is null!\n"); + break; + } + + if(!client->tcp->connected()) { + DEBUG_WEBSOCKETS("[write] not connected!\n"); + break; + } + + if((millis() - t) > WEBSOCKETS_TCP_TIMEOUT) { + DEBUG_WEBSOCKETS("[write] write TIMEOUT! %lu\n", (millis() - t)); + break; + } + + len = client->tcp->write((const uint8_t *)out, n); + if(len) { + t = millis(); + out += len; + n -= len; + total += len; + //DEBUG_WEBSOCKETS("write %d left %d!\n", len, n); + } else { + //DEBUG_WEBSOCKETS("write %d failed left %d!\n", len, n); + } +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + delay(0); #endif - } - return total; + } + return total; } -size_t WebSockets::write(WSclient_t * client, const char *out) { - if(client == NULL) return 0; - if(out == NULL) return 0; - return write(client, (uint8_t*)out, strlen(out)); +size_t WebSockets::write(WSclient_t * client, const char * out) { + if(client == NULL) + return 0; + if(out == NULL) + return 0; + return write(client, (uint8_t *)out, strlen(out)); } /** @@ -664,36 +665,37 @@ size_t WebSockets::write(WSclient_t * client, const char *out) { * @param pongTimeout uint32_t millis after which pong should timout if not received * @param disconnectTimeoutCount uint8_t how many timeouts before disconnect, 0=> do not disconnect */ -void WebSockets::enableHeartbeat(WSclient_t * client, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount){ - if(client == NULL) return; - client->pingInterval = pingInterval; - client->pongTimeout = pongTimeout; +void WebSockets::enableHeartbeat(WSclient_t * client, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { + if(client == NULL) + return; + client->pingInterval = pingInterval; + client->pongTimeout = pongTimeout; client->disconnectTimeoutCount = disconnectTimeoutCount; - client->pongReceived = false; + client->pongReceived = false; } /** * handle ping/pong heartbeat timeout process * @param client WSclient_t * - */ -void WebSockets::handleHBTimeout(WSclient_t * client){ - if (client->pingInterval) { // if heartbeat is enabled + */ +void WebSockets::handleHBTimeout(WSclient_t * client) { + if(client->pingInterval) { // if heartbeat is enabled uint32_t pi = millis() - client->lastPing; - if (client->pongReceived) { + if(client->pongReceived) { client->pongTimeoutCount = 0; } else { - if (pi > client->pongTimeout){ // pong not received in time + if(pi > client->pongTimeout) { // pong not received in time client->pongTimeoutCount++; - client->lastPing = millis() - client->pingInterval - 500; // force ping on the next run + client->lastPing = millis() - client->pingInterval - 500; // force ping on the next run DEBUG_WEBSOCKETS("[HBtimeout] pong TIMEOUT! lp=%d millis=%d pi=%d count=%d\n", client->lastPing, millis(), pi, client->pongTimeoutCount); - if (client->disconnectTimeoutCount && client->pongTimeoutCount >= client->disconnectTimeoutCount){ + if(client->disconnectTimeoutCount && client->pongTimeoutCount >= client->disconnectTimeoutCount) { DEBUG_WEBSOCKETS("[HBtimeout] count=%d, DISCONNECTING\n", client->pongTimeoutCount); clientDisconnect(client); } - } + } } } } diff --git a/src/WebSockets.h b/src/WebSockets.h index f9c2a94..6a749fa 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -27,7 +27,7 @@ #ifdef STM32_DEVICE #include -#define bit(b) (1UL << (b)) // Taken directly from Arduino.h +#define bit(b) (1UL << (b)) // Taken directly from Arduino.h #else #include #include @@ -40,16 +40,14 @@ #include #endif - #ifndef NODEBUG_WEBSOCKETS #ifdef DEBUG_ESP_PORT -#define DEBUG_WEBSOCKETS(...) DEBUG_ESP_PORT.printf( __VA_ARGS__ ) +#define DEBUG_WEBSOCKETS(...) DEBUG_ESP_PORT.printf(__VA_ARGS__) #else //#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) #endif #endif - #ifndef DEBUG_WEBSOCKETS #define DEBUG_WEBSOCKETS(...) #define NODEBUG_WEBSOCKETS @@ -57,7 +55,7 @@ #if defined(ESP8266) || defined(ESP32) -#define WEBSOCKETS_MAX_DATA_SIZE (15*1024) +#define WEBSOCKETS_MAX_DATA_SIZE (15 * 1024) #define WEBSOCKETS_USE_BIG_MEM #define GET_FREE_HEAP ESP.getFreeHeap() // moves all Header strings to Flash (~300 Byte) @@ -65,31 +63,30 @@ #elif defined(STM32_DEVICE) -#define WEBSOCKETS_MAX_DATA_SIZE (15*1024) +#define WEBSOCKETS_MAX_DATA_SIZE (15 * 1024) #define WEBSOCKETS_USE_BIG_MEM #define GET_FREE_HEAP System.freeMemory() #else //atmega328p has only 2KB ram! -#define WEBSOCKETS_MAX_DATA_SIZE (1024) +#define WEBSOCKETS_MAX_DATA_SIZE (1024) // moves all Header strings to Flash #define WEBSOCKETS_SAVE_RAM #endif +#define WEBSOCKETS_TCP_TIMEOUT (2000) -#define WEBSOCKETS_TCP_TIMEOUT (2000) - -#define NETWORK_ESP8266_ASYNC (0) -#define NETWORK_ESP8266 (1) -#define NETWORK_W5100 (2) -#define NETWORK_ENC28J60 (3) -#define NETWORK_ESP32 (4) -#define NETWORK_ESP32_ETH (5) +#define NETWORK_ESP8266_ASYNC (0) +#define NETWORK_ESP8266 (1) +#define NETWORK_W5100 (2) +#define NETWORK_ENC28J60 (3) +#define NETWORK_ESP32 (4) +#define NETWORK_ESP32_ETH (5) // max size of the WS Message Header -#define WEBSOCKETS_MAX_HEADER_SIZE (14) +#define WEBSOCKETS_MAX_HEADER_SIZE (14) #if !defined(WEBSOCKETS_NETWORK_TYPE) // select Network type based @@ -108,13 +105,12 @@ #endif // Includes and defined based on Network Type -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) // Note: // No SSL/WSS support for client in Async mode // TLS lib need a sync interface! - #if defined(ESP8266) #include #elif defined(ESP32) @@ -131,7 +127,7 @@ #define WEBSOCKETS_NETWORK_CLASS AsyncTCPbuffer #define WEBSOCKETS_NETWORK_SERVER_CLASS AsyncServer -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) #if !defined(ESP8266) && !defined(ESP31B) #error "network type ESP8266 only possible on the ESP mcu!" @@ -146,7 +142,7 @@ #define WEBSOCKETS_NETWORK_SSL_CLASS WiFiClientSecure #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_W5100) +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_W5100) #ifdef STM32_DEVICE #define WEBSOCKETS_NETWORK_CLASS TCPClient @@ -158,13 +154,13 @@ #define WEBSOCKETS_NETWORK_SERVER_CLASS EthernetServer #endif -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ENC28J60) +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ENC28J60) #include #define WEBSOCKETS_NETWORK_CLASS UIPClient #define WEBSOCKETS_NETWORK_SERVER_CLASS UIPServer -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) #include #include @@ -172,7 +168,7 @@ #define WEBSOCKETS_NETWORK_SSL_CLASS WiFiClientSecure #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32_ETH) +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32_ETH) #include #define WEBSOCKETS_NETWORK_CLASS WiFiClient @@ -182,16 +178,15 @@ #error "no network type selected!" #endif - #ifdef WEBSOCKETS_NETWORK_SSL_CLASS #define HAS_SSL #endif // moves all Header strings to Flash (~300 Byte) #ifdef WEBSOCKETS_SAVE_RAM -#define WEBSOCKETS_STRING(var) F(var) +#define WEBSOCKETS_STRING(var) F(var) #else -#define WEBSOCKETS_STRING(var) var +#define WEBSOCKETS_STRING(var) var #endif typedef enum { @@ -206,130 +201,125 @@ typedef enum { WStype_CONNECTED, WStype_TEXT, WStype_BIN, - WStype_FRAGMENT_TEXT_START, - WStype_FRAGMENT_BIN_START, - WStype_FRAGMENT, - WStype_FRAGMENT_FIN, - WStype_PING, - WStype_PONG, + WStype_FRAGMENT_TEXT_START, + WStype_FRAGMENT_BIN_START, + WStype_FRAGMENT, + WStype_FRAGMENT_FIN, + WStype_PING, + WStype_PONG, } WStype_t; typedef enum { - WSop_continuation = 0x00, ///< %x0 denotes a continuation frame - WSop_text = 0x01, ///< %x1 denotes a text frame - WSop_binary = 0x02, ///< %x2 denotes a binary frame - ///< %x3-7 are reserved for further non-control frames - WSop_close = 0x08, ///< %x8 denotes a connection close - WSop_ping = 0x09, ///< %x9 denotes a ping - WSop_pong = 0x0A ///< %xA denotes a pong - ///< %xB-F are reserved for further control frames + WSop_continuation = 0x00, ///< %x0 denotes a continuation frame + WSop_text = 0x01, ///< %x1 denotes a text frame + WSop_binary = 0x02, ///< %x2 denotes a binary frame + ///< %x3-7 are reserved for further non-control frames + WSop_close = 0x08, ///< %x8 denotes a connection close + WSop_ping = 0x09, ///< %x9 denotes a ping + WSop_pong = 0x0A ///< %xA denotes a pong + ///< %xB-F are reserved for further control frames } WSopcode_t; typedef struct { + bool fin; + bool rsv1; + bool rsv2; + bool rsv3; - bool fin; - bool rsv1; - bool rsv2; - bool rsv3; + WSopcode_t opCode; + bool mask; - WSopcode_t opCode; - bool mask; + size_t payloadLen; - size_t payloadLen; - - uint8_t * maskKey; + uint8_t * maskKey; } WSMessageHeader_t; typedef struct { - uint8_t num; ///< connection number + uint8_t num; ///< connection number - WSclientsStatus_t status; + WSclientsStatus_t status; - WEBSOCKETS_NETWORK_CLASS * tcp; + WEBSOCKETS_NETWORK_CLASS * tcp; - bool isSocketIO; ///< client for socket.io server + bool isSocketIO; ///< client for socket.io server #if defined(HAS_SSL) - bool isSSL; ///< run in ssl mode - WEBSOCKETS_NETWORK_SSL_CLASS * ssl; + bool isSSL; ///< run in ssl mode + WEBSOCKETS_NETWORK_SSL_CLASS * ssl; #endif - String cUrl; ///< http url - uint16_t cCode; ///< http code + String cUrl; ///< http url + uint16_t cCode; ///< http code - bool cIsClient = false; ///< will be used for masking - bool cIsUpgrade; ///< Connection == Upgrade - bool cIsWebsocket; ///< Upgrade == websocket + bool cIsClient = false; ///< will be used for masking + bool cIsUpgrade; ///< Connection == Upgrade + bool cIsWebsocket; ///< Upgrade == websocket - String cSessionId; ///< client Set-Cookie (session id) - String cKey; ///< client Sec-WebSocket-Key - String cAccept; ///< client Sec-WebSocket-Accept - String cProtocol; ///< client Sec-WebSocket-Protocol - String cExtensions; ///< client Sec-WebSocket-Extensions - uint16_t cVersion; ///< client Sec-WebSocket-Version + String cSessionId; ///< client Set-Cookie (session id) + String cKey; ///< client Sec-WebSocket-Key + String cAccept; ///< client Sec-WebSocket-Accept + String cProtocol; ///< client Sec-WebSocket-Protocol + String cExtensions; ///< client Sec-WebSocket-Extensions + uint16_t cVersion; ///< client Sec-WebSocket-Version - uint8_t cWsRXsize; ///< State of the RX - uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer - WSMessageHeader_t cWsHeaderDecode; + uint8_t cWsRXsize; ///< State of the RX + uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer + WSMessageHeader_t cWsHeaderDecode; - String base64Authorization; ///< Base64 encoded Auth request - String plainAuthorization; ///< Base64 encoded Auth request + String base64Authorization; ///< Base64 encoded Auth request + String plainAuthorization; ///< Base64 encoded Auth request - String extraHeaders; + String extraHeaders; - bool cHttpHeadersValid; ///< non-websocket http header validity indicator - size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count + bool cHttpHeadersValid; ///< non-websocket http header validity indicator + size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count - bool pongReceived; - uint32_t pingInterval; // how often ping will be sent, 0 means "heartbeat is not active" - uint32_t lastPing; // millis when last pong has been received - uint32_t pongTimeout; // interval in millis after which pong is considered to timeout - uint8_t disconnectTimeoutCount; // after how many subsequent pong timeouts discconnect will happen, 0 means "do not disconnect" - uint8_t pongTimeoutCount; // current pong timeout count + bool pongReceived; + uint32_t pingInterval; // how often ping will be sent, 0 means "heartbeat is not active" + uint32_t lastPing; // millis when last pong has been received + uint32_t pongTimeout; // interval in millis after which pong is considered to timeout + uint8_t disconnectTimeoutCount; // after how many subsequent pong timeouts discconnect will happen, 0 means "do not disconnect" + uint8_t pongTimeoutCount; // current pong timeout count -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) - String cHttpLine; ///< HTTP header lines +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + String cHttpLine; ///< HTTP header lines #endif } WSclient_t; - - class WebSockets { - protected: + protected: #ifdef __AVR__ - typedef void (*WSreadWaitCb)(WSclient_t * client, bool ok); + typedef void (*WSreadWaitCb)(WSclient_t * client, bool ok); #else - typedef std::function WSreadWaitCb; + typedef std::function WSreadWaitCb; #endif - virtual void clientDisconnect(WSclient_t * client) = 0; - virtual bool clientIsConnected(WSclient_t * client) = 0; - - virtual void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) = 0; - - void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0); - bool sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool fin = true, bool headerToPayload = false); + virtual void clientDisconnect(WSclient_t * client) = 0; + virtual bool clientIsConnected(WSclient_t * client) = 0; - void headerDone(WSclient_t * client); + virtual void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) = 0; - void handleWebsocket(WSclient_t * client); + void clientDisconnect(WSclient_t * client, uint16_t code, char * reason = NULL, size_t reasonLen = 0); + bool sendFrame(WSclient_t * client, WSopcode_t opcode, uint8_t * payload = NULL, size_t length = 0, bool fin = true, bool headerToPayload = false); - bool handleWebsocketWaitFor(WSclient_t * client, size_t size); - void handleWebsocketCb(WSclient_t * client); - void handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload); + void headerDone(WSclient_t * client); - String acceptKey(String & clientKey); - String base64_encode(uint8_t * data, size_t length); + void handleWebsocket(WSclient_t * client); - bool readCb(WSclient_t * client, uint8_t *out, size_t n, WSreadWaitCb cb); - virtual size_t write(WSclient_t * client, uint8_t *out, size_t n); - size_t write(WSclient_t * client, const char *out); + bool handleWebsocketWaitFor(WSclient_t * client, size_t size); + void handleWebsocketCb(WSclient_t * client); + void handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload); - void enableHeartbeat(WSclient_t * client, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); - void handleHBTimeout(WSclient_t * client); + String acceptKey(String & clientKey); + String base64_encode(uint8_t * data, size_t length); + bool readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWaitCb cb); + virtual size_t write(WSclient_t * client, uint8_t * out, size_t n); + size_t write(WSclient_t * client, const char * out); + void enableHeartbeat(WSclient_t * client, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); + void handleHBTimeout(WSclient_t * client); }; #ifndef UNUSED diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 0002561..8d48ccd 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -26,9 +26,9 @@ #include "WebSocketsClient.h" WebSocketsClient::WebSocketsClient() { - _cbEvent = NULL; - _client.num = 0; - _client.cIsClient = true; + _cbEvent = NULL; + _client.num = 0; + _client.cIsClient = true; _client.extraHeaders = WEBSOCKETS_STRING("Origin: file://"); } @@ -39,37 +39,37 @@ WebSocketsClient::~WebSocketsClient() { /** * calles to init the Websockets server */ -void WebSocketsClient::begin(const char *host, uint16_t port, const char * url, const char * protocol) { +void WebSocketsClient::begin(const char * host, uint16_t port, const char * url, const char * protocol) { _host = host; _port = port; #if defined(HAS_SSL) _fingerprint = ""; - _CA_cert = NULL; + _CA_cert = NULL; #endif - _client.num = 0; + _client.num = 0; _client.status = WSC_NOT_CONNECTED; - _client.tcp = NULL; + _client.tcp = NULL; #if defined(HAS_SSL) _client.isSSL = false; - _client.ssl = NULL; + _client.ssl = NULL; #endif - _client.cUrl = url; - _client.cCode = 0; - _client.cIsUpgrade = false; - _client.cIsWebsocket = true; - _client.cKey = ""; - _client.cAccept = ""; - _client.cProtocol = protocol; - _client.cExtensions = ""; - _client.cVersion = 0; + _client.cUrl = url; + _client.cCode = 0; + _client.cIsUpgrade = false; + _client.cIsWebsocket = true; + _client.cKey = ""; + _client.cAccept = ""; + _client.cProtocol = protocol; + _client.cExtensions = ""; + _client.cVersion = 0; _client.base64Authorization = ""; - _client.plainAuthorization = ""; - _client.isSocketIO = false; + _client.plainAuthorization = ""; + _client.isSocketIO = false; - _client.lastPing = 0; - _client.pongReceived = false; - _client.pongTimeoutCount = 0; + _client.lastPing = 0; + _client.pongReceived = false; + _client.pongTimeoutCount = 0; #ifdef ESP8266 randomSeed(RANDOM_REG32); @@ -77,12 +77,12 @@ void WebSocketsClient::begin(const char *host, uint16_t port, const char * url, // todo find better seed randomSeed(millis()); #endif -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) asyncConnect(); #endif _lastConnectionFail = 0; - _reconnectInterval = 500; + _reconnectInterval = 500; } void WebSocketsClient::begin(String host, uint16_t port, String url, String protocol) { @@ -94,26 +94,26 @@ void WebSocketsClient::begin(IPAddress host, uint16_t port, const char * url, co } #if defined(HAS_SSL) -void WebSocketsClient::beginSSL(const char *host, uint16_t port, const char * url, const char * fingerprint, const char * protocol) { +void WebSocketsClient::beginSSL(const char * host, uint16_t port, const char * url, const char * fingerprint, const char * protocol) { begin(host, port, url, protocol); _client.isSSL = true; - _fingerprint = fingerprint; - _CA_cert = NULL; + _fingerprint = fingerprint; + _CA_cert = NULL; } void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String fingerprint, String protocol) { beginSSL(host.c_str(), port, url.c_str(), fingerprint.c_str(), protocol.c_str()); } -void WebSocketsClient::beginSslWithCA(const char *host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { +void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { begin(host, port, url, protocol); _client.isSSL = true; - _fingerprint = ""; - _CA_cert = CA_cert; + _fingerprint = ""; + _CA_cert = CA_cert; } #endif -void WebSocketsClient::beginSocketIO(const char *host, uint16_t port, const char * url, const char * protocol) { +void WebSocketsClient::beginSocketIO(const char * host, uint16_t port, const char * url, const char * protocol) { begin(host, port, url, protocol); _client.isSocketIO = true; } @@ -123,27 +123,27 @@ void WebSocketsClient::beginSocketIO(String host, uint16_t port, String url, Str } #if defined(HAS_SSL) -void WebSocketsClient::beginSocketIOSSL(const char *host, uint16_t port, const char * url, const char * protocol) { +void WebSocketsClient::beginSocketIOSSL(const char * host, uint16_t port, const char * url, const char * protocol) { begin(host, port, url, protocol); _client.isSocketIO = true; - _client.isSSL = true; - _fingerprint = ""; + _client.isSSL = true; + _fingerprint = ""; } void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url, String protocol) { beginSocketIOSSL(host.c_str(), port, url.c_str(), protocol.c_str()); } -void WebSocketsClient::beginSocketIOSSLWithCA(const char *host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { +void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { begin(host, port, url, protocol); _client.isSocketIO = true; - _client.isSSL = true; - _fingerprint = ""; - _CA_cert = CA_cert; + _client.isSSL = true; + _fingerprint = ""; + _CA_cert = CA_cert; } #endif -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * called in arduino loop */ @@ -169,7 +169,7 @@ void WebSocketsClient::loop(void) { #if defined(ESP32) _client.ssl->setCACert(_CA_cert); #elif defined(ESP8266) - _client.ssl->setCACert((const uint8_t *)_CA_cert, strlen(_CA_cert) + 1); + _client.ssl->setCACert((const uint8_t *)_CA_cert, strlen(_CA_cert) + 1); #else #error setCACert not implemented #endif @@ -197,16 +197,14 @@ void WebSocketsClient::loop(void) { } else { connectFailedCb(); _lastConnectionFail = millis(); - } } else { handleClientData(); - if (_client.status == WSC_CONNECTED){ + if(_client.status == WSC_CONNECTED) { handleHBPing(); handleHBTimeout(&_client); } - } } #endif @@ -229,7 +227,7 @@ void WebSocketsClient::onEvent(WebSocketClientEvent cbEvent) { */ bool WebSocketsClient::sendTXT(uint8_t * payload, size_t length, bool headerToPayload) { if(length == 0) { - length = strlen((const char *) payload); + length = strlen((const char *)payload); } if(clientIsConnected(&_client)) { return sendFrame(&_client, WSop_text, payload, length, true, headerToPayload); @@ -238,19 +236,19 @@ bool WebSocketsClient::sendTXT(uint8_t * payload, size_t length, bool headerToPa } bool WebSocketsClient::sendTXT(const uint8_t * payload, size_t length) { - return sendTXT((uint8_t *) payload, length); + return sendTXT((uint8_t *)payload, length); } bool WebSocketsClient::sendTXT(char * payload, size_t length, bool headerToPayload) { - return sendTXT((uint8_t *) payload, length, headerToPayload); + return sendTXT((uint8_t *)payload, length, headerToPayload); } bool WebSocketsClient::sendTXT(const char * payload, size_t length) { - return sendTXT((uint8_t *) payload, length); + return sendTXT((uint8_t *)payload, length); } bool WebSocketsClient::sendTXT(String & payload) { - return sendTXT((uint8_t *) payload.c_str(), payload.length()); + return sendTXT((uint8_t *)payload.c_str(), payload.length()); } /** @@ -269,7 +267,7 @@ bool WebSocketsClient::sendBIN(uint8_t * payload, size_t length, bool headerToPa } bool WebSocketsClient::sendBIN(const uint8_t * payload, size_t length) { - return sendBIN((uint8_t *) payload, length); + return sendBIN((uint8_t *)payload, length); } /** @@ -281,7 +279,7 @@ bool WebSocketsClient::sendBIN(const uint8_t * payload, size_t length) { bool WebSocketsClient::sendPing(uint8_t * payload, size_t length) { if(clientIsConnected(&_client)) { bool sent = sendFrame(&_client, WSop_ping, payload, length); - if (sent) + if(sent) _client.lastPing = millis(); return sent; } @@ -289,7 +287,7 @@ bool WebSocketsClient::sendPing(uint8_t * payload, size_t length) { } bool WebSocketsClient::sendPing(String & payload) { - return sendPing((uint8_t *) payload.c_str(), payload.length()); + return sendPing((uint8_t *)payload.c_str(), payload.length()); } /** @@ -312,7 +310,7 @@ void WebSocketsClient::setAuthorization(const char * user, const char * password String auth = user; auth += ":"; auth += password; - _client.base64Authorization = base64_encode((uint8_t *) auth.c_str(), auth.length()); + _client.base64Authorization = base64_encode((uint8_t *)auth.c_str(), auth.length()); } } @@ -383,7 +381,6 @@ void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, u } runCbEvent(type, payload, length); - } /** @@ -391,10 +388,9 @@ void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, u * @param client WSclient_t * ptr to the client struct */ void WebSocketsClient::clientDisconnect(WSclient_t * client) { - bool event = false; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) if(client->isSSL && client->ssl) { if(client->ssl->connected()) { client->ssl->flush(); @@ -409,13 +405,13 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { if(client->tcp) { if(client->tcp->connected()) { -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) client->tcp->flush(); #endif client->tcp->stop(); } event = true; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->status = WSC_NOT_CONNECTED; #else delete client->tcp; @@ -423,13 +419,13 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { client->tcp = NULL; } - client->cCode = 0; - client->cKey = ""; - client->cAccept = ""; - client->cVersion = 0; - client->cIsUpgrade = false; + client->cCode = 0; + client->cKey = ""; + client->cAccept = ""; + client->cVersion = 0; + client->cIsUpgrade = false; client->cIsWebsocket = false; - client->cSessionId = ""; + client->cSessionId = ""; client->status = WSC_NOT_CONNECTED; @@ -445,7 +441,6 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { * @return true = conneted */ bool WebSocketsClient::clientIsConnected(WSclient_t * client) { - if(!client->tcp) { return false; } @@ -470,7 +465,7 @@ bool WebSocketsClient::clientIsConnected(WSclient_t * client) { return false; } -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * Handel incomming data from Client */ @@ -481,8 +476,7 @@ void WebSocketsClient::handleClientData(void) { case WSC_HEADER: { String headerLine = _client.tcp->readStringUntil('\n'); handleHeader(&_client, &headerLine); - } - break; + } break; case WSC_CONNECTED: WebSockets::handleWebsocket(&_client); break; @@ -491,7 +485,7 @@ void WebSocketsClient::handleClientData(void) { break; } } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) delay(0); #endif } @@ -502,7 +496,6 @@ void WebSocketsClient::handleClientData(void) { * @param client WSclient_t * ptr to the client struct */ void WebSocketsClient::sendHeader(WSclient_t * client) { - static const char * NEW_LINE = "\r\n"; DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header...\n"); @@ -521,7 +514,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { String handshake; bool ws_header = true; - String url = client->cUrl; + String url = client->cUrl; if(client->isSocketIO) { if(client->cSessionId.length() == 0) { @@ -534,15 +527,17 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { } handshake = WEBSOCKETS_STRING("GET "); - handshake += url + WEBSOCKETS_STRING(" HTTP/1.1\r\n" - "Host: "); + handshake += url + WEBSOCKETS_STRING( + " HTTP/1.1\r\n" + "Host: "); handshake += _host + ":" + _port + NEW_LINE; if(ws_header) { - handshake += WEBSOCKETS_STRING("Connection: Upgrade\r\n" - "Upgrade: websocket\r\n" - "Sec-WebSocket-Version: 13\r\n" - "Sec-WebSocket-Key: "); + handshake += WEBSOCKETS_STRING( + "Connection: Upgrade\r\n" + "Upgrade: websocket\r\n" + "Sec-WebSocket-Version: 13\r\n" + "Sec-WebSocket-Key: "); handshake += client->cKey + NEW_LINE; if(client->cProtocol.length() > 0) { @@ -577,15 +572,14 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { handshake += NEW_LINE; - DEBUG_WEBSOCKETS("[WS-Client][sendHeader] handshake %s", (uint8_t* )handshake.c_str()); - write(client, (uint8_t*) handshake.c_str(), handshake.length()); + DEBUG_WEBSOCKETS("[WS-Client][sendHeader] handshake %s", (uint8_t *)handshake.c_str()); + write(client, (uint8_t *)handshake.c_str(), handshake.length()); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine))); #endif DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header... Done (%luus).\n", (micros() - start)); - } /** @@ -593,8 +587,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { * @param client WSclient_t * ptr to the client struct */ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { - - headerLine->trim(); // remove \r + headerLine->trim(); // remove \r if(headerLine->length() > 0) { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str()); @@ -603,7 +596,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { // "HTTP/1.1 101 Switching Protocols" client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt(); } else if(headerLine->indexOf(':') >= 0) { - String headerName = headerLine->substring(0, headerLine->indexOf(':')); + String headerName = headerLine->substring(0, headerLine->indexOf(':')); String headerValue = headerLine->substring(headerLine->indexOf(':') + 1); // remove space in the beginning (RFC2616) @@ -621,7 +614,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Accept"))) { client->cAccept = headerValue; - client->cAccept.trim(); // see rfc6455 + client->cAccept.trim(); // see rfc6455 } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) { client->cProtocol = headerValue; } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) { @@ -640,10 +633,9 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } (*headerLine) = ""; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsClient::handleHeader, this, client, &(client->cHttpLine))); #endif - } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header read fin.\n"); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Client settings:\n"); @@ -665,16 +657,16 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { if(ok) { switch(client->cCode) { - case 101: ///< Switching Protocols + case 101: ///< Switching Protocols break; case 200: if(client->isSocketIO) { break; } - case 403: ///< Forbidden + case 403: ///< Forbidden // todo handle login - default: ///< Server dont unterstand requrst + default: ///< Server dont unterstand requrst ok = false; DEBUG_WEBSOCKETS("[WS-Client][handleHeader] serverCode is not 101 (%d)\n", client->cCode); clientDisconnect(client); @@ -684,7 +676,6 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } if(ok) { - if(client->cAccept.length() == 0) { ok = false; } else { @@ -698,12 +689,10 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } if(ok) { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Websocket connection init done.\n"); headerDone(client); - runCbEvent(WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length()); - + runCbEvent(WStype_CONNECTED, (uint8_t *)client->cUrl.c_str(), client->cUrl.length()); } else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) { sendHeader(client); } else { @@ -718,30 +707,30 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } void WebSocketsClient::connectedCb() { - DEBUG_WEBSOCKETS("[WS-Client] connected to %s:%u.\n", _host.c_str(), _port); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) _client.tcp->onDisconnect(std::bind([](WebSocketsClient * c, AsyncTCPbuffer * obj, WSclient_t * client) -> bool { - DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num); - client->status = WSC_NOT_CONNECTED; - client->tcp = NULL; + DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num); + client->status = WSC_NOT_CONNECTED; + client->tcp = NULL; - // reconnect - c->asyncConnect(); + // reconnect + c->asyncConnect(); - return true; - }, this, std::placeholders::_1, &_client)); + return true; + }, + this, std::placeholders::_1, &_client)); #endif _client.status = WSC_HEADER; -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) // set Timeout for readBytesUntil and readStringUntil _client.tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); #endif -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32 +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) _client.tcp->setNoDelay(true); #endif @@ -761,17 +750,15 @@ void WebSocketsClient::connectedCb() { // send Header to Server sendHeader(&_client); - } void WebSocketsClient::connectFailedCb() { DEBUG_WEBSOCKETS("[WS-Client] connection to %s:%u Failed\n", _host.c_str(), _port); } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) void WebSocketsClient::asyncConnect() { - DEBUG_WEBSOCKETS("[WS-Client] asyncConnect...\n"); AsyncClient * tcpclient = new AsyncClient(); @@ -781,51 +768,52 @@ void WebSocketsClient::asyncConnect() { return; } - tcpclient->onDisconnect([](void *obj, AsyncClient* c) { - c->free(); - delete c; - }); + tcpclient->onDisconnect([](void * obj, AsyncClient * c) { + c->free(); + delete c; + }); - tcpclient->onConnect(std::bind([](WebSocketsClient * ws , AsyncClient * tcp) { - ws->_client.tcp = new AsyncTCPbuffer(tcp); - if(!ws->_client.tcp) { - DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!\n"); - ws->connectFailedCb(); - return; - } - ws->connectedCb(); - }, this, std::placeholders::_2)); + tcpclient->onConnect(std::bind([](WebSocketsClient * ws, AsyncClient * tcp) { + ws->_client.tcp = new AsyncTCPbuffer(tcp); + if(!ws->_client.tcp) { + DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!\n"); + ws->connectFailedCb(); + return; + } + ws->connectedCb(); + }, + this, std::placeholders::_2)); - tcpclient->onError(std::bind([](WebSocketsClient * ws , AsyncClient * tcp) { - ws->connectFailedCb(); + tcpclient->onError(std::bind([](WebSocketsClient * ws, AsyncClient * tcp) { + ws->connectFailedCb(); - // reconnect - ws->asyncConnect(); - }, this, std::placeholders::_2)); + // reconnect + ws->asyncConnect(); + }, + this, std::placeholders::_2)); if(!tcpclient->connect(_host.c_str(), _port)) { connectFailedCb(); delete tcpclient; } - } #endif /** * send heartbeat ping to server in set intervals - */ -void WebSocketsClient::handleHBPing(){ - if (_client.pingInterval == 0) return; + */ +void WebSocketsClient::handleHBPing() { + if(_client.pingInterval == 0) + return; uint32_t pi = millis() - _client.lastPing; - if (pi > _client.pingInterval){ + if(pi > _client.pingInterval) { DEBUG_WEBSOCKETS("[WS-Client] sending HB ping\n"); - if (sendPing()) { - _client.lastPing = millis(); + if(sendPing()) { + _client.lastPing = millis(); _client.pongReceived = false; } } - } /** @@ -834,13 +822,13 @@ void WebSocketsClient::handleHBPing(){ * @param pongTimeout uint32_t millis after which pong should timout if not received * @param disconnectTimeoutCount uint8_t how many timeouts before disconnect, 0=> do not disconnect */ -void WebSocketsClient::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount){ +void WebSocketsClient::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { WebSockets::enableHeartbeat(&_client, pingInterval, pongTimeout, disconnectTimeoutCount); } /** * disable ping/pong heartbeat process */ -void WebSocketsClient::disableHeartbeat(){ +void WebSocketsClient::disableHeartbeat() { _client.pingInterval = 0; } diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 07c82d1..557a6d7 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -27,118 +27,116 @@ #include "WebSockets.h" -class WebSocketsClient: private WebSockets { - public: +class WebSocketsClient : private WebSockets { + public: #ifdef __AVR__ - typedef void (*WebSocketClientEvent)(WStype_t type, uint8_t * payload, size_t length); + typedef void (*WebSocketClientEvent)(WStype_t type, uint8_t * payload, size_t length); #else - typedef std::function WebSocketClientEvent; + typedef std::function WebSocketClientEvent; #endif + WebSocketsClient(void); + virtual ~WebSocketsClient(void); - WebSocketsClient(void); - virtual ~WebSocketsClient(void); - - void begin(const char *host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); - void begin(String host, uint16_t port, String url = "/", String protocol = "arduino"); - void begin(IPAddress host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); + void begin(const char * host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); + void begin(String host, uint16_t port, String url = "/", String protocol = "arduino"); + void begin(IPAddress host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); #if defined(HAS_SSL) - void beginSSL(const char *host, uint16_t port, const char * url = "/", const char * = "", const char * protocol = "arduino"); - void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino"); - void beginSslWithCA(const char *host, uint16_t port, const char * url = "/", const char * CA_cert = NULL, const char * protocol = "arduino"); + void beginSSL(const char * host, uint16_t port, const char * url = "/", const char * = "", const char * protocol = "arduino"); + void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino"); + void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", const char * CA_cert = NULL, const char * protocol = "arduino"); #endif - void beginSocketIO(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); - void beginSocketIO(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); + void beginSocketIO(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); + void beginSocketIO(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); #if defined(HAS_SSL) - void beginSocketIOSSL(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); - void beginSocketIOSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); - void beginSocketIOSSLWithCA(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino"); + void beginSocketIOSSL(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); + void beginSocketIOSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); + void beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino"); #endif -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) - void loop(void); +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) + void loop(void); #else - // Async interface not need a loop call - void loop(void) __attribute__ ((deprecated)) {} + // Async interface not need a loop call + void loop(void) __attribute__((deprecated)) {} #endif - void onEvent(WebSocketClientEvent cbEvent); + void onEvent(WebSocketClientEvent cbEvent); + + bool sendTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); + bool sendTXT(const uint8_t * payload, size_t length = 0); + bool sendTXT(char * payload, size_t length = 0, bool headerToPayload = false); + bool sendTXT(const char * payload, size_t length = 0); + bool sendTXT(String & payload); - bool sendTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); - bool sendTXT(const uint8_t * payload, size_t length = 0); - bool sendTXT(char * payload, size_t length = 0, bool headerToPayload = false); - bool sendTXT(const char * payload, size_t length = 0); - bool sendTXT(String & payload); + bool sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false); + bool sendBIN(const uint8_t * payload, size_t length); - bool sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false); - bool sendBIN(const uint8_t * payload, size_t length); + bool sendPing(uint8_t * payload = NULL, size_t length = 0); + bool sendPing(String & payload); - bool sendPing(uint8_t * payload = NULL, size_t length = 0); - bool sendPing(String & payload); + void disconnect(void); - void disconnect(void); + void setAuthorization(const char * user, const char * password); + void setAuthorization(const char * auth); - void setAuthorization(const char * user, const char * password); - void setAuthorization(const char * auth); - - void setExtraHeaders(const char * extraHeaders = NULL); + void setExtraHeaders(const char * extraHeaders = NULL); - void setReconnectInterval(unsigned long time); + void setReconnectInterval(unsigned long time); - void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); - void disableHeartbeat(); + void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); + void disableHeartbeat(); - protected: - String _host; - uint16_t _port; + protected: + String _host; + uint16_t _port; #if defined(HAS_SSL) - String _fingerprint; - const char *_CA_cert; + String _fingerprint; + const char * _CA_cert; #endif - WSclient_t _client; + WSclient_t _client; - WebSocketClientEvent _cbEvent; + WebSocketClientEvent _cbEvent; - unsigned long _lastConnectionFail; - unsigned long _reconnectInterval; + unsigned long _lastConnectionFail; + unsigned long _reconnectInterval; - void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); + void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); - void clientDisconnect(WSclient_t * client); - bool clientIsConnected(WSclient_t * client); + void clientDisconnect(WSclient_t * client); + bool clientIsConnected(WSclient_t * client); -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) - void handleClientData(void); +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) + void handleClientData(void); #endif - void sendHeader(WSclient_t * client); - void handleHeader(WSclient_t * client, String * headerLine); + void sendHeader(WSclient_t * client); + void handleHeader(WSclient_t * client, String * headerLine); - void connectedCb(); - void connectFailedCb(); + void connectedCb(); + void connectFailedCb(); - void handleHBPing(); // send ping in specified intervals + void handleHBPing(); // send ping in specified intervals -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) - void asyncConnect(); +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + void asyncConnect(); #endif - /** + /** * called for sending a Event to the app * @param type WStype_t * @param payload uint8_t * * @param length size_t */ - virtual void runCbEvent(WStype_t type, uint8_t * payload, size_t length) { - if(_cbEvent) { - _cbEvent(type, payload, length); - } + virtual void runCbEvent(WStype_t type, uint8_t * payload, size_t length) { + if(_cbEvent) { + _cbEvent(type, payload, length); } - + } }; #endif /* WEBSOCKETSCLIENT_H_ */ diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index a6492c0..b05dc5e 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -26,34 +26,34 @@ #include "WebSocketsServer.h" WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol) { - _port = port; - _origin = origin; + _port = port; + _origin = origin; _protocol = protocol; _runnning = false; _server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) - _server->onClient([](void *s, AsyncClient* c){ - ((WebSocketsServer*)s)->newClient(new AsyncTCPbuffer(c)); - }, this); +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + _server->onClient([](void * s, AsyncClient * c) { + ((WebSocketsServer *)s)->newClient(new AsyncTCPbuffer(c)); + }, + this); #endif _cbEvent = NULL; _httpHeaderValidationFunc = NULL; - _mandatoryHttpHeaders = NULL; + _mandatoryHttpHeaders = NULL; _mandatoryHttpHeaderCount = 0; memset(&_clients[0], 0x00, (sizeof(WSclient_t) * WEBSOCKETS_SERVER_CLIENT_MAX)); } - WebSocketsServer::~WebSocketsServer() { // disconnect all clients - close(); + close(); - if (_mandatoryHttpHeaders) + if(_mandatoryHttpHeaders) delete[] _mandatoryHttpHeaders; _mandatoryHttpHeaderCount = 0; @@ -69,26 +69,26 @@ void WebSocketsServer::begin(void) { for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { client = &_clients[i]; - client->num = i; + client->num = i; client->status = WSC_NOT_CONNECTED; - client->tcp = NULL; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) + client->tcp = NULL; +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) client->isSSL = false; - client->ssl = NULL; + client->ssl = NULL; #endif - client->cUrl = ""; - client->cCode = 0; - client->cKey = ""; - client->cProtocol = ""; - client->cVersion = 0; - client->cIsUpgrade = false; + client->cUrl = ""; + client->cCode = 0; + client->cKey = ""; + client->cProtocol = ""; + client->cVersion = 0; + client->cIsUpgrade = false; client->cIsWebsocket = false; client->base64Authorization = ""; client->cWsRXsize = 0; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->cHttpLine = ""; #endif } @@ -96,7 +96,7 @@ void WebSocketsServer::begin(void) { #ifdef ESP8266 randomSeed(RANDOM_REG32); #elif defined(ESP32) - #define DR_REG_RNG_BASE 0x3ff75144 +#define DR_REG_RNG_BASE 0x3ff75144 randomSeed(READ_PERI_REG(DR_REG_RNG_BASE)); #else // TODO find better seed @@ -110,28 +110,27 @@ void WebSocketsServer::begin(void) { } void WebSocketsServer::close(void) { - _runnning = false; - disconnect(); + _runnning = false; + disconnect(); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) _server->close(); -#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) _server->end(); #else // TODO how to close server? #endif - } -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * called in arduino loop */ void WebSocketsServer::loop(void) { - if(_runnning) { - handleNewClients(); - handleClientData(); - } + if(_runnning) { + handleNewClients(); + handleClientData(); + } } #endif @@ -150,21 +149,20 @@ void WebSocketsServer::onEvent(WebSocketServerEvent cbEvent) { * @param mandatoryHttpHeaderCount size_t ///< the number of items in the mandatoryHttpHeaders array */ void WebSocketsServer::onValidateHttpHeader( - WebSocketServerHttpHeaderValFunc validationFunc, - const char* mandatoryHttpHeaders[], - size_t mandatoryHttpHeaderCount) -{ - _httpHeaderValidationFunc = validationFunc; + WebSocketServerHttpHeaderValFunc validationFunc, + const char * mandatoryHttpHeaders[], + size_t mandatoryHttpHeaderCount) { + _httpHeaderValidationFunc = validationFunc; - if (_mandatoryHttpHeaders) - delete[] _mandatoryHttpHeaders; + if(_mandatoryHttpHeaders) + delete[] _mandatoryHttpHeaders; - _mandatoryHttpHeaderCount = mandatoryHttpHeaderCount; - _mandatoryHttpHeaders = new String[_mandatoryHttpHeaderCount]; + _mandatoryHttpHeaderCount = mandatoryHttpHeaderCount; + _mandatoryHttpHeaders = new String[_mandatoryHttpHeaderCount]; - for (size_t i = 0; i < _mandatoryHttpHeaderCount; i++) { - _mandatoryHttpHeaders[i] = mandatoryHttpHeaders[i]; - } + for(size_t i = 0; i < _mandatoryHttpHeaderCount; i++) { + _mandatoryHttpHeaders[i] = mandatoryHttpHeaders[i]; + } } /* @@ -180,7 +178,7 @@ bool WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bo return false; } if(length == 0) { - length = strlen((const char *) payload); + length = strlen((const char *)payload); } WSclient_t * client = &_clients[num]; if(clientIsConnected(client)) { @@ -190,19 +188,19 @@ bool WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bo } bool WebSocketsServer::sendTXT(uint8_t num, const uint8_t * payload, size_t length) { - return sendTXT(num, (uint8_t *) payload, length); + return sendTXT(num, (uint8_t *)payload, length); } bool WebSocketsServer::sendTXT(uint8_t num, char * payload, size_t length, bool headerToPayload) { - return sendTXT(num, (uint8_t *) payload, length, headerToPayload); + return sendTXT(num, (uint8_t *)payload, length, headerToPayload); } bool WebSocketsServer::sendTXT(uint8_t num, const char * payload, size_t length) { - return sendTXT(num, (uint8_t *) payload, length); + return sendTXT(num, (uint8_t *)payload, length); } bool WebSocketsServer::sendTXT(uint8_t num, String & payload) { - return sendTXT(num, (uint8_t *) payload.c_str(), payload.length()); + return sendTXT(num, (uint8_t *)payload.c_str(), payload.length()); } /** @@ -216,7 +214,7 @@ bool WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool heade WSclient_t * client; bool ret = true; if(length == 0) { - length = strlen((const char *) payload); + length = strlen((const char *)payload); } for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { @@ -226,7 +224,7 @@ bool WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool heade ret = false; } } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } @@ -234,19 +232,19 @@ bool WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool heade } bool WebSocketsServer::broadcastTXT(const uint8_t * payload, size_t length) { - return broadcastTXT((uint8_t *) payload, length); + return broadcastTXT((uint8_t *)payload, length); } bool WebSocketsServer::broadcastTXT(char * payload, size_t length, bool headerToPayload) { - return broadcastTXT((uint8_t *) payload, length, headerToPayload); + return broadcastTXT((uint8_t *)payload, length, headerToPayload); } bool WebSocketsServer::broadcastTXT(const char * payload, size_t length) { - return broadcastTXT((uint8_t *) payload, length); + return broadcastTXT((uint8_t *)payload, length); } bool WebSocketsServer::broadcastTXT(String & payload) { - return broadcastTXT((uint8_t *) payload.c_str(), payload.length()); + return broadcastTXT((uint8_t *)payload.c_str(), payload.length()); } /** @@ -269,7 +267,7 @@ bool WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length, bo } bool WebSocketsServer::sendBIN(uint8_t num, const uint8_t * payload, size_t length) { - return sendBIN(num, (uint8_t *) payload, length); + return sendBIN(num, (uint8_t *)payload, length); } /** @@ -289,7 +287,7 @@ bool WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool heade ret = false; } } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } @@ -297,10 +295,9 @@ bool WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool heade } bool WebSocketsServer::broadcastBIN(const uint8_t * payload, size_t length) { - return broadcastBIN((uint8_t *) payload, length); + return broadcastBIN((uint8_t *)payload, length); } - /** * sends a WS ping to Client * @param num uint8_t client id @@ -320,7 +317,7 @@ bool WebSocketsServer::sendPing(uint8_t num, uint8_t * payload, size_t length) { } bool WebSocketsServer::sendPing(uint8_t num, String & payload) { - return sendPing(num, (uint8_t *) payload.c_str(), payload.length()); + return sendPing(num, (uint8_t *)payload.c_str(), payload.length()); } /** @@ -339,7 +336,7 @@ bool WebSocketsServer::broadcastPing(uint8_t * payload, size_t length) { ret = false; } } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } @@ -347,10 +344,9 @@ bool WebSocketsServer::broadcastPing(uint8_t * payload, size_t length) { } bool WebSocketsServer::broadcastPing(String & payload) { - return broadcastPing((uint8_t *) payload.c_str(), payload.length()); + return broadcastPing((uint8_t *)payload.c_str(), payload.length()); } - /** * disconnect all clients */ @@ -378,7 +374,6 @@ void WebSocketsServer::disconnect(uint8_t num) { } } - /* * set the Authorization for the http request * @param user const char * @@ -410,18 +405,18 @@ void WebSocketsServer::setAuthorization(const char * auth) { int WebSocketsServer::connectedClients(bool ping) { WSclient_t * client; int count = 0; - for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { - client = &_clients[i]; - if(client->status == WSC_CONNECTED) { - if(ping != true || sendPing(i)) { - count++; - } - } - } + for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + client = &_clients[i]; + if(client->status == WSC_CONNECTED) { + if(ping != true || sendPing(i)) { + count++; + } + } + } return count; } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) /** * get an IP for a client * @param num uint8_t client id @@ -455,38 +450,36 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { // state is not connected or tcp connection is lost if(!clientIsConnected(client)) { - client->tcp = TCPclient; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) client->isSSL = false; client->tcp->setNoDelay(true); #endif -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) // set Timeout for readBytesUntil and readStringUntil client->tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); #endif client->status = WSC_HEADER; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) IPAddress ip = client->tcp->remoteIP(); DEBUG_WEBSOCKETS("[WS-Server][%d] new client from %d.%d.%d.%d\n", client->num, ip[0], ip[1], ip[2], ip[3]); #else DEBUG_WEBSOCKETS("[WS-Server][%d] new client\n", client->num); #endif - -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->tcp->onDisconnect(std::bind([](WebSocketsServer * server, AsyncTCPbuffer * obj, WSclient_t * client) -> bool { DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num); AsyncTCPbuffer ** sl = &server->_clients[client->num].tcp; if(*sl == obj) { client->status = WSC_NOT_CONNECTED; - *sl = NULL; + *sl = NULL; } return true; - }, this, std::placeholders::_1, client)); - + }, + this, std::placeholders::_1, client)); client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine))); #endif @@ -530,7 +523,6 @@ void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, u } runCbEvent(client->num, type, payload, length); - } /** @@ -538,9 +530,7 @@ void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, u * @param client WSclient_t * ptr to the client struct */ void WebSocketsServer::clientDisconnect(WSclient_t * client) { - - -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) if(client->isSSL && client->ssl) { if(client->ssl->connected()) { client->ssl->flush(); @@ -554,12 +544,12 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { if(client->tcp) { if(client->tcp->connected()) { -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) client->tcp->flush(); #endif client->tcp->stop(); } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->status = WSC_NOT_CONNECTED; #else delete client->tcp; @@ -567,16 +557,16 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { client->tcp = NULL; } - client->cUrl = ""; - client->cKey = ""; - client->cProtocol = ""; - client->cVersion = 0; - client->cIsUpgrade = false; + client->cUrl = ""; + client->cKey = ""; + client->cProtocol = ""; + client->cVersion = 0; + client->cIsUpgrade = false; client->cIsWebsocket = false; client->cWsRXsize = 0; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->cHttpLine = ""; #endif @@ -585,7 +575,6 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { DEBUG_WEBSOCKETS("[WS-Server][%d] client disconnected.\n", client->num); runCbEvent(client->num, WStype_DISCONNECTED, NULL, 0); - } /** @@ -594,7 +583,6 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { * @return true = connected */ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { - if(!client->tcp) { return false; } @@ -620,22 +608,21 @@ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { return false; } -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * Handle incoming Connection Request */ void WebSocketsServer::handleNewClients(void) { - -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) while(_server->hasClient()) { #endif bool ok = false; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) // store new connection WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); #else - WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); + WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); #endif if(!tcpClient) { @@ -647,28 +634,25 @@ void WebSocketsServer::handleNewClients(void) { if(!ok) { // no free space to handle client -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) IPAddress ip = tcpClient->remoteIP(); DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); #else - DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n"); + DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n"); #endif tcpClient->stop(); } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) delay(0); } #endif - } - /** * Handel incomming data from Client */ void WebSocketsServer::handleClientData(void) { - WSclient_t * client; for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { client = &_clients[i]; @@ -677,12 +661,10 @@ void WebSocketsServer::handleClientData(void) { if(len > 0) { //DEBUG_WEBSOCKETS("[WS-Server][%d][handleClientData] len: %d\n", client->num, len); switch(client->status) { - case WSC_HEADER: - { + case WSC_HEADER: { String headerLine = client->tcp->readStringUntil('\n'); handleHeader(client, &headerLine); - } - break; + } break; case WSC_CONNECTED: WebSockets::handleWebsocket(client); break; @@ -692,7 +674,7 @@ void WebSocketsServer::handleClientData(void) { } } } -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); #endif } @@ -704,84 +686,80 @@ void WebSocketsServer::handleClientData(void) { * @param headerName String ///< the name of the header being checked */ bool WebSocketsServer::hasMandatoryHeader(String headerName) { - for (size_t i = 0; i < _mandatoryHttpHeaderCount; i++) { - if (_mandatoryHttpHeaders[i].equalsIgnoreCase(headerName)) - return true; - } - return false; + for(size_t i = 0; i < _mandatoryHttpHeaderCount; i++) { + if(_mandatoryHttpHeaders[i].equalsIgnoreCase(headerName)) + return true; + } + return false; } - /** * handles http header reading for WebSocket upgrade * @param client WSclient_t * ///< pointer to the client struct * @param headerLine String ///< the header being read / processed */ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { + static const char * NEW_LINE = "\r\n"; + + headerLine->trim(); // remove \r + + if(headerLine->length() > 0) { + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine->c_str()); + + // websocket requests always start with GET see rfc6455 + if(headerLine->startsWith("GET ")) { + // cut URL out + client->cUrl = headerLine->substring(4, headerLine->indexOf(' ', 4)); + + //reset non-websocket http header validation state for this client + client->cHttpHeadersValid = true; + client->cMandatoryHeadersCount = 0; - static const char * NEW_LINE = "\r\n"; - - headerLine->trim(); // remove \r - - if(headerLine->length() > 0) { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] RX: %s\n", client->num, headerLine->c_str()); - - // websocket requests always start with GET see rfc6455 - if(headerLine->startsWith("GET ")) { - - // cut URL out - client->cUrl = headerLine->substring(4, headerLine->indexOf(' ', 4)); - - //reset non-websocket http header validation state for this client - client->cHttpHeadersValid = true; - client->cMandatoryHeadersCount = 0; - - } else if(headerLine->indexOf(':') >= 0) { - String headerName = headerLine->substring(0, headerLine->indexOf(':')); - String headerValue = headerLine->substring(headerLine->indexOf(':') + 1); - - // remove space in the beginning (RFC2616) - if(headerValue[0] == ' ') { - headerValue.remove(0, 1); - } - - if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) { - headerValue.toLowerCase(); - if(headerValue.indexOf(WEBSOCKETS_STRING("upgrade")) >= 0) { - client->cIsUpgrade = true; - } - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) { - if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) { - client->cIsWebsocket = true; - } - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) { - client->cVersion = headerValue.toInt(); - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Key"))) { - client->cKey = headerValue; - client->cKey.trim(); // see rfc6455 - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) { - client->cProtocol = headerValue; - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) { - client->cExtensions = headerValue; - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Authorization"))) { - client->base64Authorization = headerValue; - } else { - client->cHttpHeadersValid &= execHttpHeaderValidation(headerName, headerValue); - if(_mandatoryHttpHeaderCount > 0 && hasMandatoryHeader(headerName)) { - client->cMandatoryHeadersCount++; - } - } - - } else { - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); - } + } else if(headerLine->indexOf(':') >= 0) { + String headerName = headerLine->substring(0, headerLine->indexOf(':')); + String headerValue = headerLine->substring(headerLine->indexOf(':') + 1); + + // remove space in the beginning (RFC2616) + if(headerValue[0] == ' ') { + headerValue.remove(0, 1); + } + + if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Connection"))) { + headerValue.toLowerCase(); + if(headerValue.indexOf(WEBSOCKETS_STRING("upgrade")) >= 0) { + client->cIsUpgrade = true; + } + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Upgrade"))) { + if(headerValue.equalsIgnoreCase(WEBSOCKETS_STRING("websocket"))) { + client->cIsWebsocket = true; + } + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) { + client->cVersion = headerValue.toInt(); + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Key"))) { + client->cKey = headerValue; + client->cKey.trim(); // see rfc6455 + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Protocol"))) { + client->cProtocol = headerValue; + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Extensions"))) { + client->cExtensions = headerValue; + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Authorization"))) { + client->base64Authorization = headerValue; + } else { + client->cHttpHeadersValid &= execHttpHeaderValidation(headerName, headerValue); + if(_mandatoryHttpHeaderCount > 0 && hasMandatoryHeader(headerName)) { + client->cMandatoryHeadersCount++; + } + } + + } else { + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Header error (%s)\n", headerLine->c_str()); + } (*headerLine) = ""; -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine))); #endif } else { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Header read fin.\n", client->num); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cURL: %s\n", client->num, client->cUrl.c_str()); DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - cIsUpgrade: %d\n", client->num, client->cIsUpgrade); @@ -796,36 +774,35 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { bool ok = (client->cIsUpgrade && client->cIsWebsocket); - if(ok) { - if(client->cUrl.length() == 0) { - ok = false; - } - if(client->cKey.length() == 0) { + if(ok) { + if(client->cUrl.length() == 0) { + ok = false; + } + if(client->cKey.length() == 0) { ok = false; } if(client->cVersion != 13) { ok = false; } if(!client->cHttpHeadersValid) { - ok = false; + ok = false; } - if (client->cMandatoryHeadersCount != _mandatoryHttpHeaderCount) { - ok = false; + if(client->cMandatoryHeadersCount != _mandatoryHttpHeaderCount) { + ok = false; } } if(_base64Authorization.length() > 0) { - String auth = WEBSOCKETS_STRING("Basic "); - auth += _base64Authorization; - if(auth != client->base64Authorization) { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] HTTP Authorization failed!\n", client->num); - handleAuthorizationFailed(client); - return; - } + String auth = WEBSOCKETS_STRING("Basic "); + auth += _base64Authorization; + if(auth != client->base64Authorization) { + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] HTTP Authorization failed!\n", client->num); + handleAuthorizationFailed(client); + return; + } } if(ok) { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incoming.\n", client->num); // generate Sec-WebSocket-Accept key @@ -835,43 +812,41 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { client->status = WSC_CONNECTED; - String handshake = WEBSOCKETS_STRING("HTTP/1.1 101 Switching Protocols\r\n" - "Server: arduino-WebSocketsServer\r\n" - "Upgrade: websocket\r\n" - "Connection: Upgrade\r\n" - "Sec-WebSocket-Version: 13\r\n" - "Sec-WebSocket-Accept: "); - handshake += sKey + NEW_LINE; + String handshake = WEBSOCKETS_STRING( + "HTTP/1.1 101 Switching Protocols\r\n" + "Server: arduino-WebSocketsServer\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Version: 13\r\n" + "Sec-WebSocket-Accept: "); + handshake += sKey + NEW_LINE; if(_origin.length() > 0) { handshake += WEBSOCKETS_STRING("Access-Control-Allow-Origin: "); - handshake +=_origin + NEW_LINE; + handshake += _origin + NEW_LINE; } if(client->cProtocol.length() > 0) { - handshake += WEBSOCKETS_STRING("Sec-WebSocket-Protocol: "); - handshake +=_protocol + NEW_LINE; + handshake += WEBSOCKETS_STRING("Sec-WebSocket-Protocol: "); + handshake += _protocol + NEW_LINE; } // header end handshake += NEW_LINE; - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] handshake %s", client->num, (uint8_t*)handshake.c_str()); + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] handshake %s", client->num, (uint8_t *)handshake.c_str()); - write(client, (uint8_t*)handshake.c_str(), handshake.length()); + write(client, (uint8_t *)handshake.c_str(), handshake.length()); headerDone(client); // send ping WebSockets::sendFrame(client, WSop_ping); - runCbEvent(client->num, WStype_CONNECTED, (uint8_t *) client->cUrl.c_str(), client->cUrl.length()); + runCbEvent(client->num, WStype_CONNECTED, (uint8_t *)client->cUrl.c_str(), client->cUrl.length()); } else { handleNonWebsocketConnection(client); } } } - - - diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index e010488..4874a70 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -28,160 +28,157 @@ #include "WebSockets.h" #ifndef WEBSOCKETS_SERVER_CLIENT_MAX -#define WEBSOCKETS_SERVER_CLIENT_MAX (5) +#define WEBSOCKETS_SERVER_CLIENT_MAX (5) #endif - - - -class WebSocketsServer: protected WebSockets { -public: - +class WebSocketsServer : protected WebSockets { + public: #ifdef __AVR__ - typedef void (*WebSocketServerEvent)(uint8_t num, WStype_t type, uint8_t * payload, size_t length); - typedef bool (*WebSocketServerHttpHeaderValFunc)(String headerName, String headerValue); + typedef void (*WebSocketServerEvent)(uint8_t num, WStype_t type, uint8_t * payload, size_t length); + typedef bool (*WebSocketServerHttpHeaderValFunc)(String headerName, String headerValue); #else - typedef std::function WebSocketServerEvent; - typedef std::function WebSocketServerHttpHeaderValFunc; + typedef std::function WebSocketServerEvent; + typedef std::function WebSocketServerHttpHeaderValFunc; #endif - WebSocketsServer(uint16_t port, String origin = "", String protocol = "arduino"); - virtual ~WebSocketsServer(void); + WebSocketsServer(uint16_t port, String origin = "", String protocol = "arduino"); + virtual ~WebSocketsServer(void); - void begin(void); - void close(void); + void begin(void); + void close(void); -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) - void loop(void); +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) + void loop(void); #else - // Async interface not need a loop call - void loop(void) __attribute__ ((deprecated)) {} + // Async interface not need a loop call + void loop(void) __attribute__((deprecated)) {} #endif - void onEvent(WebSocketServerEvent cbEvent); - void onValidateHttpHeader( - WebSocketServerHttpHeaderValFunc validationFunc, - const char* mandatoryHttpHeaders[], - size_t mandatoryHttpHeaderCount); - + void onEvent(WebSocketServerEvent cbEvent); + void onValidateHttpHeader( + WebSocketServerHttpHeaderValFunc validationFunc, + const char * mandatoryHttpHeaders[], + size_t mandatoryHttpHeaderCount); - bool sendTXT(uint8_t num, uint8_t * payload, size_t length = 0, bool headerToPayload = false); - bool sendTXT(uint8_t num, const uint8_t * payload, size_t length = 0); - bool sendTXT(uint8_t num, char * payload, size_t length = 0, bool headerToPayload = false); - bool sendTXT(uint8_t num, const char * payload, size_t length = 0); - bool sendTXT(uint8_t num, String & payload); + bool sendTXT(uint8_t num, uint8_t * payload, size_t length = 0, bool headerToPayload = false); + bool sendTXT(uint8_t num, const uint8_t * payload, size_t length = 0); + bool sendTXT(uint8_t num, char * payload, size_t length = 0, bool headerToPayload = false); + bool sendTXT(uint8_t num, const char * payload, size_t length = 0); + bool sendTXT(uint8_t num, String & payload); - bool broadcastTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); - bool broadcastTXT(const uint8_t * payload, size_t length = 0); - bool broadcastTXT(char * payload, size_t length = 0, bool headerToPayload = false); - bool broadcastTXT(const char * payload, size_t length = 0); - bool broadcastTXT(String & payload); + bool broadcastTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); + bool broadcastTXT(const uint8_t * payload, size_t length = 0); + bool broadcastTXT(char * payload, size_t length = 0, bool headerToPayload = false); + bool broadcastTXT(const char * payload, size_t length = 0); + bool broadcastTXT(String & payload); - bool sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload = false); - bool sendBIN(uint8_t num, const uint8_t * payload, size_t length); + bool sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload = false); + bool sendBIN(uint8_t num, const uint8_t * payload, size_t length); - bool broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload = false); - bool broadcastBIN(const uint8_t * payload, size_t length); + bool broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload = false); + bool broadcastBIN(const uint8_t * payload, size_t length); - bool sendPing(uint8_t num, uint8_t * payload = NULL, size_t length = 0); - bool sendPing(uint8_t num, String & payload); + bool sendPing(uint8_t num, uint8_t * payload = NULL, size_t length = 0); + bool sendPing(uint8_t num, String & payload); - bool broadcastPing(uint8_t * payload = NULL, size_t length = 0); - bool broadcastPing(String & payload); + bool broadcastPing(uint8_t * payload = NULL, size_t length = 0); + bool broadcastPing(String & payload); - void disconnect(void); - void disconnect(uint8_t num); + void disconnect(void); + void disconnect(uint8_t num); - void setAuthorization(const char * user, const char * password); - void setAuthorization(const char * auth); + void setAuthorization(const char * user, const char * password); + void setAuthorization(const char * auth); - int connectedClients(bool ping = false); + int connectedClients(bool ping = false); -#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) - IPAddress remoteIP(uint8_t num); +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) + IPAddress remoteIP(uint8_t num); #endif -protected: - uint16_t _port; - String _origin; - String _protocol; - String _base64Authorization; ///< Base64 encoded Auth request - String * _mandatoryHttpHeaders; - size_t _mandatoryHttpHeaderCount; + protected: + uint16_t _port; + String _origin; + String _protocol; + String _base64Authorization; ///< Base64 encoded Auth request + String * _mandatoryHttpHeaders; + size_t _mandatoryHttpHeaderCount; - WEBSOCKETS_NETWORK_SERVER_CLASS * _server; + WEBSOCKETS_NETWORK_SERVER_CLASS * _server; - WSclient_t _clients[WEBSOCKETS_SERVER_CLIENT_MAX]; + WSclient_t _clients[WEBSOCKETS_SERVER_CLIENT_MAX]; - WebSocketServerEvent _cbEvent; - WebSocketServerHttpHeaderValFunc _httpHeaderValidationFunc; + WebSocketServerEvent _cbEvent; + WebSocketServerHttpHeaderValFunc _httpHeaderValidationFunc; - bool _runnning; + bool _runnning; - bool newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); + bool newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); - void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); + void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); - void clientDisconnect(WSclient_t * client); - bool clientIsConnected(WSclient_t * client); + void clientDisconnect(WSclient_t * client); + bool clientIsConnected(WSclient_t * client); -#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) - void handleNewClients(void); - void handleClientData(void); +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) + void handleNewClients(void); + void handleClientData(void); #endif - void handleHeader(WSclient_t * client, String * headerLine); + void handleHeader(WSclient_t * client, String * headerLine); - /** + /** * called if a non Websocket connection is coming in. * Note: can be override * @param client WSclient_t * ptr to the client struct */ - virtual void handleNonWebsocketConnection(WSclient_t * client) { - DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] no Websocket connection close.\n", client->num); - client->tcp->write("HTTP/1.1 400 Bad Request\r\n" - "Server: arduino-WebSocket-Server\r\n" - "Content-Type: text/plain\r\n" - "Content-Length: 32\r\n" - "Connection: close\r\n" - "Sec-WebSocket-Version: 13\r\n" - "\r\n" - "This is a Websocket server only!"); - clientDisconnect(client); - } - - /** + virtual void handleNonWebsocketConnection(WSclient_t * client) { + DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] no Websocket connection close.\n", client->num); + client->tcp->write( + "HTTP/1.1 400 Bad Request\r\n" + "Server: arduino-WebSocket-Server\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 32\r\n" + "Connection: close\r\n" + "Sec-WebSocket-Version: 13\r\n" + "\r\n" + "This is a Websocket server only!"); + clientDisconnect(client); + } + + /** * called if a non Authorization connection is coming in. * Note: can be override * @param client WSclient_t * ptr to the client struct */ - virtual void handleAuthorizationFailed(WSclient_t *client) { - client->tcp->write("HTTP/1.1 401 Unauthorized\r\n" - "Server: arduino-WebSocket-Server\r\n" - "Content-Type: text/plain\r\n" - "Content-Length: 45\r\n" - "Connection: close\r\n" - "Sec-WebSocket-Version: 13\r\n" - "WWW-Authenticate: Basic realm=\"WebSocket Server\"" - "\r\n" - "This Websocket server requires Authorization!"); - clientDisconnect(client); - } - - /** + virtual void handleAuthorizationFailed(WSclient_t * client) { + client->tcp->write( + "HTTP/1.1 401 Unauthorized\r\n" + "Server: arduino-WebSocket-Server\r\n" + "Content-Type: text/plain\r\n" + "Content-Length: 45\r\n" + "Connection: close\r\n" + "Sec-WebSocket-Version: 13\r\n" + "WWW-Authenticate: Basic realm=\"WebSocket Server\"" + "\r\n" + "This Websocket server requires Authorization!"); + clientDisconnect(client); + } + + /** * called for sending a Event to the app * @param num uint8_t * @param type WStype_t * @param payload uint8_t * * @param length size_t */ - virtual void runCbEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { - if(_cbEvent) { - _cbEvent(num, type, payload, length); - } + virtual void runCbEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { + if(_cbEvent) { + _cbEvent(num, type, payload, length); } + } - /* + /* * Called at client socket connect handshake negotiation time for each http header that is not * a websocket specific http header (not Connection, Upgrade, Sec-WebSocket-*) * If the custom httpHeaderValidationFunc returns false for any headerName / headerValue passed, the @@ -189,24 +186,21 @@ class WebSocketsServer: protected WebSockets { * This mechanism can be used to enable custom authentication schemes e.g. test the value * of a session cookie to determine if a user is logged on / authenticated */ - virtual bool execHttpHeaderValidation(String headerName, String headerValue) { - if(_httpHeaderValidationFunc) { - //return the value of the custom http header validation function - return _httpHeaderValidationFunc(headerName, headerValue); - } - //no custom http header validation so just assume all is good - return true; + virtual bool execHttpHeaderValidation(String headerName, String headerValue) { + if(_httpHeaderValidationFunc) { + //return the value of the custom http header validation function + return _httpHeaderValidationFunc(headerName, headerValue); } + //no custom http header validation so just assume all is good + return true; + } -private: - /* + private: + /* * returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection * @param headerName String ///< the name of the header being checked */ - bool hasMandatoryHeader(String headerName); - + bool hasMandatoryHeader(String headerName); }; - - #endif /* WEBSOCKETSSERVER_H_ */ From b1b21d188f1d403cac5051d1c16384f08b297563 Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 10 Jun 2019 13:02:25 +0200 Subject: [PATCH 182/347] update gitignore to Ignore IDE files from Eclipse and VScode --- .gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index 44b2c85..267af0d 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,11 @@ *.out *.app /tests/webSocketServer/node_modules + +# IDE +.vscode +.cproject +.project +.settings +*.swp + From 294436840c2cbc6e621d696693e05b73b26ff896 Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 10 Jun 2019 13:15:11 +0200 Subject: [PATCH 183/347] bump version to 2.1.4 --- library.json | 2 +- library.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index 978e584..efbc51b 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.1.3", + "version": "2.1.4", "license": "LGPL-2.1", "export": { "exclude": [ diff --git a/library.properties b/library.properties index a30fdbf..2fe174b 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.1.3 +version=2.1.4 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From dfa35fa9ae11b98fb071bb4aef086cb4a6a7f27d Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 10 Jun 2019 13:31:51 +0200 Subject: [PATCH 184/347] clang-format --- src/SocketIOclient.cpp | 37 ++++++++++------------- src/SocketIOclient.h | 68 ++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 57 deletions(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index 1ce8d0c..3609583 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -10,14 +10,12 @@ #include "SocketIOclient.h" SocketIOclient::SocketIOclient() { - } SocketIOclient::~SocketIOclient() { - } -void SocketIOclient::begin(const char *host, uint16_t port, const char * url, const char * protocol) { +void SocketIOclient::begin(const char * host, uint16_t port, const char * url, const char * protocol) { WebSocketsClient::beginSocketIO(host, port, url, protocol); } @@ -40,20 +38,19 @@ bool SocketIOclient::isConnected(void) { bool SocketIOclient::sendEVENT(uint8_t * payload, size_t length, bool headerToPayload) { bool ret = false; if(length == 0) { - length = strlen((const char *) payload); + length = strlen((const char *)payload); } if(clientIsConnected(&_client)) { - if(!headerToPayload) { // webSocket Header ret = WebSocketsClient::sendFrameHeader(&_client, WSop_text, length + 2, true); // Engine.IO / Socket.IO Header if(ret) { uint8_t buf[3] = { eIOtype_MESSAGE, sIOtype_EVENT, 0x00 }; - ret = WebSocketsClient::write(&_client, buf, 2); + ret = WebSocketsClient::write(&_client, buf, 2); } if(ret) { - ret = WebSocketsClient::write(&_client, payload, length ); + ret = WebSocketsClient::write(&_client, payload, length); } return ret; } else { @@ -66,19 +63,19 @@ bool SocketIOclient::sendEVENT(uint8_t * payload, size_t length, bool headerToPa } bool SocketIOclient::sendEVENT(const uint8_t * payload, size_t length) { - return sendEVENT((uint8_t *) payload, length); + return sendEVENT((uint8_t *)payload, length); } bool SocketIOclient::sendEVENT(char * payload, size_t length, bool headerToPayload) { - return sendEVENT((uint8_t *) payload, length, headerToPayload); + return sendEVENT((uint8_t *)payload, length, headerToPayload); } bool SocketIOclient::sendEVENT(const char * payload, size_t length) { - return sendEVENT((uint8_t *) payload, length); + return sendEVENT((uint8_t *)payload, length); } bool SocketIOclient::sendEVENT(String & payload) { - return sendEVENT((uint8_t *) payload.c_str(), payload.length()); + return sendEVENT((uint8_t *)payload.c_str(), payload.length()); } void SocketIOclient::loop(void) { @@ -100,15 +97,13 @@ void SocketIOclient::runCbEvent(WStype_t type, uint8_t * payload, size_t length) // send message to server when Connected // Engine.io upgrade confirmation message (required) WebSocketsClient::sendTXT(eIOtype_UPGRADE); - } - break; + } break; case WStype_TEXT: { - if(length < 1) { break; } - engineIOmessageType_t eType = (engineIOmessageType_t) payload[0]; + engineIOmessageType_t eType = (engineIOmessageType_t)payload[0]; switch(eType) { case eIOtype_PING: payload[0] = eIOtype_PONG; @@ -122,9 +117,9 @@ void SocketIOclient::runCbEvent(WStype_t type, uint8_t * payload, size_t length) if(length < 2) { break; } - socketIOmessageType_t ioType = (socketIOmessageType_t) payload[1]; - uint8_t * data = &payload[2]; - size_t lData = length - 2; + socketIOmessageType_t ioType = (socketIOmessageType_t)payload[1]; + uint8_t * data = &payload[2]; + size_t lData = length - 2; switch(ioType) { case sIOtype_EVENT: DEBUG_WEBSOCKETS("[wsIOc] get event (%d): %s\n", lData, data); @@ -141,8 +136,7 @@ void SocketIOclient::runCbEvent(WStype_t type, uint8_t * payload, size_t length) break; } - } - break; + } break; case eIOtype_OPEN: case eIOtype_CLOSE: case eIOtype_UPGRADE: @@ -155,8 +149,7 @@ void SocketIOclient::runCbEvent(WStype_t type, uint8_t * payload, size_t length) // send message to server // webSocket.sendTXT("message here"); - } - break; + } break; case WStype_BIN: DEBUG_WEBSOCKETS("[wsIOc] get binary length: %u\n", length); // hexdump(payload, length); diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index b179954..785d038 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -12,58 +12,56 @@ #define EIO_HEARTBEAT_INTERVAL 10000 -#define EIO_MAX_HEADER_SIZE (WEBSOCKETS_MAX_HEADER_SIZE + 1) -#define SIO_MAX_HEADER_SIZE (EIO_MAX_HEADER_SIZE + 1) +#define EIO_MAX_HEADER_SIZE (WEBSOCKETS_MAX_HEADER_SIZE + 1) +#define SIO_MAX_HEADER_SIZE (EIO_MAX_HEADER_SIZE + 1) typedef enum { - eIOtype_OPEN = '0', ///< Sent from the server when a new transport is opened (recheck) - eIOtype_CLOSE = '1', ///< Request the close of this transport but does not shutdown the connection itself. - eIOtype_PING = '2', ///< Sent by the client. Server should answer with a pong packet containing the same data - eIOtype_PONG = '3', ///< Sent by the server to respond to ping packets. - eIOtype_MESSAGE = '4', ///< actual message, client and server should call their callbacks with the data - eIOtype_UPGRADE = '5', ///< Before engine.io switches a transport, it tests, if server and client can communicate over this transport. If this test succeed, the client sends an upgrade packets which requests the server to flush its cache on the old transport and switch to the new transport. - eIOtype_NOOP = '6', ///< A noop packet. Used primarily to force a poll cycle when an incoming websocket connection is received. + eIOtype_OPEN = '0', ///< Sent from the server when a new transport is opened (recheck) + eIOtype_CLOSE = '1', ///< Request the close of this transport but does not shutdown the connection itself. + eIOtype_PING = '2', ///< Sent by the client. Server should answer with a pong packet containing the same data + eIOtype_PONG = '3', ///< Sent by the server to respond to ping packets. + eIOtype_MESSAGE = '4', ///< actual message, client and server should call their callbacks with the data + eIOtype_UPGRADE = '5', ///< Before engine.io switches a transport, it tests, if server and client can communicate over this transport. If this test succeed, the client sends an upgrade packets which requests the server to flush its cache on the old transport and switch to the new transport. + eIOtype_NOOP = '6', ///< A noop packet. Used primarily to force a poll cycle when an incoming websocket connection is received. } engineIOmessageType_t; - typedef enum { - sIOtype_CONNECT = '0', - sIOtype_DISCONNECT = '1', - sIOtype_EVENT = '2', - sIOtype_ACK = '3', - sIOtype_ERROR = '4', + sIOtype_CONNECT = '0', + sIOtype_DISCONNECT = '1', + sIOtype_EVENT = '2', + sIOtype_ACK = '3', + sIOtype_ERROR = '4', sIOtype_BINARY_EVENT = '5', - sIOtype_BINARY_ACK = '6', + sIOtype_BINARY_ACK = '6', } socketIOmessageType_t; -class SocketIOclient: protected WebSocketsClient { - - public: +class SocketIOclient : protected WebSocketsClient { + public: #ifdef __AVR__ - typedef void (*SocketIOclientEvent)(WStype_t type, uint8_t * payload, size_t length); + typedef void (*SocketIOclientEvent)(WStype_t type, uint8_t * payload, size_t length); #else - typedef std::function SocketIOclientEvent; + typedef std::function SocketIOclientEvent; #endif - SocketIOclient(void); - virtual ~SocketIOclient(void); + SocketIOclient(void); + virtual ~SocketIOclient(void); - void begin(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); - void begin(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); + void begin(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); + void begin(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); - bool isConnected(void); + bool isConnected(void); - bool sendEVENT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); - bool sendEVENT(const uint8_t * payload, size_t length = 0); - bool sendEVENT(char * payload, size_t length = 0, bool headerToPayload = false); - bool sendEVENT(const char * payload, size_t length = 0); - bool sendEVENT(String & payload); + bool sendEVENT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); + bool sendEVENT(const uint8_t * payload, size_t length = 0); + bool sendEVENT(char * payload, size_t length = 0, bool headerToPayload = false); + bool sendEVENT(const char * payload, size_t length = 0); + bool sendEVENT(String & payload); - void loop(void); + void loop(void); - protected: - void runCbEvent(WStype_t type, uint8_t * payload, size_t length); - uint64_t _lastHeartbeat = 0; + protected: + void runCbEvent(WStype_t type, uint8_t * payload, size_t length); + uint64_t _lastHeartbeat = 0; }; #endif /* SOCKETIOCLIENT_H_ */ From dbca2ab420076ff86fa2f1ab0324e9e10169bd3a Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 10 Jun 2019 14:57:49 +0200 Subject: [PATCH 185/347] SocketIO message RX is working --- src/SocketIOclient.cpp | 18 ++++++++++++++++-- src/SocketIOclient.h | 23 ++++++++++++++++++----- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index 3609583..3d51568 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -17,10 +17,20 @@ SocketIOclient::~SocketIOclient() { void SocketIOclient::begin(const char * host, uint16_t port, const char * url, const char * protocol) { WebSocketsClient::beginSocketIO(host, port, url, protocol); + WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); } void SocketIOclient::begin(String host, uint16_t port, String url, String protocol) { WebSocketsClient::beginSocketIO(host, port, url, protocol); + WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); +} + +/** + * set callback function + * @param cbEvent SocketIOclientEvent + */ +void SocketIOclient::onEvent(SocketIOclientEvent cbEvent) { + _cbEvent = cbEvent; } bool SocketIOclient::isConnected(void) { @@ -83,13 +93,15 @@ void SocketIOclient::loop(void) { unsigned long t = millis(); if((t - _lastConnectionFail) > EIO_HEARTBEAT_INTERVAL) { _lastConnectionFail = t; - //WebSocketsClient::sendTXT(eIOtype_PING); + DEBUG_WEBSOCKETS("[wsIOc] send ping\n"); + WebSocketsClient::sendTXT(eIOtype_PING); } } -void SocketIOclient::runCbEvent(WStype_t type, uint8_t * payload, size_t length) { +void SocketIOclient::handleCbEvent(WStype_t type, uint8_t * payload, size_t length) { switch(type) { case WStype_DISCONNECTED: + runIOCbEvent(sIOtype_DISCONNECT, NULL, 0); DEBUG_WEBSOCKETS("[wsIOc] Disconnected!\n"); break; case WStype_CONNECTED: { @@ -97,6 +109,7 @@ void SocketIOclient::runCbEvent(WStype_t type, uint8_t * payload, size_t length) // send message to server when Connected // Engine.io upgrade confirmation message (required) WebSocketsClient::sendTXT(eIOtype_UPGRADE); + runIOCbEvent(sIOtype_CONNECT, payload, length); } break; case WStype_TEXT: { if(length < 1) { @@ -136,6 +149,7 @@ void SocketIOclient::runCbEvent(WStype_t type, uint8_t * payload, size_t length) break; } + runIOCbEvent(ioType, data, lData); } break; case eIOtype_OPEN: case eIOtype_CLOSE: diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index 785d038..64b8c87 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -1,4 +1,4 @@ -/* +/** * SocketIOclient.h * * Created on: May 12, 2018 @@ -10,7 +10,7 @@ #include "WebSockets.h" -#define EIO_HEARTBEAT_INTERVAL 10000 +#define EIO_HEARTBEAT_INTERVAL 20000 #define EIO_MAX_HEADER_SIZE (WEBSOCKETS_MAX_HEADER_SIZE + 1) #define SIO_MAX_HEADER_SIZE (EIO_MAX_HEADER_SIZE + 1) @@ -38,9 +38,9 @@ typedef enum { class SocketIOclient : protected WebSocketsClient { public: #ifdef __AVR__ - typedef void (*SocketIOclientEvent)(WStype_t type, uint8_t * payload, size_t length); + typedef void (*SocketIOclientEvent)(socketIOmessageType_t type, uint8_t * payload, size_t length); #else - typedef std::function SocketIOclientEvent; + typedef std::function SocketIOclientEvent; #endif SocketIOclient(void); @@ -51,6 +51,8 @@ class SocketIOclient : protected WebSocketsClient { bool isConnected(void); + void onEvent(SocketIOclientEvent cbEvent); + bool sendEVENT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); bool sendEVENT(const uint8_t * payload, size_t length = 0); bool sendEVENT(char * payload, size_t length = 0, bool headerToPayload = false); @@ -60,8 +62,19 @@ class SocketIOclient : protected WebSocketsClient { void loop(void); protected: - void runCbEvent(WStype_t type, uint8_t * payload, size_t length); uint64_t _lastHeartbeat = 0; + SocketIOclientEvent _cbEvent; + virtual void runIOCbEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) { + if(_cbEvent) { + _cbEvent(type, payload, length); + } + } + + // Handeling events from websocket layer + virtual void runCbEvent(WStype_t type, uint8_t * payload, size_t length) { + handleCbEvent(type, payload, length); + } + void handleCbEvent(WStype_t type, uint8_t * payload, size_t length); }; #endif /* SOCKETIOCLIENT_H_ */ From 007b5ba9a859d3ac3e2011bc7bafcf951b55b658 Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 10 Jun 2019 15:13:26 +0200 Subject: [PATCH 186/347] ignore not needed WS events for SocketIO --- src/SocketIOclient.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index 3d51568..755bc9b 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -160,16 +160,15 @@ void SocketIOclient::handleCbEvent(WStype_t type, uint8_t * payload, size_t leng DEBUG_WEBSOCKETS("[wsIOc] get text: %s\n", payload); break; } - - // send message to server - // webSocket.sendTXT("message here"); } break; - case WStype_BIN: - DEBUG_WEBSOCKETS("[wsIOc] get binary length: %u\n", length); - // hexdump(payload, length); - // send data to server - // webSocket.sendBIN(payload, length); + case WStype_BIN: + case WStype_FRAGMENT_TEXT_START: + case WStype_FRAGMENT_BIN_START: + case WStype_FRAGMENT: + case WStype_FRAGMENT_FIN: + case WStype_PING: + case WStype_PONG: break; } } From 5d26a65df452be50361c6dd90098112afcc04eb0 Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 20 Jun 2019 10:02:07 +0200 Subject: [PATCH 187/347] only send payload when we have a ptr and length --- src/SocketIOclient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index 755bc9b..e9467d4 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -59,7 +59,7 @@ bool SocketIOclient::sendEVENT(uint8_t * payload, size_t length, bool headerToPa uint8_t buf[3] = { eIOtype_MESSAGE, sIOtype_EVENT, 0x00 }; ret = WebSocketsClient::write(&_client, buf, 2); } - if(ret) { + if(ret && payload && length > 0) { ret = WebSocketsClient::write(&_client, payload, length); } return ret; From 6a76efa791046167d3a7cbbf94bed118cb6bee4f Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 20 Jun 2019 10:06:21 +0200 Subject: [PATCH 188/347] fix #445 #446 set TCP timeout for ESP32 on connect --- src/WebSocketsClient.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 8d48ccd..e00a942 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -190,8 +190,11 @@ void WebSocketsClient::loop(void) { DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); return; } - +#if defined(ESP32) + if(_client.tcp->connect(_host.c_str(), _port, WEBSOCKETS_TCP_TIMEOUT)) { +#else if(_client.tcp->connect(_host.c_str(), _port)) { +#endif connectedCb(); _lastConnectionFail = 0; } else { From adf2b07f3bc9495beaa3e5755671482ded8156d8 Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 23 Jun 2019 12:14:44 +0200 Subject: [PATCH 189/347] fix #447 --- src/WebSocketsClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index f593692..db15e5b 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -762,7 +762,7 @@ void WebSocketsClient::connectedCb() { return; } } else if(_client.isSSL && !_CA_cert) { -#if defined(wificlientbearssl_h) && !defined(USING_AXTLS) +#if defined(wificlientbearssl_h) && !defined(USING_AXTLS) && !defined(wificlientsecure_h) _client.ssl->setInsecure(); #endif } From 7816bb3fa48683c065d5519969fbdc5563a5d63f Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 29 Jun 2019 18:31:14 +0200 Subject: [PATCH 190/347] adding example for new socket.IO support --- .travis.yml | 4 + .../WebSocketClientSocketIO.ino | 119 ++++++++++-------- 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9d3f31b..c319bab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,10 @@ script: - export PATH="$HOME/arduino_ide:$PATH" - which arduino - mkdir -p $HOME/Arduino/libraries + + - wget https://github.com/bblanchon/ArduinoJson/archive/6.x.zip + - unzip 6.x.zip + - mv ArduinoJson-6.x $HOME/Arduino/libraries/ArduinoJson - cp -r $TRAVIS_BUILD_DIR $HOME/Arduino/libraries/arduinoWebSockets - source $TRAVIS_BUILD_DIR/travis/common.sh - get_core $CPU diff --git a/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino b/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino index 39dce87..52aef19 100644 --- a/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino +++ b/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino @@ -10,56 +10,45 @@ #include #include +#include + #include #include ESP8266WiFiMulti WiFiMulti; -WebSocketsClient webSocket; - +SocketIOclient socketIO; #define USE_SERIAL Serial1 -#define MESSAGE_INTERVAL 30000 -#define HEARTBEAT_INTERVAL 25000 - -uint64_t messageTimestamp = 0; -uint64_t heartbeatTimestamp = 0; -bool isConnected = false; - -void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { - - +void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) { switch(type) { - case WStype_DISCONNECTED: - USE_SERIAL.printf("[WSc] Disconnected!\n"); - isConnected = false; + case sIOtype_DISCONNECT: + USE_SERIAL.printf("[IOc] Disconnected!\n"); break; - case WStype_CONNECTED: - { - USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); - isConnected = true; - - // send message to server when Connected - // socket.io upgrade confirmation message (required) - webSocket.sendTXT("5"); - } + case sIOtype_CONNECT: + USE_SERIAL.printf("[IOc] Connected to url: %s\n", payload); break; - case WStype_TEXT: - USE_SERIAL.printf("[WSc] get text: %s\n", payload); - - // send message to server - // webSocket.sendTXT("message here"); + case sIOtype_EVENT: + USE_SERIAL.printf("[IOc] get event: %s\n", payload); break; - case WStype_BIN: - USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + case sIOtype_ACK: + USE_SERIAL.printf("[IOc] get ack: %u\n", length); + hexdump(payload, length); + break; + case sIOtype_ERROR: + USE_SERIAL.printf("[IOc] get error: %u\n", length); + hexdump(payload, length); + break; + case sIOtype_BINARY_EVENT: + USE_SERIAL.printf("[IOc] get binary: %u\n", length); + hexdump(payload, length); + break; + case sIOtype_BINARY_ACK: + USE_SERIAL.printf("[IOc] get binary ack: %u\n", length); hexdump(payload, length); - - // send data to server - // webSocket.sendBIN(payload, length); break; } - } void setup() { @@ -79,6 +68,11 @@ void setup() { delay(1000); } + // disable AP + if(WiFi.getMode() & WIFI_AP) { + WiFi.softAPdisconnect(true); + } + WiFiMulti.addAP("SSID", "passpasspass"); //WiFi.disconnect(); @@ -86,28 +80,45 @@ void setup() { delay(100); } - webSocket.beginSocketIO("192.168.0.123", 81); - //webSocket.setAuthorization("user", "Password"); // HTTP Basic Authorization - webSocket.onEvent(webSocketEvent); + String ip = WiFi.localIP().toString(); + USE_SERIAL.printf("[SETUP] WiFi Connected %s\n", ip.c_str()); + + // server address, port and URL + socketIO.begin("10.11.100.100", 8880); + // event handler + socketIO.onEvent(socketIOEvent); } +unsigned long messageTimestamp = 0; void loop() { - webSocket.loop(); - - if(isConnected) { - - uint64_t now = millis(); - - if(now - messageTimestamp > MESSAGE_INTERVAL) { - messageTimestamp = now; - // example socket.io message with type "messageType" and JSON payload - webSocket.sendTXT("42[\"messageType\",{\"greeting\":\"hello\"}]"); - } - if((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) { - heartbeatTimestamp = now; - // socket.io heartbeat message - webSocket.sendTXT("2"); - } + socketIO.loop(); + + uint64_t now = millis(); + + if(now - messageTimestamp > 2000) { + messageTimestamp = now; + + // creat JSON message for Socket.IO (event) + DynamicJsonDocument doc(1024); + JsonArray array = doc.to(); + + // add evnet name + // Hint: socket.on('event_name', .... + array.add("event_name"); + + // add payload (parameters) for the event + JsonObject param1 = array.createNestedObject(); + param1["now"] = now; + + // JSON to String (serializion) + String output; + serializeJson(doc, output); + + // Send event + socketIO.sendEVENT(output); + + // Print JSON for debugging + USE_SERIAL.println(output); } } From 4ef8d733dcd443b2ae63d39cc551b782e250c1e2 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 29 Jun 2019 18:35:21 +0200 Subject: [PATCH 191/347] add missing include --- .../esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino b/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino index 52aef19..343b5f5 100644 --- a/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino +++ b/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino @@ -13,6 +13,7 @@ #include #include +#include #include From 9a803e1fb36ea97d7e17463b7548260c6bfad415 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 29 Jun 2019 19:03:36 +0200 Subject: [PATCH 192/347] bump version to 2.2.0 --- library.json | 2 +- library.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index efbc51b..9fe38a4 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.1.4", + "version": "2.2.0", "license": "LGPL-2.1", "export": { "exclude": [ diff --git a/library.properties b/library.properties index 2fe174b..4f18ec8 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.1.4 +version=2.2.0 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From bd158c9c5c19e7ae0d678c06219a1abd081db950 Mon Sep 17 00:00:00 2001 From: Luc Date: Thu, 4 Jul 2019 12:58:37 +0200 Subject: [PATCH 193/347] Fix warnings in platformIO Fix : warning: enumeration value 'WStype_ERROR' not handled in switch [-Wswitch] Fix : warning: variable 'ip' set but not used [-Wunused-but-set-variable] --- src/SocketIOclient.cpp | 2 +- src/WebSocketsServer.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index e9467d4..bdf0dfe 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -161,7 +161,7 @@ void SocketIOclient::handleCbEvent(WStype_t type, uint8_t * payload, size_t leng break; } } break; - + case WStype_ERROR: case WStype_BIN: case WStype_FRAGMENT_TEXT_START: case WStype_FRAGMENT_BIN_START: diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index b05dc5e..d65eec5 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -462,7 +462,9 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { #endif client->status = WSC_HEADER; #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#ifndef NODEBUG_WEBSOCKETS IPAddress ip = client->tcp->remoteIP(); +#endif DEBUG_WEBSOCKETS("[WS-Server][%d] new client from %d.%d.%d.%d\n", client->num, ip[0], ip[1], ip[2], ip[3]); #else DEBUG_WEBSOCKETS("[WS-Server][%d] new client\n", client->num); @@ -635,7 +637,9 @@ void WebSocketsServer::handleNewClients(void) { if(!ok) { // no free space to handle client #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#ifndef NODEBUG_WEBSOCKETS IPAddress ip = tcpClient->remoteIP(); +#endif DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); #else DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n"); From 771831c57ebb5a1266db850ad4f4cddf9af997b8 Mon Sep 17 00:00:00 2001 From: Nufflee Date: Mon, 15 Jul 2019 23:13:38 +0200 Subject: [PATCH 194/347] Syntax highlighting in README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 81b4107..581b76e 100644 --- a/README.md +++ b/README.md @@ -57,22 +57,22 @@ The mode can be activated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE ### High Level Client API ### - `begin` : Initiate connection sequence to the websocket host. -``` +```c++ void begin(const char *host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); void begin(String host, uint16_t port, String url = "/", String protocol = "arduino"); ``` - `onEvent`: Callback to handle for websocket events - ``` + ```c++ void onEvent(WebSocketClientEvent cbEvent); ``` - `WebSocketClientEvent`: Handler for websocket events - ``` + ```c++ void (*WebSocketClientEvent)(WStype_t type, uint8_t * payload, size_t length) ``` Where `WStype_t type` is defined as: - ``` + ```c++ typedef enum { WStype_ERROR, WStype_DISCONNECTED, From e2669c1c5efdedc0ce16df4c502f51b6e0f2f3df Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 20 Jul 2019 13:46:59 +0200 Subject: [PATCH 195/347] [SocketIO] allow to send any message --- src/SocketIOclient.cpp | 37 ++++++++++++++++++++++++++++++++----- src/SocketIOclient.h | 7 +++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index e9467d4..337f029 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -40,12 +40,13 @@ bool SocketIOclient::isConnected(void) { /** * send text data to client * @param num uint8_t client id + * @param type socketIOmessageType_t * @param payload uint8_t * * @param length size_t - * @param headerToPayload bool (see sendFrame for more details) + * @param headerToPayload bool (see sendFrame for more details) * @return true if ok */ -bool SocketIOclient::sendEVENT(uint8_t * payload, size_t length, bool headerToPayload) { +bool SocketIOclient::send(socketIOmessageType_t type, uint8_t * payload, size_t length, bool headerToPayload) { bool ret = false; if(length == 0) { length = strlen((const char *)payload); @@ -56,7 +57,7 @@ bool SocketIOclient::sendEVENT(uint8_t * payload, size_t length, bool headerToPa ret = WebSocketsClient::sendFrameHeader(&_client, WSop_text, length + 2, true); // Engine.IO / Socket.IO Header if(ret) { - uint8_t buf[3] = { eIOtype_MESSAGE, sIOtype_EVENT, 0x00 }; + uint8_t buf[3] = { eIOtype_MESSAGE, type, 0x00 }; ret = WebSocketsClient::write(&_client, buf, 2); } if(ret && payload && length > 0) { @@ -66,12 +67,38 @@ bool SocketIOclient::sendEVENT(uint8_t * payload, size_t length, bool headerToPa } else { // TODO implement } - - // return WebSocketsClient::sendFrame(&_client, WSop_text, payload, length, true, true, headerToPayload); } return false; } +bool SocketIOclient::send(socketIOmessageType_t type, const uint8_t * payload, size_t length) { + return send(type, (uint8_t *)payload, length); +} + +bool SocketIOclient::send(socketIOmessageType_t type, char * payload, size_t length, bool headerToPayload) { + return send(type, (uint8_t *)payload, length, headerToPayload); +} + +bool SocketIOclient::send(socketIOmessageType_t type, const char * payload, size_t length) { + return send(type, (uint8_t *)payload, length); +} + +bool SocketIOclient::send(socketIOmessageType_t type, String & payload) { + return send(type, (uint8_t *)payload.c_str(), payload.length()); +} + +/** + * send text data to client + * @param num uint8_t client id + * @param payload uint8_t * + * @param length size_t + * @param headerToPayload bool (see sendFrame for more details) + * @return true if ok + */ +bool SocketIOclient::sendEVENT(uint8_t * payload, size_t length, bool headerToPayload) { + return send(sIOtype_EVENT, payload, length, headerToPayload); +} + bool SocketIOclient::sendEVENT(const uint8_t * payload, size_t length) { return sendEVENT((uint8_t *)payload, length); } diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index 64b8c87..ee8a667 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -59,6 +59,13 @@ class SocketIOclient : protected WebSocketsClient { bool sendEVENT(const char * payload, size_t length = 0); bool sendEVENT(String & payload); + + bool send(socketIOmessageType_t type, uint8_t * payload, size_t length = 0, bool headerToPayload = false); + bool send(socketIOmessageType_t type, const uint8_t * payload, size_t length = 0); + bool send(socketIOmessageType_t type, char * payload, size_t length = 0, bool headerToPayload = false); + bool send(socketIOmessageType_t type, const char * payload, size_t length = 0); + bool send(socketIOmessageType_t type, String & payload); + void loop(void); protected: From 40152be1971b41e40b954aebaea971766994d02b Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 20 Jul 2019 13:47:40 +0200 Subject: [PATCH 196/347] code style --- src/SocketIOclient.cpp | 2 +- src/SocketIOclient.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index 337f029..8423bbe 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -96,7 +96,7 @@ bool SocketIOclient::send(socketIOmessageType_t type, String & payload) { * @return true if ok */ bool SocketIOclient::sendEVENT(uint8_t * payload, size_t length, bool headerToPayload) { - return send(sIOtype_EVENT, payload, length, headerToPayload); + return send(sIOtype_EVENT, payload, length, headerToPayload); } bool SocketIOclient::sendEVENT(const uint8_t * payload, size_t length) { diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index ee8a667..ca0a69b 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -59,7 +59,6 @@ class SocketIOclient : protected WebSocketsClient { bool sendEVENT(const char * payload, size_t length = 0); bool sendEVENT(String & payload); - bool send(socketIOmessageType_t type, uint8_t * payload, size_t length = 0, bool headerToPayload = false); bool send(socketIOmessageType_t type, const uint8_t * payload, size_t length = 0); bool send(socketIOmessageType_t type, char * payload, size_t length = 0, bool headerToPayload = false); From 0444a78441a8c3a0bc0e50732289dae1b31bd0db Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 20 Jul 2019 14:24:55 +0200 Subject: [PATCH 197/347] [SocketIO] add example for use of ACK / callback handling --- .../WebSocketClientSocketIOack.ino | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino diff --git a/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino b/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino new file mode 100644 index 0000000..bd49ad0 --- /dev/null +++ b/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino @@ -0,0 +1,162 @@ +/* + * WebSocketClientSocketIOack.ino + * + * Created on: 20.07.2019 + * + */ + +#include + +#include +#include + +#include + +#include +#include + +#include + +ESP8266WiFiMulti WiFiMulti; +SocketIOclient socketIO; + +#define USE_SERIAL Serial + + +void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) { + switch(type) { + case sIOtype_DISCONNECT: + USE_SERIAL.printf("[IOc] Disconnected!\n"); + break; + case sIOtype_CONNECT: + USE_SERIAL.printf("[IOc] Connected to url: %s\n", payload); + break; + case sIOtype_EVENT: + { + char * sptr = NULL; + int id = strtol((char *)payload, &sptr, 10); + USE_SERIAL.printf("[IOc] get event: %s id: %d\n", payload, id); + if(id) { + payload = (uint8_t *)sptr; + } + DynamicJsonDocument doc(1024); + DeserializationError error = deserializeJson(doc, payload, length); + if(error) { + USE_SERIAL.print(F("deserializeJson() failed: ")); + USE_SERIAL.println(error.c_str()); + return; + } + + String eventName = doc[0]; + USE_SERIAL.printf("[IOc] event name: %s\n", eventName.c_str()); + + // Message Includes a ID for a ACK (callback) + if(id) { + // creat JSON message for Socket.IO (ack) + DynamicJsonDocument docOut(1024); + JsonArray array = docOut.to(); + + // add payload (parameters) for the ack (callback function) + JsonObject param1 = array.createNestedObject(); + param1["now"] = millis(); + + // JSON to String (serializion) + String output; + output += id; + serializeJson(docOut, output); + + // Send event + socketIO.send(sIOtype_ACK, output); + } + } + break; + case sIOtype_ACK: + USE_SERIAL.printf("[IOc] get ack: %u\n", length); + hexdump(payload, length); + break; + case sIOtype_ERROR: + USE_SERIAL.printf("[IOc] get error: %u\n", length); + hexdump(payload, length); + break; + case sIOtype_BINARY_EVENT: + USE_SERIAL.printf("[IOc] get binary: %u\n", length); + hexdump(payload, length); + break; + case sIOtype_BINARY_ACK: + USE_SERIAL.printf("[IOc] get binary ack: %u\n", length); + hexdump(payload, length); + break; + } +} + +void setup() { + //USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + //Serial.setDebugOutput(true); + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + // disable AP + if(WiFi.getMode() & WIFI_AP) { + WiFi.softAPdisconnect(true); + } + + WiFiMulti.addAP("SSID", "passpasspass"); + + //WiFi.disconnect(); + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + String ip = WiFi.localIP().toString(); + USE_SERIAL.printf("[SETUP] WiFi Connected %s\n", ip.c_str()); + + // server address, port and URL + socketIO.begin("10.11.100.100", 8880); + + // event handler + socketIO.onEvent(socketIOEvent); +} + +unsigned long messageTimestamp = 0; +void loop() { + socketIO.loop(); + + uint64_t now = millis(); + + if(now - messageTimestamp > 2000) { + messageTimestamp = now; + + // creat JSON message for Socket.IO (event) + DynamicJsonDocument doc(1024); + JsonArray array = doc.to(); + + // add evnet name + // Hint: socket.on('event_name', .... + array.add("event_name"); + + // add payload (parameters) for the event + JsonObject param1 = array.createNestedObject(); + param1["now"] = now; + + // JSON to String (serializion) + String output; + serializeJson(doc, output); + + // Send event + socketIO.sendEVENT(output); + + // Print JSON for debugging + USE_SERIAL.println(output); + } +} From 370f217a307abfabd23ac0545ca58b1d7acff351 Mon Sep 17 00:00:00 2001 From: kenkeiras Date: Sun, 27 Oct 2019 21:40:53 +0100 Subject: [PATCH 198/347] add example for ssl websocket with CA certificate --- .../WebSocketClientSSLWithCA.ino | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino diff --git a/examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino b/examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino new file mode 100644 index 0000000..6d95d7d --- /dev/null +++ b/examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino @@ -0,0 +1,111 @@ +/* + * WebSocketClientSSLWithCA.ino + * + * Created on: 27.10.2019 + * + * note SSL is only possible with the ESP8266 + * + */ + +#include + +#include +#include + +#include + +ESP8266WiFiMulti WiFiMulti; +WebSocketsClient webSocket; + +#define USE_SERIAL Serial1 + + +// Can be obtained with: +// openssl s_client -showcerts -connect echo.websocket.org:443 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFiMulti.addAP("SSID", "passpasspass"); + + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + webSocket.beginSslWithCA("echo.websocket.org", 443, "/", ENDPOINT_CA_CERT); + webSocket.onEvent(webSocketEvent); +} + +void loop() { + webSocket.loop(); +} From 4ee0ba5630da5e46e931c31e1048fe249c751702 Mon Sep 17 00:00:00 2001 From: Amr Bekhit Date: Tue, 24 Dec 2019 17:03:32 +0300 Subject: [PATCH 199/347] Increased WEBSOCKETS_TCP_TIMEOUT to 5000ms. See https://github.com/Links2004/arduinoWebSockets/issues/500. --- src/WebSockets.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 592dda8..1e6f2f9 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -76,7 +76,7 @@ #endif -#define WEBSOCKETS_TCP_TIMEOUT (2000) +#define WEBSOCKETS_TCP_TIMEOUT (5000) #define NETWORK_ESP8266_ASYNC (0) #define NETWORK_ESP8266 (1) From 674a6e98c93907d1ac697ae9e0d697d4c6a0cb77 Mon Sep 17 00:00:00 2001 From: maurus_fritsche Date: Mon, 10 Feb 2020 19:45:55 +0100 Subject: [PATCH 200/347] Implemented HeartBeat in WebSocketsServer --- src/WebSocketsServer.cpp | 63 ++++++++++++++++++++++++++++++++++++++++ src/WebSocketsServer.h | 9 ++++++ 2 files changed, 72 insertions(+) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index d65eec5..da382b6 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -30,6 +30,9 @@ WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol _origin = origin; _protocol = protocol; _runnning = false; + _pingInterval = 0; + _pongTimeout = 0; + _disconnectTimeoutCount = 0; _server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port); @@ -91,6 +94,10 @@ void WebSocketsServer::begin(void) { #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->cHttpLine = ""; #endif + + client->pingInterval = _pingInterval; + client->pongTimeout = _pongTimeout; + client->disconnectTimeoutCount = _disconnectTimeoutCount; } #ifdef ESP8266 @@ -486,6 +493,12 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine))); #endif + client->pingInterval = _pingInterval; + client->pongTimeout = _pongTimeout; + client->disconnectTimeoutCount = _disconnectTimeoutCount; + client->lastPing = millis(); + client->pongReceived = false; + return true; break; } @@ -677,6 +690,9 @@ void WebSocketsServer::handleClientData(void) { break; } } + + handleHBPing(client); + handleHBTimeout(client); } #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); @@ -854,3 +870,50 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { } } } + +/** + * send heartbeat ping to server in set intervals + */ +void WebSocketsServer::handleHBPing(WSclient_t * client) { + if(client->pingInterval == 0) + return; + uint32_t pi = millis() - client->lastPing; + if(pi > client->pingInterval) { + DEBUG_WEBSOCKETS("[WS-Server][%d] sending HB ping\n", client->num); + if(sendPing(client->num)) { + client->lastPing = millis(); + client->pongReceived = false; + } + } +} + +/** + * enable ping/pong heartbeat process + * @param pingInterval uint32_t how often ping will be sent + * @param pongTimeout uint32_t millis after which pong should timout if not received + * @param disconnectTimeoutCount uint8_t how many timeouts before disconnect, 0=> do not disconnect + */ +void WebSocketsServer::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { + _pingInterval = pingInterval; + _pongTimeout = pongTimeout; + _disconnectTimeoutCount = disconnectTimeoutCount; + + WSclient_t * client; + for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + client = &_clients[i]; + WebSockets::enableHeartbeat(client, pingInterval, pongTimeout, disconnectTimeoutCount); + } +} + +/** + * disable ping/pong heartbeat process + */ +void WebSocketsServer::disableHeartbeat() { + _pingInterval = 0; + + WSclient_t * client; + for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + client = &_clients[i]; + client->pingInterval = 0; + } +} \ No newline at end of file diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 4874a70..74ea85f 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -91,6 +91,9 @@ class WebSocketsServer : protected WebSockets { void setAuthorization(const char * auth); int connectedClients(bool ping = false); + + void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); + void disableHeartbeat(); #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) IPAddress remoteIP(uint8_t num); @@ -112,6 +115,10 @@ class WebSocketsServer : protected WebSockets { WebSocketServerHttpHeaderValFunc _httpHeaderValidationFunc; bool _runnning; + + uint32_t _pingInterval; + uint32_t _pongTimeout; + uint8_t _disconnectTimeoutCount; bool newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); @@ -126,6 +133,8 @@ class WebSocketsServer : protected WebSockets { #endif void handleHeader(WSclient_t * client, String * headerLine); + + void handleHBPing(WSclient_t * client); // send ping in specified intervals /** * called if a non Websocket connection is coming in. From 516911900b6f21881fa5741f559bb10cad37ac5a Mon Sep 17 00:00:00 2001 From: Ben Hencke Date: Sat, 15 Feb 2020 06:37:07 -0800 Subject: [PATCH 201/347] read can return -1, check for this to avoid corrupting protocol fixes #470 --- src/WebSockets.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index a3ada67..5d13b86 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -595,7 +595,7 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait #else unsigned long t = millis(); - size_t len; + ssize_t len; DEBUG_WEBSOCKETS("[readCb] n: %zu t: %lu\n", n, t); while(n > 0) { if(client->tcp == NULL) { @@ -630,7 +630,7 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait } len = client->tcp->read((uint8_t *)out, n); - if(len) { + if(len > 0) { t = millis(); out += len; n -= len; From ebd7a528ac737eeb2dc736c073ce834e9b7fa556 Mon Sep 17 00:00:00 2001 From: Ben Hencke Date: Sat, 15 Feb 2020 06:43:46 -0800 Subject: [PATCH 202/347] add a yield here for esp32 to avoid a busy loop if data isn't available yet, but is expected, yielding here is nicer than burning the cpu in a loop, just like in esp8266 case. --- src/WebSockets.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index a3ada67..21d3ef8 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -625,6 +625,9 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait if(!client->tcp->available()) { #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) delay(0); +#endif +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) + yield(); #endif continue; } From 12684582aac21cf80e9498d763ef138e17b53620 Mon Sep 17 00:00:00 2001 From: Amr Bekhit Date: Sat, 21 Mar 2020 22:14:25 +0300 Subject: [PATCH 203/347] Initialize _reconnectInterval in constructor. This allows setReconnectInterval() to be called before begin() and stops begin() from overriding _reconnectInterval every time it is called. --- src/WebSocketsClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index db15e5b..b2c8e6f 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -30,6 +30,7 @@ WebSocketsClient::WebSocketsClient() { _client.num = 0; _client.cIsClient = true; _client.extraHeaders = WEBSOCKETS_STRING("Origin: file://"); + _reconnectInterval = 500; } WebSocketsClient::~WebSocketsClient() { @@ -82,7 +83,6 @@ void WebSocketsClient::begin(const char * host, uint16_t port, const char * url, #endif _lastConnectionFail = 0; - _reconnectInterval = 500; } void WebSocketsClient::begin(String host, uint16_t port, String url, String protocol) { From b9e13368266bc506b196f157c54cf7062e326c88 Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 3 May 2020 09:12:03 +0200 Subject: [PATCH 204/347] add new define for yield WEBSOCKETS_YIELD --- src/WebSockets.cpp | 17 +++++------------ src/WebSockets.h | 8 ++++++++ src/WebSocketsClient.cpp | 8 ++++---- src/WebSocketsServer.cpp | 22 ++++++++-------------- 4 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 100ce79..6132d28 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -623,12 +623,7 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait } if(!client->tcp->available()) { -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - delay(0); -#endif -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) - yield(); -#endif + WEBSOCKETS_YIELD(); continue; } @@ -641,13 +636,12 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait } else { //DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n); } -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - delay(0); -#endif + WEBSOCKETS_YIELD(); } if(cb) { cb(client, true); } + WEBSOCKETS_YIELD(); #endif return true; } @@ -694,10 +688,9 @@ size_t WebSockets::write(WSclient_t * client, uint8_t * out, size_t n) { } else { //DEBUG_WEBSOCKETS("write %d failed left %d!\n", len, n); } -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - delay(0); -#endif + WEBSOCKETS_YIELD(); } + WEBSOCKETS_YIELD(); return total; } diff --git a/src/WebSockets.h b/src/WebSockets.h index 1e6f2f9..10434fe 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -61,11 +61,18 @@ // moves all Header strings to Flash (~300 Byte) //#define WEBSOCKETS_SAVE_RAM +#if defined(ESP8266) +#define WEBSOCKETS_YIELD() delay(0) +#elif defined(ESP32) +#define WEBSOCKETS_YIELD() yield() +#endif + #elif defined(STM32_DEVICE) #define WEBSOCKETS_MAX_DATA_SIZE (15 * 1024) #define WEBSOCKETS_USE_BIG_MEM #define GET_FREE_HEAP System.freeMemory() +#define WEBSOCKETS_YIELD() #else @@ -73,6 +80,7 @@ #define WEBSOCKETS_MAX_DATA_SIZE (1024) // moves all Header strings to Flash #define WEBSOCKETS_SAVE_RAM +#define WEBSOCKETS_YIELD() #endif diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index b2c8e6f..179c272 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -148,6 +148,7 @@ void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, * called in arduino loop */ void WebSocketsClient::loop(void) { + WEBSOCKETS_YIELD(); if(!clientIsConnected(&_client)) { // do not flood the server if((millis() - _lastConnectionFail) < _reconnectInterval) { @@ -190,6 +191,7 @@ void WebSocketsClient::loop(void) { DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); return; } + WEBSOCKETS_YIELD(); #if defined(ESP32) if(_client.tcp->connect(_host.c_str(), _port, WEBSOCKETS_TCP_TIMEOUT)) { #else @@ -203,7 +205,7 @@ void WebSocketsClient::loop(void) { } } else { handleClientData(); - + WEBSOCKETS_YIELD(); if(_client.status == WSC_CONNECTED) { handleHBPing(); handleHBTimeout(&_client); @@ -498,9 +500,7 @@ void WebSocketsClient::handleClientData(void) { break; } } -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) - delay(0); -#endif + WEBSOCKETS_YIELD(); } #endif diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index da382b6..16ee1c8 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -135,7 +135,9 @@ void WebSocketsServer::close(void) { */ void WebSocketsServer::loop(void) { if(_runnning) { + WEBSOCKETS_YIELD(); handleNewClients(); + WEBSOCKETS_YIELD(); handleClientData(); } } @@ -231,9 +233,7 @@ bool WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool heade ret = false; } } -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - delay(0); -#endif + WEBSOCKETS_YIELD(); } return ret; } @@ -294,9 +294,7 @@ bool WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool heade ret = false; } } -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - delay(0); -#endif + WEBSOCKETS_YIELD(); } return ret; } @@ -343,9 +341,7 @@ bool WebSocketsServer::broadcastPing(uint8_t * payload, size_t length) { ret = false; } } -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - delay(0); -#endif + WEBSOCKETS_YIELD(); } return ret; } @@ -660,8 +656,8 @@ void WebSocketsServer::handleNewClients(void) { tcpClient->stop(); } -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) - delay(0); + WEBSOCKETS_YIELD(); +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) } #endif } @@ -694,9 +690,7 @@ void WebSocketsServer::handleClientData(void) { handleHBPing(client); handleHBTimeout(client); } -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - delay(0); -#endif + WEBSOCKETS_YIELD(); } } #endif From 80b0867786a42fbeb203869ab43f9d886f92c71f Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 3 May 2020 09:27:49 +0200 Subject: [PATCH 205/347] update travis for IDE 1.8.12 --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index c319bab..871c239 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,13 +11,13 @@ os: env: matrix: - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80" IDE_VERSION=1.6.5 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,dbg=Serial1" IDE_VERSION=1.6.5 - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.5 - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.9 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,dbg=Serial1" IDE_VERSION=1.6.5 - - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.6.5 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.12 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.9 - + - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.12 script: - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 - export DISPLAY=:1.0 From 9048ef9ee4e86cab1e96e8096d83638d26216189 Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 3 May 2020 09:28:55 +0200 Subject: [PATCH 206/347] code style --- src/WebSockets.h | 2 +- src/WebSocketsClient.cpp | 2 +- src/WebSocketsServer.cpp | 40 ++++++++++++++++++++-------------------- src/WebSocketsServer.h | 6 +++--- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 10434fe..0d9b707 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -61,7 +61,7 @@ // moves all Header strings to Flash (~300 Byte) //#define WEBSOCKETS_SAVE_RAM -#if defined(ESP8266) +#if defined(ESP8266) #define WEBSOCKETS_YIELD() delay(0) #elif defined(ESP32) #define WEBSOCKETS_YIELD() yield() diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 179c272..2e7f4b2 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -30,7 +30,7 @@ WebSocketsClient::WebSocketsClient() { _client.num = 0; _client.cIsClient = true; _client.extraHeaders = WEBSOCKETS_STRING("Origin: file://"); - _reconnectInterval = 500; + _reconnectInterval = 500; } WebSocketsClient::~WebSocketsClient() { diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 16ee1c8..a682ec9 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -26,12 +26,12 @@ #include "WebSocketsServer.h" WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol) { - _port = port; - _origin = origin; - _protocol = protocol; - _runnning = false; - _pingInterval = 0; - _pongTimeout = 0; + _port = port; + _origin = origin; + _protocol = protocol; + _runnning = false; + _pingInterval = 0; + _pongTimeout = 0; _disconnectTimeoutCount = 0; _server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port); @@ -95,8 +95,8 @@ void WebSocketsServer::begin(void) { client->cHttpLine = ""; #endif - client->pingInterval = _pingInterval; - client->pongTimeout = _pongTimeout; + client->pingInterval = _pingInterval; + client->pongTimeout = _pongTimeout; client->disconnectTimeoutCount = _disconnectTimeoutCount; } @@ -489,11 +489,11 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine))); #endif - client->pingInterval = _pingInterval; - client->pongTimeout = _pongTimeout; + client->pingInterval = _pingInterval; + client->pongTimeout = _pongTimeout; client->disconnectTimeoutCount = _disconnectTimeoutCount; - client->lastPing = millis(); - client->pongReceived = false; + client->lastPing = millis(); + client->pongReceived = false; return true; break; @@ -657,7 +657,7 @@ void WebSocketsServer::handleNewClients(void) { } WEBSOCKETS_YIELD(); -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) } #endif } @@ -686,7 +686,7 @@ void WebSocketsServer::handleClientData(void) { break; } } - + handleHBPing(client); handleHBTimeout(client); } @@ -873,7 +873,7 @@ void WebSocketsServer::handleHBPing(WSclient_t * client) { return; uint32_t pi = millis() - client->lastPing; if(pi > client->pingInterval) { - DEBUG_WEBSOCKETS("[WS-Server][%d] sending HB ping\n", client->num); + DEBUG_WEBSOCKETS("[WS-Server][%d] sending HB ping\n", client->num); if(sendPing(client->num)) { client->lastPing = millis(); client->pongReceived = false; @@ -888,10 +888,10 @@ void WebSocketsServer::handleHBPing(WSclient_t * client) { * @param disconnectTimeoutCount uint8_t how many timeouts before disconnect, 0=> do not disconnect */ void WebSocketsServer::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { - _pingInterval = pingInterval; - _pongTimeout = pongTimeout; + _pingInterval = pingInterval; + _pongTimeout = pongTimeout; _disconnectTimeoutCount = disconnectTimeoutCount; - + WSclient_t * client; for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { client = &_clients[i]; @@ -904,10 +904,10 @@ void WebSocketsServer::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeo */ void WebSocketsServer::disableHeartbeat() { _pingInterval = 0; - + WSclient_t * client; for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { - client = &_clients[i]; + client = &_clients[i]; client->pingInterval = 0; } } \ No newline at end of file diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 74ea85f..19c934d 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -91,7 +91,7 @@ class WebSocketsServer : protected WebSockets { void setAuthorization(const char * auth); int connectedClients(bool ping = false); - + void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); void disableHeartbeat(); @@ -115,7 +115,7 @@ class WebSocketsServer : protected WebSockets { WebSocketServerHttpHeaderValFunc _httpHeaderValidationFunc; bool _runnning; - + uint32_t _pingInterval; uint32_t _pongTimeout; uint8_t _disconnectTimeoutCount; @@ -133,7 +133,7 @@ class WebSocketsServer : protected WebSockets { #endif void handleHeader(WSclient_t * client, String * headerLine); - + void handleHBPing(WSclient_t * client); // send ping in specified intervals /** From 784088d9cc35bc21b2c845eaabdb6ad8a2638d1b Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 3 May 2020 10:03:53 +0200 Subject: [PATCH 207/347] bump version to 2.2.1 --- library.json | 2 +- library.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index 9fe38a4..49dc2c7 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.2.0", + "version": "2.2.1", "license": "LGPL-2.1", "export": { "exclude": [ diff --git a/library.properties b/library.properties index 4f18ec8..b977444 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.2.0 +version=2.2.1 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From 7a4160814cc5caa0a1ea1d7711f6f46b838e16f1 Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 3 May 2020 13:04:53 +0200 Subject: [PATCH 208/347] fix #454 --- src/WebSocketsClient.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 2e7f4b2..98ecfdb 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -706,6 +706,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { headerDone(client); runCbEvent(WStype_CONNECTED, (uint8_t *)client->cUrl.c_str(), client->cUrl.length()); +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) } else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) { if(_client.tcp->available()) { // read not needed data @@ -714,7 +715,8 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { _client.tcp->read(); } } - sendHeader(client); +#endif + sendHeader(client); } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); _lastConnectionFail = millis(); From 0c3b15c5e77c839481e6992da060a5eae2f41429 Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 3 May 2020 13:04:53 +0200 Subject: [PATCH 209/347] fix #454 --- src/WebSocketsClient.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 2e7f4b2..c67b706 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -706,6 +706,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { headerDone(client); runCbEvent(WStype_CONNECTED, (uint8_t *)client->cUrl.c_str(), client->cUrl.length()); +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) } else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) { if(_client.tcp->available()) { // read not needed data @@ -715,6 +716,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } } sendHeader(client); +#endif } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); _lastConnectionFail = millis(); From a71a4806764c1c1fcd63bcbfd0c48c0a96226177 Mon Sep 17 00:00:00 2001 From: Markus Date: Thu, 14 May 2020 18:04:46 +0200 Subject: [PATCH 210/347] fix #539 (NODEBUG_WEBSOCKETS warning) fix warning when using NODEBUG_WEBSOCKETS as compiler option. --- src/WebSockets.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/WebSockets.h b/src/WebSockets.h index 0d9b707..8e8bba1 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -50,8 +50,10 @@ #ifndef DEBUG_WEBSOCKETS #define DEBUG_WEBSOCKETS(...) +#ifndef NODEBUG_WEBSOCKETS #define NODEBUG_WEBSOCKETS #endif +#endif #if defined(ESP8266) || defined(ESP32) From ba6275e7fef215b640d86e6f420733dd1726bdaf Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 11 Jul 2020 17:55:18 +0200 Subject: [PATCH 211/347] fix #525 (detect ESP32 vesion) --- src/WebSockets.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 6132d28..ba4652a 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -39,7 +39,14 @@ extern "C" { #ifdef ESP8266 #include #elif defined(ESP32) +#include + +#if ESP_IDF_VERSION_MAJOR >= 4 +#include +#else #include +#endif + #else extern "C" { From 3f1cedb21cfa3610577865d8e633d97fb67f2844 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 11 Jul 2020 17:58:36 +0200 Subject: [PATCH 212/347] fix #541 allow loop() to be called before begin() --- src/WebSocketsClient.cpp | 5 +++++ src/WebSocketsClient.h | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index c67b706..967bc9d 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -31,6 +31,8 @@ WebSocketsClient::WebSocketsClient() { _client.cIsClient = true; _client.extraHeaders = WEBSOCKETS_STRING("Origin: file://"); _reconnectInterval = 500; + _port = 0; + _host = ""; } WebSocketsClient::~WebSocketsClient() { @@ -148,6 +150,9 @@ void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, * called in arduino loop */ void WebSocketsClient::loop(void) { + if(_port == 0) { + return; + } WEBSOCKETS_YIELD(); if(!clientIsConnected(&_client)) { // do not flood the server diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index ed3f630..0f51c94 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -91,12 +91,12 @@ class WebSocketsClient : protected WebSockets { void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); void disableHeartbeat(); + bool isConnected(void); + protected: String _host; uint16_t _port; - bool isConnected(void); - #if defined(HAS_SSL) String _fingerprint; const char * _CA_cert; From f244741caa7c224e8ea9fea3cc1470070182df59 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 11 Jul 2020 18:07:16 +0200 Subject: [PATCH 213/347] WebSocketClientSocketIO.ino:113:25: ArduinoJson, you must set ARDUINOJSON_USE_LONG_LONG error --- .../esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino b/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino index 343b5f5..06f7616 100644 --- a/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino +++ b/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino @@ -110,7 +110,7 @@ void loop() { // add payload (parameters) for the event JsonObject param1 = array.createNestedObject(); - param1["now"] = now; + param1["now"] = (uint32_t) now; // JSON to String (serializion) String output; From 44fb41e3b775d81f044a755bb415dc74c1caa31e Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 11 Jul 2020 18:16:34 +0200 Subject: [PATCH 214/347] WebSocketClientSocketIOack.ino:150:25: ARDUINOJSON_USE_LONG_LONG fix --- .../WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino b/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino index bd49ad0..0dabb49 100644 --- a/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino +++ b/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino @@ -147,7 +147,7 @@ void loop() { // add payload (parameters) for the event JsonObject param1 = array.createNestedObject(); - param1["now"] = now; + param1["now"] = (utin32_t) now; // JSON to String (serializion) String output; From 19c39d5ea09d014872359df56daf3ec4617c1163 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 11 Jul 2020 18:38:39 +0200 Subject: [PATCH 215/347] typo --- .../WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino b/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino index 0dabb49..f0f8991 100644 --- a/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino +++ b/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino @@ -147,7 +147,7 @@ void loop() { // add payload (parameters) for the event JsonObject param1 = array.createNestedObject(); - param1["now"] = (utin32_t) now; + param1["now"] = (uint32_t) now; // JSON to String (serializion) String output; From b3c5348e9b11e50069e00bc6fb53a5a62bf70f11 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 25 Jul 2020 09:07:02 +0200 Subject: [PATCH 216/347] update arduino IDE version in travis test --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 871c239..e331fd2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,12 +12,10 @@ env: matrix: - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80" IDE_VERSION=1.6.5 - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,dbg=Serial1" IDE_VERSION=1.6.5 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.5 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.9 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.12 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.13 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.9 - - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.12 + - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.13 script: - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 - export DISPLAY=:1.0 From 4acc7eff8a283be62fb548ef9e07872162eff7cf Mon Sep 17 00:00:00 2001 From: Ben Hencke Date: Thu, 16 Apr 2020 14:38:19 -0700 Subject: [PATCH 217/347] add api to check connectedness of clients by num --- src/WebSocketsServer.cpp | 12 ++++++++++++ src/WebSocketsServer.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index a682ec9..3b76343 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -419,6 +419,18 @@ int WebSocketsServer::connectedClients(bool ping) { return count; } +/** + * see if one client is connected + * @param num uint8_t client id + */ +bool WebSocketsServer::clientIsConnected(uint8_t num) { + if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) { + return false; + } + WSclient_t * client = &_clients[num]; + return clientIsConnected(client); +} + #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) /** * get an IP for a client diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 19c934d..27adf09 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -92,6 +92,8 @@ class WebSocketsServer : protected WebSockets { int connectedClients(bool ping = false); + bool clientIsConnected(uint8_t num); + void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); void disableHeartbeat(); From e185668a97d8402e4ab7827ae0e7932ee707e790 Mon Sep 17 00:00:00 2001 From: Tobias Gessler Date: Sat, 12 Sep 2020 17:20:03 +0200 Subject: [PATCH 218/347] header response timeout added --- src/WebSocketsClient.cpp | 8 ++++++++ src/WebSocketsClient.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 967bc9d..64b3f64 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -85,6 +85,7 @@ void WebSocketsClient::begin(const char * host, uint16_t port, const char * url, #endif _lastConnectionFail = 0; + _lastHeaderSent = 0; } void WebSocketsClient::begin(String host, uint16_t port, String url, String protocol) { @@ -490,6 +491,12 @@ bool WebSocketsClient::clientIsConnected(WSclient_t * client) { * Handel incomming data from Client */ void WebSocketsClient::handleClientData(void) { + if(_client.status == WSC_HEADER && _lastHeaderSent + WEBSOCKETS_TCP_TIMEOUT < millis()) { + DEBUG_WEBSOCKETS("[WS-Client][handleClientData] header response timeout.. disconnecting!\n"); + clientDisconnect(&_client); + WEBSOCKETS_YIELD(); + return; + } int len = _client.tcp->available(); if(len > 0) { switch(_client.status) { @@ -598,6 +605,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { #endif DEBUG_WEBSOCKETS("[WS-Client][sendHeader] sending header... Done (%luus).\n", (micros() - start)); + _lastHeaderSent = millis(); } /** diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 0f51c94..5069875 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -107,6 +107,7 @@ class WebSocketsClient : protected WebSockets { unsigned long _lastConnectionFail; unsigned long _reconnectInterval; + unsigned long _lastHeaderSent; void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); From 083683425f479a3e4df0b6a7d5d43980c09e1cb8 Mon Sep 17 00:00:00 2001 From: Ben Hencke Date: Wed, 16 Sep 2020 11:02:02 -0700 Subject: [PATCH 219/347] avoid flush on esp32, add/fix debugs, longer yield when waiting for data flush causes a bunch of reads as we try to close the socket on esp32. I think flush is broken on that platform. the comments indicate confusion. added some debug logs for important cases that were missing them, some missing newlines to exisitng logs. added a longer yield when waiting for data, in some super busy cases it could trigger a task watchdog or otherwise starve the system. (yield alone doesn't always switch to lower priority tasks) make some other yields conditional to avoid some waste when it would double-yield. --- src/WebSockets.cpp | 15 ++++++++++----- src/WebSockets.h | 2 ++ src/WebSocketsServer.cpp | 3 ++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index ba4652a..8c8ef82 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -501,7 +501,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t reasonCode = payload[0] << 8 | payload[1]; } #endif - DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get ask for close. Code: %d", client->num, reasonCode); + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] get ask for close. Code: %d\n", client->num, reasonCode); if(header->payloadLen > 2) { DEBUG_WEBSOCKETS(" (%s)\n", (payload + 2)); } else { @@ -510,6 +510,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t clientDisconnect(client, 1000); } break; default: + DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] got unknown opcode: %d\n", client->num, header->opCode); clientDisconnect(client, 1002); break; } @@ -630,7 +631,7 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait } if(!client->tcp->available()) { - WEBSOCKETS_YIELD(); + WEBSOCKETS_YIELD_MORE(); continue; } @@ -643,7 +644,9 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait } else { //DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n); } - WEBSOCKETS_YIELD(); + if (n > 0) { + WEBSOCKETS_YIELD(); + } } if(cb) { cb(client, true); @@ -693,9 +696,11 @@ size_t WebSockets::write(WSclient_t * client, uint8_t * out, size_t n) { total += len; //DEBUG_WEBSOCKETS("write %d left %d!\n", len, n); } else { - //DEBUG_WEBSOCKETS("write %d failed left %d!\n", len, n); + DEBUG_WEBSOCKETS("WS write %d failed left %d!\n", len, n); + } + if (n > 0) { + WEBSOCKETS_YIELD(); } - WEBSOCKETS_YIELD(); } WEBSOCKETS_YIELD(); return total; diff --git a/src/WebSockets.h b/src/WebSockets.h index 8e8bba1..b9c6f89 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -65,8 +65,10 @@ #if defined(ESP8266) #define WEBSOCKETS_YIELD() delay(0) +#define WEBSOCKETS_YIELD_MORE() delay(1) #elif defined(ESP32) #define WEBSOCKETS_YIELD() yield() +#define WEBSOCKETS_YIELD_MORE() delay(1) #endif #elif defined(STM32_DEVICE) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 3b76343..c78fffa 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -567,7 +567,7 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { if(client->tcp) { if(client->tcp->connected()) { -#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) && (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP32) client->tcp->flush(); #endif client->tcp->stop(); @@ -694,6 +694,7 @@ void WebSocketsServer::handleClientData(void) { WebSockets::handleWebsocket(client); break; default: + DEBUG_WEBSOCKETS("[WS-Server][%d][handleClientData] unknown client status %d\n", client->num, client->status); WebSockets::clientDisconnect(client, 1002); break; } From 508e0fb691de69149022488c684a1b0c8d505410 Mon Sep 17 00:00:00 2001 From: Ben Hencke Date: Wed, 16 Sep 2020 11:11:24 -0700 Subject: [PATCH 220/347] add missing platforms for WEBSOCKETS_YIELD_MORE --- src/WebSockets.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index b9c6f89..5112d38 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -77,7 +77,7 @@ #define WEBSOCKETS_USE_BIG_MEM #define GET_FREE_HEAP System.freeMemory() #define WEBSOCKETS_YIELD() - +#define WEBSOCKETS_YIELD_MORE() #else //atmega328p has only 2KB ram! @@ -85,7 +85,7 @@ // moves all Header strings to Flash #define WEBSOCKETS_SAVE_RAM #define WEBSOCKETS_YIELD() - +#define WEBSOCKETS_YIELD_MORE() #endif #define WEBSOCKETS_TCP_TIMEOUT (5000) From f65e8d9062875ccf7fff8cda79325a4f1af0cd5c Mon Sep 17 00:00:00 2001 From: lucalas Date: Thu, 1 Oct 2020 01:12:54 +0200 Subject: [PATCH 221/347] call setFingerPrint for ssl object in client with fingerprint received in beginSSL or no connection will start; --- src/WebSocketsClient.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 64b3f64..ebd83b6 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -170,6 +170,7 @@ void WebSocketsClient::loop(void) { _client.tcp = NULL; } _client.ssl = new WEBSOCKETS_NETWORK_SSL_CLASS(); + _client.ssl->setFingerprint(_fingerprint.c_str()); _client.tcp = _client.ssl; if(_CA_cert) { DEBUG_WEBSOCKETS("[WS-Client] setting CA certificate"); From e1ddbfe1a5e6e32e1c6d9615f6391e14ed9de408 Mon Sep 17 00:00:00 2001 From: lucalas Date: Thu, 1 Oct 2020 01:14:01 +0200 Subject: [PATCH 222/347] Format Code; --- src/WebSocketsClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index ebd83b6..b291056 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -170,7 +170,7 @@ void WebSocketsClient::loop(void) { _client.tcp = NULL; } _client.ssl = new WEBSOCKETS_NETWORK_SSL_CLASS(); - _client.ssl->setFingerprint(_fingerprint.c_str()); + _client.ssl->setFingerprint(_fingerprint.c_str()); _client.tcp = _client.ssl; if(_CA_cert) { DEBUG_WEBSOCKETS("[WS-Client] setting CA certificate"); From c73c77e9882765bbcd8ba7a32e6692ee35c94922 Mon Sep 17 00:00:00 2001 From: lucalas Date: Fri, 2 Oct 2020 09:29:55 +0200 Subject: [PATCH 223/347] Add check to set fingerprint; --- src/WebSocketsClient.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index b291056..17cae29 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -170,7 +170,6 @@ void WebSocketsClient::loop(void) { _client.tcp = NULL; } _client.ssl = new WEBSOCKETS_NETWORK_SSL_CLASS(); - _client.ssl->setFingerprint(_fingerprint.c_str()); _client.tcp = _client.ssl; if(_CA_cert) { DEBUG_WEBSOCKETS("[WS-Client] setting CA certificate"); @@ -180,6 +179,10 @@ void WebSocketsClient::loop(void) { _client.ssl->setCACert((const uint8_t *)_CA_cert, strlen(_CA_cert) + 1); #else #error setCACert not implemented +#endif + } else if(_fingerprint.length()) { +#if defined(wificlientbearssl_h) && !defined(USING_AXTLS) && !defined(wificlientsecure_h) + _client.ssl->setFingerprint(_fingerprint.c_str()); #endif } } else { From 91b02341baccf2b3b9dbfaed1d916530bace0d6e Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 4 Oct 2020 14:49:22 +0200 Subject: [PATCH 224/347] Native BareSSL support for ESP8266 see #557, #509, #492, #555, #352 --- src/WebSockets.h | 7 +++++ src/WebSocketsClient.cpp | 58 ++++++++++++++++++++++++++++++++-------- src/WebSocketsClient.h | 15 ++++++++++- src/WebSocketsServer.cpp | 2 +- 4 files changed, 69 insertions(+), 13 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 8e8bba1..3aac838 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -126,6 +126,7 @@ #elif defined(ESP32) #include #include +#define SSL_AXTLS #elif defined(ESP31B) #include #else @@ -145,6 +146,11 @@ #ifdef ESP8266 #include +#if defined(wificlientbearssl_h) && !defined(USING_AXTLS) && !defined(wificlientsecure_h) +#define SSL_BARESSL +#else +#define SSL_AXTLS +#endif #else #include #endif @@ -174,6 +180,7 @@ #include #include +#define SSL_AXTLS #define WEBSOCKETS_NETWORK_CLASS WiFiClient #define WEBSOCKETS_NETWORK_SSL_CLASS WiFiClientSecure #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 17cae29..6c5294e 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -46,7 +46,7 @@ void WebSocketsClient::begin(const char * host, uint16_t port, const char * url, _host = host; _port = port; #if defined(HAS_SSL) - _fingerprint = ""; + _fingerprint = SSL_FINGERPRINT_NULL; _CA_cert = NULL; #endif @@ -97,6 +97,7 @@ void WebSocketsClient::begin(IPAddress host, uint16_t port, const char * url, co } #if defined(HAS_SSL) +#if defined(SSL_AXTLS) void WebSocketsClient::beginSSL(const char * host, uint16_t port, const char * url, const char * fingerprint, const char * protocol) { begin(host, port, url, protocol); _client.isSSL = true; @@ -111,10 +112,31 @@ void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String f void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { begin(host, port, url, protocol); _client.isSSL = true; - _fingerprint = ""; + _fingerprint = SSL_FINGERPRINT_NULL; _CA_cert = CA_cert; } -#endif +#else +void WebSocketsClient::beginSSL(const char * host, uint16_t port, const char * url, const uint8_t * fingerprint, const char * protocol) { + begin(host, port, url, protocol); + _client.isSSL = true; + _fingerprint = fingerprint; + _CA_cert = NULL; +} +void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { + begin(host, port, url, protocol); + _client.isSSL = true; + _fingerprint = SSL_FINGERPRINT_NULL; + _CA_cert = new BearSSL::X509List(CA_cert); +} + +void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) { + begin(host, port, url, protocol); + _client.isSSL = true; + _fingerprint = SSL_FINGERPRINT_NULL; + _CA_cert = CA_cert; +} +#endif // SSL_AXTLS +#endif // HAS_SSL void WebSocketsClient::beginSocketIO(const char * host, uint16_t port, const char * url, const char * protocol) { begin(host, port, url, protocol); @@ -130,7 +152,7 @@ void WebSocketsClient::beginSocketIOSSL(const char * host, uint16_t port, const begin(host, port, url, protocol); _client.isSocketIO = true; _client.isSSL = true; - _fingerprint = ""; + _fingerprint = SSL_FINGERPRINT_NULL; } void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url, String protocol) { @@ -141,8 +163,12 @@ void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, begin(host, port, url, protocol); _client.isSocketIO = true; _client.isSSL = true; - _fingerprint = ""; - _CA_cert = CA_cert; + _fingerprint = SSL_FINGERPRINT_NULL; +#if defined(SSL_AXTLS) + _CA_cert = CA_cert; +#else + _CA_cert = new BearSSL::X509List(CA_cert); +#endif } #endif @@ -175,14 +201,20 @@ void WebSocketsClient::loop(void) { DEBUG_WEBSOCKETS("[WS-Client] setting CA certificate"); #if defined(ESP32) _client.ssl->setCACert(_CA_cert); -#elif defined(ESP8266) +#elif defined(ESP8266) && defined(SSL_AXTLS) _client.ssl->setCACert((const uint8_t *)_CA_cert, strlen(_CA_cert) + 1); +#elif defined(ESP8266) && defined(SSL_BARESSL) + _client.ssl->setTrustAnchors(_CA_cert); #else #error setCACert not implemented #endif - } else if(_fingerprint.length()) { -#if defined(wificlientbearssl_h) && !defined(USING_AXTLS) && !defined(wificlientsecure_h) - _client.ssl->setFingerprint(_fingerprint.c_str()); +#if defined(SSL_BARESSL) + } else if(_fingerprint) { + _client.ssl->setFingerprint(_fingerprint); +#endif + } else { +#if defined(SSL_BARESSL) + _client.ssl->setInsecure(); #endif } } else { @@ -774,14 +806,18 @@ void WebSocketsClient::connectedCb() { #endif #if defined(HAS_SSL) +#if defined(SSL_AXTLS) || defined(ESP32) if(_client.isSSL && _fingerprint.length()) { if(!_client.ssl->verify(_fingerprint.c_str(), _host.c_str())) { DEBUG_WEBSOCKETS("[WS-Client] certificate mismatch\n"); WebSockets::clientDisconnect(&_client, 1000); return; } +#else + if(_client.isSSL && _fingerprint) { +#endif } else if(_client.isSSL && !_CA_cert) { -#if defined(wificlientbearssl_h) && !defined(USING_AXTLS) && !defined(wificlientsecure_h) +#if defined(SSL_BARESSL) _client.ssl->setInsecure(); #endif } diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 5069875..f99dde7 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -43,8 +43,13 @@ class WebSocketsClient : protected WebSockets { void begin(IPAddress host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); #if defined(HAS_SSL) - void beginSSL(const char * host, uint16_t port, const char * url = "/", const char * = "", const char * protocol = "arduino"); +#ifdef SSL_AXTLS + void beginSSL(const char * host, uint16_t port, const char * url = "/", const char * fingerprint = "", const char * protocol = "arduino"); void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino"); +#else + void beginSSL(const char * host, uint16_t port, const char * url = "/", const uint8_t * fingerprint = NULL, const char * protocol = "arduino"); + void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino"); +#endif void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", const char * CA_cert = NULL, const char * protocol = "arduino"); #endif @@ -98,8 +103,16 @@ class WebSocketsClient : protected WebSockets { uint16_t _port; #if defined(HAS_SSL) +#ifdef SSL_AXTLS String _fingerprint; const char * _CA_cert; +#define SSL_FINGERPRINT_NULL "" +#else + const uint8_t * _fingerprint; + BearSSL::X509List * _CA_cert; +#define SSL_FINGERPRINT_NULL NULL +#endif + #endif WSclient_t _client; diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 3b76343..336da00 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -424,7 +424,7 @@ int WebSocketsServer::connectedClients(bool ping) { * @param num uint8_t client id */ bool WebSocketsServer::clientIsConnected(uint8_t num) { - if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) { + if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) { return false; } WSclient_t * client = &_clients[num]; From 9982818cfaaab130e7cbc1ed3a029d39e4068a6e Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 4 Oct 2020 14:56:29 +0200 Subject: [PATCH 225/347] update README travis from org to com --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 581b76e..151b024 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -WebSocket Server and Client for Arduino [![Build Status](https://travis-ci.org/Links2004/arduinoWebSockets.svg?branch=master)](https://travis-ci.org/Links2004/arduinoWebSockets) +WebSocket Server and Client for Arduino [![Build Status](https://travis-ci.com/Links2004/arduinoWebSockets.svg?branch=master)](https://travis-ci.com/Links2004/arduinoWebSockets) =========================================== a WebSocket Server and Client for Arduino based on RFC6455. From f2265118b4cf93a36c74099b615cd6310a05fe95 Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 4 Oct 2020 14:59:51 +0200 Subject: [PATCH 226/347] bump version to 2.3.0 and add note for ESP8266 BareSSL API changes --- README.md | 4 +++- library.json | 2 +- library.properties | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 151b024..599b48e 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,9 @@ a WebSocket Server and Client for Arduino based on RFC6455. ###### Note: ###### - version 2.0 and up is not compatible with AVR/ATmega, check ATmega branch. + version 2.0.0 and up is not compatible with AVR/ATmega, check ATmega branch. + + version 2.3.0 has API changes for the ESP8266 BareSSL (may brakes existing code) Arduino for AVR not supports std namespace of c++. diff --git a/library.json b/library.json index 49dc2c7..1f37235 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.2.1", + "version": "2.3.0", "license": "LGPL-2.1", "export": { "exclude": [ diff --git a/library.properties b/library.properties index b977444..130d851 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.2.1 +version=2.3.0 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From beba0f88e3175ebf837523bb173a1b100426a70d Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 4 Oct 2020 15:02:09 +0200 Subject: [PATCH 227/347] fix README.md --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 599b48e..5600252 100644 --- a/README.md +++ b/README.md @@ -81,10 +81,12 @@ Where `WStype_t type` is defined as: WStype_CONNECTED, WStype_TEXT, WStype_BIN, - WStype_FRAGMENT_TEXT_START, - WStype_FRAGMENT_BIN_START, - WStype_FRAGMENT, - WStype_FRAGMENT_FIN, + WStype_FRAGMENT_TEXT_START, + WStype_FRAGMENT_BIN_START, + WStype_FRAGMENT, + WStype_FRAGMENT_FIN, + WStype_PING, + WStype_PONG, } WStype_t; ``` From ca52afeec09d5e3ff5e498293fe0f0a9bdee710c Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 4 Oct 2020 15:11:06 +0200 Subject: [PATCH 228/347] code style --- src/WebSocketsClient.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 6c5294e..038ff94 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -211,9 +211,7 @@ void WebSocketsClient::loop(void) { #if defined(SSL_BARESSL) } else if(_fingerprint) { _client.ssl->setFingerprint(_fingerprint); -#endif } else { -#if defined(SSL_BARESSL) _client.ssl->setInsecure(); #endif } From a086303c87cc0f6aba3fdaf30d8da9b8ba9c57d2 Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 4 Oct 2020 16:06:55 +0200 Subject: [PATCH 229/347] make old Arduino IDE (1.6.x) happy with CA ``` java.lang.StackOverflowError at java.util.regex.Pattern$Loop.match(Pattern.java:4785) at java.util.regex.Pattern$GroupTail.match(Pattern.java:4717) at java.util.regex.Pattern$BranchConn.match(Pattern.java:4568) at java.util.regex.Pattern$CharProperty.match(Pattern.java:3777) at java.util.regex.Pattern$Branch.match(Pattern.java:4604) at java.util.regex.Pattern$GroupHead.match(Pattern.java:4658) at java.util.regex.Pattern$Loop.match(Pattern.java:4785) ``` --- .../WebSocketClientSSLWithCA.ino | 36 +++++++------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino b/examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino index 6d95d7d..72ffae9 100644 --- a/examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino +++ b/examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino @@ -24,30 +24,18 @@ WebSocketsClient webSocket; // openssl s_client -showcerts -connect echo.websocket.org:443 Date: Sun, 4 Oct 2020 16:20:27 +0200 Subject: [PATCH 230/347] travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e331fd2..7c59234 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,8 +10,8 @@ os: - linux env: matrix: - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80" IDE_VERSION=1.6.5 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,dbg=Serial1" IDE_VERSION=1.6.5 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80" IDE_VERSION=1.6.13 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,dbg=Serial1" IDE_VERSION=1.6.13 - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.13 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.5 - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.9 From 5caff59f7f08f0d2614b516dd14cad8064d04e92 Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 4 Oct 2020 16:34:25 +0200 Subject: [PATCH 231/347] bump version to 2.3.1 --- library.json | 2 +- library.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index 1f37235..7ac6a78 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.3.0", + "version": "2.3.1", "license": "LGPL-2.1", "export": { "exclude": [ diff --git a/library.properties b/library.properties index 130d851..203df40 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.3.0 +version=2.3.1 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From 80bf087cd0805e5fd0a38e585cf6c494c413363c Mon Sep 17 00:00:00 2001 From: itay7564 <22itaysh@gmail.com> Date: Mon, 26 Oct 2020 18:01:31 +0200 Subject: [PATCH 232/347] Add SSL client certificate support (#572) * Add client certificate support allows WiFiClientSecureBearSSL users to use client certificate and private key for the WebSocker. also added SSL functions for socket.io --- .../WebSocketClientSSLWithCA.ino | 4 ++ src/SocketIOclient.cpp | 30 +++++++++++++ src/SocketIOclient.h | 10 +++++ src/WebSocketsClient.cpp | 44 ++++++++++++++----- src/WebSocketsClient.h | 10 ++++- 5 files changed, 87 insertions(+), 11 deletions(-) diff --git a/examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino b/examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino index 72ffae9..214f5e6 100644 --- a/examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino +++ b/examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino @@ -90,6 +90,10 @@ void setup() { delay(100); } + //When using BearSSL, client certificate and private key can be set: + //webSocket.setSSLClientCertKey(clientCert, clientPrivateKey); + //clientCert and clientPrivateKey can be of types (const char *, const char *) , or of types (BearSSL::X509List, BearSSL::PrivateKey) + webSocket.beginSslWithCA("echo.websocket.org", 443, "/", ENDPOINT_CA_CERT); webSocket.onEvent(webSocketEvent); } diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index 6b14319..4233e2c 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -24,7 +24,37 @@ void SocketIOclient::begin(String host, uint16_t port, String url, String protoc WebSocketsClient::beginSocketIO(host, port, url, protocol); WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); } +#if defined(HAS_SSL) +void SocketIOclient::beginSSL(const char * host, uint16_t port, const char * url, const char * protocol) { + WebSocketsClient::beginSocketIOSSL(host, port, url, protocol); + WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); +} + +void SocketIOclient::beginSSL(String host, uint16_t port, String url, String protocol) { + WebSocketsClient::beginSocketIOSSL(host, port, url, protocol); + WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); +} +#if !defined(SSL_AXTLS) +void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { + WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol); + WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); +} + +void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) { + WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol); + WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); +} + +void SocketIOclient::setSSLClientCertKey(const char * clientCert, const char * clientPrivateKey) { + WebSocketsClient::setSSLClientCertKey(clientCert, clientPrivateKey); +} + +void SocketIOclient::setSSLClientCertKey(BearSSL::X509List * clientCert, BearSSL::PrivateKey * clientPrivateKey) { + WebSocketsClient::setSSLClientCertKey(clientCert, clientPrivateKey); +} +#endif +#endif /** * set callback function * @param cbEvent SocketIOclientEvent diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index ca0a69b..cf674cb 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -49,6 +49,16 @@ class SocketIOclient : protected WebSocketsClient { void begin(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); void begin(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); +#ifdef HAS_SSL + void beginSSL(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); + void beginSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); +#ifndef SSL_AXTLS + void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino"); + void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino"); + void setSSLClientCertKey(const char * clientCert = NULL, const char * clientPrivateKey = NULL); + void setSSLClientCertKey(BearSSL::X509List * clientCert = NULL, BearSSL::PrivateKey * clientPrivateKey = NULL); +#endif +#endif bool isConnected(void); void onEvent(SocketIOclientEvent cbEvent); diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 038ff94..6ec0af1 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -122,12 +122,6 @@ void WebSocketsClient::beginSSL(const char * host, uint16_t port, const char * u _fingerprint = fingerprint; _CA_cert = NULL; } -void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { - begin(host, port, url, protocol); - _client.isSSL = true; - _fingerprint = SSL_FINGERPRINT_NULL; - _CA_cert = new BearSSL::X509List(CA_cert); -} void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) { begin(host, port, url, protocol); @@ -135,6 +129,20 @@ void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const ch _fingerprint = SSL_FINGERPRINT_NULL; _CA_cert = CA_cert; } + +void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { + beginSslWithCA(host, port, url, new BearSSL::X509List(CA_cert), protocol); +} + +void WebSocketsClient::setSSLClientCertKey(BearSSL::X509List * clientCert, BearSSL::PrivateKey * clientPrivateKey) { + _client_cert = clientCert; + _client_key = clientPrivateKey; +} + +void WebSocketsClient::setSSLClientCertKey(const char * clientCert, const char * clientPrivateKey) { + setSSLClientCertKey(new BearSSL::X509List(clientCert), new BearSSL::PrivateKey(clientPrivateKey)); +} + #endif // SSL_AXTLS #endif // HAS_SSL @@ -148,7 +156,7 @@ void WebSocketsClient::beginSocketIO(String host, uint16_t port, String url, Str } #if defined(HAS_SSL) -void WebSocketsClient::beginSocketIOSSL(const char * host, uint16_t port, const char * url, const char * protocol) { +void WebSocketsClient::beginSocketIOSSL(const char * host, uint16_t port, const char * url, const char * protocol) { begin(host, port, url, protocol); _client.isSocketIO = true; _client.isSSL = true; @@ -159,17 +167,29 @@ void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url, beginSocketIOSSL(host.c_str(), port, url.c_str(), protocol.c_str()); } -void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { +#if defined(SSL_BARESSL) +void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) { begin(host, port, url, protocol); _client.isSocketIO = true; _client.isSSL = true; _fingerprint = SSL_FINGERPRINT_NULL; -#if defined(SSL_AXTLS) _CA_cert = CA_cert; -#else +} +#endif + +void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { + begin(host, port, url, protocol); + _client.isSocketIO = true; + _client.isSSL = true; + _fingerprint = SSL_FINGERPRINT_NULL; +#if defined(SSL_BARESSL) _CA_cert = new BearSSL::X509List(CA_cert); +#else + _CA_cert = CA_cert; #endif } + + #endif #if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) @@ -213,6 +233,10 @@ void WebSocketsClient::loop(void) { _client.ssl->setFingerprint(_fingerprint); } else { _client.ssl->setInsecure(); + } + if(_client_cert && _client_key) { + _client.ssl->setClientRSACert(_client_cert, _client_key); + DEBUG_WEBSOCKETS("[WS-Client] setting client certificate and key"); #endif } } else { diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index f99dde7..cc9a0c7 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -49,6 +49,8 @@ class WebSocketsClient : protected WebSockets { #else void beginSSL(const char * host, uint16_t port, const char * url = "/", const uint8_t * fingerprint = NULL, const char * protocol = "arduino"); void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino"); + void setSSLClientCertKey(BearSSL::X509List * clientCert = NULL, BearSSL::PrivateKey * clientPrivateKey = NULL); + void setSSLClientCertKey(const char * clientCert = NULL, const char * clientPrivateKey = NULL); #endif void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", const char * CA_cert = NULL, const char * protocol = "arduino"); #endif @@ -59,9 +61,13 @@ class WebSocketsClient : protected WebSockets { #if defined(HAS_SSL) void beginSocketIOSSL(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); void beginSocketIOSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); + void beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino"); +#if defined(SSL_BARESSL) + void beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino"); #endif - +#endif + #if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void loop(void); #else @@ -110,6 +116,8 @@ class WebSocketsClient : protected WebSockets { #else const uint8_t * _fingerprint; BearSSL::X509List * _CA_cert; + BearSSL::X509List * _client_cert; + BearSSL::PrivateKey * _client_key; #define SSL_FINGERPRINT_NULL NULL #endif From 4db14451fb8b47ee620e3ef6687fd591ab5f6a30 Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 26 Oct 2020 17:04:19 +0100 Subject: [PATCH 233/347] clang-format --- src/WebSockets.cpp | 4 ++-- src/WebSocketsClient.cpp | 11 +++++------ src/WebSocketsClient.h | 2 +- src/WebSocketsServer.h | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 8c8ef82..ef8224c 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -644,7 +644,7 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait } else { //DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n); } - if (n > 0) { + if(n > 0) { WEBSOCKETS_YIELD(); } } @@ -698,7 +698,7 @@ size_t WebSockets::write(WSclient_t * client, uint8_t * out, size_t n) { } else { DEBUG_WEBSOCKETS("WS write %d failed left %d!\n", len, n); } - if (n > 0) { + if(n > 0) { WEBSOCKETS_YIELD(); } } diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 6ec0af1..bc6a42e 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -136,7 +136,7 @@ void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const ch void WebSocketsClient::setSSLClientCertKey(BearSSL::X509List * clientCert, BearSSL::PrivateKey * clientPrivateKey) { _client_cert = clientCert; - _client_key = clientPrivateKey; + _client_key = clientPrivateKey; } void WebSocketsClient::setSSLClientCertKey(const char * clientCert, const char * clientPrivateKey) { @@ -156,7 +156,7 @@ void WebSocketsClient::beginSocketIO(String host, uint16_t port, String url, Str } #if defined(HAS_SSL) -void WebSocketsClient::beginSocketIOSSL(const char * host, uint16_t port, const char * url, const char * protocol) { +void WebSocketsClient::beginSocketIOSSL(const char * host, uint16_t port, const char * url, const char * protocol) { begin(host, port, url, protocol); _client.isSocketIO = true; _client.isSSL = true; @@ -168,12 +168,12 @@ void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url, } #if defined(SSL_BARESSL) -void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) { +void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) { begin(host, port, url, protocol); _client.isSocketIO = true; _client.isSSL = true; _fingerprint = SSL_FINGERPRINT_NULL; - _CA_cert = CA_cert; + _CA_cert = CA_cert; } #endif @@ -189,7 +189,6 @@ void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, #endif } - #endif #if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) @@ -236,7 +235,7 @@ void WebSocketsClient::loop(void) { } if(_client_cert && _client_key) { _client.ssl->setClientRSACert(_client_cert, _client_key); - DEBUG_WEBSOCKETS("[WS-Client] setting client certificate and key"); + DEBUG_WEBSOCKETS("[WS-Client] setting client certificate and key"); #endif } } else { diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index cc9a0c7..15863a7 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -67,7 +67,7 @@ class WebSocketsClient : protected WebSockets { void beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino"); #endif #endif - + #if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void loop(void); #else diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 27adf09..2541788 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -93,7 +93,7 @@ class WebSocketsServer : protected WebSockets { int connectedClients(bool ping = false); bool clientIsConnected(uint8_t num); - + void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); void disableHeartbeat(); From 7fea0b8bdf14242a6d21cffc1646e9f8f2152551 Mon Sep 17 00:00:00 2001 From: James Stubbington Date: Sat, 14 Nov 2020 11:17:10 -0600 Subject: [PATCH 234/347] Fix for Newline in Headers when extraHeaders is Empty [577] (#578) Closes https://github.com/Links2004/arduinoWebSockets/issues/577 --- src/WebSocketsClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index bc6a42e..b4ba4a4 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -636,7 +636,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { } // add extra headers; by default this includes "Origin: file://" - if(client->extraHeaders) { + if(client->extraHeaders.length() > 0) { handshake += client->extraHeaders + NEW_LINE; } From 826c6b423a0f607a01b4cb69f42690dcb9291cf1 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sat, 21 Nov 2020 13:51:16 +0100 Subject: [PATCH 235/347] esp8266: share port 80 with regular webserver (#575) --- .../WebSocketServerHooked.ino | 103 +++++++ examples/esp8266/WebSocketServerHooked/emu | 20 ++ .../WebSocketServerHooked/ws-testclient.py | 45 +++ src/WebSockets.h | 2 +- src/WebSockets4WebServer.h | 76 +++++ src/WebSocketsServer.cpp | 282 ++++++++++-------- src/WebSocketsServer.h | 68 +++-- 7 files changed, 459 insertions(+), 137 deletions(-) create mode 100644 examples/esp8266/WebSocketServerHooked/WebSocketServerHooked.ino create mode 100755 examples/esp8266/WebSocketServerHooked/emu create mode 100755 examples/esp8266/WebSocketServerHooked/ws-testclient.py create mode 100644 src/WebSockets4WebServer.h diff --git a/examples/esp8266/WebSocketServerHooked/WebSocketServerHooked.ino b/examples/esp8266/WebSocketServerHooked/WebSocketServerHooked.ino new file mode 100644 index 0000000..1a74f8d --- /dev/null +++ b/examples/esp8266/WebSocketServerHooked/WebSocketServerHooked.ino @@ -0,0 +1,103 @@ +/* + * WebSocketServerHooked.ino + * + * Created on: 22.05.2015 + * Hooked on: 28.10.2020 + * + */ + +#include + +#include +#include +#include +#include +#include + +ESP8266WiFiMulti WiFiMulti; + +ESP8266WebServer server(80); +WebSockets4WebServer webSocket; + +#define USE_SERIAL Serial + +void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { + + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[%u] Disconnected!\n", num); + break; + case WStype_CONNECTED: + { + IPAddress ip = webSocket.remoteIP(num); + USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); + + // send message to client + webSocket.sendTXT(num, "Connected"); + } + break; + case WStype_TEXT: + USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); + + // send message to client + // webSocket.sendTXT(num, "message here"); + + // send data to all connected clients + // webSocket.broadcastTXT("message here"); + break; + case WStype_BIN: + USE_SERIAL.printf("[%u] get binary length: %u\n", num, length); + hexdump(payload, length); + + // send message to client + // webSocket.sendBIN(num, payload, length); + break; + } + +} + +void setup() { + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + //Serial.setDebugOutput(true); + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFiMulti.addAP("SSID", "passpasspass"); + + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + server.on("/", []() { + server.send(200, "text/plain", "I am a regular webserver on port 80!\r\n"); + server.send(200, "text/plain", "I am also a websocket server on '/ws' on the same port 80\r\n"); + }); + + server.addHook(webSocket.hookForWebserver("/ws", webSocketEvent)); + + server.begin(); + Serial.println("HTTP server started on port 80"); + Serial.println("WebSocket server started on the same port"); + Serial.printf("my network address is either 'arduinoWebsockets.local' (mDNS) or '%s'\n", WiFi.localIP().toString().c_str()); + + if (!MDNS.begin("arduinoWebsockets")) { + Serial.println("Error setting up MDNS responder!"); + } +} + +void loop() { + server.handleClient(); + webSocket.loop(); + MDNS.update(); +} diff --git a/examples/esp8266/WebSocketServerHooked/emu b/examples/esp8266/WebSocketServerHooked/emu new file mode 100755 index 0000000..867a8cd --- /dev/null +++ b/examples/esp8266/WebSocketServerHooked/emu @@ -0,0 +1,20 @@ +#!/bin/sh + +# linux script to compile&run arduinoWebSockets in a mock environment + +if [ -z "$ESP8266ARDUINO" ]; then + echo "please set ESP8266ARDUINO env-var to where esp8266/arduino sits" + exit 1 +fi + +set -e + +where=$(pwd) + +cd $ESP8266ARDUINO/tests/host/ + +make -j FORCE32=0 \ + ULIBDIRS=../../libraries/Hash/:~/dev/proj/arduino/libraries/arduinoWebSockets \ + ${where}/WebSocketServerHooked + +valgrind ./bin/WebSocketServerHooked/WebSocketServerHooked -b "$@" diff --git a/examples/esp8266/WebSocketServerHooked/ws-testclient.py b/examples/esp8266/WebSocketServerHooked/ws-testclient.py new file mode 100755 index 0000000..546c7ff --- /dev/null +++ b/examples/esp8266/WebSocketServerHooked/ws-testclient.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +# python websocket client to test with +# emulator: server is at ws://127.0.0.1:9080/ws +# esp8266: server is at ws:///ws +# (uncomment the right line below) + +#uri = "ws://127.0.0.1:9080/ws" +uri = "ws://arduinoWebsockets.local/ws" + +import websocket +try: + import thread +except ImportError: + import _thread as thread +import time + +def on_message(ws, message): + print("message"); + print(message) + +def on_error(ws, error): + print("error") + print(error) + +def on_close(ws): + print("### closed ###") + +def on_open(ws): + print("opened") + def run(*args): + for i in range(3): + time.sleep(1) + ws.send("Hello %d" % i) + time.sleep(1) + ws.close() + print("thread terminating...") + thread.start_new_thread(run, ()) + + +if __name__ == "__main__": + websocket.enableTrace(True) + ws = websocket.WebSocketApp(uri, on_message = on_message, on_error = on_error, on_close = on_close) + ws.on_open = on_open + ws.run_forever() diff --git a/src/WebSockets.h b/src/WebSockets.h index a858c84..4fed8a0 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -42,7 +42,7 @@ #ifndef NODEBUG_WEBSOCKETS #ifdef DEBUG_ESP_PORT -#define DEBUG_WEBSOCKETS(...) DEBUG_ESP_PORT.printf(__VA_ARGS__) +#define DEBUG_WEBSOCKETS(...) { DEBUG_ESP_PORT.printf(__VA_ARGS__); DEBUG_ESP_PORT.flush(); } #else //#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) #endif diff --git a/src/WebSockets4WebServer.h b/src/WebSockets4WebServer.h new file mode 100644 index 0000000..514abbb --- /dev/null +++ b/src/WebSockets4WebServer.h @@ -0,0 +1,76 @@ +/** + * @file WebSocketsServer.cpp + * @date 28.10.2020 + * @author Markus Sattler & esp8266/arduino community + * + * Copyright (c) 2020 Markus Sattler. All rights reserved. + * This file is part of the WebSockets for Arduino. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __WEBSOCKETS4WEBSERVER_H +#define __WEBSOCKETS4WEBSERVER_H + +#include +#include + +#if WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK + +class WebSockets4WebServer: public WebSocketsServerCore { + public: + + WebSockets4WebServer(const String& origin = "", const String& protocol = "arduino"): + WebSocketsServerCore(origin, protocol) + { + begin(); + } + + ESP8266WebServer::HookFunction hookForWebserver (const String& wsRootDir, WebSocketServerEvent event) + { + onEvent(event); + + return [&, wsRootDir](const String & method, const String & url, WiFiClient * tcpClient, ESP8266WebServer::ContentTypeFunction contentType) + { + if (!(method == "GET" && url.indexOf(wsRootDir) == 0)) { + return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; + } + + // allocate a WiFiClient copy (like in WebSocketsServer::handleNewClients()) + WEBSOCKETS_NETWORK_CLASS * newTcpClient = new WEBSOCKETS_NETWORK_CLASS(*tcpClient); + + // Then initialize a new WSclient_t (like in WebSocketsServer::handleNewClient()) + WSclient_t * client = handleNewClient(newTcpClient); + + if (client) + { + // give "GET " + String headerLine; + headerLine.reserve(url.length() + 5); + headerLine = "GET "; + headerLine += url; + handleHeader(client, &headerLine); + } + + // tell webserver to not close but forget about this client + return ESP8266WebServer::CLIENT_IS_GIVEN; + }; + } +}; + +#endif // WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK + +#endif // __WEBSOCKETS4WEBSERVER_H diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index a614350..74b4228 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -25,8 +25,7 @@ #include "WebSockets.h" #include "WebSocketsServer.h" -WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol) { - _port = port; +WebSocketsServerCore::WebSocketsServerCore(const String& origin, const String& protocol) { _origin = origin; _protocol = protocol; _runnning = false; @@ -34,15 +33,6 @@ WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol _pongTimeout = 0; _disconnectTimeoutCount = 0; - _server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port); - -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) - _server->onClient([](void * s, AsyncClient * c) { - ((WebSocketsServer *)s)->newClient(new AsyncTCPbuffer(c)); - }, - this); -#endif - _cbEvent = NULL; _httpHeaderValidationFunc = NULL; @@ -52,7 +42,21 @@ WebSocketsServer::WebSocketsServer(uint16_t port, String origin, String protocol memset(&_clients[0], 0x00, (sizeof(WSclient_t) * WEBSOCKETS_SERVER_CLIENT_MAX)); } -WebSocketsServer::~WebSocketsServer() { +WebSocketsServer::WebSocketsServer(uint16_t port, const String& origin, const String& protocol): + WebSocketsServerCore(origin, protocol) { + _port = port; + + _server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port); + +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + _server->onClient([](void * s, AsyncClient * c) { + ((WebSocketsServerCore *)s)->newClient(new AsyncTCPbuffer(c)); + }, + this); +#endif +} + +WebSocketsServerCore::~WebSocketsServerCore() { // disconnect all clients close(); @@ -62,10 +66,13 @@ WebSocketsServer::~WebSocketsServer() { _mandatoryHttpHeaderCount = 0; } +WebSocketsServer::~WebSocketsServer() { +} + /** * called to initialize the Websocket server */ -void WebSocketsServer::begin(void) { +void WebSocketsServerCore::begin(void) { WSclient_t * client; // init client storage @@ -82,12 +89,16 @@ void WebSocketsServer::begin(void) { client->cUrl = ""; client->cCode = 0; client->cKey = ""; + client->cAccept = ""; client->cProtocol = ""; + client->cExtensions = ""; client->cVersion = 0; client->cIsUpgrade = false; client->cIsWebsocket = false; client->base64Authorization = ""; + client->plainAuthorization = ""; + client->extraHeaders = ""; client->cWsRXsize = 0; @@ -111,43 +122,18 @@ void WebSocketsServer::begin(void) { #endif _runnning = true; - _server->begin(); - - DEBUG_WEBSOCKETS("[WS-Server] Server Started.\n"); } -void WebSocketsServer::close(void) { +void WebSocketsServerCore::close(void) { _runnning = false; disconnect(); - -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) - _server->close(); -#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) - _server->end(); -#else - // TODO how to close server? -#endif } -#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) -/** - * called in arduino loop - */ -void WebSocketsServer::loop(void) { - if(_runnning) { - WEBSOCKETS_YIELD(); - handleNewClients(); - WEBSOCKETS_YIELD(); - handleClientData(); - } -} -#endif - /** * set callback function * @param cbEvent WebSocketServerEvent */ -void WebSocketsServer::onEvent(WebSocketServerEvent cbEvent) { +void WebSocketsServerCore::onEvent(WebSocketServerEvent cbEvent) { _cbEvent = cbEvent; } @@ -157,7 +143,7 @@ void WebSocketsServer::onEvent(WebSocketServerEvent cbEvent) { * @param mandatoryHttpHeaders[] const char* ///< the array of named http headers considered to be mandatory / must be present in order for websocket upgrade to succeed * @param mandatoryHttpHeaderCount size_t ///< the number of items in the mandatoryHttpHeaders array */ -void WebSocketsServer::onValidateHttpHeader( +void WebSocketsServerCore::onValidateHttpHeader( WebSocketServerHttpHeaderValFunc validationFunc, const char * mandatoryHttpHeaders[], size_t mandatoryHttpHeaderCount) { @@ -182,7 +168,7 @@ void WebSocketsServer::onValidateHttpHeader( * @param headerToPayload bool (see sendFrame for more details) * @return true if ok */ -bool WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) { +bool WebSocketsServerCore::sendTXT(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) { if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) { return false; } @@ -196,19 +182,19 @@ bool WebSocketsServer::sendTXT(uint8_t num, uint8_t * payload, size_t length, bo return false; } -bool WebSocketsServer::sendTXT(uint8_t num, const uint8_t * payload, size_t length) { +bool WebSocketsServerCore::sendTXT(uint8_t num, const uint8_t * payload, size_t length) { return sendTXT(num, (uint8_t *)payload, length); } -bool WebSocketsServer::sendTXT(uint8_t num, char * payload, size_t length, bool headerToPayload) { +bool WebSocketsServerCore::sendTXT(uint8_t num, char * payload, size_t length, bool headerToPayload) { return sendTXT(num, (uint8_t *)payload, length, headerToPayload); } -bool WebSocketsServer::sendTXT(uint8_t num, const char * payload, size_t length) { +bool WebSocketsServerCore::sendTXT(uint8_t num, const char * payload, size_t length) { return sendTXT(num, (uint8_t *)payload, length); } -bool WebSocketsServer::sendTXT(uint8_t num, String & payload) { +bool WebSocketsServerCore::sendTXT(uint8_t num, String & payload) { return sendTXT(num, (uint8_t *)payload.c_str(), payload.length()); } @@ -219,7 +205,7 @@ bool WebSocketsServer::sendTXT(uint8_t num, String & payload) { * @param headerToPayload bool (see sendFrame for more details) * @return true if ok */ -bool WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool headerToPayload) { +bool WebSocketsServerCore::broadcastTXT(uint8_t * payload, size_t length, bool headerToPayload) { WSclient_t * client; bool ret = true; if(length == 0) { @@ -238,19 +224,19 @@ bool WebSocketsServer::broadcastTXT(uint8_t * payload, size_t length, bool heade return ret; } -bool WebSocketsServer::broadcastTXT(const uint8_t * payload, size_t length) { +bool WebSocketsServerCore::broadcastTXT(const uint8_t * payload, size_t length) { return broadcastTXT((uint8_t *)payload, length); } -bool WebSocketsServer::broadcastTXT(char * payload, size_t length, bool headerToPayload) { +bool WebSocketsServerCore::broadcastTXT(char * payload, size_t length, bool headerToPayload) { return broadcastTXT((uint8_t *)payload, length, headerToPayload); } -bool WebSocketsServer::broadcastTXT(const char * payload, size_t length) { +bool WebSocketsServerCore::broadcastTXT(const char * payload, size_t length) { return broadcastTXT((uint8_t *)payload, length); } -bool WebSocketsServer::broadcastTXT(String & payload) { +bool WebSocketsServerCore::broadcastTXT(String & payload) { return broadcastTXT((uint8_t *)payload.c_str(), payload.length()); } @@ -262,7 +248,7 @@ bool WebSocketsServer::broadcastTXT(String & payload) { * @param headerToPayload bool (see sendFrame for more details) * @return true if ok */ -bool WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) { +bool WebSocketsServerCore::sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload) { if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) { return false; } @@ -273,7 +259,7 @@ bool WebSocketsServer::sendBIN(uint8_t num, uint8_t * payload, size_t length, bo return false; } -bool WebSocketsServer::sendBIN(uint8_t num, const uint8_t * payload, size_t length) { +bool WebSocketsServerCore::sendBIN(uint8_t num, const uint8_t * payload, size_t length) { return sendBIN(num, (uint8_t *)payload, length); } @@ -284,7 +270,7 @@ bool WebSocketsServer::sendBIN(uint8_t num, const uint8_t * payload, size_t leng * @param headerToPayload bool (see sendFrame for more details) * @return true if ok */ -bool WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload) { +bool WebSocketsServerCore::broadcastBIN(uint8_t * payload, size_t length, bool headerToPayload) { WSclient_t * client; bool ret = true; for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { @@ -299,7 +285,7 @@ bool WebSocketsServer::broadcastBIN(uint8_t * payload, size_t length, bool heade return ret; } -bool WebSocketsServer::broadcastBIN(const uint8_t * payload, size_t length) { +bool WebSocketsServerCore::broadcastBIN(const uint8_t * payload, size_t length) { return broadcastBIN((uint8_t *)payload, length); } @@ -310,7 +296,7 @@ bool WebSocketsServer::broadcastBIN(const uint8_t * payload, size_t length) { * @param length size_t * @return true if ping is send out */ -bool WebSocketsServer::sendPing(uint8_t num, uint8_t * payload, size_t length) { +bool WebSocketsServerCore::sendPing(uint8_t num, uint8_t * payload, size_t length) { if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) { return false; } @@ -321,7 +307,7 @@ bool WebSocketsServer::sendPing(uint8_t num, uint8_t * payload, size_t length) { return false; } -bool WebSocketsServer::sendPing(uint8_t num, String & payload) { +bool WebSocketsServerCore::sendPing(uint8_t num, String & payload) { return sendPing(num, (uint8_t *)payload.c_str(), payload.length()); } @@ -331,7 +317,7 @@ bool WebSocketsServer::sendPing(uint8_t num, String & payload) { * @param length size_t * @return true if ping is send out */ -bool WebSocketsServer::broadcastPing(uint8_t * payload, size_t length) { +bool WebSocketsServerCore::broadcastPing(uint8_t * payload, size_t length) { WSclient_t * client; bool ret = true; for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { @@ -346,14 +332,14 @@ bool WebSocketsServer::broadcastPing(uint8_t * payload, size_t length) { return ret; } -bool WebSocketsServer::broadcastPing(String & payload) { +bool WebSocketsServerCore::broadcastPing(String & payload) { return broadcastPing((uint8_t *)payload.c_str(), payload.length()); } /** * disconnect all clients */ -void WebSocketsServer::disconnect(void) { +void WebSocketsServerCore::disconnect(void) { WSclient_t * client; for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { client = &_clients[i]; @@ -367,7 +353,7 @@ void WebSocketsServer::disconnect(void) { * disconnect one client * @param num uint8_t client id */ -void WebSocketsServer::disconnect(uint8_t num) { +void WebSocketsServerCore::disconnect(uint8_t num) { if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) { return; } @@ -382,7 +368,7 @@ void WebSocketsServer::disconnect(uint8_t num) { * @param user const char * * @param password const char * */ -void WebSocketsServer::setAuthorization(const char * user, const char * password) { +void WebSocketsServerCore::setAuthorization(const char * user, const char * password) { if(user && password) { String auth = user; auth += ":"; @@ -395,7 +381,7 @@ void WebSocketsServer::setAuthorization(const char * user, const char * password * set the Authorizatio for the http request * @param auth const char * base64 */ -void WebSocketsServer::setAuthorization(const char * auth) { +void WebSocketsServerCore::setAuthorization(const char * auth) { if(auth) { _base64Authorization = auth; } @@ -405,7 +391,7 @@ void WebSocketsServer::setAuthorization(const char * auth) { * count the connected clients (optional ping them) * @param ping bool ping the connected clients */ -int WebSocketsServer::connectedClients(bool ping) { +int WebSocketsServerCore::connectedClients(bool ping) { WSclient_t * client; int count = 0; for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { @@ -423,7 +409,7 @@ int WebSocketsServer::connectedClients(bool ping) { * see if one client is connected * @param num uint8_t client id */ -bool WebSocketsServer::clientIsConnected(uint8_t num) { +bool WebSocketsServerCore::clientIsConnected(uint8_t num) { if(num >= WEBSOCKETS_SERVER_CLIENT_MAX) { return false; } @@ -437,7 +423,7 @@ bool WebSocketsServer::clientIsConnected(uint8_t num) { * @param num uint8_t client id * @return IPAddress */ -IPAddress WebSocketsServer::remoteIP(uint8_t num) { +IPAddress WebSocketsServerCore::remoteIP(uint8_t num) { if(num < WEBSOCKETS_SERVER_CLIENT_MAX) { WSclient_t * client = &_clients[num]; if(clientIsConnected(client)) { @@ -457,7 +443,7 @@ IPAddress WebSocketsServer::remoteIP(uint8_t num) { * handle new client connection * @param client */ -bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { +WSclient_t * WebSocketsServerCore::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { WSclient_t * client; // search free list entry for client for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { @@ -486,7 +472,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { #endif #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) - client->tcp->onDisconnect(std::bind([](WebSocketsServer * server, AsyncTCPbuffer * obj, WSclient_t * client) -> bool { + client->tcp->onDisconnect(std::bind([](WebSocketsServerCore * server, AsyncTCPbuffer * obj, WSclient_t * client) -> bool { DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num); AsyncTCPbuffer ** sl = &server->_clients[client->num].tcp; @@ -498,7 +484,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { }, this, std::placeholders::_1, client)); - client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine))); + client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServerCore::handleHeader, this, client, &(client->cHttpLine))); #endif client->pingInterval = _pingInterval; @@ -507,11 +493,11 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { client->lastPing = millis(); client->pongReceived = false; - return true; + return client; break; } } - return false; + return nullptr; } /** @@ -521,7 +507,7 @@ bool WebSocketsServer::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient) { * @param payload uint8_t * * @param length size_t */ -void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) { +void WebSocketsServerCore::messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin) { WStype_t type = WStype_ERROR; switch(opcode) { @@ -549,22 +535,11 @@ void WebSocketsServer::messageReceived(WSclient_t * client, WSopcode_t opcode, u } /** - * Disconnect an client - * @param client WSclient_t * ptr to the client struct + * Discard a native client + * @param client WSclient_t * ptr to the client struct contaning the native client "->tcp" */ -void WebSocketsServer::clientDisconnect(WSclient_t * client) { -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) - if(client->isSSL && client->ssl) { - if(client->ssl->connected()) { - client->ssl->flush(); - client->ssl->stop(); - } - delete client->ssl; - client->ssl = NULL; - client->tcp = NULL; - } -#endif - +void WebSocketsServerCore::dropNativeClient (WSclient_t * client) +{ if(client->tcp) { if(client->tcp->connected()) { #if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) && (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP32) @@ -579,6 +554,26 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { #endif client->tcp = NULL; } +} + +/** + * Disconnect an client + * @param client WSclient_t * ptr to the client struct + */ +void WebSocketsServerCore::clientDisconnect(WSclient_t * client) { +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) + if(client->isSSL && client->ssl) { + if(client->ssl->connected()) { + client->ssl->flush(); + client->ssl->stop(); + } + delete client->ssl; + client->ssl = NULL; + client->tcp = NULL; + } +#endif + + dropNativeClient(client); client->cUrl = ""; client->cKey = ""; @@ -605,7 +600,7 @@ void WebSocketsServer::clientDisconnect(WSclient_t * client) { * @param client WSclient_t * ptr to the client struct * @return true = connected */ -bool WebSocketsServer::clientIsConnected(WSclient_t * client) { +bool WebSocketsServerCore::clientIsConnected(WSclient_t * client) { if(!client->tcp) { return false; } @@ -635,27 +630,11 @@ bool WebSocketsServer::clientIsConnected(WSclient_t * client) { /** * Handle incoming Connection Request */ -void WebSocketsServer::handleNewClients(void) { -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) - while(_server->hasClient()) { -#endif - bool ok = false; +WSclient_t * WebSocketsServerCore::handleNewClient(WEBSOCKETS_NETWORK_CLASS * tcpClient) { -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) - // store new connection - WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); -#else - WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); -#endif - - if(!tcpClient) { - DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); - return; - } - - ok = newClient(tcpClient); + WSclient_t * client = newClient(tcpClient); - if(!ok) { + if(!client) { // no free space to handle client #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) #ifndef NODEBUG_WEBSOCKETS @@ -663,12 +642,33 @@ void WebSocketsServer::handleNewClients(void) { #endif DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); #else - DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n"); + DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n"); #endif - tcpClient->stop(); + dropNativeClient(client); } WEBSOCKETS_YIELD(); + + return client; +} + +/** + * Handle incoming Connection Request + */ +void WebSocketsServer::handleNewClients(void) { +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) + while(_server->hasClient()) { +#endif + + // store new connection + WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); + if(!tcpClient) { + DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); + return; + } + + handleNewClient(tcpClient); + #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) } #endif @@ -677,7 +677,7 @@ void WebSocketsServer::handleNewClients(void) { /** * Handel incomming data from Client */ -void WebSocketsServer::handleClientData(void) { +void WebSocketsServerCore::handleClientData(void) { WSclient_t * client; for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { client = &_clients[i]; @@ -712,7 +712,7 @@ void WebSocketsServer::handleClientData(void) { * returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection * @param headerName String ///< the name of the header being checked */ -bool WebSocketsServer::hasMandatoryHeader(String headerName) { +bool WebSocketsServerCore::hasMandatoryHeader(String headerName) { for(size_t i = 0; i < _mandatoryHttpHeaderCount; i++) { if(_mandatoryHttpHeaders[i].equalsIgnoreCase(headerName)) return true; @@ -725,7 +725,7 @@ bool WebSocketsServer::hasMandatoryHeader(String headerName) { * @param client WSclient_t * ///< pointer to the client struct * @param headerLine String ///< the header being read / processed */ -void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { +void WebSocketsServerCore::handleHeader(WSclient_t * client, String * headerLine) { static const char * NEW_LINE = "\r\n"; headerLine->trim(); // remove \r @@ -784,7 +784,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { (*headerLine) = ""; #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) - client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServer::handleHeader, this, client, &(client->cHttpLine))); + client->tcp->readStringUntil('\n', &(client->cHttpLine), std::bind(&WebSocketsServerCore::handleHeader, this, client, &(client->cHttpLine))); #endif } else { DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Header read fin.\n", client->num); @@ -881,7 +881,7 @@ void WebSocketsServer::handleHeader(WSclient_t * client, String * headerLine) { /** * send heartbeat ping to server in set intervals */ -void WebSocketsServer::handleHBPing(WSclient_t * client) { +void WebSocketsServerCore::handleHBPing(WSclient_t * client) { if(client->pingInterval == 0) return; uint32_t pi = millis() - client->lastPing; @@ -900,7 +900,7 @@ void WebSocketsServer::handleHBPing(WSclient_t * client) { * @param pongTimeout uint32_t millis after which pong should timout if not received * @param disconnectTimeoutCount uint8_t how many timeouts before disconnect, 0=> do not disconnect */ -void WebSocketsServer::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { +void WebSocketsServerCore::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { _pingInterval = pingInterval; _pongTimeout = pongTimeout; _disconnectTimeoutCount = disconnectTimeoutCount; @@ -915,7 +915,7 @@ void WebSocketsServer::enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeo /** * disable ping/pong heartbeat process */ -void WebSocketsServer::disableHeartbeat() { +void WebSocketsServerCore::disableHeartbeat() { _pingInterval = 0; WSclient_t * client; @@ -923,4 +923,52 @@ void WebSocketsServer::disableHeartbeat() { client = &_clients[i]; client->pingInterval = 0; } -} \ No newline at end of file +} + +//////////////////// +// WebSocketServer + +/** + * called to initialize the Websocket server + */ +void WebSocketsServer::begin(void) { + WebSocketsServerCore::begin(); + _server->begin(); + + DEBUG_WEBSOCKETS("[WS-Server] Server Started.\n"); +} + +void WebSocketsServer::close(void) { + WebSocketsServer::close(); +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) + _server->close(); +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + _server->end(); +#else + // TODO how to close server? +#endif +} + +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +/** + * called in arduino loop + */ +void WebSocketsServerCore::loop(void) { + if(_runnning) { + WEBSOCKETS_YIELD(); + handleClientData(); + } +} + +/** + * called in arduino loop + */ +void WebSocketsServer::loop(void) { + if(_runnning) { + WEBSOCKETS_YIELD(); + handleNewClients(); + WebSocketsServerCore::loop(); + } +} +#endif + diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 2541788..8089c18 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -31,27 +31,21 @@ #define WEBSOCKETS_SERVER_CLIENT_MAX (5) #endif -class WebSocketsServer : protected WebSockets { +class WebSocketsServerCore : protected WebSockets { public: -#ifdef __AVR__ - typedef void (*WebSocketServerEvent)(uint8_t num, WStype_t type, uint8_t * payload, size_t length); - typedef bool (*WebSocketServerHttpHeaderValFunc)(String headerName, String headerValue); -#else - typedef std::function WebSocketServerEvent; - typedef std::function WebSocketServerHttpHeaderValFunc; -#endif - WebSocketsServer(uint16_t port, String origin = "", String protocol = "arduino"); - virtual ~WebSocketsServer(void); + WebSocketsServerCore(const String& origin = "", const String& protocol = "arduino"); + virtual ~WebSocketsServerCore(void); void begin(void); void close(void); -#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) - void loop(void); +#ifdef __AVR__ + typedef void (*WebSocketServerEvent)(uint8_t num, WStype_t type, uint8_t * payload, size_t length); + typedef bool (*WebSocketServerHttpHeaderValFunc)(String headerName, String headerValue); #else - // Async interface not need a loop call - void loop(void) __attribute__((deprecated)) {} + typedef std::function WebSocketServerEvent; + typedef std::function WebSocketServerHttpHeaderValFunc; #endif void onEvent(WebSocketServerEvent cbEvent); @@ -101,16 +95,17 @@ class WebSocketsServer : protected WebSockets { IPAddress remoteIP(uint8_t num); #endif +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) + void loop(void); // handle client data only +#endif + protected: - uint16_t _port; String _origin; String _protocol; String _base64Authorization; ///< Base64 encoded Auth request String * _mandatoryHttpHeaders; size_t _mandatoryHttpHeaderCount; - WEBSOCKETS_NETWORK_SERVER_CLASS * _server; - WSclient_t _clients[WEBSOCKETS_SERVER_CLIENT_MAX]; WebSocketServerEvent _cbEvent; @@ -122,7 +117,7 @@ class WebSocketsServer : protected WebSockets { uint32_t _pongTimeout; uint8_t _disconnectTimeoutCount; - bool newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); + WSclient_t * newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); @@ -130,7 +125,6 @@ class WebSocketsServer : protected WebSockets { bool clientIsConnected(WSclient_t * client); #if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) - void handleNewClients(void); void handleClientData(void); #endif @@ -206,12 +200,48 @@ class WebSocketsServer : protected WebSockets { return true; } +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) + WSclient_t * handleNewClient(WEBSOCKETS_NETWORK_CLASS * tcpClient); +#endif + + /** + * drop native tcp connection (client->tcp) + */ + void dropNativeClient (WSclient_t * client); + private: /* * returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection * @param headerName String ///< the name of the header being checked */ bool hasMandatoryHeader(String headerName); + +}; + +class WebSocketsServer: public WebSocketsServerCore { + public: + + WebSocketsServer(uint16_t port, const String& origin = "", const String& protocol = "arduino"); + virtual ~WebSocketsServer(void); + + void begin(void); + void close(void); + +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) + void loop(void); // handle incoming client and client data +#else + // Async interface not need a loop call + void loop(void) __attribute__((deprecated)) {} +#endif + + protected: + +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) + void handleNewClients(void); +#endif + + uint16_t _port; + WEBSOCKETS_NETWORK_SERVER_CLASS * _server; }; #endif /* WEBSOCKETSSERVER_H_ */ From 28cd929e7e0b53f5e8dfeb264812afef40e9efb1 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 21 Nov 2020 14:06:30 +0100 Subject: [PATCH 236/347] code style --- src/WebSocketsServer.cpp | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 74b4228..a8b4374 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -25,7 +25,7 @@ #include "WebSockets.h" #include "WebSocketsServer.h" -WebSocketsServerCore::WebSocketsServerCore(const String& origin, const String& protocol) { +WebSocketsServerCore::WebSocketsServerCore(const String & origin, const String & protocol) { _origin = origin; _protocol = protocol; _runnning = false; @@ -42,9 +42,9 @@ WebSocketsServerCore::WebSocketsServerCore(const String& origin, const String& p memset(&_clients[0], 0x00, (sizeof(WSclient_t) * WEBSOCKETS_SERVER_CLIENT_MAX)); } -WebSocketsServer::WebSocketsServer(uint16_t port, const String& origin, const String& protocol): - WebSocketsServerCore(origin, protocol) { - _port = port; +WebSocketsServer::WebSocketsServer(uint16_t port, const String & origin, const String & protocol) + : WebSocketsServerCore(origin, protocol) { + _port = port; _server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port); @@ -538,8 +538,7 @@ void WebSocketsServerCore::messageReceived(WSclient_t * client, WSopcode_t opcod * Discard a native client * @param client WSclient_t * ptr to the client struct contaning the native client "->tcp" */ -void WebSocketsServerCore::dropNativeClient (WSclient_t * client) -{ +void WebSocketsServerCore::dropNativeClient(WSclient_t * client) { if(client->tcp) { if(client->tcp->connected()) { #if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) && (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP32) @@ -631,25 +630,24 @@ bool WebSocketsServerCore::clientIsConnected(WSclient_t * client) { * Handle incoming Connection Request */ WSclient_t * WebSocketsServerCore::handleNewClient(WEBSOCKETS_NETWORK_CLASS * tcpClient) { + WSclient_t * client = newClient(tcpClient); - WSclient_t * client = newClient(tcpClient); - - if(!client) { - // no free space to handle client + if(!client) { + // no free space to handle client #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) #ifndef NODEBUG_WEBSOCKETS - IPAddress ip = tcpClient->remoteIP(); + IPAddress ip = tcpClient->remoteIP(); #endif - DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); + DEBUG_WEBSOCKETS("[WS-Server] no free space new client from %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); #else - DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n"); + DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n"); #endif - dropNativeClient(client); - } + dropNativeClient(client); + } - WEBSOCKETS_YIELD(); + WEBSOCKETS_YIELD(); - return client; + return client; } /** @@ -971,4 +969,3 @@ void WebSocketsServer::loop(void) { } } #endif - From f20fbbfcd9a7b91070c7b46518f008bfa801e1f4 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 21 Nov 2020 14:07:14 +0100 Subject: [PATCH 237/347] code style --- src/WebSockets.h | 6 +++++- src/WebSockets4WebServer.h | 23 +++++++++-------------- src/WebSocketsServer.h | 16 ++++++---------- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 4fed8a0..4a892ca 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -42,7 +42,11 @@ #ifndef NODEBUG_WEBSOCKETS #ifdef DEBUG_ESP_PORT -#define DEBUG_WEBSOCKETS(...) { DEBUG_ESP_PORT.printf(__VA_ARGS__); DEBUG_ESP_PORT.flush(); } +#define DEBUG_WEBSOCKETS(...) \ + { \ + DEBUG_ESP_PORT.printf(__VA_ARGS__); \ + DEBUG_ESP_PORT.flush(); \ + } #else //#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) #endif diff --git a/src/WebSockets4WebServer.h b/src/WebSockets4WebServer.h index 514abbb..50b0355 100644 --- a/src/WebSockets4WebServer.h +++ b/src/WebSockets4WebServer.h @@ -30,22 +30,18 @@ #if WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK -class WebSockets4WebServer: public WebSocketsServerCore { +class WebSockets4WebServer : public WebSocketsServerCore { public: - - WebSockets4WebServer(const String& origin = "", const String& protocol = "arduino"): - WebSocketsServerCore(origin, protocol) - { + WebSockets4WebServer(const String & origin = "", const String & protocol = "arduino") + : WebSocketsServerCore(origin, protocol) { begin(); } - ESP8266WebServer::HookFunction hookForWebserver (const String& wsRootDir, WebSocketServerEvent event) - { + ESP8266WebServer::HookFunction hookForWebserver(const String & wsRootDir, WebSocketServerEvent event) { onEvent(event); - return [&, wsRootDir](const String & method, const String & url, WiFiClient * tcpClient, ESP8266WebServer::ContentTypeFunction contentType) - { - if (!(method == "GET" && url.indexOf(wsRootDir) == 0)) { + return [&, wsRootDir](const String & method, const String & url, WiFiClient * tcpClient, ESP8266WebServer::ContentTypeFunction contentType) { + if(!(method == "GET" && url.indexOf(wsRootDir) == 0)) { return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; } @@ -55,8 +51,7 @@ class WebSockets4WebServer: public WebSocketsServerCore { // Then initialize a new WSclient_t (like in WebSocketsServer::handleNewClient()) WSclient_t * client = handleNewClient(newTcpClient); - if (client) - { + if(client) { // give "GET " String headerLine; headerLine.reserve(url.length() + 5); @@ -71,6 +66,6 @@ class WebSockets4WebServer: public WebSocketsServerCore { } }; -#endif // WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK +#endif // WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK -#endif // __WEBSOCKETS4WEBSERVER_H +#endif // __WEBSOCKETS4WEBSERVER_H diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 8089c18..978cd55 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -33,8 +33,7 @@ class WebSocketsServerCore : protected WebSockets { public: - - WebSocketsServerCore(const String& origin = "", const String& protocol = "arduino"); + WebSocketsServerCore(const String & origin = "", const String & protocol = "arduino"); virtual ~WebSocketsServerCore(void); void begin(void); @@ -96,7 +95,7 @@ class WebSocketsServerCore : protected WebSockets { #endif #if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) - void loop(void); // handle client data only + void loop(void); // handle client data only #endif protected: @@ -207,7 +206,7 @@ class WebSocketsServerCore : protected WebSockets { /** * drop native tcp connection (client->tcp) */ - void dropNativeClient (WSclient_t * client); + void dropNativeClient(WSclient_t * client); private: /* @@ -215,27 +214,24 @@ class WebSocketsServerCore : protected WebSockets { * @param headerName String ///< the name of the header being checked */ bool hasMandatoryHeader(String headerName); - }; -class WebSocketsServer: public WebSocketsServerCore { +class WebSocketsServer : public WebSocketsServerCore { public: - - WebSocketsServer(uint16_t port, const String& origin = "", const String& protocol = "arduino"); + WebSocketsServer(uint16_t port, const String & origin = "", const String & protocol = "arduino"); virtual ~WebSocketsServer(void); void begin(void); void close(void); #if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) - void loop(void); // handle incoming client and client data + void loop(void); // handle incoming client and client data #else // Async interface not need a loop call void loop(void) __attribute__((deprecated)) {} #endif protected: - #if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void handleNewClients(void); #endif From 4f52a0f38ec8ef939ebeee676a3b0854f9ebe5cf Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 21 Nov 2020 14:07:32 +0100 Subject: [PATCH 238/347] cleanup server client init --- src/WebSocketsServer.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index a8b4374..20b2373 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -86,22 +86,27 @@ void WebSocketsServerCore::begin(void) { client->isSSL = false; client->ssl = NULL; #endif - client->cUrl = ""; - client->cCode = 0; - client->cKey = ""; - client->cAccept = ""; - client->cProtocol = ""; - client->cExtensions = ""; - client->cVersion = 0; + client->cUrl = ""; + client->cCode = 0; + + client->cIsClient = false; client->cIsUpgrade = false; client->cIsWebsocket = false; - client->base64Authorization = ""; - client->plainAuthorization = ""; - client->extraHeaders = ""; + client->cSessionId = ""; + client->cKey = ""; + client->cAccept = ""; + client->cProtocol = ""; + client->cExtensions = ""; + client->cVersion = 0; client->cWsRXsize = 0; + client->base64Authorization = ""; + client->plainAuthorization = ""; + + client->extraHeaders = ""; + #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->cHttpLine = ""; #endif From fb26433e75e52c68225cebf9a507d181f28d4180 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 21 Nov 2020 14:33:25 +0100 Subject: [PATCH 239/347] add error messages if Webserver Hook Functions are not supported by platform --- src/WebSockets4WebServer.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/WebSockets4WebServer.h b/src/WebSockets4WebServer.h index 50b0355..6884baf 100644 --- a/src/WebSockets4WebServer.h +++ b/src/WebSockets4WebServer.h @@ -65,6 +65,13 @@ class WebSockets4WebServer : public WebSocketsServerCore { }; } }; +#else // WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK + +#ifndef WEBSERVER_HAS_HOOK +#error Your current Framework / Arduino core version does not support Webserver Hook Functions +#else +#error Your Hardware Platform does not support Webserver Hook Functions +#endif #endif // WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK From 08caf3bfc6625ebf6da9bb39f39d58dd113ceff4 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 21 Nov 2020 14:45:53 +0100 Subject: [PATCH 240/347] code style --- src/WebSockets4WebServer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSockets4WebServer.h b/src/WebSockets4WebServer.h index 6884baf..01a7f8a 100644 --- a/src/WebSockets4WebServer.h +++ b/src/WebSockets4WebServer.h @@ -65,7 +65,7 @@ class WebSockets4WebServer : public WebSocketsServerCore { }; } }; -#else // WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK +#else // WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK #ifndef WEBSERVER_HAS_HOOK #error Your current Framework / Arduino core version does not support Webserver Hook Functions From 25318111a11f8f887f0e1860a49d7b2b7df0f055 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 21 Nov 2020 16:16:59 +0100 Subject: [PATCH 241/347] add namespace join to socket.io examples --- .../WebSocketClientSocketIO/WebSocketClientSocketIO.ino | 3 +++ .../WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino | 3 +++ 2 files changed, 6 insertions(+) diff --git a/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino b/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino index 06f7616..26574ca 100644 --- a/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino +++ b/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino @@ -29,6 +29,9 @@ void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) break; case sIOtype_CONNECT: USE_SERIAL.printf("[IOc] Connected to url: %s\n", payload); + + // join default namespace (no auto join in Socket.IO V3) + socketIO.send(sIOtype_CONNECT, "/"); break; case sIOtype_EVENT: USE_SERIAL.printf("[IOc] get event: %s\n", payload); diff --git a/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino b/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino index f0f8991..ab9ff68 100644 --- a/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino +++ b/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino @@ -30,6 +30,9 @@ void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) break; case sIOtype_CONNECT: USE_SERIAL.printf("[IOc] Connected to url: %s\n", payload); + + // join default namespace (no auto join in Socket.IO V3) + socketIO.send(sIOtype_CONNECT, "/"); break; case sIOtype_EVENT: { From 04919f848f2bb50d5a54b66bd00a9badcdc978fa Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 21 Nov 2020 16:17:43 +0100 Subject: [PATCH 242/347] only try to send socket.io messages in WSC_CONNECTED state handle sIOtype_CONNECT messages send 2probe on websocket connect (#574) --- src/SocketIOclient.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index 4233e2c..8fd8ad5 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -81,7 +81,7 @@ bool SocketIOclient::send(socketIOmessageType_t type, uint8_t * payload, size_t if(length == 0) { length = strlen((const char *)payload); } - if(clientIsConnected(&_client)) { + if(clientIsConnected(&_client) && _client.status == WSC_CONNECTED) { if(!headerToPayload) { // webSocket Header ret = WebSocketsClient::sendFrameHeader(&_client, WSop_text, length + 2, true); @@ -165,6 +165,7 @@ void SocketIOclient::handleCbEvent(WStype_t type, uint8_t * payload, size_t leng DEBUG_WEBSOCKETS("[wsIOc] Connected to url: %s\n", payload); // send message to server when Connected // Engine.io upgrade confirmation message (required) + WebSocketsClient::sendTXT("2probe"); WebSocketsClient::sendTXT(eIOtype_UPGRADE); runIOCbEvent(sIOtype_CONNECT, payload, length); } break; @@ -195,6 +196,8 @@ void SocketIOclient::handleCbEvent(WStype_t type, uint8_t * payload, size_t leng DEBUG_WEBSOCKETS("[wsIOc] get event (%d): %s\n", lData, data); break; case sIOtype_CONNECT: + DEBUG_WEBSOCKETS("[wsIOc] connected (%d): %s\n", lData, data); + return; case sIOtype_DISCONNECT: case sIOtype_ACK: case sIOtype_ERROR: From 9470961d85d469688cf0fc90ec200b914dddca16 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 21 Nov 2020 16:19:08 +0100 Subject: [PATCH 243/347] socket.io improve Cookie handling --- src/WebSocketsClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index b4ba4a4..c20e8e1 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -705,7 +705,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) { client->cVersion = headerValue.toInt(); } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Set-Cookie"))) { - if(headerValue.indexOf(WEBSOCKETS_STRING("HttpOnly")) > -1) { + if(headerValue.indexOf(';') > -1) { client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1, headerValue.indexOf(";")); } else { client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1); From c5900db6364e76442e06a46f0d721af8bb5ef8b3 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 21 Nov 2020 16:19:59 +0100 Subject: [PATCH 244/347] add handling for Socket.IO V3 connection --- src/WebSockets.h | 1 + src/WebSocketsClient.cpp | 53 +++++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 4a892ca..91d95eb 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -215,6 +215,7 @@ typedef enum { WSC_NOT_CONNECTED, WSC_HEADER, + WSC_BODY, WSC_CONNECTED } WSclientsStatus_t; diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index c20e8e1..bd31268 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -505,7 +505,8 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { client->cIsWebsocket = false; client->cSessionId = ""; - client->status = WSC_NOT_CONNECTED; + client->status = WSC_NOT_CONNECTED; + _lastConnectionFail = millis(); DEBUG_WEBSOCKETS("[WS-Client] client disconnected.\n"); if(event) { @@ -548,12 +549,13 @@ bool WebSocketsClient::clientIsConnected(WSclient_t * client) { * Handel incomming data from Client */ void WebSocketsClient::handleClientData(void) { - if(_client.status == WSC_HEADER && _lastHeaderSent + WEBSOCKETS_TCP_TIMEOUT < millis()) { + if((_client.status == WSC_HEADER || _client.status == WSC_BODY) && _lastHeaderSent + WEBSOCKETS_TCP_TIMEOUT < millis()) { DEBUG_WEBSOCKETS("[WS-Client][handleClientData] header response timeout.. disconnecting!\n"); clientDisconnect(&_client); WEBSOCKETS_YIELD(); return; } + int len = _client.tcp->available(); if(len > 0) { switch(_client.status) { @@ -561,6 +563,12 @@ void WebSocketsClient::handleClientData(void) { String headerLine = _client.tcp->readStringUntil('\n'); handleHeader(&_client, &headerLine); } break; + case WSC_BODY: { + char buf[256] = { 0 }; + _client.tcp->readBytes(&buf[0], std::min((size_t)len, sizeof(buf))); + String bodyLine = buf; + handleHeader(&_client, &bodyLine); + } break; case WSC_CONNECTED: WebSockets::handleWebsocket(&_client); break; @@ -672,6 +680,22 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { headerLine->trim(); // remove \r + // this code handels the http body for Socket.IO V3 requests + if(headerLine->length() > 0 && client->isSocketIO && client->status == WSC_BODY && client->cSessionId.length() == 0) { + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] socket.io json: %s\n", headerLine->c_str()); + String sid_begin = WEBSOCKETS_STRING("\"sid\":\""); + if(headerLine->indexOf(sid_begin) > -1) { + int start = headerLine->indexOf(sid_begin) + sid_begin.length(); + int end = headerLine->indexOf('"', start); + client->cSessionId = headerLine->substring(start, end); + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cSessionId: %s\n", client->cSessionId.c_str()); + + // Trigger websocket connection code path + *headerLine = ""; + } + } + + // headle HTTP header if(headerLine->length() > 0) { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] RX: %s\n", headerLine->c_str()); @@ -736,6 +760,14 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cVersion: %d\n", client->cVersion); DEBUG_WEBSOCKETS("[WS-Client][handleHeader] - cSessionId: %s\n", client->cSessionId.c_str()); + if(client->isSocketIO && client->cSessionId.length() == 0 && clientIsConnected(client)) { + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] still missing cSessionId try socket.io V3\n"); + client->status = WSC_BODY; + return; + } else { + client->status = WSC_HEADER; + } + bool ok = (client->cIsUpgrade && client->cIsWebsocket); if(ok) { @@ -777,15 +809,18 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { runCbEvent(WStype_CONNECTED, (uint8_t *)client->cUrl.c_str(), client->cUrl.length()); #if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) - } else if(clientIsConnected(client) && client->isSocketIO && client->cSessionId.length() > 0) { - if(_client.tcp->available()) { - // read not needed data - DEBUG_WEBSOCKETS("[WS-Client][handleHeader] still data in buffer (%d), clean up.\n", _client.tcp->available()); - while(_client.tcp->available() > 0) { - _client.tcp->read(); + } else if(client->isSocketIO) { + if(client->cSessionId.length() > 0) { + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] found cSessionId\n"); + if(clientIsConnected(client) && _client.tcp->available()) { + // read not needed data + DEBUG_WEBSOCKETS("[WS-Client][handleHeader] still data in buffer (%d), clean up.\n", _client.tcp->available()); + while(_client.tcp->available() > 0) { + _client.tcp->read(); + } } + sendHeader(client); } - sendHeader(client); #endif } else { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] no Websocket connection close.\n"); From 8239e1625eac399c7ff40a46f9f60dc16a4e3848 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 21 Nov 2020 16:21:04 +0100 Subject: [PATCH 245/347] update travis config --- .travis.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7c59234..a2a9096 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ sudo: false dist: - - xenial + - bionic addons: apt: packages: @@ -43,9 +43,3 @@ notifications: email: on_success: change on_failure: change - webhooks: - urls: - - https://webhooks.gitter.im/e/1aa78fbe15080b0c2e37 - on_success: change # options: [always|never|change] default: always - on_failure: always # options: [always|never|change] default: always - on_start: false # default: false From 074a6748337518e0187eb7cdcba009d06d84ef9a Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 21 Nov 2020 16:25:18 +0100 Subject: [PATCH 246/347] bionic is broken for Arduino IDE 1.6.13 so we keep xenial --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a2a9096..6cdf5db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ sudo: false dist: - - bionic + - xenial addons: apt: packages: From f0cc36dede2de94f50f28a4ea7d1e5f02bdc9d9b Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 21 Nov 2020 18:13:22 +0100 Subject: [PATCH 247/347] bump version to 2.3.2 --- library.json | 2 +- library.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index 7ac6a78..fbf044f 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.3.1", + "version": "2.3.2", "license": "LGPL-2.1", "export": { "exclude": [ diff --git a/library.properties b/library.properties index 203df40..0c51754 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.3.1 +version=2.3.2 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) From 74411bf729f48df7f60abb01e8b2ed9c5926d106 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 22 Nov 2020 20:02:32 +0100 Subject: [PATCH 248/347] use native contructor and destructor to initialize WSclient_t --- src/WebSockets.h | 16 ++++++++++-- src/WebSockets4WebServer.h | 2 ++ src/WebSocketsServer.cpp | 50 ++++++-------------------------------- 3 files changed, 24 insertions(+), 44 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 91d95eb..fa200b0 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -258,7 +258,19 @@ typedef struct { uint8_t * maskKey; } WSMessageHeader_t; -typedef struct { +struct WSclient_t { + + WSclient_t() = default; + + WSclient_t(uint8_t num, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount): + num(num), + status(WSC_NOT_CONNECTED), + pingInterval(pingInterval), + pongTimeout(pongTimeout), + disconnectTimeoutCount(disconnectTimeoutCount) + { + } + uint8_t num; ///< connection number WSclientsStatus_t status; @@ -309,7 +321,7 @@ typedef struct { String cHttpLine; ///< HTTP header lines #endif -} WSclient_t; +}; class WebSockets { protected: diff --git a/src/WebSockets4WebServer.h b/src/WebSockets4WebServer.h index 01a7f8a..ba2b020 100644 --- a/src/WebSockets4WebServer.h +++ b/src/WebSockets4WebServer.h @@ -41,6 +41,8 @@ class WebSockets4WebServer : public WebSocketsServerCore { onEvent(event); return [&, wsRootDir](const String & method, const String & url, WiFiClient * tcpClient, ESP8266WebServer::ContentTypeFunction contentType) { + (void)contentType; + if(!(method == "GET" && url.indexOf(wsRootDir) == 0)) { return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; } diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 20b2373..1b85ecb 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -38,8 +38,6 @@ WebSocketsServerCore::WebSocketsServerCore(const String & origin, const String & _httpHeaderValidationFunc = NULL; _mandatoryHttpHeaders = NULL; _mandatoryHttpHeaderCount = 0; - - memset(&_clients[0], 0x00, (sizeof(WSclient_t) * WEBSOCKETS_SERVER_CLIENT_MAX)); } WebSocketsServer::WebSocketsServer(uint16_t port, const String & origin, const String & protocol) @@ -73,47 +71,15 @@ WebSocketsServer::~WebSocketsServer() { * called to initialize the Websocket server */ void WebSocketsServerCore::begin(void) { - WSclient_t * client; - // init client storage - for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { - client = &_clients[i]; - - client->num = i; - client->status = WSC_NOT_CONNECTED; - client->tcp = NULL; -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) - client->isSSL = false; - client->ssl = NULL; -#endif - client->cUrl = ""; - client->cCode = 0; - - client->cIsClient = false; - client->cIsUpgrade = false; - client->cIsWebsocket = false; - - client->cSessionId = ""; - client->cKey = ""; - client->cAccept = ""; - client->cProtocol = ""; - client->cExtensions = ""; - client->cVersion = 0; - - client->cWsRXsize = 0; - - client->base64Authorization = ""; - client->plainAuthorization = ""; - - client->extraHeaders = ""; - -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) - client->cHttpLine = ""; -#endif - - client->pingInterval = _pingInterval; - client->pongTimeout = _pongTimeout; - client->disconnectTimeoutCount = _disconnectTimeoutCount; + for (int i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + WSclient_t * client = &_clients[i]; + + // reset instance: + // destructor in place + client->~WSclient_t(); + // constructor in place + new (client) WSclient_t(i, _pingInterval, _pongTimeout, _disconnectTimeoutCount); } #ifdef ESP8266 From 52547ec47c56858db39c35ee705eae8bce4a7dbf Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 22 Nov 2020 21:42:20 +0100 Subject: [PATCH 249/347] fix clients init logic --- src/WebSockets.h | 20 ++++++++++++-------- src/WebSocketsServer.cpp | 26 ++++++++++++++++++-------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index fa200b0..35d7d8c 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -260,17 +260,21 @@ typedef struct { struct WSclient_t { - WSclient_t() = default; - - WSclient_t(uint8_t num, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount): - num(num), - status(WSC_NOT_CONNECTED), - pingInterval(pingInterval), - pongTimeout(pongTimeout), - disconnectTimeoutCount(disconnectTimeoutCount) + WSclient_t (): status(WSC_NOT_CONNECTED) { } + void init (uint8_t num, + uint32_t pingInterval, + uint32_t pongTimeout, + uint8_t disconnectTimeoutCount) + { + this->num = num; + this->pingInterval = pingInterval; + this->pongTimeout = pongTimeout; + this->disconnectTimeoutCount = disconnectTimeoutCount; + } + uint8_t num; ///< connection number WSclientsStatus_t status; diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 1b85ecb..50d92ed 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -71,15 +71,14 @@ WebSocketsServer::~WebSocketsServer() { * called to initialize the Websocket server */ void WebSocketsServerCore::begin(void) { - // init client storage - for (int i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { - WSclient_t * client = &_clients[i]; - // reset instance: - // destructor in place - client->~WSclient_t(); - // constructor in place - new (client) WSclient_t(i, _pingInterval, _pongTimeout, _disconnectTimeoutCount); + // adjust clients storage: + // _clients[i]'s constructor are already called, + // all its members are initialized to their default value, + // except the ones explicitly detailed in WSclient_t() constructor. + // Then we need to initialize some members to non-trivial values: + for (int i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + _clients[i].init(i, _pingInterval, _pongTimeout, _disconnectTimeoutCount); } #ifdef ESP8266 @@ -98,6 +97,17 @@ void WebSocketsServerCore::begin(void) { void WebSocketsServerCore::close(void) { _runnning = false; disconnect(); + + // reset _clients[] + for (int i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + WSclient_t * client = &_clients[i]; + + // reset instance: + // destructor in place + client->~WSclient_t(); + // constructor in place (reset Strings, set scalars to 0) + new (client) WSclient_t; + } } /** From e7ab9136936a607407f7ae32d6c569165d583d08 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 22 Nov 2020 22:06:18 +0100 Subject: [PATCH 250/347] fix clearing _Client[] --- src/WebSocketsServer.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 50d92ed..c8ac2ef 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -98,15 +98,10 @@ void WebSocketsServerCore::close(void) { _runnning = false; disconnect(); - // reset _clients[] + // restore _clients[] to their initial state + // before next call to ::begin() for (int i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { - WSclient_t * client = &_clients[i]; - - // reset instance: - // destructor in place - client->~WSclient_t(); - // constructor in place (reset Strings, set scalars to 0) - new (client) WSclient_t; + _clients[i] = WSclient_t(); } } From ebb87cdc8aa1f4024afeb9d65521c338abbf05e5 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 22 Nov 2020 22:47:10 +0100 Subject: [PATCH 251/347] + constructors for scalars --- src/WebSockets.h | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 35d7d8c..00d65b2 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -258,11 +258,7 @@ typedef struct { uint8_t * maskKey; } WSMessageHeader_t; -struct WSclient_t { - - WSclient_t (): status(WSC_NOT_CONNECTED) - { - } +typedef struct { void init (uint8_t num, uint32_t pingInterval, @@ -275,34 +271,34 @@ struct WSclient_t { this->disconnectTimeoutCount = disconnectTimeoutCount; } - uint8_t num; ///< connection number + uint8_t num = 0; ///< connection number - WSclientsStatus_t status; + WSclientsStatus_t status = WSC_NOT_CONNECTED; - WEBSOCKETS_NETWORK_CLASS * tcp; + WEBSOCKETS_NETWORK_CLASS * tcp = nullptr; - bool isSocketIO; ///< client for socket.io server + bool isSocketIO = false; ///< client for socket.io server #if defined(HAS_SSL) - bool isSSL; ///< run in ssl mode + bool isSSL = false; ///< run in ssl mode WEBSOCKETS_NETWORK_SSL_CLASS * ssl; #endif - String cUrl; ///< http url - uint16_t cCode; ///< http code + String cUrl; ///< http url + uint16_t cCode = 0; ///< http code bool cIsClient = false; ///< will be used for masking - bool cIsUpgrade; ///< Connection == Upgrade - bool cIsWebsocket; ///< Upgrade == websocket + bool cIsUpgrade = false; ///< Connection == Upgrade + bool cIsWebsocket = false; ///< Upgrade == websocket String cSessionId; ///< client Set-Cookie (session id) String cKey; ///< client Sec-WebSocket-Key String cAccept; ///< client Sec-WebSocket-Accept String cProtocol; ///< client Sec-WebSocket-Protocol String cExtensions; ///< client Sec-WebSocket-Extensions - uint16_t cVersion; ///< client Sec-WebSocket-Version + uint16_t cVersion = 0; ///< client Sec-WebSocket-Version - uint8_t cWsRXsize; ///< State of the RX + uint8_t cWsRXsize = 0; ///< State of the RX uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer WSMessageHeader_t cWsHeaderDecode; @@ -311,21 +307,21 @@ struct WSclient_t { String extraHeaders; - bool cHttpHeadersValid; ///< non-websocket http header validity indicator + bool cHttpHeadersValid = false; ///< non-websocket http header validity indicator size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count - bool pongReceived; - uint32_t pingInterval; // how often ping will be sent, 0 means "heartbeat is not active" - uint32_t lastPing; // millis when last pong has been received - uint32_t pongTimeout; // interval in millis after which pong is considered to timeout - uint8_t disconnectTimeoutCount; // after how many subsequent pong timeouts discconnect will happen, 0 means "do not disconnect" - uint8_t pongTimeoutCount; // current pong timeout count + bool pongReceived = false; + uint32_t pingInterval = 0; // how often ping will be sent, 0 means "heartbeat is not active" + uint32_t lastPing = 0; // millis when last pong has been received + uint32_t pongTimeout = 0; // interval in millis after which pong is considered to timeout + uint8_t disconnectTimeoutCount = 0; // after how many subsequent pong timeouts discconnect will happen, 0 means "do not disconnect" + uint8_t pongTimeoutCount = 0; // current pong timeout count #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) String cHttpLine; ///< HTTP header lines #endif -}; +} WSclient_t; class WebSockets { protected: From 6bee53a8bdc8abf9549941756b4ddc9fa287c953 Mon Sep 17 00:00:00 2001 From: Markus Date: Tue, 5 Jan 2021 18:11:48 +0100 Subject: [PATCH 252/347] github actions test --- .github/workflows/main.yml | 50 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..88e9e66 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,50 @@ +# This is a basic workflow to help you get started with Actions + +name: CI + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the master branch + push: + branches: [ master ] + pull_request: + branches: [ master ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + - name: build examples + run: | + /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 + export DISPLAY=:1.0 + sleep 3 + wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz + tar xf arduino-$IDE_VERSION-linux64.tar.xz + mv arduino-$IDE_VERSION $HOME/arduino_ide + export PATH="$HOME/arduino_ide:$PATH" + which arduino + mkdir -p $HOME/Arduino/libraries + + wget https://github.com/bblanchon/ArduinoJson/archive/6.x.zip + unzip 6.x.zip + mv ArduinoJson-6.x $HOME/Arduino/libraries/ArduinoJson + cp -r $GITHUB_WORKSPACE $HOME/Arduino/libraries/arduinoWebSockets + source $GITHUB_WORKSPACE/travis/common.sh + get_core $CPU + cd $GITHUB_WORKSPACE + arduino --board $BOARD --save-prefs + arduino --get-pref sketchbook.path + arduino --pref update.check=false + build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets/examples/$CPU $CPU From dc30a2b7bfd89bb532dc6a9d7ae7590046c73c29 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 5 Jan 2021 18:28:59 +0100 Subject: [PATCH 253/347] github actions test2 --- .github/workflows/main.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 88e9e66..4b32bd0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -19,13 +19,23 @@ jobs: build: # The type of runner that the job will run on runs-on: ubuntu-latest + strategy: + matrix: + env: + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80" IDE_VERSION=1.6.13 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,dbg=Serial1" IDE_VERSION=1.6.13 + - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.13 + - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.5 + - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.9 + - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.13 + env: ${{ matrix.env }} # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v2 - - name: build examples + - name: prepare run: | /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 export DISPLAY=:1.0 @@ -47,4 +57,9 @@ jobs: arduino --board $BOARD --save-prefs arduino --get-pref sketchbook.path arduino --pref update.check=false + + - name: build examples + run: | + source $GITHUB_WORKSPACE/travis/common.sh + cd $GITHUB_WORKSPACE build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets/examples/$CPU $CPU From c68e015322f8fdf35f6f3953a595a267fd8eafb7 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 5 Jan 2021 18:32:11 +0100 Subject: [PATCH 254/347] github actions test3 --- .github/workflows/main.yml | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4b32bd0..6dad303 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,12 +22,24 @@ jobs: strategy: matrix: env: - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80" IDE_VERSION=1.6.13 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,dbg=Serial1" IDE_VERSION=1.6.13 - - CPU="esp8266" BOARD="esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80" IDE_VERSION=1.8.13 - - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.5 - - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.9 - - CPU="esp32" BOARD="espressif:esp32:esp32:FlashFreq=80" IDE_VERSION=1.8.13 + - CPU: esp8266 + BOARD: esp8266com:esp8266:generic:xtal=80 + IDE_VERSION: 1.6.13 + - CPU: esp8266 + BOARD: esp8266com:esp8266:generic:xtal=80,dbg=Serial1 + IDE_VERSION: 1.6.13 + - CPU: esp8266 + BOARD: esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80 + IDE_VERSION: 1.8.13 + - CPU: esp32 + BOARD: espressif:esp32:esp32:FlashFreq=80 + IDE_VERSION: 1.8.5 + - CPU: esp32 + BOARD: espressif:esp32:esp32:FlashFreq=80 + IDE_VERSION: 1.8.9 + - CPU: esp32 + BOARD: espressif:esp32:esp32:FlashFreq=80 + IDE_VERSION: 1.8.13 env: ${{ matrix.env }} # Steps represent a sequence of tasks that will be executed as part of the job From 1b4f186fa605ca47a644fafcc287c0e945579cc1 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 5 Jan 2021 18:35:22 +0100 Subject: [PATCH 255/347] use github actions for build --- .github/workflows/main.yml | 176 ++++++++++++++++++++++++++++--------- travis/common.sh | 68 +++++++++++++- 2 files changed, 199 insertions(+), 45 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6dad303..d0ed693 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,77 +1,167 @@ -# This is a basic workflow to help you get started with Actions - name: CI - -# Controls when the action will run. on: - # Triggers the workflow on push or pull request events but only for the master branch + schedule: + - cron: '0 0 * * 5' push: branches: [ master ] pull_request: branches: [ master ] + release: + types: [ published, created, edited ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: - # This workflow contains a single job called "build" + + prepare_example_json: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: generate examples + id: set-matrix + run: | + source $GITHUB_WORKSPACE/travis/common.sh + cd $GITHUB_WORKSPACE + echo -en "::set-output name=matrix::" + echo -en "[" + + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.6.13 esp8266com:esp8266:generic:xtal=80 + echo -en "," + + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.6.13 esp8266com:esp8266:generic:xtal=80,dbg=Serial1 + echo -en "," + + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.13 esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80 + echo -en "," + + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.13 espressif:esp32:esp32:FlashFreq=80 + + echo -en "]" + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + + prepare_ide: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + IDE_VERSION: [1.8.13, 1.6.13] + env: + IDE_VERSION: ${{ matrix.IDE_VERSION }} + + steps: + - uses: actions/checkout@v2 + + - name: Get Date + id: get-date + run: | + echo "::set-output name=date::$(/bin/date -u "+%Y%m%d")" + shell: bash + + - uses: actions/cache@v2 + id: cache_all + with: + path: | + /home/runner/arduino_ide + /home/runner/Arduino + key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.IDE_VERSION }} + + - name: download IDE + if: steps.cache_all.outputs.cache-hit != 'true' + run: | + wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz -q + tar xf arduino-$IDE_VERSION-linux64.tar.xz + mv arduino-$IDE_VERSION $HOME/arduino_ide + + - name: download ArduinoJson + if: steps.cache_all.outputs.cache-hit != 'true' + run: | + mkdir -p $HOME/Arduino/libraries + wget https://github.com/bblanchon/ArduinoJson/archive/6.x.zip -q + unzip 6.x.zip + mv ArduinoJson-6.x $HOME/Arduino/libraries/ArduinoJson + + - name: download esp8266 + if: steps.cache_all.outputs.cache-hit != 'true' + run: | + source $GITHUB_WORKSPACE/travis/common.sh + get_core esp8266 + + - name: download esp32 + if: steps.cache_all.outputs.cache-hit != 'true' && matrix.IDE_VERSION != '1.6.13' + run: | + source $GITHUB_WORKSPACE/travis/common.sh + get_core esp32 + build: - # The type of runner that the job will run on + needs: [prepare_ide, prepare_example_json] runs-on: ubuntu-latest strategy: - matrix: - env: - - CPU: esp8266 - BOARD: esp8266com:esp8266:generic:xtal=80 - IDE_VERSION: 1.6.13 - - CPU: esp8266 - BOARD: esp8266com:esp8266:generic:xtal=80,dbg=Serial1 - IDE_VERSION: 1.6.13 - - CPU: esp8266 - BOARD: esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80 - IDE_VERSION: 1.8.13 - - CPU: esp32 - BOARD: espressif:esp32:esp32:FlashFreq=80 - IDE_VERSION: 1.8.5 - - CPU: esp32 - BOARD: espressif:esp32:esp32:FlashFreq=80 - IDE_VERSION: 1.8.9 - - CPU: esp32 - BOARD: espressif:esp32:esp32:FlashFreq=80 - IDE_VERSION: 1.8.13 - env: ${{ matrix.env }} + fail-fast: false + matrix: + include: ${{ fromJson(needs.prepare_example_json.outputs.matrix) }} + env: + CPU: ${{ matrix.cpu }} + BOARD: ${{ matrix.board }} + IDE_VERSION: ${{ matrix.ideversion }} + SKETCH: ${{ matrix.sketch }} # Steps represent a sequence of tasks that will be executed as part of the job steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v2 - - - name: prepare + + - name: Get Date + id: get-date + run: | + echo "::set-output name=date::$(/bin/date -u "+%Y%m%d")" + shell: bash + + - uses: actions/cache@v2 + id: cache_all + with: + path: | + /home/runner/arduino_ide + /home/runner/Arduino + key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.ideversion }} + + - name: install python serial + if: matrix.cpu == 'esp32' + run: | + sudo pip3 install pyserial + sudo pip install pyserial +# sudo apt install python-is-python3 + + - name: start DISPLAY run: | /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 export DISPLAY=:1.0 sleep 3 - wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz - tar xf arduino-$IDE_VERSION-linux64.tar.xz - mv arduino-$IDE_VERSION $HOME/arduino_ide + + - name: test IDE + run: | export PATH="$HOME/arduino_ide:$PATH" which arduino - mkdir -p $HOME/Arduino/libraries - wget https://github.com/bblanchon/ArduinoJson/archive/6.x.zip - unzip 6.x.zip - mv ArduinoJson-6.x $HOME/Arduino/libraries/ArduinoJson + - name: copy code + run: | cp -r $GITHUB_WORKSPACE $HOME/Arduino/libraries/arduinoWebSockets - source $GITHUB_WORKSPACE/travis/common.sh - get_core $CPU - cd $GITHUB_WORKSPACE + + - name: config IDE + run: | + export DISPLAY=:1.0 + export PATH="$HOME/arduino_ide:$PATH" arduino --board $BOARD --save-prefs arduino --get-pref sketchbook.path arduino --pref update.check=false - - name: build examples + - name: build example run: | + export DISPLAY=:1.0 + export PATH="$HOME/arduino_ide:$PATH" source $GITHUB_WORKSPACE/travis/common.sh cd $GITHUB_WORKSPACE - build_sketches arduino $HOME/Arduino/libraries/arduinoWebSockets/examples/$CPU $CPU + build_sketch arduino $SKETCH + diff --git a/travis/common.sh b/travis/common.sh index be959fa..364000e 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -27,6 +27,66 @@ function build_sketches() done } +function build_sketch() +{ + local arduino=$1 + local sketch=$2 + $arduino --verify $sketch; + local result=$? + if [ $result -ne 0 ]; then + echo "Build failed ($sketch) build verbose..." + $arduino --verify --verbose --preserve-temp-files $sketch + result=$? + fi + if [ $result -ne 0 ]; then + echo "Build failed ($1) $sketch" + return $result + fi +} + +function get_sketches_json() +{ + local arduino=$1 + local srcpath=$2 + local platform=$3 + local sketches=($(find $srcpath -name *.ino)) + echo -en "[" + for sketch in "${sketches[@]}" ; do + local sketchdir=$(dirname $sketch) + if [[ -f "$sketchdir/.$platform.skip" ]]; then + continue + fi + echo -en "\"$sketch\"" + if [[ $sketch != ${sketches[-1]} ]] ; then + echo -en "," + fi + + done + echo -en "]" +} + +function get_sketches_json_matrix() +{ + local arduino=$1 + local srcpath=$2 + local platform=$3 + local ideversion=$4 + local board=$5 + local sketches=($(find $srcpath -name *.ino)) + for sketch in "${sketches[@]}" ; do + local sketchdir=$(dirname $sketch) + local sketchname=$(basename $sketch) + if [[ -f "$sketchdir/.$platform.skip" ]]; then + continue + fi + echo -en "{\"name\":\"$sketchname\",\"board\":\"$board\",\"ideversion\":\"$ideversion\",\"cpu\":\"$platform\",\"sketch\":\"$sketch\"}" + if [[ $sketch != ${sketches[-1]} ]] ; then + echo -en "," + fi + done +} + + function get_core() { @@ -38,7 +98,9 @@ function get_core() mkdir esp8266com cd esp8266com git clone https://github.com/esp8266/Arduino.git esp8266 - cd esp8266/tools + cd esp8266/ + rm -rf .git + cd tools python get.py fi @@ -46,7 +108,9 @@ function get_core() mkdir espressif cd espressif git clone https://github.com/espressif/arduino-esp32.git esp32 - cd esp32/tools + cd esp32/ + rm -rf .git + cd tools python get.py fi From 822618f606ffd80da7574203ca680bbcb0899edd Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 5 Jan 2021 21:15:09 +0100 Subject: [PATCH 256/347] code style fix --- src/WebSockets.h | 54 +++++++++++++++++++--------------------- src/WebSocketsServer.cpp | 5 ++-- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index 00d65b2..aded4bb 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -259,15 +259,13 @@ typedef struct { } WSMessageHeader_t; typedef struct { - - void init (uint8_t num, - uint32_t pingInterval, - uint32_t pongTimeout, - uint8_t disconnectTimeoutCount) - { - this->num = num; - this->pingInterval = pingInterval; - this->pongTimeout = pongTimeout; + void init(uint8_t num, + uint32_t pingInterval, + uint32_t pongTimeout, + uint8_t disconnectTimeoutCount) { + this->num = num; + this->pingInterval = pingInterval; + this->pongTimeout = pongTimeout; this->disconnectTimeoutCount = disconnectTimeoutCount; } @@ -284,19 +282,19 @@ typedef struct { WEBSOCKETS_NETWORK_SSL_CLASS * ssl; #endif - String cUrl; ///< http url - uint16_t cCode = 0; ///< http code + String cUrl; ///< http url + uint16_t cCode = 0; ///< http code - bool cIsClient = false; ///< will be used for masking - bool cIsUpgrade = false; ///< Connection == Upgrade - bool cIsWebsocket = false; ///< Upgrade == websocket + bool cIsClient = false; ///< will be used for masking + bool cIsUpgrade = false; ///< Connection == Upgrade + bool cIsWebsocket = false; ///< Upgrade == websocket - String cSessionId; ///< client Set-Cookie (session id) - String cKey; ///< client Sec-WebSocket-Key - String cAccept; ///< client Sec-WebSocket-Accept - String cProtocol; ///< client Sec-WebSocket-Protocol - String cExtensions; ///< client Sec-WebSocket-Extensions - uint16_t cVersion = 0; ///< client Sec-WebSocket-Version + String cSessionId; ///< client Set-Cookie (session id) + String cKey; ///< client Sec-WebSocket-Key + String cAccept; ///< client Sec-WebSocket-Accept + String cProtocol; ///< client Sec-WebSocket-Protocol + String cExtensions; ///< client Sec-WebSocket-Extensions + uint16_t cVersion = 0; ///< client Sec-WebSocket-Version uint8_t cWsRXsize = 0; ///< State of the RX uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer @@ -307,15 +305,15 @@ typedef struct { String extraHeaders; - bool cHttpHeadersValid = false; ///< non-websocket http header validity indicator - size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count + bool cHttpHeadersValid = false; ///< non-websocket http header validity indicator + size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count - bool pongReceived = false; - uint32_t pingInterval = 0; // how often ping will be sent, 0 means "heartbeat is not active" - uint32_t lastPing = 0; // millis when last pong has been received - uint32_t pongTimeout = 0; // interval in millis after which pong is considered to timeout - uint8_t disconnectTimeoutCount = 0; // after how many subsequent pong timeouts discconnect will happen, 0 means "do not disconnect" - uint8_t pongTimeoutCount = 0; // current pong timeout count + bool pongReceived = false; + uint32_t pingInterval = 0; // how often ping will be sent, 0 means "heartbeat is not active" + uint32_t lastPing = 0; // millis when last pong has been received + uint32_t pongTimeout = 0; // interval in millis after which pong is considered to timeout + uint8_t disconnectTimeoutCount = 0; // after how many subsequent pong timeouts discconnect will happen, 0 means "do not disconnect" + uint8_t pongTimeoutCount = 0; // current pong timeout count #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) String cHttpLine; ///< HTTP header lines diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index c8ac2ef..b1d575a 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -71,13 +71,12 @@ WebSocketsServer::~WebSocketsServer() { * called to initialize the Websocket server */ void WebSocketsServerCore::begin(void) { - // adjust clients storage: // _clients[i]'s constructor are already called, // all its members are initialized to their default value, // except the ones explicitly detailed in WSclient_t() constructor. // Then we need to initialize some members to non-trivial values: - for (int i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + for(int i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { _clients[i].init(i, _pingInterval, _pongTimeout, _disconnectTimeoutCount); } @@ -100,7 +99,7 @@ void WebSocketsServerCore::close(void) { // restore _clients[] to their initial state // before next call to ::begin() - for (int i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { + for(int i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { _clients[i] = WSclient_t(); } } From 4a05eab627221342b4e7e31b61f2029b4274e183 Mon Sep 17 00:00:00 2001 From: Markus Date: Tue, 5 Jan 2021 21:30:28 +0100 Subject: [PATCH 257/347] Update README.md use github actions as Build Status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5600252..26d124c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -WebSocket Server and Client for Arduino [![Build Status](https://travis-ci.com/Links2004/arduinoWebSockets.svg?branch=master)](https://travis-ci.com/Links2004/arduinoWebSockets) +WebSocket Server and Client for Arduino [![Build Status](https://github.com/Links2004/arduinoWebSockets/workflows/CI/badge.svg?branch=master)](https://github.com/Links2004/arduinoWebSockets/actions?query=workflow%3ACI+branch%3Amaster) =========================================== a WebSocket Server and Client for Arduino based on RFC6455. From e70262dab9660c3c00d76104d753eb3ffabe76ef Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 5 Jan 2021 21:50:40 +0100 Subject: [PATCH 258/347] add done job --- .github/workflows/main.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d0ed693..addd95d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -165,3 +165,10 @@ jobs: cd $GITHUB_WORKSPACE build_sketch arduino $SKETCH + done: + needs: [prepare_ide, prepare_example_json, build] + runs-on: ubuntu-latest + steps: + name: Done + run: | + echo DONE From c98baafda710f60eb027f5a224b4bc95f78bce1d Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 5 Jan 2021 21:54:58 +0100 Subject: [PATCH 259/347] jobs steps array --- .github/workflows/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index addd95d..f40d1f4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -169,6 +169,6 @@ jobs: needs: [prepare_ide, prepare_example_json, build] runs-on: ubuntu-latest steps: - name: Done - run: | - echo DONE + - name: Done + run: | + echo DONE From 2f21590e552e0ebcbb0b50857bcf09c9fd86b99d Mon Sep 17 00:00:00 2001 From: Links Date: Wed, 6 Jan 2021 09:18:27 +0100 Subject: [PATCH 260/347] no need for a full clone --- travis/common.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/travis/common.sh b/travis/common.sh index 364000e..0f0ec67 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -97,7 +97,7 @@ function get_core() if [ "$1" = "esp8266" ] ; then mkdir esp8266com cd esp8266com - git clone https://github.com/esp8266/Arduino.git esp8266 + git clone --depth 1 https://github.com/esp8266/Arduino.git esp8266 cd esp8266/ rm -rf .git cd tools @@ -107,7 +107,7 @@ function get_core() if [ "$1" = "esp32" ] ; then mkdir espressif cd espressif - git clone https://github.com/espressif/arduino-esp32.git esp32 + git clone --depth 1 https://github.com/espressif/arduino-esp32.git esp32 cd esp32/ rm -rf .git cd tools From 0e729cd8962600eda14f51f9b4fca80411f76827 Mon Sep 17 00:00:00 2001 From: Links Date: Wed, 6 Jan 2021 09:39:19 +0100 Subject: [PATCH 261/347] cleanup clone_library --- travis/common.sh | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/travis/common.sh b/travis/common.sh index 0f0ec67..234b1f6 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -86,8 +86,6 @@ function get_sketches_json_matrix() done } - - function get_core() { echo Setup core for $1 @@ -115,3 +113,19 @@ function get_core() fi } + +function clone_library() { + local url=$1 + echo clone $(basename $url) + mkdir -p $HOME/Arduino/libraries + cd $HOME/Arduino/libraries + git clone --depth 1 $url + rm -rf */.git + rm -rf */.github + rm -rf */examples +} + +function hash_library_names() { + cd $HOME/Arduino/libraries + ls | sha1sum -z | cut -c1-5 +} \ No newline at end of file From fd83d6ad45f3ce7556ee6240cbf6519a157a03db Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 7 Jan 2021 09:59:49 +0100 Subject: [PATCH 262/347] add WebSocketsVersion.h and some build checks --- .github/workflows/main.yml | 12 +++++- library.json | 26 ++++++------ src/WebSockets.h | 2 + src/WebSocketsVersion.h | 36 +++++++++++++++++ travis/version.py | 81 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 143 insertions(+), 14 deletions(-) create mode 100644 src/WebSocketsVersion.h create mode 100755 travis/version.py diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f40d1f4..fa78115 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,6 +14,14 @@ on: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: + check_version_files: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: check version + run: | + $GITHUB_WORKSPACE/travis/version.py --check prepare_example_json: runs-on: ubuntu-latest @@ -147,6 +155,7 @@ jobs: - name: copy code run: | + mkdir -p $HOME/Arduino/libraries/ cp -r $GITHUB_WORKSPACE $HOME/Arduino/libraries/arduinoWebSockets - name: config IDE @@ -158,6 +167,7 @@ jobs: arduino --pref update.check=false - name: build example + timeout-minutes: 20 run: | export DISPLAY=:1.0 export PATH="$HOME/arduino_ide:$PATH" @@ -166,7 +176,7 @@ jobs: build_sketch arduino $SKETCH done: - needs: [prepare_ide, prepare_example_json, build] + needs: [prepare_ide, prepare_example_json, build, check_version_files] runs-on: ubuntu-latest steps: - name: Done diff --git a/library.json b/library.json index fbf044f..9944b75 100644 --- a/library.json +++ b/library.json @@ -1,25 +1,25 @@ { - "name": "WebSockets", - "description": "WebSocket Server and Client for Arduino based on RFC6455", - "keywords": "wifi, http, web, server, client, websocket", "authors": [ { + "maintainer": true, "name": "Markus Sattler", - "url": "https://github.com/Links2004", - "maintainer": true + "url": "https://github.com/Links2004" } ], - "repository": { - "type": "git", - "url": "https://github.com/Links2004/arduinoWebSockets.git" - }, - "version": "2.3.2", - "license": "LGPL-2.1", + "description": "WebSocket Server and Client for Arduino based on RFC6455", "export": { "exclude": [ "tests" ] }, "frameworks": "arduino", - "platforms": "atmelavr, espressif8266, espressif32" -} + "keywords": "wifi, http, web, server, client, websocket", + "license": "LGPL-2.1", + "name": "WebSockets", + "platforms": "atmelavr, espressif8266, espressif32", + "repository": { + "type": "git", + "url": "https://github.com/Links2004/arduinoWebSockets.git" + }, + "version": "2.3.2" +} \ No newline at end of file diff --git a/src/WebSockets.h b/src/WebSockets.h index aded4bb..b182bd5 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -40,6 +40,8 @@ #include #endif +#include "WebSocketsVersion.h" + #ifndef NODEBUG_WEBSOCKETS #ifdef DEBUG_ESP_PORT #define DEBUG_WEBSOCKETS(...) \ diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h new file mode 100644 index 0000000..2d8968b --- /dev/null +++ b/src/WebSocketsVersion.h @@ -0,0 +1,36 @@ +/** + * @file WebSocketsVersion.h + * @date 07.01.2021 + * @author Markus Sattler + * + * Copyright (c) 2015 Markus Sattler. All rights reserved. + * This file is part of the WebSockets for Arduino. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef WEBSOCKETSVERSION_H_ +#define WEBSOCKETSVERSION_H_ + +#define WEBSOCKETS_VERSION "2.3.2" + +#define WEBSOCKETS_VERSION_MAJOR 2 +#define WEBSOCKETS_VERSION_MINOR 3 +#define WEBSOCKETS_VERSION_PATCH 2 + +#define WEBSOCKETS_VERSION_INT 2003002 + +#endif /* WEBSOCKETSVERSION_H_ */ diff --git a/travis/version.py b/travis/version.py new file mode 100755 index 0000000..be1359f --- /dev/null +++ b/travis/version.py @@ -0,0 +1,81 @@ +#!/usr/bin/python3 + +import json +import configparser +import argparse +import re +import os + +travis_dir = os.path.dirname(os.path.abspath(__file__)) +base_dir = os.path.abspath(travis_dir + "/../") + +def get_library_properties_version(): + library_properties = {} + with open(f'{base_dir}/library.properties', 'r') as f: + library_properties = configparser.ConfigParser() + library_properties.read_string('[root]\n' + f.read()) + return library_properties['root']['version'] + +def get_library_json_version(): + library_json = {} + with open(f'{base_dir}/library.json', 'r') as f: + library_json = json.load(f) + return library_json['version'] + +def get_header_versions(): + data = {} + define = re.compile('^#define WEBSOCKETS_VERSION_?(.*) "?([0-9\.]*)"?$') + with open(f'{base_dir}/src/WebSocketsVersion.h', 'r') as f: + for line in f: + m = define.match(line) + if m: + name = m[1] + if name == "": + name = "VERSION" + data[name] = m[2] + return data + + +parser = argparse.ArgumentParser(description='Checks and update Version files') +parser.add_argument( + '--update', action=argparse.BooleanOptionalAction, default=False) +parser.add_argument( + '--check', action=argparse.BooleanOptionalAction, default=True) + +args = parser.parse_args() + +if args.update: + library_properties_version = get_library_properties_version() + + with open(f'{base_dir}/library.json', 'r') as f: + library_json = json.load(f) + + library_json['version'] = library_properties_version + + with open(f'{base_dir}/library.json', 'w') as f: + json.dump(library_json, f, indent=4, sort_keys=True) + + +library_json_version = get_library_json_version() +library_properties_version = get_library_properties_version() +header_version = get_header_versions() + +print("WebSocketsVersion.h", header_version) +print(f"library.json: {library_json_version}") +print(f"library.properties: {library_properties_version}") + +if args.check: + if library_json_version != library_properties_version or header_version['VERSION'] != library_properties_version: + raise Exception('versions did not match!') + + hvs = header_version['VERSION'].split('.') + if header_version['MAJOR'] != hvs[0]: + raise Exception('header MAJOR version wrong!') + if header_version['MINOR'] != hvs[1]: + raise Exception('header MINOR version wrong!') + if header_version['PATCH'] != hvs[2]: + raise Exception('header PATCH version wrong!') + + intversion = int(hvs[0]) * 1000000 + int(hvs[1]) * 1000 + int(hvs[2]) + if int(header_version['INT']) != intversion: + raise Exception('header INT version wrong!') \ No newline at end of file From 784b7f9cb88de2b2051ee88f935bcd50741e4565 Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 7 Jan 2021 10:05:30 +0100 Subject: [PATCH 263/347] no python3.9 on github actions --- travis/version.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/travis/version.py b/travis/version.py index be1359f..dd2ec26 100755 --- a/travis/version.py +++ b/travis/version.py @@ -38,9 +38,9 @@ def get_header_versions(): parser = argparse.ArgumentParser(description='Checks and update Version files') parser.add_argument( - '--update', action=argparse.BooleanOptionalAction, default=False) + '--update', action='store_true', default=False) parser.add_argument( - '--check', action=argparse.BooleanOptionalAction, default=True) + '--check', action='store_true', default=True) args = parser.parse_args() From 39e6a8e709234b08c1ba75bd4df22fa109a3392f Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 7 Jan 2021 10:14:30 +0100 Subject: [PATCH 264/347] print version in DEBUG mode --- src/WebSocketsClient.cpp | 2 ++ src/WebSocketsServer.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index bd31268..8583ede 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -86,6 +86,8 @@ void WebSocketsClient::begin(const char * host, uint16_t port, const char * url, _lastConnectionFail = 0; _lastHeaderSent = 0; + + DEBUG_WEBSOCKETS("[WS-Client] Websocket Version: " WEBSOCKETS_VERSION "\n"); } void WebSocketsClient::begin(String host, uint16_t port, String url, String protocol) { diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index b1d575a..1faabd6 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -91,6 +91,8 @@ void WebSocketsServerCore::begin(void) { #endif _runnning = true; + + DEBUG_WEBSOCKETS("[WS-Server] Websocket Version: " WEBSOCKETS_VERSION "\n"); } void WebSocketsServerCore::close(void) { From ec22d67c12f68c66cde73e9d5629c7de35274704 Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 7 Jan 2021 10:24:23 +0100 Subject: [PATCH 265/347] version.py can now create WebSocketsVersion.h --- src/WebSocketsVersion.h | 2 +- travis/version.py | 61 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index 2d8968b..9a05e69 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -2,7 +2,7 @@ * @file WebSocketsVersion.h * @date 07.01.2021 * @author Markus Sattler - * + * * Copyright (c) 2015 Markus Sattler. All rights reserved. * This file is part of the WebSockets for Arduino. * diff --git a/travis/version.py b/travis/version.py index dd2ec26..71454ab 100755 --- a/travis/version.py +++ b/travis/version.py @@ -5,10 +5,57 @@ import argparse import re import os +import datetime travis_dir = os.path.dirname(os.path.abspath(__file__)) base_dir = os.path.abspath(travis_dir + "/../") +def write_header_file(version): + hvs = version.split('.') + intversion = int(hvs[0]) * 1000000 + int(hvs[1]) * 1000 + int(hvs[2]) + now = datetime.datetime.now() + + text = f'''/** + * @file WebSocketsVersion.h + * @date {now.strftime("%d.%m.%Y")} + * @author Markus Sattler + * + * Copyright (c) 2015 Markus Sattler. All rights reserved. + * This file is part of the WebSockets for Arduino. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef WEBSOCKETSVERSION_H_ +#define WEBSOCKETSVERSION_H_ + +#define WEBSOCKETS_VERSION "{version}" + +#define WEBSOCKETS_VERSION_MAJOR {hvs[0]} +#define WEBSOCKETS_VERSION_MINOR {hvs[1]} +#define WEBSOCKETS_VERSION_PATCH {hvs[2]} + +#define WEBSOCKETS_VERSION_INT {intversion} + +#endif /* WEBSOCKETSVERSION_H_ */ +''' + with open(f'{base_dir}/src/WebSocketsVersion.h', 'w') as f: + f.write(text) + + def get_library_properties_version(): library_properties = {} with open(f'{base_dir}/library.properties', 'r') as f: @@ -16,12 +63,14 @@ def get_library_properties_version(): library_properties.read_string('[root]\n' + f.read()) return library_properties['root']['version'] + def get_library_json_version(): library_json = {} with open(f'{base_dir}/library.json', 'r') as f: library_json = json.load(f) return library_json['version'] + def get_header_versions(): data = {} define = re.compile('^#define WEBSOCKETS_VERSION_?(.*) "?([0-9\.]*)"?$') @@ -31,8 +80,8 @@ def get_header_versions(): if m: name = m[1] if name == "": - name = "VERSION" - data[name] = m[2] + name = "VERSION" + data[name] = m[2] return data @@ -46,7 +95,7 @@ def get_header_versions(): if args.update: library_properties_version = get_library_properties_version() - + with open(f'{base_dir}/library.json', 'r') as f: library_json = json.load(f) @@ -55,6 +104,8 @@ def get_header_versions(): with open(f'{base_dir}/library.json', 'w') as f: json.dump(library_json, f, indent=4, sort_keys=True) + write_header_file(library_properties_version) + library_json_version = get_library_json_version() library_properties_version = get_library_properties_version() @@ -76,6 +127,6 @@ def get_header_versions(): if header_version['PATCH'] != hvs[2]: raise Exception('header PATCH version wrong!') - intversion = int(hvs[0]) * 1000000 + int(hvs[1]) * 1000 + int(hvs[2]) + intversion = int(hvs[0]) * 1000000 + int(hvs[1]) * 1000 + int(hvs[2]) if int(header_version['INT']) != intversion: - raise Exception('header INT version wrong!') \ No newline at end of file + raise Exception('header INT version wrong!') From 410489f7c5234690e5874e6731ed34cfe1305e9d Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 7 Jan 2021 10:27:42 +0100 Subject: [PATCH 266/347] bump version to 2.3.3 --- library.json | 2 +- library.properties | 2 +- src/WebSocketsVersion.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library.json b/library.json index 9944b75..2643ba6 100644 --- a/library.json +++ b/library.json @@ -21,5 +21,5 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.3.2" + "version": "2.3.3" } \ No newline at end of file diff --git a/library.properties b/library.properties index 0c51754..4ff5abc 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.3.2 +version=2.3.3 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index 9a05e69..09075d8 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -25,12 +25,12 @@ #ifndef WEBSOCKETSVERSION_H_ #define WEBSOCKETSVERSION_H_ -#define WEBSOCKETS_VERSION "2.3.2" +#define WEBSOCKETS_VERSION "2.3.3" #define WEBSOCKETS_VERSION_MAJOR 2 #define WEBSOCKETS_VERSION_MINOR 3 -#define WEBSOCKETS_VERSION_PATCH 2 +#define WEBSOCKETS_VERSION_PATCH 3 -#define WEBSOCKETS_VERSION_INT 2003002 +#define WEBSOCKETS_VERSION_INT 2003003 #endif /* WEBSOCKETSVERSION_H_ */ From 0ecef8c552a949267babdec6cdd9c97ea84082b0 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 19 Jan 2021 16:58:37 +0100 Subject: [PATCH 267/347] Fixing WebSocket Close see #610 --- src/WebSocketsServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 1faabd6..495cb55 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -914,7 +914,7 @@ void WebSocketsServer::begin(void) { } void WebSocketsServer::close(void) { - WebSocketsServer::close(); + WebSocketsServerCore::close(); #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) _server->close(); #elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) From 900d81e5345fe2dbe74fd175749c80e2bbda2f00 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 19 Jan 2021 16:59:03 +0100 Subject: [PATCH 268/347] make WSclient_t * newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); public --- src/WebSocketsServer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 978cd55..5bdcd04 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -98,6 +98,8 @@ class WebSocketsServerCore : protected WebSockets { void loop(void); // handle client data only #endif + WSclient_t * newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); + protected: String _origin; String _protocol; @@ -116,8 +118,6 @@ class WebSocketsServerCore : protected WebSockets { uint32_t _pongTimeout; uint8_t _disconnectTimeoutCount; - WSclient_t * newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient); - void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); void clientDisconnect(WSclient_t * client); From 3a2b757155d7fe151be0516f43ca7e8288eac32f Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 31 Jan 2021 10:27:36 +0100 Subject: [PATCH 269/347] EIO=4 ping handling #611 --- src/SocketIOclient.cpp | 24 +++++++++++++++++++++--- src/SocketIOclient.h | 5 +++++ src/WebSocketsClient.cpp | 3 +++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index 8fd8ad5..a06efa2 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -18,31 +18,37 @@ SocketIOclient::~SocketIOclient() { void SocketIOclient::begin(const char * host, uint16_t port, const char * url, const char * protocol) { WebSocketsClient::beginSocketIO(host, port, url, protocol); WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + initClient(); } void SocketIOclient::begin(String host, uint16_t port, String url, String protocol) { WebSocketsClient::beginSocketIO(host, port, url, protocol); WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + initClient(); } #if defined(HAS_SSL) void SocketIOclient::beginSSL(const char * host, uint16_t port, const char * url, const char * protocol) { WebSocketsClient::beginSocketIOSSL(host, port, url, protocol); WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + initClient(); } void SocketIOclient::beginSSL(String host, uint16_t port, String url, String protocol) { WebSocketsClient::beginSocketIOSSL(host, port, url, protocol); WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + initClient(); } -#if !defined(SSL_AXTLS) +#if defined(SSL_BARESSL) void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol); WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + initClient(); } void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) { WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol); WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + initClient(); } void SocketIOclient::setSSLClientCertKey(const char * clientCert, const char * clientPrivateKey) { @@ -55,6 +61,18 @@ void SocketIOclient::setSSLClientCertKey(BearSSL::X509List * clientCert, BearSSL #endif #endif + +void SocketIOclient::configureEIOping(bool disableHeartbeat) { + _disableHeartbeat = disableHeartbeat; +} + +void SocketIOclient::initClient(void) { + if(_client.cUrl.indexOf("EIO=4") != -1) { + DEBUG_WEBSOCKETS("[wsIOc] found EIO=4 disable EIO ping on client\n"); + configureEIOping(true); + } +} + /** * set callback function * @param cbEvent SocketIOclientEvent @@ -148,8 +166,8 @@ bool SocketIOclient::sendEVENT(String & payload) { void SocketIOclient::loop(void) { WebSocketsClient::loop(); unsigned long t = millis(); - if((t - _lastConnectionFail) > EIO_HEARTBEAT_INTERVAL) { - _lastConnectionFail = t; + if(!_disableHeartbeat && (t - _lastHeartbeat) > EIO_HEARTBEAT_INTERVAL) { + _lastHeartbeat = t; DEBUG_WEBSOCKETS("[wsIOc] send ping\n"); WebSocketsClient::sendTXT(eIOtype_PING); } diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index cf674cb..6deb168 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -77,7 +77,10 @@ class SocketIOclient : protected WebSocketsClient { void loop(void); + void configureEIOping(bool disableHeartbeat = false); + protected: + bool _disableHeartbeat = false; uint64_t _lastHeartbeat = 0; SocketIOclientEvent _cbEvent; virtual void runIOCbEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) { @@ -86,6 +89,8 @@ class SocketIOclient : protected WebSocketsClient { } } + void initClient(void); + // Handeling events from websocket layer virtual void runCbEvent(WStype_t type, uint8_t * payload, size_t length) { handleCbEvent(type, payload, length); diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 8583ede..50ed631 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -945,6 +945,9 @@ void WebSocketsClient::handleHBPing() { if(sendPing()) { _client.lastPing = millis(); _client.pongReceived = false; + } else { + DEBUG_WEBSOCKETS("[WS-Client] sending HB ping failed\n"); + WebSockets::clientDisconnect(&_client, 1000); } } } From 0a4fcd44c2c69d46b0bbd39646e3e9e94d319d84 Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 31 Jan 2021 10:27:36 +0100 Subject: [PATCH 270/347] EIO=4 ping handling #611 --- src/SocketIOclient.cpp | 24 +++++++++++++++++++++--- src/SocketIOclient.h | 5 +++++ src/WebSocketsClient.cpp | 3 +++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index 8fd8ad5..a06efa2 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -18,31 +18,37 @@ SocketIOclient::~SocketIOclient() { void SocketIOclient::begin(const char * host, uint16_t port, const char * url, const char * protocol) { WebSocketsClient::beginSocketIO(host, port, url, protocol); WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + initClient(); } void SocketIOclient::begin(String host, uint16_t port, String url, String protocol) { WebSocketsClient::beginSocketIO(host, port, url, protocol); WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + initClient(); } #if defined(HAS_SSL) void SocketIOclient::beginSSL(const char * host, uint16_t port, const char * url, const char * protocol) { WebSocketsClient::beginSocketIOSSL(host, port, url, protocol); WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + initClient(); } void SocketIOclient::beginSSL(String host, uint16_t port, String url, String protocol) { WebSocketsClient::beginSocketIOSSL(host, port, url, protocol); WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + initClient(); } -#if !defined(SSL_AXTLS) +#if defined(SSL_BARESSL) void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol); WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + initClient(); } void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) { WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol); WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + initClient(); } void SocketIOclient::setSSLClientCertKey(const char * clientCert, const char * clientPrivateKey) { @@ -55,6 +61,18 @@ void SocketIOclient::setSSLClientCertKey(BearSSL::X509List * clientCert, BearSSL #endif #endif + +void SocketIOclient::configureEIOping(bool disableHeartbeat) { + _disableHeartbeat = disableHeartbeat; +} + +void SocketIOclient::initClient(void) { + if(_client.cUrl.indexOf("EIO=4") != -1) { + DEBUG_WEBSOCKETS("[wsIOc] found EIO=4 disable EIO ping on client\n"); + configureEIOping(true); + } +} + /** * set callback function * @param cbEvent SocketIOclientEvent @@ -148,8 +166,8 @@ bool SocketIOclient::sendEVENT(String & payload) { void SocketIOclient::loop(void) { WebSocketsClient::loop(); unsigned long t = millis(); - if((t - _lastConnectionFail) > EIO_HEARTBEAT_INTERVAL) { - _lastConnectionFail = t; + if(!_disableHeartbeat && (t - _lastHeartbeat) > EIO_HEARTBEAT_INTERVAL) { + _lastHeartbeat = t; DEBUG_WEBSOCKETS("[wsIOc] send ping\n"); WebSocketsClient::sendTXT(eIOtype_PING); } diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index cf674cb..6deb168 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -77,7 +77,10 @@ class SocketIOclient : protected WebSocketsClient { void loop(void); + void configureEIOping(bool disableHeartbeat = false); + protected: + bool _disableHeartbeat = false; uint64_t _lastHeartbeat = 0; SocketIOclientEvent _cbEvent; virtual void runIOCbEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) { @@ -86,6 +89,8 @@ class SocketIOclient : protected WebSocketsClient { } } + void initClient(void); + // Handeling events from websocket layer virtual void runCbEvent(WStype_t type, uint8_t * payload, size_t length) { handleCbEvent(type, payload, length); diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 8583ede..50ed631 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -945,6 +945,9 @@ void WebSocketsClient::handleHBPing() { if(sendPing()) { _client.lastPing = millis(); _client.pongReceived = false; + } else { + DEBUG_WEBSOCKETS("[WS-Client] sending HB ping failed\n"); + WebSockets::clientDisconnect(&_client, 1000); } } } From 435519912005cb1cb103b075f1c53c8ef04fa7e0 Mon Sep 17 00:00:00 2001 From: Links Date: Sun, 31 Jan 2021 20:31:52 +0100 Subject: [PATCH 271/347] bump version 2.3.4 --- library.json | 2 +- library.properties | 2 +- src/WebSocketsVersion.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library.json b/library.json index 2643ba6..8f96629 100644 --- a/library.json +++ b/library.json @@ -21,5 +21,5 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.3.3" + "version": "2.3.4" } \ No newline at end of file diff --git a/library.properties b/library.properties index 4ff5abc..a9bff7a 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.3.3 +version=2.3.4 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index 09075d8..2194280 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -1,6 +1,6 @@ /** * @file WebSocketsVersion.h - * @date 07.01.2021 + * @date 31.01.2021 * @author Markus Sattler * * Copyright (c) 2015 Markus Sattler. All rights reserved. @@ -25,12 +25,12 @@ #ifndef WEBSOCKETSVERSION_H_ #define WEBSOCKETSVERSION_H_ -#define WEBSOCKETS_VERSION "2.3.3" +#define WEBSOCKETS_VERSION "2.3.4" #define WEBSOCKETS_VERSION_MAJOR 2 #define WEBSOCKETS_VERSION_MINOR 3 -#define WEBSOCKETS_VERSION_PATCH 3 +#define WEBSOCKETS_VERSION_PATCH 4 -#define WEBSOCKETS_VERSION_INT 2003003 +#define WEBSOCKETS_VERSION_INT 2003004 #endif /* WEBSOCKETSVERSION_H_ */ From f55bf8d4ededd2d7acf36788e5cfe6e6393dd235 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 9 Feb 2021 18:26:21 +0100 Subject: [PATCH 272/347] bump version to 2.3.5 --- library.json | 2 +- library.properties | 2 +- src/WebSocketsVersion.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library.json b/library.json index 8f96629..5fd2023 100644 --- a/library.json +++ b/library.json @@ -21,5 +21,5 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.3.4" + "version": "2.3.5" } \ No newline at end of file diff --git a/library.properties b/library.properties index a9bff7a..db55e15 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.3.4 +version=2.3.5 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index 2194280..3e1aa0c 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -1,6 +1,6 @@ /** * @file WebSocketsVersion.h - * @date 31.01.2021 + * @date 09.02.2021 * @author Markus Sattler * * Copyright (c) 2015 Markus Sattler. All rights reserved. @@ -25,12 +25,12 @@ #ifndef WEBSOCKETSVERSION_H_ #define WEBSOCKETSVERSION_H_ -#define WEBSOCKETS_VERSION "2.3.4" +#define WEBSOCKETS_VERSION "2.3.5" #define WEBSOCKETS_VERSION_MAJOR 2 #define WEBSOCKETS_VERSION_MINOR 3 -#define WEBSOCKETS_VERSION_PATCH 4 +#define WEBSOCKETS_VERSION_PATCH 5 -#define WEBSOCKETS_VERSION_INT 2003004 +#define WEBSOCKETS_VERSION_INT 2003005 #endif /* WEBSOCKETSVERSION_H_ */ From 738e43fda411125a4b783b4cc9182a486f5c7b77 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 6 Mar 2021 08:56:08 +0100 Subject: [PATCH 273/347] install libgtk-3-0 --- .github/workflows/main.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fa78115..4b417d0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,7 +25,7 @@ jobs: prepare_example_json: runs-on: ubuntu-latest - steps: + steps: - uses: actions/checkout@v2 - name: generate examples @@ -60,7 +60,7 @@ jobs: env: IDE_VERSION: ${{ matrix.IDE_VERSION }} - steps: + steps: - uses: actions/checkout@v2 - name: Get Date @@ -121,6 +121,10 @@ jobs: steps: - uses: actions/checkout@v2 + - name: install libgtk-3-0 + run: | + sudo apt-get install libgtk-3-0 + - name: Get Date id: get-date run: | @@ -134,7 +138,7 @@ jobs: /home/runner/arduino_ide /home/runner/Arduino key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.ideversion }} - + - name: install python serial if: matrix.cpu == 'esp32' run: | @@ -157,7 +161,7 @@ jobs: run: | mkdir -p $HOME/Arduino/libraries/ cp -r $GITHUB_WORKSPACE $HOME/Arduino/libraries/arduinoWebSockets - + - name: config IDE run: | export DISPLAY=:1.0 From 7c3b1b7408c8c70f40f0cfe82f002ff6fd7197fc Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 6 Mar 2021 08:59:21 +0100 Subject: [PATCH 274/347] install libgtk-3-0 --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4b417d0..d9f1b96 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -121,9 +121,9 @@ jobs: steps: - uses: actions/checkout@v2 - - name: install libgtk-3-0 + - name: install libgtk2.0-0 run: | - sudo apt-get install libgtk-3-0 + sudo apt-get install -y libgtk2.0-0 - name: Get Date id: get-date From ed685e551f9a1a992037f5fdc791a36c4c43abc0 Mon Sep 17 00:00:00 2001 From: Links Date: Sat, 6 Mar 2021 09:22:52 +0100 Subject: [PATCH 275/347] fix _fingerprint is set checks for ESP32 see #633 and #632 --- src/WebSocketsClient.cpp | 11 +++++++---- src/WebSocketsClient.h | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 50ed631..e3519c8 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -229,8 +229,11 @@ void WebSocketsClient::loop(void) { #else #error setCACert not implemented #endif -#if defined(SSL_BARESSL) - } else if(_fingerprint) { +#if defined(ESP32) + } else if(!SSL_FINGERPRINT_IS_SET) { + _client.ssl->setInsecure(); +#elif defined(SSL_BARESSL) + } else if(SSL_FINGERPRINT_IS_SET) { _client.ssl->setFingerprint(_fingerprint); } else { _client.ssl->setInsecure(); @@ -865,14 +868,14 @@ void WebSocketsClient::connectedCb() { #if defined(HAS_SSL) #if defined(SSL_AXTLS) || defined(ESP32) - if(_client.isSSL && _fingerprint.length()) { + if(_client.isSSL && SSL_FINGERPRINT_IS_SET) { if(!_client.ssl->verify(_fingerprint.c_str(), _host.c_str())) { DEBUG_WEBSOCKETS("[WS-Client] certificate mismatch\n"); WebSockets::clientDisconnect(&_client, 1000); return; } #else - if(_client.isSSL && _fingerprint) { + if(_client.isSSL && SSL_FINGERPRINT_IS_SET) { #endif } else if(_client.isSSL && !_CA_cert) { #if defined(SSL_BARESSL) diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 15863a7..efa7631 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -112,12 +112,14 @@ class WebSocketsClient : protected WebSockets { #ifdef SSL_AXTLS String _fingerprint; const char * _CA_cert; +#define SSL_FINGERPRINT_IS_SET (_fingerprint.length()) #define SSL_FINGERPRINT_NULL "" #else const uint8_t * _fingerprint; BearSSL::X509List * _CA_cert; BearSSL::X509List * _client_cert; BearSSL::PrivateKey * _client_key; +#define SSL_FINGERPRINT_IS_SET (_fingerprint != NULL) #define SSL_FINGERPRINT_NULL NULL #endif From a14b6b73b4f05e189ca49d6e84202c2b55db528a Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 8 Mar 2021 17:22:23 +0100 Subject: [PATCH 276/347] bump version to 2.3.6 --- library.json | 2 +- library.properties | 2 +- src/WebSocketsVersion.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library.json b/library.json index 5fd2023..2f7aec6 100644 --- a/library.json +++ b/library.json @@ -21,5 +21,5 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.3.5" + "version": "2.3.6" } \ No newline at end of file diff --git a/library.properties b/library.properties index db55e15..b9899d0 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.3.5 +version=2.3.6 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index 3e1aa0c..e0ab39c 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -1,6 +1,6 @@ /** * @file WebSocketsVersion.h - * @date 09.02.2021 + * @date 08.03.2021 * @author Markus Sattler * * Copyright (c) 2015 Markus Sattler. All rights reserved. @@ -25,12 +25,12 @@ #ifndef WEBSOCKETSVERSION_H_ #define WEBSOCKETSVERSION_H_ -#define WEBSOCKETS_VERSION "2.3.5" +#define WEBSOCKETS_VERSION "2.3.6" #define WEBSOCKETS_VERSION_MAJOR 2 #define WEBSOCKETS_VERSION_MINOR 3 -#define WEBSOCKETS_VERSION_PATCH 5 +#define WEBSOCKETS_VERSION_PATCH 6 -#define WEBSOCKETS_VERSION_INT 2003005 +#define WEBSOCKETS_VERSION_INT 2003006 #endif /* WEBSOCKETSVERSION_H_ */ From 72aae526552bc05646892676b9e398a49db3a3ab Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 17 Jun 2021 19:42:09 +0200 Subject: [PATCH 277/347] set EIO to version 4 in SocketIO examples see #682 --- .../WebSocketClientSocketIO.ino | 6 +++--- .../WebSocketClientSocketIOack.ino | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino b/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino index 26574ca..1bb4ecd 100644 --- a/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino +++ b/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino @@ -88,7 +88,7 @@ void setup() { USE_SERIAL.printf("[SETUP] WiFi Connected %s\n", ip.c_str()); // server address, port and URL - socketIO.begin("10.11.100.100", 8880); + socketIO.begin("10.11.100.100", 8880, "/socket.io/?EIO=4"); // event handler socketIO.onEvent(socketIOEvent); @@ -106,7 +106,7 @@ void loop() { // creat JSON message for Socket.IO (event) DynamicJsonDocument doc(1024); JsonArray array = doc.to(); - + // add evnet name // Hint: socket.on('event_name', .... array.add("event_name"); @@ -119,7 +119,7 @@ void loop() { String output; serializeJson(doc, output); - // Send event + // Send event socketIO.sendEVENT(output); // Print JSON for debugging diff --git a/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino b/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino index ab9ff68..3e4f87e 100644 --- a/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino +++ b/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino @@ -49,7 +49,7 @@ void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) USE_SERIAL.println(error.c_str()); return; } - + String eventName = doc[0]; USE_SERIAL.printf("[IOc] event name: %s\n", eventName.c_str()); @@ -58,7 +58,7 @@ void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) // creat JSON message for Socket.IO (ack) DynamicJsonDocument docOut(1024); JsonArray array = docOut.to(); - + // add payload (parameters) for the ack (callback function) JsonObject param1 = array.createNestedObject(); param1["now"] = millis(); @@ -68,7 +68,7 @@ void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) output += id; serializeJson(docOut, output); - // Send event + // Send event socketIO.send(sIOtype_ACK, output); } } @@ -125,7 +125,7 @@ void setup() { USE_SERIAL.printf("[SETUP] WiFi Connected %s\n", ip.c_str()); // server address, port and URL - socketIO.begin("10.11.100.100", 8880); + socketIO.begin("10.11.100.100", 8880, "/socket.io/?EIO=4"); // event handler socketIO.onEvent(socketIOEvent); @@ -143,7 +143,7 @@ void loop() { // creat JSON message for Socket.IO (event) DynamicJsonDocument doc(1024); JsonArray array = doc.to(); - + // add evnet name // Hint: socket.on('event_name', .... array.add("event_name"); @@ -156,7 +156,7 @@ void loop() { String output; serializeJson(doc, output); - // Send event + // Send event socketIO.sendEVENT(output); // Print JSON for debugging From f8da05aa876c9cc9d6b6a4a51de5f8d96b794253 Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 17 Jun 2021 19:43:15 +0200 Subject: [PATCH 278/347] add Socket.IO example for ESP32 --- .../WebSocketClientSocketIOack.ino | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 examples/esp32/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino diff --git a/examples/esp32/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino b/examples/esp32/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino new file mode 100644 index 0000000..af3572f --- /dev/null +++ b/examples/esp32/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino @@ -0,0 +1,155 @@ +/* + * WebSocketClientSocketIOack.ino + * + * Created on: 20.07.2019 + * + */ + +#include + +#include +#include +#include + +#include + +#include +#include + +WiFiMulti WiFiMulti; +SocketIOclient socketIO; + +#define USE_SERIAL Serial + + +void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) { + switch(type) { + case sIOtype_DISCONNECT: + USE_SERIAL.printf("[IOc] Disconnected!\n"); + break; + case sIOtype_CONNECT: + USE_SERIAL.printf("[IOc] Connected to url: %s\n", payload); + + // join default namespace (no auto join in Socket.IO V3) + socketIO.send(sIOtype_CONNECT, "/"); + break; + case sIOtype_EVENT: + { + char * sptr = NULL; + int id = strtol((char *)payload, &sptr, 10); + USE_SERIAL.printf("[IOc] get event: %s id: %d\n", payload, id); + if(id) { + payload = (uint8_t *)sptr; + } + DynamicJsonDocument doc(1024); + DeserializationError error = deserializeJson(doc, payload, length); + if(error) { + USE_SERIAL.print(F("deserializeJson() failed: ")); + USE_SERIAL.println(error.c_str()); + return; + } + + String eventName = doc[0]; + USE_SERIAL.printf("[IOc] event name: %s\n", eventName.c_str()); + + // Message Includes a ID for a ACK (callback) + if(id) { + // creat JSON message for Socket.IO (ack) + DynamicJsonDocument docOut(1024); + JsonArray array = docOut.to(); + + // add payload (parameters) for the ack (callback function) + JsonObject param1 = array.createNestedObject(); + param1["now"] = millis(); + + // JSON to String (serializion) + String output; + output += id; + serializeJson(docOut, output); + + // Send event + socketIO.send(sIOtype_ACK, output); + } + } + break; + case sIOtype_ACK: + USE_SERIAL.printf("[IOc] get ack: %u\n", length); + break; + case sIOtype_ERROR: + USE_SERIAL.printf("[IOc] get error: %u\n", length); + break; + case sIOtype_BINARY_EVENT: + USE_SERIAL.printf("[IOc] get binary: %u\n", length); + break; + case sIOtype_BINARY_ACK: + USE_SERIAL.printf("[IOc] get binary ack: %u\n", length); + break; + } +} + +void setup() { + //USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + //Serial.setDebugOutput(true); + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFiMulti.addAP("SSID", "passpasspass"); + + //WiFi.disconnect(); + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + String ip = WiFi.localIP().toString(); + USE_SERIAL.printf("[SETUP] WiFi Connected %s\n", ip.c_str()); + + // server address, port and URL + socketIO.begin("10.11.100.100", 8880, "/socket.io/?EIO=4"); + + // event handler + socketIO.onEvent(socketIOEvent); +} + +unsigned long messageTimestamp = 0; +void loop() { + socketIO.loop(); + + uint64_t now = millis(); + + if(now - messageTimestamp > 2000) { + messageTimestamp = now; + + // creat JSON message for Socket.IO (event) + DynamicJsonDocument doc(1024); + JsonArray array = doc.to(); + + // add evnet name + // Hint: socket.on('event_name', .... + array.add("event_name"); + + // add payload (parameters) for the event + JsonObject param1 = array.createNestedObject(); + param1["now"] = (uint32_t) now; + + // JSON to String (serializion) + String output; + serializeJson(doc, output); + + // Send event + socketIO.sendEVENT(output); + + // Print JSON for debugging + USE_SERIAL.println(output); + } +} From b242882ac556e1a3e4756794414740ab007bedf7 Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 17 Jun 2021 19:56:45 +0200 Subject: [PATCH 279/347] add git submodule update --init to esp8266 build --- travis/common.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/travis/common.sh b/travis/common.sh index 234b1f6..81d60e9 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -28,7 +28,7 @@ function build_sketches() } function build_sketch() -{ +{ local arduino=$1 local sketch=$2 $arduino --verify $sketch; @@ -60,7 +60,7 @@ function get_sketches_json() if [[ $sketch != ${sketches[-1]} ]] ; then echo -en "," fi - + done echo -en "]" } @@ -97,6 +97,7 @@ function get_core() cd esp8266com git clone --depth 1 https://github.com/esp8266/Arduino.git esp8266 cd esp8266/ + git submodule update --init rm -rf .git cd tools python get.py @@ -127,5 +128,5 @@ function clone_library() { function hash_library_names() { cd $HOME/Arduino/libraries - ls | sha1sum -z | cut -c1-5 + ls | sha1sum -z | cut -c1-5 } \ No newline at end of file From c897f605679d41aeb4f09325ab8070ad09d4cc15 Mon Sep 17 00:00:00 2001 From: Links Date: Thu, 17 Jun 2021 20:04:28 +0200 Subject: [PATCH 280/347] update arduino IDE from 1.8.13 to 1.8.15 --- .github/workflows/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d9f1b96..6fb322d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -42,10 +42,10 @@ jobs: get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.6.13 esp8266com:esp8266:generic:xtal=80,dbg=Serial1 echo -en "," - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.13 esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80 + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.15 esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80 echo -en "," - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.13 espressif:esp32:esp32:FlashFreq=80 + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.15 espressif:esp32:esp32:FlashFreq=80 echo -en "]" outputs: @@ -56,7 +56,7 @@ jobs: strategy: fail-fast: false matrix: - IDE_VERSION: [1.8.13, 1.6.13] + IDE_VERSION: [1.8.15, 1.6.13] env: IDE_VERSION: ${{ matrix.IDE_VERSION }} From 860ac9da694040c1f5238fe06cf3f182a9f63e10 Mon Sep 17 00:00:00 2001 From: Hasenradball Date: Sat, 19 Jun 2021 21:52:13 +0200 Subject: [PATCH 281/347] Prevent Compiler Warning: --> add // falls through prevent Compiler warning by adding // falls through to imform compiler. --- src/WebSocketsClient.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index e3519c8..562a661 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -784,8 +784,10 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { if(client->isSocketIO) { break; } + // falls through case 403: ///< Forbidden // todo handle login + // falls through default: ///< Server dont unterstand requrst ok = false; DEBUG_WEBSOCKETS("[WS-Client][handleHeader] serverCode is not 101 (%d)\n", client->cCode); From 27f86a10ad3571c4ec454a7e47739539b8c19e01 Mon Sep 17 00:00:00 2001 From: Links Date: Fri, 9 Jul 2021 17:17:42 +0200 Subject: [PATCH 282/347] allow access to setExtraHeaders and setReconnectInterval for SocketIOclient fix: #690 --- src/SocketIOclient.cpp | 8 ++++++++ src/SocketIOclient.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index a06efa2..bf61195 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -85,6 +85,14 @@ bool SocketIOclient::isConnected(void) { return WebSocketsClient::isConnected(); } +void SocketIOclient::setExtraHeaders(const char * extraHeaders) { + return WebSocketsClient::setExtraHeaders(extraHeaders); +} + +void SocketIOclient::setReconnectInterval(unsigned long time) { + return WebSocketsClient::setReconnectInterval(time); +} + /** * send text data to client * @param num uint8_t client id diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index 6deb168..a71afed 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -75,6 +75,9 @@ class SocketIOclient : protected WebSocketsClient { bool send(socketIOmessageType_t type, const char * payload, size_t length = 0); bool send(socketIOmessageType_t type, String & payload); + void setExtraHeaders(const char * extraHeaders = NULL); + void setReconnectInterval(unsigned long time); + void loop(void); void configureEIOping(bool disableHeartbeat = false); From 46b2ae1c97c2bc07555be2cd32776a93a490635f Mon Sep 17 00:00:00 2001 From: Links Date: Wed, 14 Jul 2021 19:28:25 +0200 Subject: [PATCH 283/347] fix #695, #696 --- src/SocketIOclient.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index a71afed..2eccea3 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -9,6 +9,7 @@ #define SOCKETIOCLIENT_H_ #include "WebSockets.h" +#include "WebSocketsClient.h" #define EIO_HEARTBEAT_INTERVAL 20000 From 108090e8cf39d4997be947c4f1e0600de2198276 Mon Sep 17 00:00:00 2001 From: mvermand22 Date: Fri, 3 Sep 2021 14:23:21 +0200 Subject: [PATCH 284/347] Update WebSocketsServer.cpp Created a dummy client in order to be able to drop the TCP Client. --- src/WebSocketsServer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 495cb55..81734ba 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -619,6 +619,10 @@ WSclient_t * WebSocketsServerCore::handleNewClient(WEBSOCKETS_NETWORK_CLASS * tc #else DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n"); #endif + // no client! => create dummy! + WSclient_t dummy = WSclient_t(); + client = & dummy; + client->tcp = tcpClient; dropNativeClient(client); } From 28ed6151454fc0a3568a14abbc88b9b9aee4bba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=C3=ADn=20Skala?= Date: Tue, 26 Oct 2021 00:01:24 +0200 Subject: [PATCH 285/347] Add minimal example for ESP OTA --- examples/esp8266/WebSocketClientOTA/README.md | 27 ++ .../WebSocketClientOTA/WebSocketClientOTA.ino | 263 ++++++++++++++++++ .../python_ota_server/main.py | 235 ++++++++++++++++ .../python_ota_server/requirements.txt | 2 + 4 files changed, 527 insertions(+) create mode 100644 examples/esp8266/WebSocketClientOTA/README.md create mode 100644 examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino create mode 100644 examples/esp8266/WebSocketClientOTA/python_ota_server/main.py create mode 100644 examples/esp8266/WebSocketClientOTA/python_ota_server/requirements.txt diff --git a/examples/esp8266/WebSocketClientOTA/README.md b/examples/esp8266/WebSocketClientOTA/README.md new file mode 100644 index 0000000..496eef2 --- /dev/null +++ b/examples/esp8266/WebSocketClientOTA/README.md @@ -0,0 +1,27 @@ +## Minimal example of WebsocketClientOTA and Python server + +Take this as small example, how achieve OTA update on ESP8266 and ESP32. + +Python server was wrote from train so take it only as bare example. +It's working, but it's not mean to run in production. + + +### Usage: + +Start server: +```bash +cd python_ota_server +python3 -m venv .venv +source .venv/bin/activate +pip3 install -r requirements.txt +python3 main.py +``` + +Flash ESP with example sketch and start it. + +Change version inside example sketch to higher and compile it and save it to bin file. + +Rename it to `mydevice-1.0.1-esp8266.bin` and place it inside new folder firmware (server create it). + +When the ESP connect to server, it check if version flashed is equal to fw in firmware folder. If higher FW version is present, +start the flash process. \ No newline at end of file diff --git a/examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino b/examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino new file mode 100644 index 0000000..2c87c25 --- /dev/null +++ b/examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino @@ -0,0 +1,263 @@ +/* + * WebSocketClientOTA.ino + * + * Created on: 25.10.2021 + * + */ + +#include +#include + +#ifdef ESP8266 + #include + #include + #include +#endif +#ifdef ESP32 + #include "WiFi.h" + #include "ESPmDNS.h" + #include +#endif + +#include +#include + +#include + +#include + +ESP8266WiFiMulti WiFiMulti; +WebSocketsClient webSocket; + +#define USE_SERIAL Serial + +// Variables: +// Settable: +const char *version = "1.0.0"; +const char *name = "mydevice"; + +// Others: +#ifdef ESP8266 + const char *chip = "esp8266"; +#endif +#ifdef ESP32 + const char *chip = "esp32"; +#endif + +uint32_t maxSketchSpace = 0; +int SketchSize = 0; +bool ws_conn = false; + +String IpAddress2String(const IPAddress& ipAddress) +{ + return String(ipAddress[0]) + String(".") + + String(ipAddress[1]) + String(".") + + String(ipAddress[2]) + String(".") + + String(ipAddress[3]); +} + +void greetings_(){ + StaticJsonDocument<200> doc; + doc["type"] = "greetings"; + doc["mac"] = WiFi.macAddress(); + doc["ip"] = IpAddress2String(WiFi.localIP()); + doc["version"] = version; + doc["name"] = name; + doc["chip"] = chip; + + char data[200]; + serializeJson(doc, data); + webSocket.sendTXT(data); +} + +void register_(){ + StaticJsonDocument<200> doc; + doc["type"] = "register"; + doc["mac"] = WiFi.macAddress(); + + char data[200]; + serializeJson(doc, data); + webSocket.sendTXT(data); + ws_conn = true; +} + +typedef void (*CALLBACK_FUNCTION)(JsonDocument &msg); + +typedef struct { + char type[50]; + CALLBACK_FUNCTION func; +} RESPONSES_STRUCT; + +void OTA(JsonDocument &msg){ + USE_SERIAL.print(F("[WSc] OTA mode: ")); + const char* go = "go"; + const char* ok = "ok"; + if(strncmp( msg["value"], go, strlen(go)) == 0 ) { + USE_SERIAL.print(F("go\n")); + SketchSize = int(msg["size"]); + maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; + USE_SERIAL.printf("[WSc] Max sketch size: %u\n", maxSketchSpace); + USE_SERIAL.printf("[WSc] Sketch size: %d\n", SketchSize); + USE_SERIAL.setDebugOutput(true); + if (!Update.begin(maxSketchSpace)) { //start with max available size + Update.printError(Serial); + ESP.restart(); + } + } else if (strncmp( msg["value"], ok, strlen(ok)) == 0) { + USE_SERIAL.print(F("OK\n")); + register_(); + } else { + USE_SERIAL.print(F("unknown value : ")); + USE_SERIAL.print(msg["value"].as()); + USE_SERIAL.print(F("\n")); + } +} + +void STATE(JsonDocument &msg){ + // Do something with message +} + +RESPONSES_STRUCT responses[] = { + {"ota", OTA}, + {"state", STATE}, +}; + +void text(uint8_t * payload, size_t length){ + // Convert mesage to something usable + char msgch[length]; + for (unsigned int i = 0; i < length; i++) + { + USE_SERIAL.print((char)payload[i]); + msgch[i] = ((char)payload[i]); + } + msgch[length] = '\0'; + + // Parse Json + StaticJsonDocument<200> doc_in; + DeserializationError error = deserializeJson(doc_in, msgch); + + if (error) { + USE_SERIAL.print(F("deserializeJson() failed: ")); + USE_SERIAL.println(error.c_str()); + return; + } + + // Handle each TYPE of message + int b = 0; + + for( b=0 ; strlen(responses[b].type) ; b++ ) + { + if( strncmp(doc_in["type"], responses[b].type, strlen(responses[b].type)) == 0 ) { + responses[b].func(doc_in); + } + } +} + +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { + + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[WSc] Disconnected!\n"); + break; + case WStype_CONNECTED: { + USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); + + // send message to server when Connected + // webSocket.sendTXT("Connected"); + greetings_(); + } + break; + case WStype_TEXT: + USE_SERIAL.printf("[WSc] get text: %s\n", payload); + + // send message to server + // webSocket.sendTXT("message here"); + text(payload, length); + break; + case WStype_BIN: + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + // hexdump(payload, length); + if (Update.write(payload, length) != length) { + Update.printError(Serial); + ESP.restart(); + } + yield(); + SketchSize -= length; + USE_SERIAL.printf("[WSc] Sketch size left: %u\n", SketchSize); + if (SketchSize < 1){ + if (Update.end(true)) { //true to set the size to the current progress + USE_SERIAL.printf("Update Success: \nRebooting...\n"); + delay(5); + yield(); + ESP.restart(); + } else { + Update.printError(USE_SERIAL); + ESP.restart(); + } + USE_SERIAL.setDebugOutput(false); + } + + // send data to server + // webSocket.sendBIN(payload, length); + break; + case WStype_PING: + // pong will be send automatically + USE_SERIAL.printf("[WSc] get ping\n"); + break; + case WStype_PONG: + // answer to a ping we send + USE_SERIAL.printf("[WSc] get pong\n"); + break; + } + +} + +void setup() { + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + //Serial.setDebugOutput(true); + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.print(F("\nMAC: ")); + USE_SERIAL.println(WiFi.macAddress()); + USE_SERIAL.print(F("\nDevice: ")); + USE_SERIAL.println(name); + USE_SERIAL.printf("\nVersion: %s\n", version); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFiMulti.addAP("SSID", "PASS"); + + //WiFi.disconnect(); + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + // server address, port and URL + webSocket.begin("10.0.1.5", 8081, "/"); + + // event handler + webSocket.onEvent(webSocketEvent); + + // use HTTP Basic Authorization this is optional remove if not needed + // webSocket.setAuthorization("USER", "PASS"); + + // try ever 5000 again if connection has failed + webSocket.setReconnectInterval(5000); + + // start heartbeat (optional) + // ping server every 15000 ms + // expect pong from server within 3000 ms + // consider connection disconnected if pong is not received 2 times + webSocket.enableHeartbeat(15000, 3000, 2); + +} + +void loop() { + webSocket.loop(); +} diff --git a/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py b/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py new file mode 100644 index 0000000..7e7fba1 --- /dev/null +++ b/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py @@ -0,0 +1,235 @@ +"""Minimal example of Python websocket server +handling OTA updates for ESP32 amd ESP8266 + +Check and upload of firmware works. +Register and state function are jus for example. +""" +# pylint: disable=W0703,E1101 +import asyncio +import copy +import json +import logging +import subprocess +import threading +import time +from os import listdir +from os.path import join as join_pth +from pathlib import Path + +import websockets +from packaging import version + +# Logger settings +logging.basicConfig(filename="ws_server.log") +Logger = logging.getLogger('WS-OTA') +Logger.addHandler(logging.StreamHandler()) +Logger.setLevel(logging.INFO) + +# Path to directory with FW +fw_path = join_pth(Path().absolute(), "firmware") + + +def create_path(path: str) -> None: + """Check if path exist or create it""" + Path(path).mkdir(parents=True, exist_ok=True) + + +def shell(command): + """Handle execution of shell commands""" + with subprocess.Popen(command, shell=True, + stdout=subprocess.PIPE, + universal_newlines=True + ) as process: + for stdout_line in iter(process.stdout.readline, ""): + Logger.debug(stdout_line) + process.stdout.close() + return_code = process.wait() + Logger.debug("Shell returned: %s", return_code) + + return process.returncode + return None + + +async def binary_send(websocket, fw_file): + """Read firmware file, divide it to chunks and send them""" + with open(fw_file, "rb") as binaryfile: + + while True: + chunk = binaryfile.read(2048) + if not chunk: + break + try: + await websocket.send(chunk) + except Exception as exception: + Logger.exception(exception) + return False + time.sleep(0.2) + + +def version_checker(name, vdev, vapp): + """Parse and compare FW version""" + + if version.parse(vdev) < version.parse(vapp): + Logger.info("Client(%s) version %s is smaller than %s: Go for update", name, vdev, vapp) + return True + Logger.info("Client(%s) version %s is greater or equal to %s: Not updating", name, vdev, vapp) + return False + + +class WsOtaHandler (threading.Thread): + """Thread handling ota update + + Runing ota directly from message would kill WS + as message bus would timeout. + """ + def __init__(self, name, message, websocket): + threading.Thread.__init__(self, daemon=True) + self.name = name + self.msg = message + self.websocket = websocket + + def run(self, ): + try: + asyncio.run(self.start_) + except Exception as exception: + Logger.exception(exception) + finally: + pass + + async def start_(self): + """Start _ota se asyncio future""" + msg_task = asyncio.ensure_future( + self._ota()) + + done, pending = await asyncio.wait( + [msg_task], + return_when=asyncio.FIRST_COMPLETED, + ) + Logger.info("WS Ota Handler done: %s", done) + for task in pending: + task.cancel() + + async def _ota(self): + """Check for new fw and update or pass""" + device_name = self.msg['name'] + device_chip = self.msg['chip'] + device_version = self.msg['version'] + fw_version = '' + fw_name = '' + fw_device = '' + + for filename in listdir(fw_path): + fw_info = filename.split("-") + fw_device = fw_info[0] + if fw_device == device_name: + fw_version = fw_info[1] + fw_name = filename + break + + if not fw_version: + Logger.info("Client(%s): No fw found!", device_name) + msg = '{"type": "ota", "value":"ok"}' + await self.websocket.send(msg) + return + + if not version_checker(device_name, device_version, fw_version): + return + + fw_file = join_pth(fw_path, fw_name) + if device_chip == 'esp8266' and not fw_file.endswith('.gz'): + # We can compress fw to make it smaller for upload + fw_cpress = fw_file + fw_file = fw_cpress + ".gz" + cpress = f"gzip -9 {fw_cpress}" + cstate = shell(cpress) + if cstate: + Logger.error("Cannot compress firmware: %s", fw_name) + return + + # Get size of fw + size = Path(fw_file).stat().st_size + + # Request ota mode + msg = '{"type": "ota", "value":"go", "size":' + str(size) + '}' + await self.websocket.send(msg) + + # send file by chunks trough websocket + await binary_send(self.websocket, fw_file) + + +async def _register(websocket, message): + mac = message.get('mac') + name = message.get('name') + Logger.info("Client(%s) mac: %s", name, mac) + # Some code + + response = {'response_type': 'registry', 'state': 'ok'} + await websocket.send(json.dumps(response)) + + +async def _state(websocket, message): + mac = message.get('mac') + name = message.get('name') + Logger.info("Client(%s) mac: %s", name, mac) + # Some code + + response = {'response_type': 'state', 'state': 'ok'} + await websocket.send(json.dumps(response)) + + +async def _unhandleld(websocket, msg): + Logger.info("Unhandled message from device: %s", str(msg)) + response = {'response_type': 'response', 'state': 'nok'} + await websocket.send(json.dumps(response)) + + +async def _greetings(websocket, message): + WsOtaHandler('thread_ota', copy.deepcopy(message), websocket).start() + + +async def message_received(websocket, message) -> None: + """Handle incoming messages + + Check if message contain json and run waned function + """ + switcher = {"greetings": _greetings, + "register": _register, + "state": _state + } + + if message[0:1] == "{": + try: + msg_json = json.loads(message) + except Exception as exception: + Logger.error(exception) + return + + type_ = msg_json.get('type') + name = msg_json.get('name') + func = switcher.get(type_, _unhandleld) + Logger.debug("Client(%s)said: %s", name, type_) + + try: + await func(websocket, msg_json) + except Exception as exception: + Logger.error(exception) + + +# pylint: disable=W0613 +async def ws_server(websocket, path) -> None: + """Run in cycle and wait for new messages""" + async for message in websocket: + await message_received(websocket, message) + + +async def main(): + """Server starter + + Normal user can bind only port nubers greater than 1024 + """ + async with websockets.serve(ws_server, "10.0.1.5", 8081): + await asyncio.Future() # run forever + + +create_path(fw_path) +asyncio.run(main()) diff --git a/examples/esp8266/WebSocketClientOTA/python_ota_server/requirements.txt b/examples/esp8266/WebSocketClientOTA/python_ota_server/requirements.txt new file mode 100644 index 0000000..4fc2553 --- /dev/null +++ b/examples/esp8266/WebSocketClientOTA/python_ota_server/requirements.txt @@ -0,0 +1,2 @@ +packaging +websockets \ No newline at end of file From 61ea44942e5f987dbe229d07efd047b566c4a48b Mon Sep 17 00:00:00 2001 From: Khoi Hoang <57012152+khoih-prog@users.noreply.github.com> Date: Thu, 17 Feb 2022 14:46:24 -0500 Subject: [PATCH 286/347] Suppress `esp32/sha.h` warning --- src/WebSockets.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index ef8224c..13e1b32 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -42,9 +42,13 @@ extern "C" { #include #if ESP_IDF_VERSION_MAJOR >= 4 -#include + #if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(1, 0, 6) ) + #include "sha/sha_parallel_engine.h" + #else + #include + #endif #else -#include + #include #endif #else From 8d76469e901e2f0868637f7a79d9dbcf8d4ca855 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 5 Apr 2022 19:03:19 +0200 Subject: [PATCH 287/347] update to Arduino IDE 1.8.19 for testing and dropped testing with 1.6.13 --- .github/workflows/main.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6fb322d..249ef1a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,16 +36,13 @@ jobs: echo -en "::set-output name=matrix::" echo -en "[" - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.6.13 esp8266com:esp8266:generic:xtal=80 + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,dbg=Serial1 echo -en "," - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.6.13 esp8266com:esp8266:generic:xtal=80,dbg=Serial1 + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80 echo -en "," - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.15 esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80 - echo -en "," - - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.15 espressif:esp32:esp32:FlashFreq=80 + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.19 espressif:esp32:esp32:FlashFreq=80 echo -en "]" outputs: @@ -56,7 +53,7 @@ jobs: strategy: fail-fast: false matrix: - IDE_VERSION: [1.8.15, 1.6.13] + IDE_VERSION: [1.8.19] env: IDE_VERSION: ${{ matrix.IDE_VERSION }} @@ -99,7 +96,7 @@ jobs: get_core esp8266 - name: download esp32 - if: steps.cache_all.outputs.cache-hit != 'true' && matrix.IDE_VERSION != '1.6.13' + if: steps.cache_all.outputs.cache-hit != 'true' run: | source $GITHUB_WORKSPACE/travis/common.sh get_core esp32 From ab9af162b2b50fd75438c6b39cebc3da4fd58623 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 5 Apr 2022 19:10:57 +0200 Subject: [PATCH 288/347] fix code style --- src/WebSockets.cpp | 22 ++++++++-------- src/WebSockets.h | 2 +- src/WebSocketsClient.h | 10 ++++---- src/WebSocketsServer.cpp | 8 +++--- src/WebSocketsServer.h | 54 ++++++++++++++++++++-------------------- 5 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 13e1b32..49f5480 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -42,13 +42,13 @@ extern "C" { #include #if ESP_IDF_VERSION_MAJOR >= 4 - #if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(1, 0, 6) ) - #include "sha/sha_parallel_engine.h" - #else - #include - #endif +#if(ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(1, 0, 6)) +#include "sha/sha_parallel_engine.h" #else - #include +#include +#endif +#else +#include #endif #else @@ -472,7 +472,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t payload[header->payloadLen] = 0x00; if(header->mask) { - //decode XOR + // decode XOR for(size_t i = 0; i < header->payloadLen; i++) { payload[i] = (payload[i] ^ header->maskKey[i % 4]); } @@ -526,7 +526,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t // reset input client->cWsRXsize = 0; #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) - //register callback for next message + // register callback for next message handleWebsocketWaitFor(client, 2); #endif @@ -644,9 +644,9 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait t = millis(); out += len; n -= len; - //DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n); + // DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n); } else { - //DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n); + // DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n); } if(n > 0) { WEBSOCKETS_YIELD(); @@ -698,7 +698,7 @@ size_t WebSockets::write(WSclient_t * client, uint8_t * out, size_t n) { out += len; n -= len; total += len; - //DEBUG_WEBSOCKETS("write %d left %d!\n", len, n); + // DEBUG_WEBSOCKETS("write %d left %d!\n", len, n); } else { DEBUG_WEBSOCKETS("WS write %d failed left %d!\n", len, n); } diff --git a/src/WebSockets.h b/src/WebSockets.h index b182bd5..60c13d9 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -86,7 +86,7 @@ #define WEBSOCKETS_YIELD_MORE() #else -//atmega328p has only 2KB ram! +// atmega328p has only 2KB ram! #define WEBSOCKETS_MAX_DATA_SIZE (1024) // moves all Header strings to Flash #define WEBSOCKETS_SAVE_RAM diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index efa7631..6cc98d4 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -154,11 +154,11 @@ class WebSocketsClient : protected WebSockets { #endif /** - * called for sending a Event to the app - * @param type WStype_t - * @param payload uint8_t * - * @param length size_t - */ + * called for sending a Event to the app + * @param type WStype_t + * @param payload uint8_t * + * @param length size_t + */ virtual void runCbEvent(WStype_t type, uint8_t * payload, size_t length) { if(_cbEvent) { _cbEvent(type, payload, length); diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 81734ba..c206363 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -621,8 +621,8 @@ WSclient_t * WebSocketsServerCore::handleNewClient(WEBSOCKETS_NETWORK_CLASS * tc #endif // no client! => create dummy! WSclient_t dummy = WSclient_t(); - client = & dummy; - client->tcp = tcpClient; + client = &dummy; + client->tcp = tcpClient; dropNativeClient(client); } @@ -663,7 +663,7 @@ void WebSocketsServerCore::handleClientData(void) { if(clientIsConnected(client)) { int len = client->tcp->available(); if(len > 0) { - //DEBUG_WEBSOCKETS("[WS-Server][%d][handleClientData] len: %d\n", client->num, len); + // DEBUG_WEBSOCKETS("[WS-Server][%d][handleClientData] len: %d\n", client->num, len); switch(client->status) { case WSC_HEADER: { String headerLine = client->tcp->readStringUntil('\n'); @@ -717,7 +717,7 @@ void WebSocketsServerCore::handleHeader(WSclient_t * client, String * headerLine // cut URL out client->cUrl = headerLine->substring(4, headerLine->indexOf(' ', 4)); - //reset non-websocket http header validation state for this client + // reset non-websocket http header validation state for this client client->cHttpHeadersValid = true; client->cMandatoryHeadersCount = 0; diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 5bdcd04..543cba9 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -132,10 +132,10 @@ class WebSocketsServerCore : protected WebSockets { void handleHBPing(WSclient_t * client); // send ping in specified intervals /** - * called if a non Websocket connection is coming in. - * Note: can be override - * @param client WSclient_t * ptr to the client struct - */ + * called if a non Websocket connection is coming in. + * Note: can be override + * @param client WSclient_t * ptr to the client struct + */ virtual void handleNonWebsocketConnection(WSclient_t * client) { DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] no Websocket connection close.\n", client->num); client->tcp->write( @@ -151,10 +151,10 @@ class WebSocketsServerCore : protected WebSockets { } /** - * called if a non Authorization connection is coming in. - * Note: can be override - * @param client WSclient_t * ptr to the client struct - */ + * called if a non Authorization connection is coming in. + * Note: can be override + * @param client WSclient_t * ptr to the client struct + */ virtual void handleAuthorizationFailed(WSclient_t * client) { client->tcp->write( "HTTP/1.1 401 Unauthorized\r\n" @@ -170,12 +170,12 @@ class WebSocketsServerCore : protected WebSockets { } /** - * called for sending a Event to the app - * @param num uint8_t - * @param type WStype_t - * @param payload uint8_t * - * @param length size_t - */ + * called for sending a Event to the app + * @param num uint8_t + * @param type WStype_t + * @param payload uint8_t * + * @param length size_t + */ virtual void runCbEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { if(_cbEvent) { _cbEvent(num, type, payload, length); @@ -183,19 +183,19 @@ class WebSocketsServerCore : protected WebSockets { } /* - * Called at client socket connect handshake negotiation time for each http header that is not - * a websocket specific http header (not Connection, Upgrade, Sec-WebSocket-*) - * If the custom httpHeaderValidationFunc returns false for any headerName / headerValue passed, the - * socket negotiation is considered invalid and the upgrade to websockets request is denied / rejected - * This mechanism can be used to enable custom authentication schemes e.g. test the value - * of a session cookie to determine if a user is logged on / authenticated - */ + * Called at client socket connect handshake negotiation time for each http header that is not + * a websocket specific http header (not Connection, Upgrade, Sec-WebSocket-*) + * If the custom httpHeaderValidationFunc returns false for any headerName / headerValue passed, the + * socket negotiation is considered invalid and the upgrade to websockets request is denied / rejected + * This mechanism can be used to enable custom authentication schemes e.g. test the value + * of a session cookie to determine if a user is logged on / authenticated + */ virtual bool execHttpHeaderValidation(String headerName, String headerValue) { if(_httpHeaderValidationFunc) { - //return the value of the custom http header validation function + // return the value of the custom http header validation function return _httpHeaderValidationFunc(headerName, headerValue); } - //no custom http header validation so just assume all is good + // no custom http header validation so just assume all is good return true; } @@ -205,14 +205,14 @@ class WebSocketsServerCore : protected WebSockets { /** * drop native tcp connection (client->tcp) - */ + */ void dropNativeClient(WSclient_t * client); private: /* - * returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection - * @param headerName String ///< the name of the header being checked - */ + * returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection + * @param headerName String ///< the name of the header being checked + */ bool hasMandatoryHeader(String headerName); }; From 28c0cf3094e202ebc5ded47cda307a418dea9055 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 5 Apr 2022 19:11:11 +0200 Subject: [PATCH 289/347] fix #728 dropNativeClient null ptr --- src/WebSocketsClient.cpp | 6 +++--- src/WebSocketsServer.cpp | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 562a661..2be6f32 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -786,9 +786,9 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { } // falls through case 403: ///< Forbidden - // todo handle login - // falls through - default: ///< Server dont unterstand requrst + // todo handle login + // falls through + default: ///< Server dont unterstand requrst ok = false; DEBUG_WEBSOCKETS("[WS-Client][handleHeader] serverCode is not 101 (%d)\n", client->cCode); clientDisconnect(client); diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index c206363..c2f533b 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -516,6 +516,9 @@ void WebSocketsServerCore::messageReceived(WSclient_t * client, WSopcode_t opcod * @param client WSclient_t * ptr to the client struct contaning the native client "->tcp" */ void WebSocketsServerCore::dropNativeClient(WSclient_t * client) { + if(!client) { + return; + } if(client->tcp) { if(client->tcp->connected()) { #if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) && (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP32) From 52b3aa8ea4833e414426deb6940be2fc5d8438dd Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 5 Apr 2022 19:40:57 +0200 Subject: [PATCH 290/347] enable debug for CI --- .github/workflows/main.yml | 1 + travis/common.sh | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 249ef1a..d7bea65 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -170,6 +170,7 @@ jobs: - name: build example timeout-minutes: 20 run: | + set -ex export DISPLAY=:1.0 export PATH="$HOME/arduino_ide:$PATH" source $GITHUB_WORKSPACE/travis/common.sh diff --git a/travis/common.sh b/travis/common.sh index 81d60e9..c1c2328 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -ex + function build_sketches() { local arduino=$1 From 5881a99a300672a7f6de61de76ba68f10a69ae96 Mon Sep 17 00:00:00 2001 From: Links Date: Tue, 5 Apr 2022 20:07:59 +0200 Subject: [PATCH 291/347] bump version to 2.3.7 --- library.json | 2 +- library.properties | 2 +- src/WebSocketsVersion.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library.json b/library.json index 2f7aec6..8675831 100644 --- a/library.json +++ b/library.json @@ -21,5 +21,5 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.3.6" + "version": "2.3.7" } \ No newline at end of file diff --git a/library.properties b/library.properties index b9899d0..aab19e8 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.3.6 +version=2.3.7 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index e0ab39c..bf2526c 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -1,6 +1,6 @@ /** * @file WebSocketsVersion.h - * @date 08.03.2021 + * @date 05.04.2022 * @author Markus Sattler * * Copyright (c) 2015 Markus Sattler. All rights reserved. @@ -25,12 +25,12 @@ #ifndef WEBSOCKETSVERSION_H_ #define WEBSOCKETSVERSION_H_ -#define WEBSOCKETS_VERSION "2.3.6" +#define WEBSOCKETS_VERSION "2.3.7" #define WEBSOCKETS_VERSION_MAJOR 2 #define WEBSOCKETS_VERSION_MINOR 3 -#define WEBSOCKETS_VERSION_PATCH 6 +#define WEBSOCKETS_VERSION_PATCH 7 -#define WEBSOCKETS_VERSION_INT 2003006 +#define WEBSOCKETS_VERSION_INT 2003007 #endif /* WEBSOCKETSVERSION_H_ */ From 3073c156b12d15849d0f651554cade465c401103 Mon Sep 17 00:00:00 2001 From: sivar2311 Date: Mon, 16 May 2022 15:05:37 +0200 Subject: [PATCH 292/347] Fix compiler warning "function may return address of local variable" --- src/WebSocketsServer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index c2f533b..af95023 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -627,6 +627,7 @@ WSclient_t * WebSocketsServerCore::handleNewClient(WEBSOCKETS_NETWORK_CLASS * tc client = &dummy; client->tcp = tcpClient; dropNativeClient(client); + return nullptr; } WEBSOCKETS_YIELD(); From 1fb67c88688cea79cc9d344ec27ca7bc02b9d74a Mon Sep 17 00:00:00 2001 From: Links Date: Fri, 24 Jun 2022 10:23:50 +0200 Subject: [PATCH 293/347] esp8266 build, change config options --- .github/workflows/main.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d7bea65..de0561b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,10 +36,10 @@ jobs: echo -en "::set-output name=matrix::" echo -en "[" - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,dbg=Serial1 + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 echo -en "," - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80 + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 echo -en "," get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.19 espressif:esp32:esp32:FlashFreq=80 @@ -161,11 +161,12 @@ jobs: - name: config IDE run: | + set +x export DISPLAY=:1.0 export PATH="$HOME/arduino_ide:$PATH" arduino --board $BOARD --save-prefs arduino --get-pref sketchbook.path - arduino --pref update.check=false + - name: build example timeout-minutes: 20 From 04249a9b62fc03773f08b8c51d52bb2748dc7ef1 Mon Sep 17 00:00:00 2001 From: Links Date: Fri, 24 Jun 2022 10:35:37 +0200 Subject: [PATCH 294/347] more debug --- .github/workflows/main.yml | 2 +- travis/common.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index de0561b..22c523b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -166,7 +166,7 @@ jobs: export PATH="$HOME/arduino_ide:$PATH" arduino --board $BOARD --save-prefs arduino --get-pref sketchbook.path - + arduino --get-pref - name: build example timeout-minutes: 20 diff --git a/travis/common.sh b/travis/common.sh index c1c2328..135021d 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -31,6 +31,7 @@ function build_sketches() function build_sketch() { + set -e +x local arduino=$1 local sketch=$2 $arduino --verify $sketch; From 2110ad0a10e1620646448b06effbe2946b5f2269 Mon Sep 17 00:00:00 2001 From: Links Date: Fri, 24 Jun 2022 10:48:51 +0200 Subject: [PATCH 295/347] more debug --- .github/workflows/main.yml | 1 + travis/common.sh | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 22c523b..810563e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -165,6 +165,7 @@ jobs: export DISPLAY=:1.0 export PATH="$HOME/arduino_ide:$PATH" arduino --board $BOARD --save-prefs + arduino --pref update.check=false --pref build.verbose=false --pref cache.enable=true --pref compiler.cache_core=true --pref compiler.warning_level=default --save-prefs arduino --get-pref sketchbook.path arduino --get-pref diff --git a/travis/common.sh b/travis/common.sh index 135021d..2754bdc 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -1,6 +1,6 @@ #!/bin/bash -set -ex +set -x function build_sketches() { @@ -31,10 +31,9 @@ function build_sketches() function build_sketch() { - set -e +x local arduino=$1 local sketch=$2 - $arduino --verify $sketch; + $arduino --verify --verbose $sketch; local result=$? if [ $result -ne 0 ]; then echo "Build failed ($sketch) build verbose..." From dd8675c6a920301c0311af591a5bf4122b006b66 Mon Sep 17 00:00:00 2001 From: skwad77 <64254158+skwad77@users.noreply.github.com> Date: Wed, 27 Apr 2022 17:15:49 +0200 Subject: [PATCH 296/347] don't update cSessionId on unwanted Set-Cookie --- src/WebSocketsClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 2be6f32..4ff62f0 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -733,7 +733,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) { client->cExtensions = headerValue; } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Sec-WebSocket-Version"))) { client->cVersion = headerValue.toInt(); - } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Set-Cookie"))) { + } else if(headerName.equalsIgnoreCase(WEBSOCKETS_STRING("Set-Cookie")) && headerValue.indexOf(" io=") > -1) { if(headerValue.indexOf(';') > -1) { client->cSessionId = headerValue.substring(headerValue.indexOf('=') + 1, headerValue.indexOf(";")); } else { From 2b0e8f6fe9f9bcfcda3d0ce26a6a9e9906e7e33a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=C3=ADn=20Skala?= Date: Mon, 22 Aug 2022 12:22:49 +0200 Subject: [PATCH 297/347] Fix async run --- examples/esp8266/WebSocketClientOTA/python_ota_server/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py b/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py index 7e7fba1..174e2d3 100644 --- a/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py +++ b/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py @@ -90,7 +90,7 @@ def __init__(self, name, message, websocket): def run(self, ): try: - asyncio.run(self.start_) + asyncio.run(self.start_()) except Exception as exception: Logger.exception(exception) finally: From ccdba4ed8a12afa94d237143da82cf6a82345fd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=C3=ADn=20Skala?= Date: Mon, 22 Aug 2022 12:28:53 +0200 Subject: [PATCH 298/347] Fix response type prefix (LoadProhibitedCause) --- examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino | 6 +++++- .../esp8266/WebSocketClientOTA/python_ota_server/main.py | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino b/examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino index 2c87c25..6a809c0 100644 --- a/examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino +++ b/examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino @@ -117,6 +117,10 @@ void STATE(JsonDocument &msg){ // Do something with message } +// Count of responses handled by RESPONSES_STRUCT +// increase increase if another response handler is added +int nrOfResponses = 2; + RESPONSES_STRUCT responses[] = { {"ota", OTA}, {"state", STATE}, @@ -145,7 +149,7 @@ void text(uint8_t * payload, size_t length){ // Handle each TYPE of message int b = 0; - for( b=0 ; strlen(responses[b].type) ; b++ ) + for( b=0 ; b Date: Mon, 22 Aug 2022 12:33:59 +0200 Subject: [PATCH 299/347] Use async sleep, increase chunk size --- examples/esp8266/WebSocketClientOTA/python_ota_server/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py b/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py index 1c1c5b6..5d2750c 100644 --- a/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py +++ b/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py @@ -55,7 +55,7 @@ async def binary_send(websocket, fw_file): with open(fw_file, "rb") as binaryfile: while True: - chunk = binaryfile.read(2048) + chunk = binaryfile.read(4096) if not chunk: break try: @@ -63,7 +63,7 @@ async def binary_send(websocket, fw_file): except Exception as exception: Logger.exception(exception) return False - time.sleep(0.2) + asyncio.sleep(0.2) def version_checker(name, vdev, vapp): From f1ffaede0b80486652a397c82566146300c44ef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=C3=ADn=20Skala?= Date: Mon, 22 Aug 2022 12:50:37 +0200 Subject: [PATCH 300/347] Fix Typo --- .../esp8266/WebSocketClientOTA/WebSocketClientOTA.ino | 2 +- .../esp8266/WebSocketClientOTA/python_ota_server/main.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino b/examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino index 6a809c0..6b902d8 100644 --- a/examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino +++ b/examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino @@ -127,7 +127,7 @@ RESPONSES_STRUCT responses[] = { }; void text(uint8_t * payload, size_t length){ - // Convert mesage to something usable + // Convert message to something usable char msgch[length]; for (unsigned int i = 0; i < length; i++) { diff --git a/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py b/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py index 5d2750c..92acc95 100644 --- a/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py +++ b/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py @@ -79,7 +79,7 @@ def version_checker(name, vdev, vapp): class WsOtaHandler (threading.Thread): """Thread handling ota update - Runing ota directly from message would kill WS + Running ota directly from message would kill WS as message bus would timeout. """ def __init__(self, name, message, websocket): @@ -177,7 +177,7 @@ async def _state(websocket, message): await websocket.send(json.dumps(response)) -async def _unhandleld(websocket, msg): +async def _unhandled(websocket, msg): Logger.info("Unhandled message from device: %s", str(msg)) response = {'type': 'response', 'state': 'nok'} await websocket.send(json.dumps(response)) @@ -206,7 +206,7 @@ async def message_received(websocket, message) -> None: type_ = msg_json.get('type') name = msg_json.get('name') - func = switcher.get(type_, _unhandleld) + func = switcher.get(type_, _unhandled) Logger.debug("Client(%s)said: %s", name, type_) try: @@ -225,7 +225,7 @@ async def ws_server(websocket, path) -> None: async def main(): """Server starter - Normal user can bind only port nubers greater than 1024 + Normal user can bind only port numbers greater than 1024 """ async with websockets.serve(ws_server, "10.0.1.5", 8081): await asyncio.Future() # run forever From 323592f622e0ec8f9ce1f995c5777d9bbaaae1ec Mon Sep 17 00:00:00 2001 From: jakubdybczak Date: Sun, 14 Aug 2022 18:03:16 +0200 Subject: [PATCH 301/347] Add possibility to change WEBSOCKETS_TCP_TIMEOUT --- src/WebSockets.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/WebSockets.h b/src/WebSockets.h index 60c13d9..3ee3f3a 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -94,7 +94,9 @@ #define WEBSOCKETS_YIELD_MORE() #endif +#ifndef WEBSOCKETS_TCP_TIMEOUT #define WEBSOCKETS_TCP_TIMEOUT (5000) +#endif #define NETWORK_ESP8266_ASYNC (0) #define NETWORK_ESP8266 (1) From d9a5c629f053fb234877aafd9b61986c25de7825 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Thu, 12 Jan 2023 09:53:42 -0800 Subject: [PATCH 302/347] Port to Raspberry Pi Pico W core Add support for the onboard WiFi chip on the Raspberry Pi Pico W (RP2040 based ) board using the arduino-pico Arduino core at https://github.com/earlephilhower/arduino-pico The PicoW WiFi stack is a mashup of the ESP8266 and ESP32 cores, so only minimal changes were required. Defines a new NETWORK_TYPE for the PicoW. ESP8266 examples renames to ESP8266_PICO because they all work unmodified (except for OTA which is handled differently on the Pico) --- README.md | 1 + .../WebSocketClient/WebSocketClient.ino | 0 .../WebSocketClientOTA/README.md | 0 .../WebSocketClientOTA/WebSocketClientOTA.ino | 11 +++++---- .../python_ota_server/main.py | 0 .../python_ota_server/requirements.txt | 0 .../WebSocketClientSSL/WebSocketClientSSL.ino | 0 .../WebSocketClientSSLWithCA.ino | 0 .../WebSocketClientSocketIO.ino | 0 .../WebSocketClientSocketIOack.ino | 0 .../WebSocketClientStomp.ino | 0 .../WebSocketClientStompOverSockJs.ino | 0 .../WebSocketServer/WebSocketServer.ino | 0 .../WebSocketServerAllFunctionsDemo.ino | 0 .../WebSocketServerFragmentation.ino | 0 .../WebSocketServerHooked.ino | 0 .../WebSocketServerHooked/emu | 0 .../WebSocketServerHooked/ws-testclient.py | 0 .../WebSocketServerHttpHeaderValidation.ino | 0 .../WebSocketServer_LEDcontrol.ino | 0 src/WebSockets.cpp | 2 +- src/WebSockets.h | 23 +++++++++++++++++++ src/WebSockets4WebServer.h | 17 ++++++++++---- src/WebSocketsClient.cpp | 8 ++++--- src/WebSocketsServer.cpp | 18 ++++++++------- src/WebSocketsServer.h | 2 +- src/libb64/cdecode.c | 2 +- src/libb64/cencode.c | 2 +- 28 files changed, 61 insertions(+), 25 deletions(-) rename examples/{esp8266 => esp8266_pico}/WebSocketClient/WebSocketClient.ino (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketClientOTA/README.md (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketClientOTA/WebSocketClientOTA.ino (98%) rename examples/{esp8266 => esp8266_pico}/WebSocketClientOTA/python_ota_server/main.py (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketClientOTA/python_ota_server/requirements.txt (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketClientSSL/WebSocketClientSSL.ino (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketClientSocketIO/WebSocketClientSocketIO.ino (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketClientStomp/WebSocketClientStomp.ino (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketClientStompOverSockJs/WebSocketClientStompOverSockJs.ino (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketServer/WebSocketServer.ino (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketServerAllFunctionsDemo/WebSocketServerAllFunctionsDemo.ino (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketServerFragmentation/WebSocketServerFragmentation.ino (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketServerHooked/WebSocketServerHooked.ino (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketServerHooked/emu (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketServerHooked/ws-testclient.py (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketServerHttpHeaderValidation/WebSocketServerHttpHeaderValidation.ino (100%) rename examples/{esp8266 => esp8266_pico}/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino (100%) diff --git a/README.md b/README.md index 26d124c..83faaab 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ a WebSocket Server and Client for Arduino based on RFC6455. - ESP8266 [Arduino for ESP8266](https://github.com/esp8266/Arduino/) - ESP32 [Arduino for ESP32](https://github.com/espressif/arduino-esp32) - ESP31B + - Raspberry Pi Pico W [Arduino for Pico](https://github.com/earlephilhower/arduino-pico) - Particle with STM32 ARM Cortex M3 - ATmega328 with Ethernet Shield (ATmega branch) - ATmega328 with enc28j60 (ATmega branch) diff --git a/examples/esp8266/WebSocketClient/WebSocketClient.ino b/examples/esp8266_pico/WebSocketClient/WebSocketClient.ino similarity index 100% rename from examples/esp8266/WebSocketClient/WebSocketClient.ino rename to examples/esp8266_pico/WebSocketClient/WebSocketClient.ino diff --git a/examples/esp8266/WebSocketClientOTA/README.md b/examples/esp8266_pico/WebSocketClientOTA/README.md similarity index 100% rename from examples/esp8266/WebSocketClientOTA/README.md rename to examples/esp8266_pico/WebSocketClientOTA/README.md diff --git a/examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino b/examples/esp8266_pico/WebSocketClientOTA/WebSocketClientOTA.ino similarity index 98% rename from examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino rename to examples/esp8266_pico/WebSocketClientOTA/WebSocketClientOTA.ino index 6b902d8..88e14c4 100644 --- a/examples/esp8266/WebSocketClientOTA/WebSocketClientOTA.ino +++ b/examples/esp8266_pico/WebSocketClientOTA/WebSocketClientOTA.ino @@ -8,15 +8,16 @@ #include #include -#ifdef ESP8266 +#if defined(ESP8266) #include #include - #include -#endif -#ifdef ESP32 + #include +#elif defined(ESP32) #include "WiFi.h" #include "ESPmDNS.h" - #include + #include +#else + #error Unsupported device #endif #include diff --git a/examples/esp8266/WebSocketClientOTA/python_ota_server/main.py b/examples/esp8266_pico/WebSocketClientOTA/python_ota_server/main.py similarity index 100% rename from examples/esp8266/WebSocketClientOTA/python_ota_server/main.py rename to examples/esp8266_pico/WebSocketClientOTA/python_ota_server/main.py diff --git a/examples/esp8266/WebSocketClientOTA/python_ota_server/requirements.txt b/examples/esp8266_pico/WebSocketClientOTA/python_ota_server/requirements.txt similarity index 100% rename from examples/esp8266/WebSocketClientOTA/python_ota_server/requirements.txt rename to examples/esp8266_pico/WebSocketClientOTA/python_ota_server/requirements.txt diff --git a/examples/esp8266/WebSocketClientSSL/WebSocketClientSSL.ino b/examples/esp8266_pico/WebSocketClientSSL/WebSocketClientSSL.ino similarity index 100% rename from examples/esp8266/WebSocketClientSSL/WebSocketClientSSL.ino rename to examples/esp8266_pico/WebSocketClientSSL/WebSocketClientSSL.ino diff --git a/examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino b/examples/esp8266_pico/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino similarity index 100% rename from examples/esp8266/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino rename to examples/esp8266_pico/WebSocketClientSSLWithCA/WebSocketClientSSLWithCA.ino diff --git a/examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino b/examples/esp8266_pico/WebSocketClientSocketIO/WebSocketClientSocketIO.ino similarity index 100% rename from examples/esp8266/WebSocketClientSocketIO/WebSocketClientSocketIO.ino rename to examples/esp8266_pico/WebSocketClientSocketIO/WebSocketClientSocketIO.ino diff --git a/examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino b/examples/esp8266_pico/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino similarity index 100% rename from examples/esp8266/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino rename to examples/esp8266_pico/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino diff --git a/examples/esp8266/WebSocketClientStomp/WebSocketClientStomp.ino b/examples/esp8266_pico/WebSocketClientStomp/WebSocketClientStomp.ino similarity index 100% rename from examples/esp8266/WebSocketClientStomp/WebSocketClientStomp.ino rename to examples/esp8266_pico/WebSocketClientStomp/WebSocketClientStomp.ino diff --git a/examples/esp8266/WebSocketClientStompOverSockJs/WebSocketClientStompOverSockJs.ino b/examples/esp8266_pico/WebSocketClientStompOverSockJs/WebSocketClientStompOverSockJs.ino similarity index 100% rename from examples/esp8266/WebSocketClientStompOverSockJs/WebSocketClientStompOverSockJs.ino rename to examples/esp8266_pico/WebSocketClientStompOverSockJs/WebSocketClientStompOverSockJs.ino diff --git a/examples/esp8266/WebSocketServer/WebSocketServer.ino b/examples/esp8266_pico/WebSocketServer/WebSocketServer.ino similarity index 100% rename from examples/esp8266/WebSocketServer/WebSocketServer.ino rename to examples/esp8266_pico/WebSocketServer/WebSocketServer.ino diff --git a/examples/esp8266/WebSocketServerAllFunctionsDemo/WebSocketServerAllFunctionsDemo.ino b/examples/esp8266_pico/WebSocketServerAllFunctionsDemo/WebSocketServerAllFunctionsDemo.ino similarity index 100% rename from examples/esp8266/WebSocketServerAllFunctionsDemo/WebSocketServerAllFunctionsDemo.ino rename to examples/esp8266_pico/WebSocketServerAllFunctionsDemo/WebSocketServerAllFunctionsDemo.ino diff --git a/examples/esp8266/WebSocketServerFragmentation/WebSocketServerFragmentation.ino b/examples/esp8266_pico/WebSocketServerFragmentation/WebSocketServerFragmentation.ino similarity index 100% rename from examples/esp8266/WebSocketServerFragmentation/WebSocketServerFragmentation.ino rename to examples/esp8266_pico/WebSocketServerFragmentation/WebSocketServerFragmentation.ino diff --git a/examples/esp8266/WebSocketServerHooked/WebSocketServerHooked.ino b/examples/esp8266_pico/WebSocketServerHooked/WebSocketServerHooked.ino similarity index 100% rename from examples/esp8266/WebSocketServerHooked/WebSocketServerHooked.ino rename to examples/esp8266_pico/WebSocketServerHooked/WebSocketServerHooked.ino diff --git a/examples/esp8266/WebSocketServerHooked/emu b/examples/esp8266_pico/WebSocketServerHooked/emu similarity index 100% rename from examples/esp8266/WebSocketServerHooked/emu rename to examples/esp8266_pico/WebSocketServerHooked/emu diff --git a/examples/esp8266/WebSocketServerHooked/ws-testclient.py b/examples/esp8266_pico/WebSocketServerHooked/ws-testclient.py similarity index 100% rename from examples/esp8266/WebSocketServerHooked/ws-testclient.py rename to examples/esp8266_pico/WebSocketServerHooked/ws-testclient.py diff --git a/examples/esp8266/WebSocketServerHttpHeaderValidation/WebSocketServerHttpHeaderValidation.ino b/examples/esp8266_pico/WebSocketServerHttpHeaderValidation/WebSocketServerHttpHeaderValidation.ino similarity index 100% rename from examples/esp8266/WebSocketServerHttpHeaderValidation/WebSocketServerHttpHeaderValidation.ino rename to examples/esp8266_pico/WebSocketServerHttpHeaderValidation/WebSocketServerHttpHeaderValidation.ino diff --git a/examples/esp8266/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino b/examples/esp8266_pico/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino similarity index 100% rename from examples/esp8266/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino rename to examples/esp8266_pico/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 49f5480..260129f 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -482,7 +482,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t switch(header->opCode) { case WSop_text: DEBUG_WEBSOCKETS("[WS][%d][handleWebsocket] text: %s\n", client->num, payload); - // no break here! + // fallthrough case WSop_binary: case WSop_continuation: messageReceived(client, header->opCode, payload, header->payloadLen, header->fin); diff --git a/src/WebSockets.h b/src/WebSockets.h index 3ee3f3a..f6b6f38 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -84,6 +84,15 @@ #define GET_FREE_HEAP System.freeMemory() #define WEBSOCKETS_YIELD() #define WEBSOCKETS_YIELD_MORE() + +#elif defined(ARDUINO_ARCH_RP2040) + +#define WEBSOCKETS_MAX_DATA_SIZE (15 * 1024) +#define WEBSOCKETS_USE_BIG_MEM +#define GET_FREE_HEAP rp2040.getFreeHeap() +#define WEBSOCKETS_YIELD() yield() +#define WEBSOCKETS_YIELD_MORE() delay(1) + #else // atmega328p has only 2KB ram! @@ -104,6 +113,7 @@ #define NETWORK_ENC28J60 (3) #define NETWORK_ESP32 (4) #define NETWORK_ESP32_ETH (5) +#define NETWORK_RP2040 (6) // max size of the WS Message Header #define WEBSOCKETS_MAX_HEADER_SIZE (14) @@ -118,6 +128,10 @@ #elif defined(ESP32) #define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP32 //#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP32_ETH + +#elif defined(ARDUINO_ARCH_RP2040) +#define WEBSOCKETS_NETWORK_TYPE NETWORK_RP2040 + #else #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 @@ -201,6 +215,15 @@ #define WEBSOCKETS_NETWORK_CLASS WiFiClient #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) + +#include +#include +#define SSL_BARESSL +#define WEBSOCKETS_NETWORK_CLASS WiFiClient +#define WEBSOCKETS_NETWORK_SSL_CLASS WiFiClientSecure +#define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer + #else #error "no network type selected!" #endif diff --git a/src/WebSockets4WebServer.h b/src/WebSockets4WebServer.h index ba2b020..81db221 100644 --- a/src/WebSockets4WebServer.h +++ b/src/WebSockets4WebServer.h @@ -28,23 +28,30 @@ #include #include -#if WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266 && WEBSERVER_HAS_HOOK + +#if ((WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040)) && WEBSERVER_HAS_HOOK class WebSockets4WebServer : public WebSocketsServerCore { +#if defined(ESP8266) + using WebServerClass = ESP8266WebServer; +#else + using WebServerClass = WebServer; +#endif + public: WebSockets4WebServer(const String & origin = "", const String & protocol = "arduino") : WebSocketsServerCore(origin, protocol) { begin(); } - ESP8266WebServer::HookFunction hookForWebserver(const String & wsRootDir, WebSocketServerEvent event) { + WebServerClass::HookFunction hookForWebserver(const String & wsRootDir, WebSocketServerEvent event) { onEvent(event); - return [&, wsRootDir](const String & method, const String & url, WiFiClient * tcpClient, ESP8266WebServer::ContentTypeFunction contentType) { + return [&, wsRootDir](const String & method, const String & url, WiFiClient * tcpClient, WebServerClass::ContentTypeFunction contentType) { (void)contentType; if(!(method == "GET" && url.indexOf(wsRootDir) == 0)) { - return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; + return WebServerClass::CLIENT_REQUEST_CAN_CONTINUE; } // allocate a WiFiClient copy (like in WebSocketsServer::handleNewClients()) @@ -63,7 +70,7 @@ class WebSockets4WebServer : public WebSocketsServerCore { } // tell webserver to not close but forget about this client - return ESP8266WebServer::CLIENT_IS_GIVEN; + return WebServerClass::CLIENT_IS_GIVEN; }; } }; diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 4ff62f0..505f1e0 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -76,6 +76,8 @@ void WebSocketsClient::begin(const char * host, uint16_t port, const char * url, #ifdef ESP8266 randomSeed(RANDOM_REG32); +#elif defined(ARDUINO_ARCH_RP2040) + randomSeed(rp2040.hwrand32()); #else // todo find better seed randomSeed(millis()); @@ -224,7 +226,7 @@ void WebSocketsClient::loop(void) { _client.ssl->setCACert(_CA_cert); #elif defined(ESP8266) && defined(SSL_AXTLS) _client.ssl->setCACert((const uint8_t *)_CA_cert, strlen(_CA_cert) + 1); -#elif defined(ESP8266) && defined(SSL_BARESSL) +#elif (defined(ESP8266) || defined(ARDUINO_ARCH_RP2040)) && defined(SSL_BARESSL) _client.ssl->setTrustAnchors(_CA_cert); #else #error setCACert not implemented @@ -473,7 +475,7 @@ void WebSocketsClient::messageReceived(WSclient_t * client, WSopcode_t opcode, u void WebSocketsClient::clientDisconnect(WSclient_t * client) { bool event = false; -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) if(client->isSSL && client->ssl) { if(client->ssl->connected()) { client->ssl->flush(); @@ -864,7 +866,7 @@ void WebSocketsClient::connectedCb() { _client.tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); #endif -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) _client.tcp->setNoDelay(true); #endif diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index af95023..ea93ecc 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -85,6 +85,8 @@ void WebSocketsServerCore::begin(void) { #elif defined(ESP32) #define DR_REG_RNG_BASE 0x3ff75144 randomSeed(READ_PERI_REG(DR_REG_RNG_BASE)); +#elif defined(ARDUINO_ARCH_RP2040) + randomSeed(rp2040.hwrand32()); #else // TODO find better seed randomSeed(millis()); @@ -394,7 +396,7 @@ bool WebSocketsServerCore::clientIsConnected(uint8_t num) { return clientIsConnected(client); } -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) /** * get an IP for a client * @param num uint8_t client id @@ -439,7 +441,7 @@ WSclient_t * WebSocketsServerCore::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclien client->tcp->setTimeout(WEBSOCKETS_TCP_TIMEOUT); #endif client->status = WSC_HEADER; -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) #ifndef NODEBUG_WEBSOCKETS IPAddress ip = client->tcp->remoteIP(); #endif @@ -521,7 +523,7 @@ void WebSocketsServerCore::dropNativeClient(WSclient_t * client) { } if(client->tcp) { if(client->tcp->connected()) { -#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) && (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) && (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP32) && (WEBSOCKETS_NETWORK_TYPE != NETWORK_RP2040) client->tcp->flush(); #endif client->tcp->stop(); @@ -540,7 +542,7 @@ void WebSocketsServerCore::dropNativeClient(WSclient_t * client) { * @param client WSclient_t * ptr to the client struct */ void WebSocketsServerCore::clientDisconnect(WSclient_t * client) { -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) if(client->isSSL && client->ssl) { if(client->ssl->connected()) { client->ssl->flush(); @@ -614,7 +616,7 @@ WSclient_t * WebSocketsServerCore::handleNewClient(WEBSOCKETS_NETWORK_CLASS * tc if(!client) { // no free space to handle client -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) #ifndef NODEBUG_WEBSOCKETS IPAddress ip = tcpClient->remoteIP(); #endif @@ -639,7 +641,7 @@ WSclient_t * WebSocketsServerCore::handleNewClient(WEBSOCKETS_NETWORK_CLASS * tc * Handle incoming Connection Request */ void WebSocketsServer::handleNewClients(void) { -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) while(_server->hasClient()) { #endif @@ -652,7 +654,7 @@ void WebSocketsServer::handleNewClients(void) { handleNewClient(tcpClient); -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) } #endif } @@ -923,7 +925,7 @@ void WebSocketsServer::begin(void) { void WebSocketsServer::close(void) { WebSocketsServerCore::close(); -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) _server->close(); #elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) _server->end(); diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 543cba9..197c37f 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -90,7 +90,7 @@ class WebSocketsServerCore : protected WebSockets { void enableHeartbeat(uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount); void disableHeartbeat(); -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) IPAddress remoteIP(uint8_t num); #endif diff --git a/src/libb64/cdecode.c b/src/libb64/cdecode.c index e135da2..615068a 100644 --- a/src/libb64/cdecode.c +++ b/src/libb64/cdecode.c @@ -9,7 +9,7 @@ For details, see http://sourceforge.net/projects/libb64 #include #endif -#if defined(ESP32) +#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) #define CORE_HAS_LIBB64 #endif diff --git a/src/libb64/cencode.c b/src/libb64/cencode.c index afe1463..cdc0f67 100644 --- a/src/libb64/cencode.c +++ b/src/libb64/cencode.c @@ -9,7 +9,7 @@ For details, see http://sourceforge.net/projects/libb64 #include #endif -#if defined(ESP32) +#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) #define CORE_HAS_LIBB64 #endif From 82c357c036e67b2a733128cbe54a1a2616c39f86 Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 1 May 2023 14:30:20 +0200 Subject: [PATCH 303/347] fix OTA example build and build tests for esp8266 examples --- .github/workflows/main.yml | 4 +-- .../WebSocketClientOTA/WebSocketClientOTA.ino | 34 ++++++++----------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 810563e..6d50afb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,10 +36,10 @@ jobs: echo -en "::set-output name=matrix::" echo -en "[" - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 echo -en "," - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 echo -en "," get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.19 espressif:esp32:esp32:FlashFreq=80 diff --git a/examples/esp8266_pico/WebSocketClientOTA/WebSocketClientOTA.ino b/examples/esp8266_pico/WebSocketClientOTA/WebSocketClientOTA.ino index 88e14c4..c0cbcfb 100644 --- a/examples/esp8266_pico/WebSocketClientOTA/WebSocketClientOTA.ino +++ b/examples/esp8266_pico/WebSocketClientOTA/WebSocketClientOTA.ino @@ -10,24 +10,27 @@ #if defined(ESP8266) #include + #include #include #include + #include + + ESP8266WiFiMulti WiFiMulti; #elif defined(ESP32) - #include "WiFi.h" + #include + #include #include "ESPmDNS.h" #include + + WiFiMulti WiFiMulti; #else #error Unsupported device #endif #include -#include - #include -#include -ESP8266WiFiMulti WiFiMulti; WebSocketsClient webSocket; #define USE_SERIAL Serial @@ -49,19 +52,12 @@ uint32_t maxSketchSpace = 0; int SketchSize = 0; bool ws_conn = false; -String IpAddress2String(const IPAddress& ipAddress) -{ - return String(ipAddress[0]) + String(".") + - String(ipAddress[1]) + String(".") + - String(ipAddress[2]) + String(".") + - String(ipAddress[3]); -} void greetings_(){ StaticJsonDocument<200> doc; doc["type"] = "greetings"; doc["mac"] = WiFi.macAddress(); - doc["ip"] = IpAddress2String(WiFi.localIP()); + doc["ip"] = WiFi.localIP().toString(); doc["version"] = version; doc["name"] = name; doc["chip"] = chip; @@ -89,7 +85,7 @@ typedef struct { CALLBACK_FUNCTION func; } RESPONSES_STRUCT; -void OTA(JsonDocument &msg){ +void OTA_RESPONSES(JsonDocument &msg){ USE_SERIAL.print(F("[WSc] OTA mode: ")); const char* go = "go"; const char* ok = "ok"; @@ -114,17 +110,17 @@ void OTA(JsonDocument &msg){ } } -void STATE(JsonDocument &msg){ +void STA_RESPONSES(JsonDocument &msg){ // Do something with message } // Count of responses handled by RESPONSES_STRUCT // increase increase if another response handler is added -int nrOfResponses = 2; +const int nrOfResponses = 2; -RESPONSES_STRUCT responses[] = { - {"ota", OTA}, - {"state", STATE}, +RESPONSES_STRUCT responses[nrOfResponses] = { + {"ota", OTA_RESPONSES}, + {"state", STA_RESPONSES}, }; void text(uint8_t * payload, size_t length){ From 4115a87c16bd65bc124eae57bcb9b1f1cb7c4b8b Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 1 May 2023 14:36:07 +0200 Subject: [PATCH 304/347] `set-output` command is deprecated --- .github/workflows/main.yml | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6d50afb..4a4a698 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -33,18 +33,20 @@ jobs: run: | source $GITHUB_WORKSPACE/travis/common.sh cd $GITHUB_WORKSPACE - echo -en "::set-output name=matrix::" - echo -en "[" - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 - echo -en "," + echo -en "matrix=" >> $GITHUB_STATE + echo -en "[" >> $GITHUB_STATE - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 - echo -en "," + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 >> $GITHUB_STATE + echo -en "," >> $GITHUB_STATE - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.19 espressif:esp32:esp32:FlashFreq=80 + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 >> $GITHUB_STATE + echo -en "," >> $GITHUB_STATE - echo -en "]" + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.19 espressif:esp32:esp32:FlashFreq=80 >> $GITHUB_STATE + + echo -en "]" >> $GITHUB_STATE + echo >> $GITHUB_STATE outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} @@ -63,7 +65,7 @@ jobs: - name: Get Date id: get-date run: | - echo "::set-output name=date::$(/bin/date -u "+%Y%m%d")" + echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_STATE shell: bash - uses: actions/cache@v2 @@ -125,7 +127,7 @@ jobs: - name: Get Date id: get-date run: | - echo "::set-output name=date::$(/bin/date -u "+%Y%m%d")" + echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_STATE shell: bash - uses: actions/cache@v2 From a4f13a1410ebcbd319ae4a5447c1fa3a1a08ff55 Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 1 May 2023 14:36:26 +0200 Subject: [PATCH 305/347] clang-format --- src/WebSockets.h | 10 +++++----- src/WebSockets4WebServer.h | 7 +++---- src/WebSocketsClient.cpp | 8 ++++---- src/WebSocketsServer.cpp | 6 +++--- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/WebSockets.h b/src/WebSockets.h index f6b6f38..db6c0e8 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -50,7 +50,7 @@ DEBUG_ESP_PORT.flush(); \ } #else -//#define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) +// #define DEBUG_WEBSOCKETS(...) os_printf( __VA_ARGS__ ) #endif #endif @@ -67,7 +67,7 @@ #define WEBSOCKETS_USE_BIG_MEM #define GET_FREE_HEAP ESP.getFreeHeap() // moves all Header strings to Flash (~300 Byte) -//#define WEBSOCKETS_SAVE_RAM +// #define WEBSOCKETS_SAVE_RAM #if defined(ESP8266) #define WEBSOCKETS_YIELD() delay(0) @@ -122,12 +122,12 @@ // select Network type based #if defined(ESP8266) || defined(ESP31B) #define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266 -//#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC -//#define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 +// #define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP8266_ASYNC +// #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 #elif defined(ESP32) #define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP32 -//#define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP32_ETH +// #define WEBSOCKETS_NETWORK_TYPE NETWORK_ESP32_ETH #elif defined(ARDUINO_ARCH_RP2040) #define WEBSOCKETS_NETWORK_TYPE NETWORK_RP2040 diff --git a/src/WebSockets4WebServer.h b/src/WebSockets4WebServer.h index 81db221..595f38b 100644 --- a/src/WebSockets4WebServer.h +++ b/src/WebSockets4WebServer.h @@ -28,14 +28,13 @@ #include #include - -#if ((WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040)) && WEBSERVER_HAS_HOOK +#if((WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040)) && WEBSERVER_HAS_HOOK class WebSockets4WebServer : public WebSocketsServerCore { #if defined(ESP8266) - using WebServerClass = ESP8266WebServer; + using WebServerClass = ESP8266WebServer; #else - using WebServerClass = WebServer; + using WebServerClass = WebServer; #endif public: diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 505f1e0..f1155e0 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -226,7 +226,7 @@ void WebSocketsClient::loop(void) { _client.ssl->setCACert(_CA_cert); #elif defined(ESP8266) && defined(SSL_AXTLS) _client.ssl->setCACert((const uint8_t *)_CA_cert, strlen(_CA_cert) + 1); -#elif (defined(ESP8266) || defined(ARDUINO_ARCH_RP2040)) && defined(SSL_BARESSL) +#elif(defined(ESP8266) || defined(ARDUINO_ARCH_RP2040)) && defined(SSL_BARESSL) _client.ssl->setTrustAnchors(_CA_cert); #else #error setCACert not implemented @@ -428,9 +428,9 @@ bool WebSocketsClient::isConnected(void) { return (_client.status == WSC_CONNECTED); } -//################################################################################# -//################################################################################# -//################################################################################# +// ################################################################################# +// ################################################################################# +// ################################################################################# /** * diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index ea93ecc..79a52ce 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -414,9 +414,9 @@ IPAddress WebSocketsServerCore::remoteIP(uint8_t num) { } #endif -//################################################################################# -//################################################################################# -//################################################################################# +// ################################################################################# +// ################################################################################# +// ################################################################################# /** * handle new client connection From 22dff6598f03f829ce99740054f08698029398c4 Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 1 May 2023 14:48:18 +0200 Subject: [PATCH 306/347] make OTA work with ArduinoJson 6.x --- .../WebSocketClientOTA/WebSocketClientOTA.ino | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/esp8266_pico/WebSocketClientOTA/WebSocketClientOTA.ino b/examples/esp8266_pico/WebSocketClientOTA/WebSocketClientOTA.ino index c0cbcfb..3a988a5 100644 --- a/examples/esp8266_pico/WebSocketClientOTA/WebSocketClientOTA.ino +++ b/examples/esp8266_pico/WebSocketClientOTA/WebSocketClientOTA.ino @@ -56,8 +56,8 @@ bool ws_conn = false; void greetings_(){ StaticJsonDocument<200> doc; doc["type"] = "greetings"; - doc["mac"] = WiFi.macAddress(); - doc["ip"] = WiFi.localIP().toString(); + doc["mac"] = WiFi.macAddress().c_str(); + doc["ip"] = WiFi.localIP().toString().c_str(); doc["version"] = version; doc["name"] = name; doc["chip"] = chip; @@ -70,7 +70,7 @@ void greetings_(){ void register_(){ StaticJsonDocument<200> doc; doc["type"] = "register"; - doc["mac"] = WiFi.macAddress(); + doc["mac"] = WiFi.macAddress().c_str(); char data[200]; serializeJson(doc, data); @@ -87,9 +87,8 @@ typedef struct { void OTA_RESPONSES(JsonDocument &msg){ USE_SERIAL.print(F("[WSc] OTA mode: ")); - const char* go = "go"; - const char* ok = "ok"; - if(strncmp( msg["value"], go, strlen(go)) == 0 ) { + String val = msg["value"]; + if(val == "go") { USE_SERIAL.print(F("go\n")); SketchSize = int(msg["size"]); maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; @@ -100,12 +99,12 @@ void OTA_RESPONSES(JsonDocument &msg){ Update.printError(Serial); ESP.restart(); } - } else if (strncmp( msg["value"], ok, strlen(ok)) == 0) { + } else if (val == "ok") { USE_SERIAL.print(F("OK\n")); register_(); } else { USE_SERIAL.print(F("unknown value : ")); - USE_SERIAL.print(msg["value"].as()); + USE_SERIAL.print(val); USE_SERIAL.print(F("\n")); } } @@ -146,9 +145,10 @@ void text(uint8_t * payload, size_t length){ // Handle each TYPE of message int b = 0; + String t = doc_in["type"]; for( b=0 ; b Date: Mon, 1 May 2023 14:51:36 +0200 Subject: [PATCH 307/347] add RP2040 as supported and bump version --- library.json | 4 ++-- library.properties | 2 +- src/WebSocketsVersion.h | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/library.json b/library.json index 8675831..d29c1a7 100644 --- a/library.json +++ b/library.json @@ -16,10 +16,10 @@ "keywords": "wifi, http, web, server, client, websocket", "license": "LGPL-2.1", "name": "WebSockets", - "platforms": "atmelavr, espressif8266, espressif32", + "platforms": "atmelavr, espressif8266, espressif32, raspberrypi", "repository": { "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.3.7" + "version": "2.4.0" } \ No newline at end of file diff --git a/library.properties b/library.properties index aab19e8..097048e 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.3.7 +version=2.4.0 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index bf2526c..e349bbf 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -1,6 +1,6 @@ /** * @file WebSocketsVersion.h - * @date 05.04.2022 + * @date 01.05.2023 * @author Markus Sattler * * Copyright (c) 2015 Markus Sattler. All rights reserved. @@ -25,12 +25,12 @@ #ifndef WEBSOCKETSVERSION_H_ #define WEBSOCKETSVERSION_H_ -#define WEBSOCKETS_VERSION "2.3.7" +#define WEBSOCKETS_VERSION "2.4.0" #define WEBSOCKETS_VERSION_MAJOR 2 -#define WEBSOCKETS_VERSION_MINOR 3 -#define WEBSOCKETS_VERSION_PATCH 7 +#define WEBSOCKETS_VERSION_MINOR 4 +#define WEBSOCKETS_VERSION_PATCH 0 -#define WEBSOCKETS_VERSION_INT 2003007 +#define WEBSOCKETS_VERSION_INT 2004000 #endif /* WEBSOCKETSVERSION_H_ */ From bb900a77b6cc4f448de337d58c57d159e17dc1fb Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 1 May 2023 14:53:30 +0200 Subject: [PATCH 308/347] GITHUB_STATE --> GITHUB_OUTPUT --- .github/workflows/main.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4a4a698..279fe85 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -34,19 +34,19 @@ jobs: source $GITHUB_WORKSPACE/travis/common.sh cd $GITHUB_WORKSPACE - echo -en "matrix=" >> $GITHUB_STATE - echo -en "[" >> $GITHUB_STATE + echo -en "matrix=" >> $GITHUB_OUTPUT + echo -en "[" >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 >> $GITHUB_STATE - echo -en "," >> $GITHUB_STATE + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 >> $GITHUB_OUTPUT + echo -en "," >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 >> $GITHUB_STATE - echo -en "," >> $GITHUB_STATE + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 >> $GITHUB_OUTPUT + echo -en "," >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.19 espressif:esp32:esp32:FlashFreq=80 >> $GITHUB_STATE + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.19 espressif:esp32:esp32:FlashFreq=80 >> $GITHUB_OUTPUT - echo -en "]" >> $GITHUB_STATE - echo >> $GITHUB_STATE + echo -en "]" >> $GITHUB_OUTPUT + echo >> $GITHUB_OUTPUT outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} @@ -65,7 +65,7 @@ jobs: - name: Get Date id: get-date run: | - echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_STATE + echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT shell: bash - uses: actions/cache@v2 @@ -127,7 +127,7 @@ jobs: - name: Get Date id: get-date run: | - echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_STATE + echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT shell: bash - uses: actions/cache@v2 From a215cca4feaa1c46b7118d05ba294ecb7eba9d20 Mon Sep 17 00:00:00 2001 From: Links Date: Mon, 1 May 2023 15:02:36 +0200 Subject: [PATCH 309/347] bump version 2.4.1 --- library.json | 2 +- library.properties | 2 +- src/WebSocketsVersion.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library.json b/library.json index d29c1a7..3647d91 100644 --- a/library.json +++ b/library.json @@ -21,5 +21,5 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.4.0" + "version": "2.4.1" } \ No newline at end of file diff --git a/library.properties b/library.properties index 097048e..38aa97b 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.4.0 +version=2.4.1 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index e349bbf..89dac96 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -25,12 +25,12 @@ #ifndef WEBSOCKETSVERSION_H_ #define WEBSOCKETSVERSION_H_ -#define WEBSOCKETS_VERSION "2.4.0" +#define WEBSOCKETS_VERSION "2.4.1" #define WEBSOCKETS_VERSION_MAJOR 2 #define WEBSOCKETS_VERSION_MINOR 4 -#define WEBSOCKETS_VERSION_PATCH 0 +#define WEBSOCKETS_VERSION_PATCH 1 -#define WEBSOCKETS_VERSION_INT 2004000 +#define WEBSOCKETS_VERSION_INT 2004001 #endif /* WEBSOCKETSVERSION_H_ */ From 751cf87b6cd684c9d339f0314a18b0ee866d449c Mon Sep 17 00:00:00 2001 From: mavyfaby Date: Mon, 22 May 2023 19:54:29 +0800 Subject: [PATCH 310/347] feat(socketio): add `disconnect` function --- src/SocketIOclient.cpp | 4 ++++ src/SocketIOclient.h | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index bf61195..25ee070 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -93,6 +93,10 @@ void SocketIOclient::setReconnectInterval(unsigned long time) { return WebSocketsClient::setReconnectInterval(time); } +void SocketIOclient::disconnect(void) { + WebSocketsClient::disconnect(); +} + /** * send text data to client * @param num uint8_t client id diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index 2eccea3..dd78f81 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -61,8 +61,9 @@ class SocketIOclient : protected WebSocketsClient { #endif #endif bool isConnected(void); - + void onEvent(SocketIOclientEvent cbEvent); + void disconnect(void); bool sendEVENT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); bool sendEVENT(const uint8_t * payload, size_t length = 0); From 30d5e136665a52880f641ddd7245b3ba05ecd32b Mon Sep 17 00:00:00 2001 From: matth-x <63792403+matth-x@users.noreply.github.com> Date: Sat, 19 Aug 2023 19:08:56 +0200 Subject: [PATCH 311/347] set minimum bufsize for base64 encode --- src/WebSockets.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 260129f..22352fc 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -571,6 +571,7 @@ String WebSockets::acceptKey(String & clientKey) { */ String WebSockets::base64_encode(uint8_t * data, size_t length) { size_t size = ((length * 1.6f) + 1); + size = std::max(size, (size_t) 5); //minimum buffer size char * buffer = (char *)malloc(size); if(buffer) { base64_encodestate _state; From da7efc789e7ee3870c6745549e9a9b0dd1e5a3c4 Mon Sep 17 00:00:00 2001 From: Links2004 Date: Fri, 5 Jan 2024 14:57:05 +0100 Subject: [PATCH 312/347] update github actions to arduino-cli for build tests --- .github/workflows/main.yml | 54 +++++++++++++------------------------- src/SocketIOclient.h | 2 +- src/WebSockets.cpp | 2 +- travis/common.sh | 26 +++++++++++++++++- 4 files changed, 45 insertions(+), 39 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 279fe85..0724e14 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,13 +37,13 @@ jobs: echo -en "matrix=" >> $GITHUB_OUTPUT echo -en "[" >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 >> $GITHUB_OUTPUT + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 0.35.0 esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 >> $GITHUB_OUTPUT echo -en "," >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 >> $GITHUB_OUTPUT + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 0.35.0 esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 >> $GITHUB_OUTPUT echo -en "," >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.19 espressif:esp32:esp32:FlashFreq=80 >> $GITHUB_OUTPUT + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 0.35.0 esp32:esp32:esp32:FlashFreq=80 >> $GITHUB_OUTPUT echo -en "]" >> $GITHUB_OUTPUT echo >> $GITHUB_OUTPUT @@ -55,9 +55,10 @@ jobs: strategy: fail-fast: false matrix: - IDE_VERSION: [1.8.19] + IDE_VERSION: [0.35.0] env: IDE_VERSION: ${{ matrix.IDE_VERSION }} + ARDUINO_DIRECTORIES_DATA: /home/runner/arduino_ide steps: - uses: actions/checkout@v2 @@ -74,14 +75,15 @@ jobs: path: | /home/runner/arduino_ide /home/runner/Arduino - key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.IDE_VERSION }} + key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.IDE_VERSION }}-cli - name: download IDE if: steps.cache_all.outputs.cache-hit != 'true' run: | - wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz -q - tar xf arduino-$IDE_VERSION-linux64.tar.xz - mv arduino-$IDE_VERSION $HOME/arduino_ide + wget https://github.com/arduino/arduino-cli/releases/download/v$IDE_VERSION/arduino-cli$IDE_VERSION_Linux_64bit.tar.gz -q + tar xf arduino-cli_$IDE_VERSION_Linux_64bit.tar.gz + mkdir -p $ARDUINO_DIRECTORIES_DATA + mv arduino-cli $ARDUINO_DIRECTORIES_DATA/ - name: download ArduinoJson if: steps.cache_all.outputs.cache-hit != 'true' @@ -91,17 +93,12 @@ jobs: unzip 6.x.zip mv ArduinoJson-6.x $HOME/Arduino/libraries/ArduinoJson - - name: download esp8266 + - name: download cores if: steps.cache_all.outputs.cache-hit != 'true' run: | + export PATH="$ARDUINO_DIRECTORIES_DATA:$PATH" source $GITHUB_WORKSPACE/travis/common.sh - get_core esp8266 - - - name: download esp32 - if: steps.cache_all.outputs.cache-hit != 'true' - run: | - source $GITHUB_WORKSPACE/travis/common.sh - get_core esp32 + get_core_cli build: needs: [prepare_ide, prepare_example_json] @@ -115,6 +112,7 @@ jobs: BOARD: ${{ matrix.board }} IDE_VERSION: ${{ matrix.ideversion }} SKETCH: ${{ matrix.sketch }} + ARDUINO_DIRECTORIES_DATA: /home/runner/arduino_ide # Steps represent a sequence of tasks that will be executed as part of the job steps: @@ -136,7 +134,7 @@ jobs: path: | /home/runner/arduino_ide /home/runner/Arduino - key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.ideversion }} + key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.ideversion }}-cli - name: install python serial if: matrix.cpu == 'esp32' @@ -145,32 +143,16 @@ jobs: sudo pip install pyserial # sudo apt install python-is-python3 - - name: start DISPLAY - run: | - /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16 - export DISPLAY=:1.0 - sleep 3 - - name: test IDE run: | - export PATH="$HOME/arduino_ide:$PATH" - which arduino + export PATH="$ARDUINO_DIRECTORIES_DATA:$PATH" + which arduino-cli - name: copy code run: | mkdir -p $HOME/Arduino/libraries/ cp -r $GITHUB_WORKSPACE $HOME/Arduino/libraries/arduinoWebSockets - - name: config IDE - run: | - set +x - export DISPLAY=:1.0 - export PATH="$HOME/arduino_ide:$PATH" - arduino --board $BOARD --save-prefs - arduino --pref update.check=false --pref build.verbose=false --pref cache.enable=true --pref compiler.cache_core=true --pref compiler.warning_level=default --save-prefs - arduino --get-pref sketchbook.path - arduino --get-pref - - name: build example timeout-minutes: 20 run: | @@ -179,7 +161,7 @@ jobs: export PATH="$HOME/arduino_ide:$PATH" source $GITHUB_WORKSPACE/travis/common.sh cd $GITHUB_WORKSPACE - build_sketch arduino $SKETCH + build_sketch_cli "$SKETCH" "$BOARD" done: needs: [prepare_ide, prepare_example_json, build, check_version_files] diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index dd78f81..d607401 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -61,7 +61,7 @@ class SocketIOclient : protected WebSocketsClient { #endif #endif bool isConnected(void); - + void onEvent(SocketIOclientEvent cbEvent); void disconnect(void); diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 22352fc..694aec2 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -571,7 +571,7 @@ String WebSockets::acceptKey(String & clientKey) { */ String WebSockets::base64_encode(uint8_t * data, size_t length) { size_t size = ((length * 1.6f) + 1); - size = std::max(size, (size_t) 5); //minimum buffer size + size = std::max(size, (size_t)5); // minimum buffer size char * buffer = (char *)malloc(size); if(buffer) { base64_encodestate _state; diff --git a/travis/common.sh b/travis/common.sh index 2754bdc..3b2d345 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -29,6 +29,22 @@ function build_sketches() done } +function build_sketch_cli() +{ + local sketch=$1 + local board=$2 + arduino-cli --log --log-level info compile -b "$board" "$sketch" + if [ $result -ne 0 ]; then + echo "Build failed ($sketch) build verbose..." + arduino-cli --log --log-level debug compile -b "$board" "$sketch" + result=$? + fi + if [ $result -ne 0 ]; then + echo "Build failed ($1) $sketch" + return $result + fi +} + function build_sketch() { local arduino=$1 @@ -88,11 +104,19 @@ function get_sketches_json_matrix() done } +function get_core_cli() { + arduino-cli core update-index --additional-urls https://arduino.esp8266.com/stable/package_esp8266com_index.json,https://espressif.github.io/arduino-esp32/package_esp32_index.json,https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json + arduino-cli core install esp8266:esp8266 + arduino-cli core install esp32:esp32 + arduino-cli core install arduino:mbed_rp2040 +} + function get_core() { echo Setup core for $1 - cd $HOME/arduino_ide/hardware + mkdir -p $HOME/arduino_ide/packages/hardware + cd $HOME/arduino_ide/packages/hardware if [ "$1" = "esp8266" ] ; then mkdir esp8266com From 92480b898728abf74effdfbb380735af7399802c Mon Sep 17 00:00:00 2001 From: Links2004 Date: Fri, 5 Jan 2024 15:00:16 +0100 Subject: [PATCH 313/347] IDE_VERSION --> CLI_VERSION --- .github/workflows/main.yml | 14 +++++++------- travis/common.sh | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0724e14..ae0a7d8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -55,9 +55,9 @@ jobs: strategy: fail-fast: false matrix: - IDE_VERSION: [0.35.0] + CLI_VERSION: [0.35.0] env: - IDE_VERSION: ${{ matrix.IDE_VERSION }} + CLI_VERSION: ${{ matrix.CLI_VERSION }} ARDUINO_DIRECTORIES_DATA: /home/runner/arduino_ide steps: @@ -75,13 +75,13 @@ jobs: path: | /home/runner/arduino_ide /home/runner/Arduino - key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.IDE_VERSION }}-cli + key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.CLI_VERSION }}-cli - name: download IDE if: steps.cache_all.outputs.cache-hit != 'true' run: | - wget https://github.com/arduino/arduino-cli/releases/download/v$IDE_VERSION/arduino-cli$IDE_VERSION_Linux_64bit.tar.gz -q - tar xf arduino-cli_$IDE_VERSION_Linux_64bit.tar.gz + wget https://github.com/arduino/arduino-cli/releases/download/v${CLI_VERSION}/arduino-cli${CLI_VERSION}_Linux_64bit.tar.gz -q + tar xf arduino-cli_${CLI_VERSION}_Linux_64bit.tar.gz mkdir -p $ARDUINO_DIRECTORIES_DATA mv arduino-cli $ARDUINO_DIRECTORIES_DATA/ @@ -110,7 +110,7 @@ jobs: env: CPU: ${{ matrix.cpu }} BOARD: ${{ matrix.board }} - IDE_VERSION: ${{ matrix.ideversion }} + CLI_VERSION: ${{ matrix.cliversion }} SKETCH: ${{ matrix.sketch }} ARDUINO_DIRECTORIES_DATA: /home/runner/arduino_ide @@ -134,7 +134,7 @@ jobs: path: | /home/runner/arduino_ide /home/runner/Arduino - key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.ideversion }}-cli + key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.cliversion }}-cli - name: install python serial if: matrix.cpu == 'esp32' diff --git a/travis/common.sh b/travis/common.sh index 3b2d345..ffe3d2f 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -88,7 +88,7 @@ function get_sketches_json_matrix() local arduino=$1 local srcpath=$2 local platform=$3 - local ideversion=$4 + local cliversion=$4 local board=$5 local sketches=($(find $srcpath -name *.ino)) for sketch in "${sketches[@]}" ; do @@ -97,7 +97,7 @@ function get_sketches_json_matrix() if [[ -f "$sketchdir/.$platform.skip" ]]; then continue fi - echo -en "{\"name\":\"$sketchname\",\"board\":\"$board\",\"ideversion\":\"$ideversion\",\"cpu\":\"$platform\",\"sketch\":\"$sketch\"}" + echo -en "{\"name\":\"$sketchname\",\"board\":\"$board\",\"cliversion\":\"$cliversion\",\"cpu\":\"$platform\",\"sketch\":\"$sketch\"}" if [[ $sketch != ${sketches[-1]} ]] ; then echo -en "," fi From 437c0252f1a1c250e4cb433f37ac1066024b3d8a Mon Sep 17 00:00:00 2001 From: Links2004 Date: Fri, 5 Jan 2024 15:01:53 +0100 Subject: [PATCH 314/347] fix cli download URL --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ae0a7d8..f4bc5de 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -80,7 +80,7 @@ jobs: - name: download IDE if: steps.cache_all.outputs.cache-hit != 'true' run: | - wget https://github.com/arduino/arduino-cli/releases/download/v${CLI_VERSION}/arduino-cli${CLI_VERSION}_Linux_64bit.tar.gz -q + wget https://github.com/arduino/arduino-cli/releases/download/v${CLI_VERSION}/arduino-cli_${CLI_VERSION}_Linux_64bit.tar.gz -q tar xf arduino-cli_${CLI_VERSION}_Linux_64bit.tar.gz mkdir -p $ARDUINO_DIRECTORIES_DATA mv arduino-cli $ARDUINO_DIRECTORIES_DATA/ From 241c73a8060c8b72839e9cff7eca042b32d2c4de Mon Sep 17 00:00:00 2001 From: Links2004 Date: Fri, 5 Jan 2024 15:06:30 +0100 Subject: [PATCH 315/347] use ARDUINO_BOARD_MANAGER_ADDITIONAL_URLS env for setting board URLs --- travis/common.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/travis/common.sh b/travis/common.sh index ffe3d2f..84ed157 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -105,7 +105,8 @@ function get_sketches_json_matrix() } function get_core_cli() { - arduino-cli core update-index --additional-urls https://arduino.esp8266.com/stable/package_esp8266com_index.json,https://espressif.github.io/arduino-esp32/package_esp32_index.json,https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json + export ARDUINO_BOARD_MANAGER_ADDITIONAL_URLS="https://arduino.esp8266.com/stable/package_esp8266com_index.json https://espressif.github.io/arduino-esp32/package_esp32_index.json https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json" + arduino-cli core update-index arduino-cli core install esp8266:esp8266 arduino-cli core install esp32:esp32 arduino-cli core install arduino:mbed_rp2040 From 3352c833b8a11c2324ca7e685b043c9353a1edbf Mon Sep 17 00:00:00 2001 From: patrick Date: Wed, 22 Nov 2023 20:35:40 -0500 Subject: [PATCH 316/347] - Fix memory leak by calling delete _server in the WebSocketsServer destructor. - Improve performance by looking for match to existing socket before creating a new one --- src/WebSocketsServer.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 79a52ce..dc1a494 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -65,6 +65,7 @@ WebSocketsServerCore::~WebSocketsServerCore() { } WebSocketsServer::~WebSocketsServer() { + delete _server; } /** @@ -428,8 +429,16 @@ WSclient_t * WebSocketsServerCore::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclien for(uint8_t i = 0; i < WEBSOCKETS_SERVER_CLIENT_MAX; i++) { client = &_clients[i]; + // look for match to existing socket before creating a new one + if (clientIsConnected(client)) + { + // Check to see if it is the same socket - if so, return it + if (client->tcp->getSocketNumber() == TCPclient->getSocketNumber()) + { + return client; + } + } else { // state is not connected or tcp connection is lost - if(!clientIsConnected(client)) { client->tcp = TCPclient; #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) From 4acc33589a1bbf145203a948e4737af89030d01d Mon Sep 17 00:00:00 2001 From: Shreyansh Jain Date: Sun, 6 Aug 2023 12:24:55 +0200 Subject: [PATCH 317/347] added option arguments in socket io being, for pingInterval, pongTimeout, and disconnectTimeoutCount --- src/SocketIOclient.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index 25ee070..b691691 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -15,39 +15,39 @@ SocketIOclient::SocketIOclient() { SocketIOclient::~SocketIOclient() { } -void SocketIOclient::begin(const char * host, uint16_t port, const char * url, const char * protocol) { +void SocketIOclient::begin(const char * host, uint16_t port, const char * url, const char * protocol, uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5) { WebSocketsClient::beginSocketIO(host, port, url, protocol); - WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); } -void SocketIOclient::begin(String host, uint16_t port, String url, String protocol) { +void SocketIOclient::begin(String host, uint16_t port, String url, String protocol, uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5) { WebSocketsClient::beginSocketIO(host, port, url, protocol); - WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); } #if defined(HAS_SSL) -void SocketIOclient::beginSSL(const char * host, uint16_t port, const char * url, const char * protocol) { +void SocketIOclient::beginSSL(const char * host, uint16_t port, const char * url, const char * protocol, uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5) { WebSocketsClient::beginSocketIOSSL(host, port, url, protocol); - WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); } -void SocketIOclient::beginSSL(String host, uint16_t port, String url, String protocol) { +void SocketIOclient::beginSSL(String host, uint16_t port, String url, String protocol. uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5) { WebSocketsClient::beginSocketIOSSL(host, port, url, protocol); - WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); } #if defined(SSL_BARESSL) -void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol) { +void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol, uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5) { WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol); - WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); } -void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) { +void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol, uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5) { WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol); - WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5); + WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); } From aed167bee075422469820ce079aa00b32b714696 Mon Sep 17 00:00:00 2001 From: Shreyansh Jain Date: Sun, 6 Aug 2023 12:24:55 +0200 Subject: [PATCH 318/347] updated the header file for the same changes --- src/SocketIOclient.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index d607401..e33a6fd 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -47,15 +47,15 @@ class SocketIOclient : protected WebSocketsClient { SocketIOclient(void); virtual ~SocketIOclient(void); - void begin(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); - void begin(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); + void begin(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino", uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5); + void begin(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino", uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5); #ifdef HAS_SSL - void beginSSL(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); - void beginSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); + void beginSSL(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino", uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5); + void beginSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino", uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5); #ifndef SSL_AXTLS - void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino"); - void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino"); + void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino", uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5); + void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino", uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5); void setSSLClientCertKey(const char * clientCert = NULL, const char * clientPrivateKey = NULL); void setSSLClientCertKey(BearSSL::X509List * clientCert = NULL, BearSSL::PrivateKey * clientPrivateKey = NULL); #endif From 3b143bc6f36456756361ba2e4c8820cca729eb21 Mon Sep 17 00:00:00 2001 From: Lukas Runge Date: Sun, 6 Aug 2023 12:24:55 +0200 Subject: [PATCH 319/347] =?UTF-8?q?=F0=9F=90=9B=E2=9E=96=20removed=20defau?= =?UTF-8?q?lt=20values=20from=20*.cpp=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SocketIOclient.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index b691691..93f8998 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -15,37 +15,37 @@ SocketIOclient::SocketIOclient() { SocketIOclient::~SocketIOclient() { } -void SocketIOclient::begin(const char * host, uint16_t port, const char * url, const char * protocol, uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5) { +void SocketIOclient::begin(const char * host, uint16_t port, const char * url, const char * protocol, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { WebSocketsClient::beginSocketIO(host, port, url, protocol); WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); } -void SocketIOclient::begin(String host, uint16_t port, String url, String protocol, uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5) { +void SocketIOclient::begin(String host, uint16_t port, String url, String protocol, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { WebSocketsClient::beginSocketIO(host, port, url, protocol); WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); } #if defined(HAS_SSL) -void SocketIOclient::beginSSL(const char * host, uint16_t port, const char * url, const char * protocol, uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5) { +void SocketIOclient::beginSSL(const char * host, uint16_t port, const char * url, const char * protocol, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { WebSocketsClient::beginSocketIOSSL(host, port, url, protocol); WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); } -void SocketIOclient::beginSSL(String host, uint16_t port, String url, String protocol. uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5) { +void SocketIOclient::beginSSL(String host, uint16_t port, String url, String protocol, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { WebSocketsClient::beginSocketIOSSL(host, port, url, protocol); WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); } #if defined(SSL_BARESSL) -void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol, uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5) { +void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol); WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); } -void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol, uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5) { +void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol); WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); From 313f2e0170a663d174f8ba85b561d13d407f681a Mon Sep 17 00:00:00 2001 From: Links2004 Date: Fri, 5 Jan 2024 15:26:26 +0100 Subject: [PATCH 320/347] update actions/cache@v3 --- .github/workflows/main.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f4bc5de..2bd0aaa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -69,7 +69,7 @@ jobs: echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT shell: bash - - uses: actions/cache@v2 + - uses: actions/cache@v3 id: cache_all with: path: | @@ -128,7 +128,7 @@ jobs: echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT shell: bash - - uses: actions/cache@v2 + - uses: actions/cache@v3 id: cache_all with: path: | @@ -157,7 +157,6 @@ jobs: timeout-minutes: 20 run: | set -ex - export DISPLAY=:1.0 export PATH="$HOME/arduino_ide:$PATH" source $GITHUB_WORKSPACE/travis/common.sh cd $GITHUB_WORKSPACE From be9fd8e2679c680565b97df0aa4fb766cb509d51 Mon Sep 17 00:00:00 2001 From: Links2004 Date: Fri, 5 Jan 2024 15:26:59 +0100 Subject: [PATCH 321/347] fix getSocketNumber for ESP --- src/WebSocketsServer.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index dc1a494..4a0b413 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -430,15 +430,15 @@ WSclient_t * WebSocketsServerCore::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclien client = &_clients[i]; // look for match to existing socket before creating a new one - if (clientIsConnected(client)) - { - // Check to see if it is the same socket - if so, return it - if (client->tcp->getSocketNumber() == TCPclient->getSocketNumber()) - { - return client; - } + if(clientIsConnected(client)) { +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_W5100) + // Check to see if it is the same socket - if so, return it + if(client->tcp->getSocketNumber() == TCPclient->getSocketNumber()) { + return client; + } +#endif } else { - // state is not connected or tcp connection is lost + // state is not connected or tcp connection is lost client->tcp = TCPclient; #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) From 6a26f74f958b7d31d71442d59e376a98cb53bedd Mon Sep 17 00:00:00 2001 From: Links2004 Date: Fri, 5 Jan 2024 15:27:49 +0100 Subject: [PATCH 322/347] code style --- src/SocketIOclient.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index 93f8998..1533316 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -27,25 +27,25 @@ void SocketIOclient::begin(String host, uint16_t port, String url, String protoc initClient(); } #if defined(HAS_SSL) -void SocketIOclient::beginSSL(const char * host, uint16_t port, const char * url, const char * protocol, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { +void SocketIOclient::beginSSL(const char * host, uint16_t port, const char * url, const char * protocol, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { WebSocketsClient::beginSocketIOSSL(host, port, url, protocol); WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); } -void SocketIOclient::beginSSL(String host, uint16_t port, String url, String protocol, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { +void SocketIOclient::beginSSL(String host, uint16_t port, String url, String protocol, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { WebSocketsClient::beginSocketIOSSL(host, port, url, protocol); WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); } #if defined(SSL_BARESSL) -void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { +void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, const char * CA_cert, const char * protocol, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol); WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); } -void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { +void SocketIOclient::beginSSLWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol, uint32_t pingInterval, uint32_t pongTimeout, uint8_t disconnectTimeoutCount) { WebSocketsClient::beginSocketIOSSLWithCA(host, port, url, CA_cert, protocol); WebSocketsClient::enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount); initClient(); From 503105a9fec1144755df0b5bee4b00444a602d57 Mon Sep 17 00:00:00 2001 From: Hasenradball Date: Fri, 5 Jan 2024 17:24:45 +0100 Subject: [PATCH 323/347] Remove compiler warnings (#854) * [Prevent unwanted Compiler Warnings]: Issue #772 --- src/WebSockets.cpp | 2 +- src/WebSocketsServer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 694aec2..2d3a254 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -750,7 +750,7 @@ void WebSockets::handleHBTimeout(WSclient_t * client) { client->pongTimeoutCount++; client->lastPing = millis() - client->pingInterval - 500; // force ping on the next run - DEBUG_WEBSOCKETS("[HBtimeout] pong TIMEOUT! lp=%d millis=%d pi=%d count=%d\n", client->lastPing, millis(), pi, client->pongTimeoutCount); + DEBUG_WEBSOCKETS("[HBtimeout] pong TIMEOUT! lp=%d millis=%lu pi=%d count=%d\n", client->lastPing, millis(), pi, client->pongTimeoutCount); if(client->disconnectTimeoutCount && client->pongTimeoutCount >= client->disconnectTimeoutCount) { DEBUG_WEBSOCKETS("[HBtimeout] count=%d, DISCONNECTING\n", client->pongTimeoutCount); diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 4a0b413..e11e1cf 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -655,7 +655,7 @@ void WebSocketsServer::handleNewClients(void) { #endif // store new connection - WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); + WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->accept()); if(!tcpClient) { DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); return; From 8d193b176d9aa6eaeaa0a6dd150c4e61dc083738 Mon Sep 17 00:00:00 2001 From: Hasenradball Date: Fri, 5 Jan 2024 17:25:57 +0100 Subject: [PATCH 324/347] [Prevent unwanted Compiler Warnings]: Issue #772 - wrong format specifier in line 754 (#773) * [Prevent unwanted Compiler Warnings]: Issue #772 From 93707d455fff3c667aedd92b485276101f5e6eba Mon Sep 17 00:00:00 2001 From: Links2004 Date: Fri, 5 Jan 2024 17:28:16 +0100 Subject: [PATCH 325/347] fix build_sketch_cli result handling --- travis/common.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/travis/common.sh b/travis/common.sh index 84ed157..53df57c 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -34,6 +34,7 @@ function build_sketch_cli() local sketch=$1 local board=$2 arduino-cli --log --log-level info compile -b "$board" "$sketch" + result=$? if [ $result -ne 0 ]; then echo "Build failed ($sketch) build verbose..." arduino-cli --log --log-level debug compile -b "$board" "$sketch" From c5e7a5eb0896f762e423c31ff1a99cdf8c55a5af Mon Sep 17 00:00:00 2001 From: Moritz Ulmer Date: Mon, 17 Jun 2024 12:09:37 +0100 Subject: [PATCH 326/347] Add support for CA bundles (#885) Why: - Allow CA cert bundles to be used This change addresses the need by: - Adding a constructor that takes a pointer to the bundle - Setting the WiFiClientSecure to use the bundle - Adding an example --- README.md | 10 + .../WebSocketClientSSLBundle.ino | 129 + .../WebSocketClientSSLBundle/.gitignore | 8 + .../WebSocketClientSSLBundle/cacrt_all.pem | 3581 +++++++++++++++++ .../cmn_crt_authorities.csv | 39 + .../gen_crt_bundle.py | 227 ++ .../WebSocketClientSSLBundle/lib/README | 46 + .../WebSocketClientSSLBundle/platformio.ini | 25 + .../WebSocketClientSSLBundle/readme.md | 12 + .../run_gen_script.py | 6 + .../WebSocketClientSSLBundle/src/main.cpp | 127 + src/WebSocketsClient.cpp | 18 + src/WebSocketsClient.h | 4 + 13 files changed, 4232 insertions(+) create mode 100644 examples/esp32/WebSocketClientSSLBundle/WebSocketClientSSLBundle.ino create mode 100644 examples/esp32_pio/WebSocketClientSSLBundle/.gitignore create mode 100644 examples/esp32_pio/WebSocketClientSSLBundle/cacrt_all.pem create mode 100644 examples/esp32_pio/WebSocketClientSSLBundle/cmn_crt_authorities.csv create mode 100644 examples/esp32_pio/WebSocketClientSSLBundle/gen_crt_bundle.py create mode 100644 examples/esp32_pio/WebSocketClientSSLBundle/lib/README create mode 100644 examples/esp32_pio/WebSocketClientSSLBundle/platformio.ini create mode 100644 examples/esp32_pio/WebSocketClientSSLBundle/readme.md create mode 100644 examples/esp32_pio/WebSocketClientSSLBundle/run_gen_script.py create mode 100644 examples/esp32_pio/WebSocketClientSSLBundle/src/main.cpp diff --git a/README.md b/README.md index 83faaab..fdc4e4c 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,16 @@ a WebSocket Server and Client for Arduino based on RFC6455. by running the device behind an SSL proxy. See [Nginx](examples/Nginx/esp8266.ssl.reverse.proxy.conf) for a sample Nginx server configuration file to enable this. +### Root CA Cert Bundles for SSL/TLS connections ### + +Secure connections require the certificate of the server to be verified. One option is to provide a single certificate in the chain of trust. However, for flexibility and robustness, a certificate bundle is recommended. If a server changes the root CA from which it derives its certificates, this will not be a problem. With a single CA cert it will not connect. + + - For [technical details](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/protocols/esp_crt_bundle.html) + - For a [PlatformIO setup](https://github.com/Duckle29/esp32-certBundle/) + - For an [example](examples/esp32/WebSocketClientSSLBundle/) + +Including a bundle with all CA certs will use 77.2 kB but this list can be reduced to 16.5 kB for the 41 most common. This results in 90% absolute usage coverage and 99% market share coverage according to [W3Techs](https://w3techs.com/technologies/overview/ssl_certificate). The bundle is inserted into the compiled firmware. The bundle is not loaded into RAM, only its index. + ### ESP Async TCP ### This libary can run in Async TCP mode on the ESP. diff --git a/examples/esp32/WebSocketClientSSLBundle/WebSocketClientSSLBundle.ino b/examples/esp32/WebSocketClientSSLBundle/WebSocketClientSSLBundle.ino new file mode 100644 index 0000000..b9385a7 --- /dev/null +++ b/examples/esp32/WebSocketClientSSLBundle/WebSocketClientSSLBundle.ino @@ -0,0 +1,129 @@ +/* + * main.cpp + * + * Created on: 15.06.2024 + * + */ + +#include +#include +#include + +#include + +// Use the incbin library to embedd the cert binary +// extern const uint8_t rootca_crt_bundle_start[] asm( +// "_binary_data_cert_x509_crt_bundle_bin_start"); + +WiFiMulti wifiMulti; +WebSocketsClient webSocket; + +#define USE_SERIAL Serial + +void setClock() { + configTime(0, 0, "pool.ntp.org", "time.nist.gov"); + + USE_SERIAL.print(F("Waiting for NTP time sync: ")); + time_t nowSecs = time(nullptr); + while(nowSecs < 8 * 3600 * 2) { + delay(500); + USE_SERIAL.print(F(".")); + yield(); + nowSecs = time(nullptr); + } + + USE_SERIAL.println(); + struct tm timeinfo; + gmtime_r(&nowSecs, &timeinfo); + USE_SERIAL.print(F("Current time: ")); + USE_SERIAL.print(asctime(&timeinfo)); +} + +void hexdump(const void * mem, uint32_t len, uint8_t cols = 16) { + const uint8_t * src = (const uint8_t *)mem; + USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); + for(uint32_t i = 0; i < len; i++) { + if(i % cols == 0) { + USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); + } + USE_SERIAL.printf("%02X ", *src); + src++; + } + USE_SERIAL.printf("\n"); +} + +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[WSc] Disconnected!\n"); + break; + case WStype_CONNECTED: + USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); + + // send message to server when Connected + webSocket.sendTXT("Connected"); + break; + case WStype_TEXT: + USE_SERIAL.printf("[WSc] get text: %s\n", payload); + + // send message to server + // webSocket.sendTXT("message here"); + break; + case WStype_BIN: + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); + + // send data to server + // webSocket.sendBIN(payload, length); + break; + case WStype_ERROR: + case WStype_FRAGMENT_TEXT_START: + case WStype_FRAGMENT_BIN_START: + case WStype_FRAGMENT: + case WStype_FRAGMENT_FIN: + break; + } +} + +void setup() { + USE_SERIAL.begin(115200); + + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + wifiMulti.addAP("SSID", "WIFI_PASSPHRASE"); + + // WiFi.disconnect(); + while(wifiMulti.run() != WL_CONNECTED) { + delay(100); + } + + setClock(); + + // server address, port and URL. This server can be flakey. + // Expected response: Request served by 0123456789abcdef + // webSocket.beginSslWithBundle("echo.websocket.org", 443, "/", rootca_crt_bundle_start, ""); + webSocket.beginSslWithBundle("echo.websocket.org", 443, "/", NULL, ""); + + // event handler + webSocket.onEvent(webSocketEvent); + + // use HTTP Basic Authorization this is optional enable if needed + // webSocket.setAuthorization("user", "Password"); + + // try ever 5000 again if connection has failed + webSocket.setReconnectInterval(5000); +} + +void loop() { + webSocket.loop(); +} diff --git a/examples/esp32_pio/WebSocketClientSSLBundle/.gitignore b/examples/esp32_pio/WebSocketClientSSLBundle/.gitignore new file mode 100644 index 0000000..7599937 --- /dev/null +++ b/examples/esp32_pio/WebSocketClientSSLBundle/.gitignore @@ -0,0 +1,8 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch +*secret* +!*secrets.hpp.template +*x509_crt_bundle.bin \ No newline at end of file diff --git a/examples/esp32_pio/WebSocketClientSSLBundle/cacrt_all.pem b/examples/esp32_pio/WebSocketClientSSLBundle/cacrt_all.pem new file mode 100644 index 0000000..f78a610 --- /dev/null +++ b/examples/esp32_pio/WebSocketClientSSLBundle/cacrt_all.pem @@ -0,0 +1,3581 @@ +## +## Bundle of CA Root Certificates +## +## Certificate data from Mozilla as of: Mon Mar 11 15:25:27 2024 GMT +## +## This is a bundle of X.509 certificates of public Certificate Authorities +## (CA). These were automatically extracted from Mozilla's root certificates +## file (certdata.txt). This file can be found in the mozilla source tree: +## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt +## +## It contains the certificates in PEM format and therefore +## can be directly used with curl / libcurl / php_curl, or with +## an Apache+mod_ssl webserver for SSL client authentication. +## Just configure this file as the SSLCACertificateFile. +## +## Conversion done with mk-ca-bundle.pl version 1.29. +## SHA256: 4d96bd539f4719e9ace493757afbe4a23ee8579de1c97fbebc50bba3c12e8c1e +## + + +GlobalSign Root CA +================== +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx +GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds +b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV +BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD +VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa +DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc +THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb +Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP +c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX +gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF +AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj +Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG +j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH +hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC +X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +Entrust.net Premium 2048 Secure Server CA +========================================= +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u +ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp +bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV +BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx +NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 +d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl +MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u +ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL +Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr +hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW +nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi +VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ +KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy +T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT +J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e +nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +Baltimore CyberTrust Root +========================= +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE +ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li +ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC +SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs +dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME +uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB +UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C +G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 +XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr +l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI +VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB +BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh +cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 +hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa +Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H +RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +Entrust Root Certification Authority +==================================== +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw +b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG +A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 +MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu +MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu +Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v +dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz +A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww +Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 +j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN +rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 +MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH +hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM +Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa +v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS +W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 +tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +Comodo AAA Services root +======================== +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw +MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl +c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV +BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG +C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs +i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW +Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH +Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK +Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f +BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl +cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz +LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm +7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z +8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C +12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +QuoVadis Root CA 2 +================== +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx +ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6 +XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk +lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB +lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy +lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt +66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn +wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh +D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy +BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie +J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud +DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU +a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv +Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3 +UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm +VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK ++JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW +IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1 +WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X +f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II +4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8 +VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +QuoVadis Root CA 3 +================== +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx +OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg +DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij +KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K +DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv +BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp +p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8 +nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX +MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM +Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz +uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT +BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj +YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB +BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD +VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4 +ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE +AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV +qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s +hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z +POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2 +Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp +8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC +bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu +g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p +vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr +qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +XRamp Global CA Root +==================== +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE +BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj +dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx +HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg +U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu +IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx +foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE +zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs +AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry +xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap +oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC +AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc +/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n +nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz +8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +Go Daddy Class 2 CA +=================== +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY +VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG +A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g +RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD +ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv +2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 +qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j +YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY +vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O +BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o +atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu +MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG +A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim +PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt +I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI +Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b +vZ8= +-----END CERTIFICATE----- + +Starfield Class 2 CA +==================== +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc +U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo +MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG +A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG +SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY +bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ +JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm +epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN +F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF +MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f +hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo +bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs +afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM +PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD +KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 +QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +DigiCert Assured ID Root CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx +MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO +9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy +UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW +/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy +oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf +GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF +66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq +hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc +EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn +SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i +8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +DigiCert Global Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw +MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn +TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 +BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H +4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y +7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB +o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm +8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF +BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr +EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt +tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 +UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +DigiCert High Assurance EV Root CA +================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw +KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw +MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ +MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu +Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t +Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS +OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 +MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ +NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe +h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB +Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY +JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ +V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp +myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK +mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K +-----END CERTIFICATE----- + +SwissSign Gold CA - G2 +====================== +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw +EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN +MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp +c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq +t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C +jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg +vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF +ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR +AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend +jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO +peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR +7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi +GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64 +OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm +5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr +44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf +Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m +Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp +mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk +vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf +KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br +NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj +viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- + +SwissSign Silver CA - G2 +======================== +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT +BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X +DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 +aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 +N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm ++/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH +6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu +MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h +qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 +FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs +ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc +celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X +CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB +tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P +4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F +kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L +3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx +/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa +DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP +e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu +WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ +DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub +DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- + +SecureTrust CA +============== +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy +dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe +BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX +OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t +DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH +GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b +01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH +ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj +aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu +SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf +mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ +nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +Secure Global CA +================ +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH +bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg +MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx +YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ +bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g +8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV +HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi +0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn +oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA +MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ +OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn +CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 +3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +COMODO Certification Authority +============================== +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb +MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD +T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH ++7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww +xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV +4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA +1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI +rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k +b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC +AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP +OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc +IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN ++8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== +-----END CERTIFICATE----- + +COMODO ECC Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix +GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X +4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni +wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG +FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA +U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +Certigna +======== +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw +EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 +MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI +Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q +XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH +GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p +ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg +DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf +Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ +tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ +BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J +SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA +hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ +ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu +PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY +1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +ePKI Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG +EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx +MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq +MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs +IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi +lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv +qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX +12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O +WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ +ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao +lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ +vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi +Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi +MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 +1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq +KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV +xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP +NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r +GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE +xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx +gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy +sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD +BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +certSIGN ROOT CA +================ +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD +VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa +Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE +CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I +JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH +rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 +ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD +0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 +AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B +Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB +AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 +SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 +x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt +vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz +TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +NetLock Arany (Class Gold) Főtanúsítvány +======================================== +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G +A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 +dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB +cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx +MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO +ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 +c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu +0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw +/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk +H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw +fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 +neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW +qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta +YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna +NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu +dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +SecureSign RootCA11 +=================== +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi +SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS +b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw +KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 +cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL +TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO +wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq +g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP +O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA +bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX +t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh +OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r +bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ +Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 +y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 +lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER +MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv +c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE +BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt +U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA +fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG +0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA +pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm +1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC +AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf +QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE +FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o +lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX +I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 +yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi +LXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +GlobalSign Root CA - R3 +======================= +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt +iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ +0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 +rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl +OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 +xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 +lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 +EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E +bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 +YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r +kpeDMdmztcpHWD9f +-----END CERTIFICATE----- + +Izenpe.com +========== +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG +EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz +MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu +QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ +03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK +ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU ++zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC +PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT +OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK +F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK +0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ +0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB +leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID +AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ +SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG +NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l +Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga +kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q +hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs +g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 +aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 +nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC +ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo +Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z +WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +Go Daddy Root Certificate Authority - G2 +======================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu +MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G +A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq +9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD ++qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd +fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl +NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 +BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac +vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r +5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV +N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 +-----END CERTIFICATE----- + +Starfield Root Certificate Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 +eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw +DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg +VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB +dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv +W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs +bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk +N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf +ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU +JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol +TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx +4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw +F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ +c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +Starfield Services Root Certificate Authority - G2 +================================================== +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl +IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT +dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 +h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa +hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP +LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB +rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG +SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP +E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy +xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza +YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 +-----END CERTIFICATE----- + +AffirmTrust Commercial +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw +MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb +DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV +C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 +BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww +MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV +HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG +hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi +qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv +0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh +sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +AffirmTrust Networking +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw +MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE +Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI +dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 +/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb +h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV +HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu +UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 +12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 +WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 +/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +AffirmTrust Premium +=================== +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy +OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy +dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn +BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV +5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs ++7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd +GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R +p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI +S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 +6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 +/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo ++Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv +MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC +6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S +L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK ++4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV +BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg +IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 +g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb +zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== +-----END CERTIFICATE----- + +AffirmTrust Premium ECC +======================= +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV +BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx +MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U +cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ +N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW +BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK +BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X +57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM +eQ== +-----END CERTIFICATE----- + +Certum Trusted Network CA +========================= +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK +ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy +MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU +ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC +l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J +J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 +fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 +cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB +Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw +DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj +jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 +mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj +Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +TWCA Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ +VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG +EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB +IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx +QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC +oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP +4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r +y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG +9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC +mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW +QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY +T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny +Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +Security Communication RootCA2 +============================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC +SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy +aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ ++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R +3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV +spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K +EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 +QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB +CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj +u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk +3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q +tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 +mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +Actalis Authentication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM +BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE +AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky +MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz +IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ +wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa +by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 +zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f +YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 +oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l +EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 +hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 +EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 +jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY +iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI +WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 +JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx +K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ +Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC +4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo +2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz +lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem +OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 +vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +Buypass Class 2 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X +DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 +g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn +9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b +/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU +CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff +awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI +zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn +Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX +Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs +M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI +osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S +aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd +DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD +LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 +oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC +wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS +CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN +rJgWVqA= +-----END CERTIFICATE----- + +Buypass Class 3 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X +DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH +sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR +5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh +7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ +ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH +2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV +/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ +RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA +Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq +j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G +uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG +Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 +ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 +KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz +6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug +UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe +eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi +Cp/HuZc= +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 3 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx +MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK +9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU +NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF +iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W +0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr +AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb +fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT +ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h +P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe +Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE +LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD +ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA +BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv +KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z +p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC +AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ +4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y +eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw +MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G +PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw +OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm +2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV +dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph +X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 EV 2009 +================================= +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS +egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh +zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T +7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60 +sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35 +11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv +cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v +ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El +MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp +b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh +c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+ +PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX +ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA +NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv +w9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +CA Disig Root R2 +================ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw +EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp +ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx +EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp +c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC +w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia +xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7 +A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S +GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV +g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa +5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE +koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A +Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i +Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u +Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV +sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je +dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8 +1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx +mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01 +utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0 +sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg +UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV +7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +ACCVRAIZ1 +========= +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB +SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1 +MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH +UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM +jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0 +RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD +aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ +0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG +WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7 +8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR +5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J +9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK +Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw +Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu +Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM +Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA +QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh +AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA +YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj +AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA +IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk +aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0 +dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2 +MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI +hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E +R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN +YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49 +nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ +TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3 +sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg +Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd +3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p +EfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +TWCA Global Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT +CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD +QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK +EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg +Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C +nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV +r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR +Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV +tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W +KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99 +sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p +yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn +kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI +zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g +cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M +8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg +/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg +lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP +A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m +i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8 +EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3 +zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0= +-----END CERTIFICATE----- + +TeliaSonera Root CA v1 +====================== +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE +CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4 +MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW +VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+ +6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA +3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k +B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn +Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH +oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3 +F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ +oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7 +gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc +TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB +AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW +DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm +zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW +pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV +G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc +c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT +JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2 +qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6 +Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems +WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 2 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx +MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ +SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F +vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970 +2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV +WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy +YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4 +r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf +vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR +3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg== +-----END CERTIFICATE----- + +Atos TrustedRoot 2011 +===================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU +cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4 +MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG +A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV +hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr +54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+ +DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320 +HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR +z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R +l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ +bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h +k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh +TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9 +61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G +3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +QuoVadis Root CA 1 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE +PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm +PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6 +Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN +ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l +g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV +7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX +9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f +iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg +t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI +hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3 +GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct +Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP ++V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh +3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa +wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6 +O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0 +FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV +hMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +QuoVadis Root CA 2 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh +ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY +NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t +oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o +MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l +V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo +L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ +sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD +6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh +lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI +hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K +pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9 +x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz +dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X +U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw +mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD +zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN +JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr +O3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +QuoVadis Root CA 3 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286 +IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL +Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe +6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3 +I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U +VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7 +5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi +Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM +dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt +rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI +hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS +t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ +TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du +DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib +Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD +hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX +0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW +dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2 +PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +DigiCert Assured ID Root G2 +=========================== +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw +MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH +35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq +bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw +VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP +YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn +lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO +w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv +0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz +d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW +hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M +jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +DigiCert Assured ID Root G3 +=========================== +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD +VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 +MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ +BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb +RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs +KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF +UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy +YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy +1vUhZscv6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +DigiCert Global Root G2 +======================= +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx +MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ +kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO +3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV +BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM +UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB +o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu +5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr +F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U +WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH +QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/ +iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +DigiCert Global Root G3 +======================= +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD +VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw +MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k +aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C +AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O +YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp +Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y +3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34 +VOKa5Vt8sycX +-----END CERTIFICATE----- + +DigiCert Trusted Root G4 +======================== +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw +HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 +MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp +pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o +k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa +vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY +QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6 +MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm +mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7 +f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH +dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8 +oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY +ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr +yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy +7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah +ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN +5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb +/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa +5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK +G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP +82Z+ +-----END CERTIFICATE----- + +COMODO RSA Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn +dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ +FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+ +5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG +x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX +2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL +OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3 +sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C +GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5 +WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt +rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+ +nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg +tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW +sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp +pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA +zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq +ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52 +7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I +LaZRfyHBNVOFBkpdn627G190 +-----END CERTIFICATE----- + +USERTrust RSA Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK +ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK +ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz +0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j +Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn +RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O ++T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq +/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE +Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM +lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8 +yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+ +eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW +FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ +7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ +Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM +8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi +FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi +yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c +J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw +sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx +Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +USERTrust ECC Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2 +0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez +nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV +HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB +HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu +9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R5 +=========================== +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6 +SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS +h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd +BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx +uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 +yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +IdenTrust Commercial Root CA 1 +============================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS +b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES +MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB +IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld +hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/ +mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi +1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C +XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl +3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy +NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV +WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg +xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix +uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI +hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg +ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt +ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV +YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX +feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro +kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe +2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz +Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R +cGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +IdenTrust Public Sector Root CA 1 +================================= +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv +ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV +UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS +b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy +P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6 +Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI +rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf +qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS +mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn +ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh +LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v +iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL +4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B +Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw +DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A +mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt +GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt +m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx +NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4 +Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI +ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC +ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ +3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +Entrust Root Certification Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy +bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug +b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw +HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT +DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx +OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP +/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz +HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU +s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y +TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx +AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6 +0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z +iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi +nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+ +vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO +e4pIb4tF9g== +-----END CERTIFICATE----- + +Entrust Root Certification Authority - EC1 +========================================== +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx +FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn +YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw +FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs +LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg +dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt +IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy +AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef +9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h +vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8 +kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +CFCA EV ROOT +============ +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE +CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB +IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw +MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD +DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV +BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD +7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN +uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW +ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7 +xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f +py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K +gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol +hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ +tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf +BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q +ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua +4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG +E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX +BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn +aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy +PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX +kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C +ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GB CA +=============================== +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG +EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw +MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds +b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX +scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP +rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk +9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o +Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg +GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI +hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD +dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0 +VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui +HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +SZAFIR ROOT CA2 +=============== +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG +A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV +BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ +BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD +VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q +qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK +DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE +2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ +ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi +ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC +AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5 +O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67 +oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul +4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6 ++/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +Certum Trusted Network CA 2 +=========================== +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE +BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1 +bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y +ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ +TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB +IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9 +7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o +CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b +Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p +uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130 +GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ +9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB +Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye +hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM +BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI +hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW +Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA +L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo +clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM +pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb +w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo +J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm +ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX +is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7 +zAYspsbiDrW5viSP +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions RootCA 2015 +======================================================= +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT +BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0 +aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl +YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx +MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg +QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV +BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw +MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv +bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh +iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+ +6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd +FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr +i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F +GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2 +fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu +iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI +hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+ +D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM +d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y +d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn +82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb +davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F +Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt +J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa +JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q +p/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions ECC RootCA 2015 +=========================================================== +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0 +aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u +cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj +aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw +MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj +IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD +VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290 +Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP +dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK +Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA +GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn +dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +ISRG Root X1 +============ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE +BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD +EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG +EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT +DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r +Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1 +3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K +b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN +Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ +4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf +1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu +hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH +usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r +OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G +A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY +9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV +0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt +hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw +TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx +e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA +JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD +YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n +JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ +m+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +AC RAIZ FNMT-RCM +================ +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT +AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw +MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD +TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf +qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr +btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL +j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou +08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw +WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT +tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ +47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC +ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa +i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o +dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s +D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ +j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT +Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW ++YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7 +Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d +8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm +5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG +rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +Amazon Root CA 1 +================ +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD +VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1 +MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv +bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH +FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ +gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t +dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce +VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3 +DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM +CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy +8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa +2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2 +xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +Amazon Root CA 2 +================ +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD +VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1 +MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv +bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4 +kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp +N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9 +AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd +fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx +kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS +btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0 +Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN +c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+ +3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw +DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA +A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE +YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW +xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ +gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW +aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV +Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3 +KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi +JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw= +-----END CERTIFICATE----- + +Amazon Root CA 3 +================ +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG +EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy +NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ +MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB +f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr +Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43 +rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc +eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +Amazon Root CA 4 +================ +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG +EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy +NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ +MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN +/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri +83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA +MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1 +AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 +============================================= +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIxGDAWBgNVBAcT +D0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlr +IEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0wKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24g +TWVya2V6aSAtIEthbXUgU00xNjA0BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRp +ZmlrYXNpIC0gU3VydW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYD +VQQGEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXllIEJpbGlt +c2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklUQUsxLTArBgNVBAsTJEth +bXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBTTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11 +IFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAr3UwM6q7a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y8 +6Ij5iySrLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INrN3wc +wv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2XYacQuFWQfw4tJzh0 +3+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/iSIzL+aFCr2lqBs23tPcLG07xxO9 +WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4fAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQU +ZT/HiobGPN08VFw1+DrtUgxHV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJ +KoZIhvcNAQELBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPfIPP54+M638yc +lNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4lzwDGrpDxpa5RXI4s6ehlj2R +e37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0j +q5Rm+K37DwhuJi1/FwcJsoz7UMCflo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- + +GDCA TrustAUTH R5 ROOT +====================== +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCQ04xMjAw +BgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8wHQYDVQQD +DBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVow +YjELMAkGA1UEBhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJjDp6L3TQs +AlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBjTnnEt1u9ol2x8kECK62p +OqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+uKU49tm7srsHwJ5uu4/Ts765/94Y9cnrr +pftZTqfrlYwiOXnhLQiPzLyRuEH3FMEjqcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ +9Cy5WmYqsBebnh52nUpmMUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQ +xXABZG12ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloPzgsM +R6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3GkL30SgLdTMEZeS1SZ +D2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeCjGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4 +oR24qoAATILnsn8JuLwwoC8N9VKejveSswoAHQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx +9hoh49pwBiFYFIeFd3mqgnkCAwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlR +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZmDRd9FBUb1Ov9 +H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5COmSdI31R9KrO9b7eGZONn35 +6ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ryL3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd ++PwyvzeG5LuOmCd+uh8W4XAR8gPfJWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQ +HtZa37dG/OaG+svgIHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBD +F8Io2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV09tL7ECQ +8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQXR4EzzffHqhmsYzmIGrv +/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrqT8p+ck0LcIymSLumoRT2+1hEmRSuqguT +aaApJUqlyyvdimYHFngVV3Eb7PVHhPOeMTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- + +SSL.com Root Certification Authority RSA +======================================== +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxDjAM +BgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24x +MTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYw +MjEyMTczOTM5WhcNNDEwMjEyMTczOTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx +EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NM +LmNvbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2RxFdHaxh3a3by/ZPkPQ/C +Fp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aXqhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8 +P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcCC52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/ge +oeOy3ZExqysdBP+lSgQ36YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkp +k8zruFvh/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrFYD3Z +fBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93EJNyAKoFBbZQ+yODJ +gUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVcUS4cK38acijnALXRdMbX5J+tB5O2 +UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi8 +1xtZPCvM8hnIk2snYxnP/Okm+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4s +bE6x/c+cCbqiM+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGVcpNxJK1ok1iOMq8bs3AD/CUr +dIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBcHadm47GUBwwyOabqG7B52B2ccETjit3E+ZUf +ijhDPwGFpUenPUayvOUiaPd7nNgsPgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAsl +u1OJD7OAUN5F7kR/q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjq +erQ0cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jra6x+3uxj +MxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90IH37hVZkLId6Tngr75qNJ +vTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/YK9f1JmzJBjSWFupwWRoyeXkLtoh/D1JI +Pb9s2KJELtFOt3JY04kTlf5Eq/jXixtunLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406y +wKBjYZC6VWg3dGq2ktufoYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NI +WuuA8ShYIc2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- + +SSL.com Root Certification Authority ECC +======================================== +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMCVVMxDjAMBgNV +BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xMTAv +BgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEy +MTgxNDAzWhcNNDEwMjEyMTgxNDAzWjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAO +BgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuBBAAiA2IA +BEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI7Z4INcgn64mMU1jrYor+ +8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPgCemB+vNH06NjMGEwHQYDVR0OBBYEFILR +hXMw5zUE044CkvvlpNHEIejNMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTT +jgKS++Wk0cQh6M0wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCW +e+0F+S8Tkdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+gA0z +5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- + +SSL.com EV Root Certification Authority RSA R2 +============================================== +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAlVTMQ4w +DAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9u +MTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MB4XDTE3MDUzMTE4MTQzN1oXDTQyMDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQI +DAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYD +VQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvqM0fNTPl9fb69LT3w23jh +hqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssufOePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7w +cXHswxzpY6IXFJ3vG2fThVUCAtZJycxa4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTO +Zw+oz12WGQvE43LrrdF9HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+ +B6KjBSYRaZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcAb9Zh +CBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQGp8hLH94t2S42Oim +9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQVPWKchjgGAGYS5Fl2WlPAApiiECto +RHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMOpgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+Slm +JuwgUHfbSguPvuUCYHBBXtSuUDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48 ++qvWBkofZ6aYMBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa49QaAJadz20Zp +qJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBWs47LCp1Jjr+kxJG7ZhcFUZh1 +++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nx +Y/hoLVUE0fKNsKTPvDxeH3jnpaAgcLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2G +guDKBAdRUNf/ktUM79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDz +OFSz/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXtll9ldDz7 +CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEmKf7GUmG6sXP/wwyc5Wxq +lD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKKQbNmC1r7fSOl8hqw/96bg5Qu0T/fkreR +rwU7ZcegbLHNYhLDkBvjJc40vG93drEQw/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1 +hlMYegouCRw2n5H9gooiS9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX +9hwJ1C07mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- + +SSL.com EV Root Certification Authority ECC +=========================================== +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMCVVMxDjAMBgNV +BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xNDAy +BgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYw +MjEyMTgxNTIzWhcNNDEwMjEyMTgxNTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx +EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NM +LmNvbSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMAVIbc/R/fALhBYlzccBYy +3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1KthkuWnBaBu2+8KGwytAJKaNjMGEwHQYDVR0O +BBYEFFvKXuXe0oGqzagtZFG22XKbl+ZPMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe +5d7SgarNqC1kUbbZcpuX5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJ +N+vp1RPZytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZgh5Mm +m7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- + +GlobalSign Root CA - R6 +======================= +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEgMB4GA1UECxMX +R2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds +b2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQxMjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9i +YWxTaWduIFJvb3QgQ0EgLSBSNjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFs +U2lnbjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQss +grRIxutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1kZguSgMpE +3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxDaNc9PIrFsmbVkJq3MQbF +vuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJwLnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqM +PKq0pPbzlUoSB239jLKJz9CgYXfIWHSw1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+ +azayOeSsJDa38O+2HBNXk7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05O +WgtH8wY2SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/hbguy +CLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4nWUx2OVvq+aWh2IMP +0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpYrZxCRXluDocZXFSxZba/jJvcE+kN +b7gu3GduyYsRtYQUigAZcIN5kZeR1BonvzceMgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQE +AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNV +HSMEGDAWgBSubAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGtIxg93eFyRJa0 +lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr6155wsTLxDKZmOMNOsIeDjHfrY +BzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLjvUYAGm0CuiVdjaExUd1URhxN25mW7xocBFym +Fe944Hn+Xds+qkxV/ZoVqW/hpvvfcDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr +3TsTjxKM4kEaSHpzoHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB1 +0jZpnOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfspA9MRf/T +uTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+vJJUEeKgDu+6B5dpffItK +oZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+t +JDfLRVpOoERIyNiwmcUVhAn21klJwGW45hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GC CA +=============================== +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQswCQYDVQQGEwJD +SDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEo +MCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRa +Fw00MjA1MDkwOTU4MzNaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQL +ExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4nieUqjFqdr +VCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4Wp2OQ0jnUsYd4XxiWD1Ab +NTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd +BgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7TrYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0E +AwMDaAAwZQIwJsdpW9zV57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtk +AjEA2zQgMgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- + +UCA Global G2 Root +================== +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9MQswCQYDVQQG +EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBHbG9iYWwgRzIgUm9vdDAeFw0x +NjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0xCzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlU +cnVzdDEbMBkGA1UEAwwSVUNBIEdsb2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxeYrb3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmT +oni9kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzmVHqUwCoV +8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/RVogvGjqNO7uCEeBHANBS +h6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDcC/Vkw85DvG1xudLeJ1uK6NjGruFZfc8o +LTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIjtm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/ +R+zvWr9LesGtOxdQXGLYD0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBe +KW4bHAyvj5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6DlNaBa +4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6iIis7nCs+dwp4wwc +OxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznPO6Q0ibd5Ei9Hxeepl2n8pndntd97 +8XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFIHEjMz15DD/pQwIX4wVZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo +5sOASD0Ee/ojL3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl1qnN3e92mI0A +Ds0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oUb3n09tDh05S60FdRvScFDcH9 +yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LVPtateJLbXDzz2K36uGt/xDYotgIVilQsnLAX +c47QN6MUPJiVAAwpBVueSUmxX8fjy88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHo +jhJi6IjMtX9Gl8CbEGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZk +bxqgDMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI+Vg7RE+x +ygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGyYiGqhkCyLmTTX8jjfhFn +RR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bXUB+K+wb1whnw0A== +-----END CERTIFICATE----- + +UCA Extended Validation Root +============================ +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBHMQswCQYDVQQG +EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9u +IFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMxMDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8G +A1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrs +iWogD4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvSsPGP2KxF +Rv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aopO2z6+I9tTcg1367r3CTu +eUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dksHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR +59mzLC52LqGj3n5qiAno8geK+LLNEOfic0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH +0mK1lTnj8/FtDw5lhIpjVMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KR +el7sFsLzKuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/TuDv +B0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41Gsx2VYVdWf6/wFlth +WG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs1+lvK9JKBZP8nm9rZ/+I8U6laUpS +NwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQDfwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS +3H5aBZ8eNJr34RQwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQEL +BQADggIBADaNl8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQVBcZEhrxH9cM +aVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5c6sq1WnIeJEmMX3ixzDx/BR4 +dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb ++7lsq+KePRXBOy5nAliRn+/4Qh8st2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOW +F3sGPjLtx7dCvHaj2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwi +GpWOvpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2CxR9GUeOc +GMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmxcmtpzyKEC2IPrNkZAJSi +djzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbMfjKaiJUINlK73nZfdklJrX+9ZSCyycEr +dhh2n1ax +-----END CERTIFICATE----- + +Certigna Root CA +================ +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAwWjELMAkGA1UE +BhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAwMiA0ODE0NjMwODEwMDAzNjEZ +MBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0xMzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjda +MFoxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYz +MDgxMDAwMzYxGTAXBgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sOty3tRQgX +stmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9MCiBtnyN6tMbaLOQdLNyz +KNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPuI9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8 +JXrJhFwLrN1CTivngqIkicuQstDuI7pmTLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16 +XdG+RCYyKfHx9WzMfgIhC59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq +4NYKpkDfePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3YzIoej +wpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWTCo/1VTp2lc5ZmIoJ +lXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1kJWumIWmbat10TWuXekG9qxf5kBdI +jzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp/ +/TBt2dzhauH8XwIDAQABo4IBGjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczovL3d3d3cuY2Vy +dGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilodHRwOi8vY3JsLmNlcnRpZ25h +LmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYraHR0cDovL2NybC5kaGlteW90aXMuY29tL2Nl +cnRpZ25hcm9vdGNhLmNybDANBgkqhkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOIt +OoldaDgvUSILSo3L6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxP +TGRGHVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH60BGM+RFq +7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncBlA2c5uk5jR+mUYyZDDl3 +4bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdio2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd +8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS +6Cvu5zHbugRqh5jnxV/vfaci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaY +tlu3zM63Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayhjWZS +aX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw3kAP+HwV96LOPNde +E4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- + +emSign Root CA - G1 +=================== +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJJTjET +MBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRl +ZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBHMTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgx +ODMwMDBaMGcxCzAJBgNVBAYTAklOMRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVk +aHJhIFRlY2hub2xvZ2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQzf2N4aLTN +LnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO8oG0x5ZOrRkVUkr+PHB1 +cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aqd7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHW +DV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhMtTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ +6DqS0hdW5TUaQBw+jSztOd9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrH +hQIDAQABo0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQDAgEG +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31xPaOfG1vR2vjTnGs2 +vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjMwiI/aTvFthUvozXGaCocV685743Q +NcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6dGNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q ++Mri/Tm3R7nrft8EI6/6nAYH6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeih +U80Bv2noWgbyRQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- + +emSign ECC Root CA - G3 +======================= +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQGEwJJTjETMBEG +A1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEg +MB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4 +MTgzMDAwWjBrMQswCQYDVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11 +ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0WXTsuwYc +58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xySfvalY8L1X44uT6EYGQIr +MgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuBzhccLikenEhjQjAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+D +CBeQyh+KTOgNG3qxrdWBCUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7 +jHvrZQnD+JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- + +emSign Root CA - C1 +=================== +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkGA1UEBhMCVVMx +EzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNp +Z24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UE +BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQD +ExNlbVNpZ24gUm9vdCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+up +ufGZBczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZHdPIWoU/ +Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH3DspVpNqs8FqOp099cGX +OFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvHGPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4V +I5b2P/AgNBbeCsbEBEV5f6f9vtKppa+cxSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleooms +lMuoaJuvimUnzYnu3Yy1aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+ +XJGFehiqTbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD +ggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87/kOXSTKZEhVb3xEp +/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4kqNPEjE2NuLe/gDEo2APJ62gsIq1 +NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrGYQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9 +wC68AivTxEDkigcxHpvOJpkT+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQ +BmIMMMAVSKeoWXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- + +emSign ECC Root CA - C3 +======================= +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQGEwJVUzETMBEG +A1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMxIDAeBgNVBAMTF2VtU2lnbiBF +Q0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UE +BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQD +ExdlbVNpZ24gRUNDIFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd +6bciMK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4OjavtisIGJAnB9 +SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0OBBYEFPtaSNCAIEDyqOkA +B2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gA +MGUCMQC02C8Cif22TGK6Q04ThHK1rt0c3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwU +ZOR8loMRnLDRWmFLpg9J0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- + +Hongkong Post Root CA 3 +======================= +-----BEGIN CERTIFICATE----- +MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQELBQAwbzELMAkG +A1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJSG9uZyBLb25nMRYwFAYDVQQK +Ew1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25na29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2 +MDMwMjI5NDZaFw00MjA2MDMwMjI5NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtv +bmcxEjAQBgNVBAcTCUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMX +SG9uZ2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz +iNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFOdem1p+/l6TWZ5Mwc50tf +jTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mIVoBc+L0sPOFMV4i707mV78vH9toxdCim +5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOe +sL4jpNrcyCse2m5FHomY2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj +0mRiikKYvLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+TtbNe/ +JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZbx39ri1UbSsUgYT2u +y1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+l2oBlKN8W4UdKjk60FSh0Tlxnf0h ++bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YKTE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsG +xVd7GYYKecsAyVKvQv83j+GjHno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwID +AQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e +i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEwDQYJKoZIhvcN +AQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG7BJ8dNVI0lkUmcDrudHr9Egw +W62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCkMpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWld +y8joRTnU+kLBEUx3XZL7av9YROXrgZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov ++BS5gLNdTaqX4fnkGMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDc +eqFS3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJmOzj/2ZQw +9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+l6mc1X5VTMbeRRAc6uk7 +nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6cJfTzPV4e0hz5sy229zdcxsshTrD3mUcY +hcErulWuBurQB7Lcq9CClnXO0lD+mefPL5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB +60PZ2Pierc+xYw5F9KBaLJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fq +dBb9HxEGmpv0 +-----END CERTIFICATE----- + +Entrust Root Certification Authority - G4 +========================================= +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAwgb4xCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3Qu +bmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1 +dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eSAtIEc0MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYT +AlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3D +umSXbcr3DbVZwbPLqGgZ2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV +3imz/f3ET+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j5pds +8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAMC1rlLAHGVK/XqsEQ +e9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73TDtTUXm6Hnmo9RR3RXRv06QqsYJn7 +ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNXwbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5X +xNMhIWNlUpEbsZmOeX7m640A2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV +7rtNOzK+mndmnqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwlN4y6mACXi0mW +Hv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNjc0kCAwEAAaNCMEAwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9n +MA0GCSqGSIb3DQEBCwUAA4ICAQAS5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4Q +jbRaZIxowLByQzTSGwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht +7LGrhFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/B7NTeLUK +YvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uIAeV8KEsD+UmDfLJ/fOPt +jqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbwH5Lk6rWS02FREAutp9lfx1/cH6NcjKF+ +m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKW +RGhXxNUzzxkvFMSUHHuk2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjA +JOgc47OlIQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk5F6G ++TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuYn/PIjhs4ViFqUZPT +kcpG2om3PVODLAgfi49T3f+sHw== +-----END CERTIFICATE----- + +Microsoft ECC Root Certificate Authority 2017 +============================================= +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQgRUND +IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4 +MjMxNjA0WjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQ +BgcqhkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZRogPZnZH6 +thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYbhGBKia/teQ87zvH2RPUB +eMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIy5lycFIM ++Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlf +Xu5gKcs68tvWMoQZP3zVL8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaR +eNtUjGUBiudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- + +Microsoft RSA Root Certificate Authority 2017 +============================================= +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQg +UlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIw +NzE4MjMwMDIzWjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u +MTYwNAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZNt9GkMml +7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0ZdDMbRnMlfl7rEqUrQ7e +S0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw7 +1VdyvD/IybLeS2v4I2wDwAW9lcfNcztmgGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+ +dkC0zVJhUXAoP8XFWvLJjEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49F +yGcohJUcaDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaGYaRS +MLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6W6IYZVcSn2i51BVr +lMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4KUGsTuqwPN1q3ErWQgR5WrlcihtnJ +0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJ +ClTUFLkqqNfs+avNJVgyeY+QW5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZCLgLNFgVZJ8og +6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OCgMNPOsduET/m4xaRhPtthH80 +dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk ++ONVFT24bcMKpBLBaYVu32TxU5nhSnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex +/2kskZGT4d9Mozd2TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDy +AmH3pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGRxpl/j8nW +ZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiAppGWSZI1b7rCoucL5mxAyE +7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKT +c0QWbej09+CVgI+WXTik9KveCjCHk9hNAHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D +5KbvtwEwXlGjefVwaaZBRA+GsCyRxj3qrg+E +-----END CERTIFICATE----- + +e-Szigno Root CA 2017 +===================== +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNVBAYTAkhVMREw +DwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUt +MjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJvb3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZa +Fw00MjA4MjIxMjA3MDZaMHExCzAJBgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UE +CgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3pp +Z25vIFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtvxie+RJCx +s1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+HWyx7xf58etqjYzBhMA8G +A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSHERUI0arBeAyxr87GyZDv +vzAEwDAfBgNVHSMEGDAWgBSHERUI0arBeAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEA +tVfd14pVCzbhhkT61NlojbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxO +svxyqltZ+efcMQ== +-----END CERTIFICATE----- + +certSIGN Root CA G2 +=================== +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNVBAYTAlJPMRQw +EgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjAeFw0xNzAy +MDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJBgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lH +TiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAMDFdRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05 +N0IwvlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZuIt4Imfk +abBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhpn+Sc8CnTXPnGFiWeI8Mg +wT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKscpc/I1mbySKEwQdPzH/iV8oScLumZfNp +dWO9lfsbl83kqK/20U6o2YpxJM02PbyWxPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91Qqh +ngLjYl/rNUssuHLoPj1PrCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732 +jcZZroiFDsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fxDTvf +95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgyLcsUDFDYg2WD7rlc +z8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6CeWRgKRM+o/1Pcmqr4tTluCRVLERL +iohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1Ud +DgQWBBSCIS1mxteg4BXrzkwJd8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOB +ywaK8SJJ6ejqkX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQlqiCA2ClV9+BB +/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0OJD7uNGzcgbJceaBxXntC6Z5 +8hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+cNywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5 +BiKDUyUM/FHE5r7iOZULJK2v0ZXkltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklW +atKcsWMy5WHgUyIOpwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tU +Sxfj03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZkPuXaTH4M +NMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE1LlSVHJ7liXMvGnjSG4N +0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MXQRBdJ3NghVdJIgc= +-----END CERTIFICATE----- + +Trustwave Global Certification Authority +======================================== +-----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJV +UzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2 +ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTAeFw0xNzA4MjMxOTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJV +UzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2 +ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALldUShLPDeS0YLOvR29 +zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0XznswuvCAAJWX/NKSqIk4cXGIDtiLK0thAf +LdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4Bq +stTnoApTAbqOl5F2brz81Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9o +WN0EACyW80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotPJqX+ +OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1lRtzuzWniTY+HKE40 +Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfwhI0Vcnyh78zyiGG69Gm7DIwLdVcE +uE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm ++9jaJXLE9gCxInm943xZYkqcBW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqj +ifLJS3tBEW1ntwiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1UdDwEB/wQEAwIB +BjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W0OhUKDtkLSGm+J1WE2pIPU/H +PinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfeuyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0H +ZJDmHvUqoai7PF35owgLEQzxPy0QlG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla +4gt5kNdXElE1GYhBaCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5R +vbbEsLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPTMaCm/zjd +zyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qequ5AvzSxnI9O4fKSTx+O +856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxhVicGaeVyQYHTtgGJoC86cnn+OjC/QezH +Yj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu +3R3y4G5OBVixwJAWKqQ9EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP +29FpHOTKyeC2nOnOcXHebD8WpHk= +-----END CERTIFICATE----- + +Trustwave Global ECC P256 Certification Authority +================================================= +-----BEGIN CERTIFICATE----- +MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYDVQQGEwJVUzER +MA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRy +dXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDI1 +NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH77bOYj +43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoNFWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqm +P62jQzBBMA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt +0UrrdaVKEJmzsaGLSvcwCgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjz +RM4q3wghDDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 +-----END CERTIFICATE----- + +Trustwave Global ECC P384 Certification Authority +================================================= +-----BEGIN CERTIFICATE----- +MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYDVQQGEwJVUzER +MA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRy +dXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDM4 +NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuBBAAiA2IABGvaDXU1CDFH +Ba5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJj9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr +/TklZvFe/oyujUF5nQlgziip04pt89ZF1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNV +HQ8BAf8EBQMDBwYAMB0GA1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNn +ADBkAjA3AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsCMGcl +CrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVuSw== +-----END CERTIFICATE----- + +NAVER Global Root Certification Authority +========================================= +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEMBQAwaTELMAkG +A1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRGT1JNIENvcnAuMTIwMAYDVQQD +DClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4 +NDJaFw0zNzA4MTgyMzU5NTlaMGkxCzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVT +UyBQTEFURk9STSBDb3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVAiQqrDZBb +UGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH38dq6SZeWYp34+hInDEW ++j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lEHoSTGEq0n+USZGnQJoViAbbJAh2+g1G7 +XNr4rRVqmfeSVPc0W+m/6imBEtRTkZazkVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2 +aacp+yPOiNgSnABIqKYPszuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4 +Yb8ObtoqvC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHfnZ3z +VHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaGYQ5fG8Ir4ozVu53B +A0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo0es+nPxdGoMuK8u180SdOqcXYZai +cdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3aCJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejy +YhbLgGvtPe31HzClrkvJE+2KAQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNV +HQ4EFgQU0p+I36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoNqo0hV4/GPnrK +21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatjcu3cvuzHV+YwIHHW1xDBE1UB +jCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm+LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bx +hYTeodoS76TiEJd6eN4MUZeoIUCLhr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTg +E34h5prCy8VCZLQelHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTH +D8z7p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8piKCk5XQ +A76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLRLBT/DShycpWbXgnbiUSY +qqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oG +I/hGoiLtk/bdmuYqh7GYVPEi92tF4+KOdh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmg +kpzNNIaRkPpkUZ3+/uul9XXeifdy +-----END CERTIFICATE----- + +AC RAIZ FNMT-RCM SERVIDORES SEGUROS +=================================== +-----BEGIN CERTIFICATE----- +MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQswCQYDVQQGEwJF +UzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgwFgYDVQRhDA9WQVRFUy1RMjgy +NjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1SQ00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4 +MTIyMDA5MzczM1oXDTQzMTIyMDA5MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQt +UkNNMQ4wDAYDVQQLDAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNB +QyBSQUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuBBAAiA2IA +BPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LHsbI6GA60XYyzZl2hNPk2 +LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oKUm8BA06Oi6NCMEAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqG +SM49BAMDA2kAMGYCMQCuSuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoD +zBOQn5ICMQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJyv+c= +-----END CERTIFICATE----- + +GlobalSign Root R46 +=================== +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUAMEYxCzAJBgNV +BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJv +b3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAX +BgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08Es +CVeJOaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQGvGIFAha/ +r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud316HCkD7rRlr+/fKYIje +2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo0q3v84RLHIf8E6M6cqJaESvWJ3En7YEt +bWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSEy132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvj +K8Cd+RTyG/FWaha/LIWFzXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD4 +12lPFzYE+cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCNI/on +ccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzsx2sZy/N78CsHpdls +eVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqaByFrgY/bxFn63iLABJzjqls2k+g9 +vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEM +BQADggIBAHx47PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg +JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti2kM3S+LGteWy +gxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIkpnnpHs6i58FZFZ8d4kuaPp92 +CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRFFRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZm +OUdkLG5NrmJ7v2B0GbhWrJKsFjLtrWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qq +JZ4d16GLuc1CLgSkZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwye +qiv5u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP4vkYxboz +nxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6N3ec592kD3ZDZopD8p/7 +DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3vouXsXgxT7PntgMTzlSdriVZzH81Xwj3 +QEUxeCp6 +-----END CERTIFICATE----- + +GlobalSign Root E46 +=================== +-----BEGIN CERTIFICATE----- +MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYxCzAJBgNVBAYT +AkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJvb3Qg +RTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNV +BAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkB +jtjqR+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGddyXqBPCCj +QjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQxCpCPtsad0kRL +gLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZk +vLtoURMMA/cVi4RguYv/Uo7njLwcAjA8+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+ +CAezNIm8BZ/3Hobui3A= +-----END CERTIFICATE----- + +GLOBALTRUST 2020 +================ +-----BEGIN CERTIFICATE----- +MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkGA1UEBhMCQVQx +IzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVT +VCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYxMDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAh +BgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAy +MDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWi +D59bRatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9ZYybNpyrO +VPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3QWPKzv9pj2gOlTblzLmM +CcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPwyJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCm +fecqQjuCgGOlYx8ZzHyyZqjC0203b+J+BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKA +A1GqtH6qRNdDYfOiaxaJSaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9OR +JitHHmkHr96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj04KlG +DfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9MedKZssCz3AwyIDMvU +clOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIwq7ejMZdnrY8XD2zHc+0klGvIg5rQ +mjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1Ud +IwQYMBaAFNwuH9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA +VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJCXtzoRlgHNQIw +4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd6IwPS3BD0IL/qMy/pJTAvoe9 +iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS +8cE54+X1+NZK3TTN+2/BT+MAi1bikvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2 +HcqtbepBEX4tdJP7wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxS +vTOBTI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6CMUO+1918 +oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn4rnvyOL2NSl6dPrFf4IF +YqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+IaFvowdlxfv1k7/9nR4hYJS8+hge9+6jl +gqispdNpQ80xiEmEU5LAsTkbOYMBMMTyqfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg== +-----END CERTIFICATE----- + +ANF Secure Server Root CA +========================= +-----BEGIN CERTIFICATE----- +MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNVBAUTCUc2MzI4 +NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lv +bjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNVBAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3Qg +Q0EwHhcNMTkwOTA0MTAwMDM4WhcNMzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEw +MQswCQYDVQQGEwJFUzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQw +EgYDVQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9vdCBDQTCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCjcqQZAZ2cC4Ffc0m6p6zz +BE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9qyGFOtibBTI3/TO80sh9l2Ll49a2pcbnv +T1gdpd50IJeh7WhM3pIXS7yr/2WanvtH2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcv +B2VSAKduyK9o7PQUlrZXH1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXse +zx76W0OLzc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyRp1RM +VwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQzW7i1o0TJrH93PB0j +7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/SiOL9V8BY9KHcyi1Swr1+KuCLH5z +JTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJnLNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe +8TZBAQIvfXOn3kLMTOmJDVb3n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVO +Hj1tyRRM4y5Bu8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj +o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAOBgNVHQ8BAf8E +BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEATh65isagmD9uw2nAalxJ +UqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzx +j6ptBZNscsdW699QIyjlRRA96Gejrw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDt +dD+4E5UGUcjohybKpFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM +5gf0vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjqOknkJjCb +5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ/zo1PqVUSlJZS2Db7v54 +EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ92zg/LFis6ELhDtjTO0wugumDLmsx2d1H +hk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI+PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGy +g77FGr8H6lnco4g175x2MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3 +r5+qPeoott7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw= +-----END CERTIFICATE----- + +Certum EC-384 CA +================ +-----BEGIN CERTIFICATE----- +MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQswCQYDVQQGEwJQ +TDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2 +MDcyNDU0WhcNNDMwMzI2MDcyNDU0WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERh +dGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx +GTAXBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATEKI6rGFtq +vm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7TmFy8as10CW4kjPMIRBSqn +iBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68KjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFI0GZnQkdjrzife81r1HfS+8EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNo +ADBlAjADVS2m5hjEfO/JUG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0 +QoSZ/6vnnvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= +-----END CERTIFICATE----- + +Certum Trusted Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6MQswCQYDVQQG +EwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0g +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0Ew +HhcNMTgwMzE2MTIxMDEzWhcNNDMwMzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMY +QXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZn0EGze2jusDbCSzBfN8p +fktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/qp1x4EaTByIVcJdPTsuclzxFUl6s1wB52 +HO8AU5853BSlLCIls3Jy/I2z5T4IHhQqNwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2 +fJmItdUDmj0VDT06qKhF8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGt +g/BKEiJ3HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGamqi4 +NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi7VdNIuJGmj8PkTQk +fVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSFytKAQd8FqKPVhJBPC/PgP5sZ0jeJ +P/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0PqafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSY +njYJdmZm/Bo/6khUHL4wvYBQv3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHK +HRzQ+8S1h9E6Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1 +vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQADggIBAEii1QAL +LtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4WxmB82M+w85bj/UvXgF2Ez8s +ALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvozMrnadyHncI013nR03e4qllY/p0m+jiGPp2K +h2RX5Rc64vmNueMzeMGQ2Ljdt4NR5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8 +CYyqOhNf6DR5UMEQGfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA +4kZf5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq0Uc9Nneo +WWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7DP78v3DSk+yshzWePS/Tj +6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTMqJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmT +OPQD8rv7gmsHINFSH5pkAnuYZttcTVoP0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZck +bxJF0WddCajJFdr60qZfE2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb +-----END CERTIFICATE----- + +TunTrust Root CA +================ +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQELBQAwYTELMAkG +A1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUgQ2VydGlmaWNhdGlvbiBFbGVj +dHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJvb3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQw +NDI2MDg1NzU2WjBhMQswCQYDVQQGEwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBD +ZXJ0aWZpY2F0aW9uIEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZn56eY+hz +2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd2JQDoOw05TDENX37Jk0b +bjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgFVwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7 +NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZGoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAd +gjH8KcwAWJeRTIAAHDOFli/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViW +VSHbhlnUr8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2eY8f +Tpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIbMlEsPvLfe/ZdeikZ +juXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISgjwBUFfyRbVinljvrS5YnzWuioYas +DXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwS +VXAkPcvCFDVDXSdOvsC9qnyW5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI +04Y+oXNZtPdEITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 +90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+zxiD2BkewhpMl +0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYuQEkHDVneixCwSQXi/5E/S7fd +Ao74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRY +YdZ2vyJ/0Adqp2RT8JeNnYA/u8EH22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJp +adbGNjHh/PqAulxPxOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65x +xBzndFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5Xc0yGYuP +jCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7bnV2UqL1g52KAdoGDDIzM +MEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQCvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9z +ZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZHu/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3r +AZ3r2OvEhJn7wAzMMujjd9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= +-----END CERTIFICATE----- + +HARICA TLS RSA Root CA 2021 +=========================== +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQG +EwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u +cyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0EgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUz +OFoXDTQ1MDIxMzEwNTUzN1owbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRl +bWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNB +IFJvb3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569lmwVnlskN +JLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE4VGC/6zStGndLuwRo0Xu +a2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uva9of08WRiFukiZLRgeaMOVig1mlDqa2Y +Ulhu2wr7a89o+uOkXjpFc5gH6l8Cct4MpbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K +5FrZx40d/JiZ+yykgmvwKh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEv +dmn8kN3bLW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcYAuUR +0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqBAGMUuTNe3QvboEUH +GjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYqE613TBoYm5EPWNgGVMWX+Ko/IIqm +haZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHrW2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQ +CPxrvrNQKlr9qEgYRtaQQJKQCoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAUX15QvWiWkKQU +EapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3f5Z2EMVGpdAgS1D0NTsY9FVq +QRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxajaH6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxD +QpSbIPDRzbLrLFPCU3hKTwSUQZqPJzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcR +j88YxeMn/ibvBZ3PzzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5 +vZStjBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0/L5H9MG0 +qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pTBGIBnfHAT+7hOtSLIBD6 +Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79aPib8qXPMThcFarmlwDB31qlpzmq6YR/ +PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YWxw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnn +kf3/W9b3raYvAwtt41dU63ZTGI0RmLo= +-----END CERTIFICATE----- + +HARICA TLS ECC Root CA 2021 +=========================== +-----BEGIN CERTIFICATE----- +MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQswCQYDVQQGEwJH +UjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBD +QTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoX +DTQ1MDIxMzExMDEwOVowbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWlj +IGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJv +b3QgQ0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7KKrxcm1l +AEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9YSTHMmE5gEYd103KUkE+b +ECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW +0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAi +rcJRQO9gcS3ujwLEXQNwSaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/Qw +CZ61IygNnxS2PFOiTAZpffpskcYqSUXm7LcT4Tps +-----END CERTIFICATE----- + +Autoridad de Certificacion Firmaprofesional CIF A62634068 +========================================================= +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCRVMxQjBA +BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIw +QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB +NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD +Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P +B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY +7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH +ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI +plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX +MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX +LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK +bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU +vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1Ud +DgQWBBRlzeurNR4APn7VdMActHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4w +gZswgZgGBFUdIAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j +b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABCAG8AbgBhAG4A +bwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAwADEANzAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9miWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL +4QjbEwj4KKE1soCzC1HA01aajTNFSa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDb +LIpgD7dvlAceHabJhfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1il +I45PVf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZEEAEeiGaP +cjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV1aUsIC+nmCjuRfzxuIgA +LI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2tCsvMo2ebKHTEm9caPARYpoKdrcd7b/+A +lun4jWq9GJAd/0kakFI3ky88Al2CdgtR5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH +9IBk9W6VULgRfhVwOEqwf9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpf +NIbnYrX9ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNKGbqE +ZycPvEJdvSRUDewdcAZfpLz6IHxV +-----END CERTIFICATE----- + +vTrus ECC Root CA +================= +-----BEGIN CERTIFICATE----- +MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMwRzELMAkGA1UE +BhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBS +b290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDczMTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAa +BgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYw +EAYHKoZIzj0CAQYFK4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+c +ToL0v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUde4BdS49n +TPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIwV53dVvHH4+m4SVBrm2nDb+zDfSXkV5UT +QJtS0zvzQBm8JsctBp61ezaf9SXUY2sAAjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQL +YgmRWAD5Tfs0aNoJrSEGGJTO +-----END CERTIFICATE----- + +vTrus Root CA +============= +-----BEGIN CERTIFICATE----- +MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQELBQAwQzELMAkG +A1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xFjAUBgNVBAMTDXZUcnVzIFJv +b3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMxMDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoG +A1UEChMTaVRydXNDaGluYSBDby4sTHRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZots +SKYcIrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykUAyyNJJrI +ZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+GrPSbcKvdmaVayqwlHeF +XgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z98Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KA +YPxMvDVTAWqXcoKv8R1w6Jz1717CbMdHflqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70 +kLJrxLT5ZOrpGgrIDajtJ8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2 +AXPKBlim0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZNpGvu +/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQUqqzApVg+QxMaPnu +1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHWOXSuTEGC2/KmSNGzm/MzqvOmwMVO +9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMBAAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYg +scasGrz2iTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOC +AgEAKbqSSaet8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd +nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1jbhd47F18iMjr +jld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvMKar5CKXiNxTKsbhm7xqC5PD4 +8acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIivTDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJn +xDHO2zTlJQNgJXtxmOTAGytfdELSS8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554Wg +icEFOwE30z9J4nfrI8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4 +sEb9b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNBUvupLnKW +nyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1PTi07NEPhmg4NpGaXutIc +SkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929vensBxXVsFy6K2ir40zSbofitzmdHxghm+H +l3s= +-----END CERTIFICATE----- + +ISRG Root X2 +============ +-----BEGIN CERTIFICATE----- +MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQswCQYDVQQGEwJV +UzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElT +UkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVT +MSkwJwYDVQQKEyBJbnRlcm5ldCBTZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNS +RyBSb290IFgyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0H +ttwW+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9ItgKbppb +d9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZIzj0EAwMDaAAwZQIwe3lORlCEwkSHRhtF +cP9Ymd70/aTSVaYgLXTWNLxBo1BfASdWtL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5 +U6VR5CmD1/iQMVtCnwr1/q4AaOeMSQ+2b1tbFfLn +-----END CERTIFICATE----- + +HiPKI Root CA - G1 +================== +-----BEGIN CERTIFICATE----- +MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQG +EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xGzAZBgNVBAMMEkhpUEtJ +IFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRaFw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYT +AlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kg +Um9vdCBDQSAtIEcxMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0 +o9QwqNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twvVcg3Px+k +wJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6lZgRZq2XNdZ1AYDgr/SE +YYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnzQs7ZngyzsHeXZJzA9KMuH5UHsBffMNsA +GJZMoYFL3QRtU6M9/Aes1MU3guvklQgZKILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfd +hSi8MEyr48KxRURHH+CKFgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj +1jOXTyFjHluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDry+K4 +9a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ/W3c1pzAtH2lsN0/ +Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgMa/aOEmem8rJY5AIJEzypuxC00jBF +8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQD +AgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi +7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqcSE5XCV0vrPSl +tJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6FzaZsT0pPBWGTMpWmWSBUdGSquE +wx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9TcXzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07Q +JNBAsNB1CI69aO4I1258EHBGG3zgiLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv +5wiZqAxeJoBF1PhoL5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+Gpz +jLrFNe85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wrkkVbbiVg +hUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+vhV4nYWBSipX3tUZQ9rb +yltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQUYDksswBVLuT1sw5XxJFBAJw/6KXf6vb/ +yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R4 +=========================== +-----BEGIN CERTIFICATE----- +MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYDVQQLExtHbG9i +YWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds +b2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgwMTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9i +YWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds +b2JhbFNpZ24wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkW +ymOxuYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNVHQ8BAf8E +BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/+wpu+74zyTyjhNUwCgYI +KoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147bmF0774BxL4YSFlhgjICICadVGNA3jdg +UM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm +-----END CERTIFICATE----- + +GTS Root R1 +=========== +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQGEwJV +UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg +UjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE +ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM +f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7wCl7raKb0 +xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjwTcLCeoiKu7rPWRnWr4+w +B7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0PfyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXW +nOunVmSPlk9orj2XwoSPwLxAwAtcvfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk +9+aCEI3oncKKiPo4Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zq +kUspzBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92wO1A +K/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70paDPvOmbsB4om3xPX +V2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDW +cfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQAD +ggIBAJ+qQibbC5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuyh6f88/qBVRRi +ClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM47HLwEXWdyzRSjeZ2axfG34ar +J45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8JZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYci +NuaCp+0KueIHoI17eko8cdLiA6EfMgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5me +LMFrUKTX5hgUvYU/Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJF +fbdT6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ0E6yove+ +7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm2tIMPNuzjsmhDYAPexZ3 +FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bbbP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3 +gm3c +-----END CERTIFICATE----- + +GTS Root R2 +=========== +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQGEwJV +UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg +UjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE +ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv +CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY6Dlo7JUl +e3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAuMC6C/Pq8tBcKSOWIm8Wb +a96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS ++LFjKBC4swm4VndAoiaYecb+3yXuPuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7M +kogwTZq9TwtImoS1mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJG +r61K8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RWIr9q +S34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKaG73VululycslaVNV +J1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCqgc7dGtxRcw1PcOnlthYhGXmy5okL +dWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQAD +ggIBAB/Kzt3HvqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8 +0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyCB19m3H0Q/gxh +swWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2uNmSRXbBoGOqKYcl3qJfEycel +/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMgyALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVn +jWQye+mew4K6Ki3pHrTgSAai/GevHyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y5 +9PYjJbigapordwj6xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M +7YNRTOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924SgJPFI/2R8 +0L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV7LXTWtiBmelDGDfrs7vR +WGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjW +HYbL +-----END CERTIFICATE----- + +GTS Root R3 +=========== +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJVUzEi +MCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMw +HhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZ +R29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjO +PQIBBgUrgQQAIgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout +736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL24CejQjBA +MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTB8Sa6oC2uhYHP0/Eq +Er24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azT +L818+FsuVbu/3ZL3pAzcMeGiAjEA/JdmZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV +11RZt+cRLInUue4X +-----END CERTIFICATE----- + +GTS Root R4 +=========== +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJVUzEi +MCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQw +HhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZ +R29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjO +PQIBBgUrgQQAIgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu +hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvRHYqjQjBA +MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSATNbrdP9JNqPV2Py1 +PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/C +r8deVl5c1RxYIigL9zC2L7F8AjEA8GE8p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh +4rsUecrNIdSUtUlD +-----END CERTIFICATE----- + +Telia Root CA v2 +================ +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQxCzAJBgNVBAYT +AkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2 +MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQK +DBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ7 +6zBqAMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9vVYiQJ3q +9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9lRdU2HhE8Qx3FZLgmEKn +pNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTODn3WhUidhOPFZPY5Q4L15POdslv5e2QJl +tI5c0BE0312/UqeBAMN/mUWZFdUXyApT7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW +5olWK8jjfN7j/4nlNW4o6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNr +RBH0pUPCTEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6WT0E +BXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63RDolUK5X6wK0dmBR4 +M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZIpEYslOqodmJHixBTB0hXbOKSTbau +BcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGjYzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7W +xy+G2CQ5MB0GA1UdDgQWBBRyrOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ +8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi0f6X+J8wfBj5 +tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMMA8iZGok1GTzTyVR8qPAs5m4H +eW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBSSRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+C +y748fdHif64W1lZYudogsYMVoe+KTTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygC +QMez2P2ccGrGKMOF6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15 +h2Er3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMtTy3EHD70 +sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pTVmBds9hCG1xLEooc6+t9 +xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAWysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQ +raVplI/owd8k+BsHMYeB2F326CjYSlKArBPuUBQemMc= +-----END CERTIFICATE----- + +D-TRUST BR Root CA 1 2020 +========================= +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQswCQYDVQQGEwJE +RTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEJSIFJvb3QgQ0EgMSAy +MDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNV +BAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7 +dPYSzuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0QVK5buXu +QqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/VbNafAkl1bK6CKBrqx9t +MA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6gPKA6hjhodHRwOi8vY3JsLmQtdHJ1c3Qu +bmV0L2NybC9kLXRydXN0X2JyX3Jvb3RfY2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxP +PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjOPQQD +AwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFWwKrY7RjEsK70Pvom +AjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHVdWNbFJWcHwHP2NVypw87 +-----END CERTIFICATE----- + +D-TRUST EV Root CA 1 2020 +========================= +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQswCQYDVQQGEwJE +RTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEVWIFJvb3QgQ0EgMSAy +MDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNV +BAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8 +ZRCC/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rDwpdhQntJ +raOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3OqQo5FD4pPfsazK2/umL +MA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6gPKA6hjhodHRwOi8vY3JsLmQtdHJ1c3Qu +bmV0L2NybC9kLXRydXN0X2V2X3Jvb3RfY2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxP +PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjOPQQD +AwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CAy/m0sRtW9XLS/BnR +AjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJbgfM0agPnIjhQW+0ZT0MW +-----END CERTIFICATE----- + +DigiCert TLS ECC P384 Root G5 +============================= +-----BEGIN CERTIFICATE----- +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURpZ2lDZXJ0IFRMUyBFQ0MgUDM4 +NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQg +Um9vdCBHNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1Tzvd +lHJS7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp0zVozptj +n4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICISB4CIfBFqMA4GA1UdDwEB +/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQCJao1H5+z8blUD2Wds +Jk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQLgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIx +AJSdYsiJvRmEFOml+wG4DXZDjC5Ty3zfDBeWUA== +-----END CERTIFICATE----- + +DigiCert TLS RSA4096 Root G5 +============================ +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBNMQswCQYDVQQG +EwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0 +MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcNNDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2 +IFJvb3QgRzUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS8 +7IE+ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG02C+JFvuU +AT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgpwgscONyfMXdcvyej/Ces +tyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZMpG2T6T867jp8nVid9E6P/DsjyG244gXa +zOvswzH016cpVIDPRFtMbzCe88zdH5RDnU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnV +DdXifBBiqmvwPXbzP6PosMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9q +TXeXAaDxZre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cdLvvy +z6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvXKyY//SovcfXWJL5/ +MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNeXoVPzthwiHvOAbWWl9fNff2C+MIk +wcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPLtgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4E +FgQUUTMc7TZArxfTJc1paPKvTiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7HPNtQOa27PShN +lnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLFO4uJ+DQtpBflF+aZfTCIITfN +MBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQREtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/ +u4cnYiWB39yhL/btp/96j1EuMPikAdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9G +OUrYU9DzLjtxpdRv/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh +47a+p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilwMUc/dNAU +FvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WFqUITVuwhd4GTWgzqltlJ +yqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCKovfepEWFJqgejF0pW8hL2JpqA15w8oVP +bEtoL8pU9ozaMv7Da4M/OMZ+ +-----END CERTIFICATE----- + +Certainly Root R1 +================= +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAwPTELMAkGA1UE +BhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2VydGFpbmx5IFJvb3QgUjEwHhcN +MjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2Vy +dGFpbmx5MRowGAYDVQQDExFDZXJ0YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBANA21B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O +5MQTvqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbedaFySpvXl +8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b01C7jcvk2xusVtyWMOvwl +DbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGI +XsXwClTNSaa/ApzSRKft43jvRl5tcdF5cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkN +KPl6I7ENPT2a/Z2B7yyQwHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQ +AjeZjOVJ6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA2Cnb +rlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyHWyf5QBGenDPBt+U1 +VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMReiFPCyEQtkA6qyI6BJyLm4SGcprS +p6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBTgqj8ljZ9EXME66C6ud0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAsz +HQNTVfSVcOQrPbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d +8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi1wrykXprOQ4v +MMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrdrRT90+7iIgXr0PK3aBLXWopB +GsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9ditaY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+ +gjwN/KUD+nsa2UUeYNrEjvn8K8l7lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgH +JBu6haEaBQmAupVjyTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7 +fpYnKx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLyyCwzk5Iw +x06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5nwXARPbv0+Em34yaXOp/S +X3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6OV+KmalBWQewLK8= +-----END CERTIFICATE----- + +Certainly Root E1 +================= +-----BEGIN CERTIFICATE----- +MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQswCQYDVQQGEwJV +UzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlubHkgUm9vdCBFMTAeFw0yMTA0 +MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJBgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlu +bHkxGjAYBgNVBAMTEUNlcnRhaW5seSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4 +fxzf7flHh4axpMCK+IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9 +YBk2QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4hevIIgcwCgYIKoZIzj0E +AwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozmut6Dacpps6kFtZaSF4fC0urQe87YQVt8 +rgIwRt7qy12a7DLCZRawTDBcMPPaTnOGBtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR +-----END CERTIFICATE----- + +Security Communication RootCA3 +============================== +-----BEGIN CERTIFICATE----- +MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNVBAYTAkpQMSUw +IwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScwJQYDVQQDEx5TZWN1cml0eSBD +b21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQsw +CQYDVQQGEwJKUDElMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UE +AxMeU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4rCmDvu20r +hvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzAlrenfna84xtSGc4RHwsE +NPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MGTfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2 +/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF79+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGm +npjKIG58u4iFW/vAEGK78vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtY +XLVqAvO4g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3weGVPK +p7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst+3A7caoreyYn8xrC +3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M0V9hvqG8OmpI6iZVIhZdXw3/JzOf +GAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQT9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0Vcw +CBEF/VfR2ccCAwEAAaNCMEAwHQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS +YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PAFNr0Y/Dq9HHu +Tofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd9XbXv8S2gVj/yP9kaWJ5rW4O +H3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQIUYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASx +YfQAW0q3nHE3GYV5v4GwxxMOdnE+OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZ +XSEIx2C/pHF7uNkegr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml ++LLfiAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUVnuiZIesn +KwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD2NCcnWXL0CsnMQMeNuE9 +dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI//1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm +6Vwdp6POXiUyK+OVrCoHzrQoeIY8LaadTdJ0MN1kURXbg4NR16/9M51NZg== +-----END CERTIFICATE----- + +Security Communication ECC RootCA1 +================================== +-----BEGIN CERTIFICATE----- +MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYTAkpQMSUwIwYD +VQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYDVQQDEyJTZWN1cml0eSBDb21t +dW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYxNjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTEL +MAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNV +BAMTIlNlY3VyaXR5IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+CnnfdldB9sELLo +5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpKULGjQjBAMB0GA1UdDgQW +BBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAK +BggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3L +snNdo4gIxwwCMQDAqy0Obe0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70e +N9k= +-----END CERTIFICATE----- + +BJCA Global Root CA1 +==================== +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQG +EwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJK +Q0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAzMTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkG +A1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQD +DBRCSkNBIEdsb2JhbCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFm +CL3ZxRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZspDyRhyS +sTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O558dnJCNPYwpj9mZ9S1Wn +P3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgRat7GGPZHOiJBhyL8xIkoVNiMpTAK+BcW +yqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRj +eulumijWML3mG90Vr4TqnMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNn +MoH1V6XKV0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/pj+b +OT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZOz2nxbkRs1CTqjSSh +GL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXnjSXWgXSHRtQpdaJCbPdzied9v3pK +H9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMB +AAGjQjBAMB0GA1UdDgQWBBTF7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 +YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3KliawLwQ8hOnThJ +dMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u+2D2/VnGKhs/I0qUJDAnyIm8 +60Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuh +TaRjAv04l5U/BXCga99igUOLtFkNSoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW +4AB+dAb/OMRyHdOoP2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmp +GQrI+pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRzznfSxqxx +4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9eVzYH6Eze9mCUAyTF6ps +3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4S +SPfSKcOYKMryMguTjClPPGAyzQWWYezyr/6zcCwupvI= +-----END CERTIFICATE----- + +BJCA Global Root CA2 +==================== +-----BEGIN CERTIFICATE----- +MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQswCQYDVQQGEwJD +TjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJKQ0Eg +R2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgyMVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UE +BhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRC +SkNBIEdsb2JhbCBSb290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jl +SR9BIgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK++kpRuDCK +/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJKsVF/BvDRgh9Obl+rg/xI +1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8 +W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8g +UXOQwKhbYdDFUDn9hf7B43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== +-----END CERTIFICATE----- + +Sectigo Public Server Authentication Root E46 +============================================= +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQswCQYDVQQGEwJH +QjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBTZXJ2 +ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5 +WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0 +aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUr +gQQAIgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccCWvkEN/U0 +NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+6xnOQ6OjQjBAMB0GA1Ud +DgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAKBggqhkjOPQQDAwNnADBkAjAn7qRaqCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RH +lAFWovgzJQxC36oCMB3q4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21U +SAGKcw== +-----END CERTIFICATE----- + +Sectigo Public Server Authentication Root R46 +============================================= +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBfMQswCQYDVQQG +EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1 +OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3 +DQEBAQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDaef0rty2k +1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnzSDBh+oF8HqcIStw+Kxwf +GExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xfiOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMP +FF1bFOdLvt30yNoDN9HWOaEhUTCDsG3XME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vu +ZDCQOc2TZYEhMbUjUDM3IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5Qaz +Yw6A3OASVYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgESJ/A +wSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu+Zd4KKTIRJLpfSYF +plhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt8uaZFURww3y8nDnAtOFr94MlI1fZ +EoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+LHaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW +6aWWrL3DkJiy4Pmi1KZHQ3xtzwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWI +IUkwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQYKlJfp/imTYp +E0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52gDY9hAaLMyZlbcp+nv4fjFg4 +exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZAFv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M +0ejf5lG5Nkc/kLnHvALcWxxPDkjBJYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI +84HxZmduTILA7rpXDhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9m +pFuiTdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5dHn5Hrwd +Vw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65LvKRRFHQV80MNNVIIb/b +E/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmm +J1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAYQqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- + +SSL.com TLS RSA Root CA 2022 +============================ +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQG +EwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBSU0Eg +Um9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloXDTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMC +VVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJv +b3QgQ0EgMjAyMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u +9nTPL3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OYt6/wNr/y +7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0insS657Lb85/bRi3pZ7Qcac +oOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3PnxEX4MN8/HdIGkWCVDi1FW24IBydm5M +R7d1VVm0U3TZlMZBrViKMWYPHqIbKUBOL9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDG +D6C1vBdOSHtRwvzpXGk3R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEW +TO6Af77wdr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS+YCk +8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYSd66UNHsef8JmAOSq +g+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoGAtUjHBPW6dvbxrB6y3snm/vg1UYk +7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2fgTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsu +N+7jhHonLs0ZNbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt +hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsMQtfhWsSWTVTN +j8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvfR4iyrT7gJ4eLSYwfqUdYe5by +iB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJDPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjU +o3KUQyxi4U5cMj29TH0ZR6LDSeeWP4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqo +ENjwuSfr98t67wVylrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7Egkaib +MOlqbLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2wAgDHbICi +vRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3qr5nsLFR+jM4uElZI7xc7 +P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sjiMho6/4UIyYOf8kpIEFR3N+2ivEC+5BB0 +9+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= +-----END CERTIFICATE----- + +SSL.com TLS ECC Root CA 2022 +============================ +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQswCQYDVQQGEwJV +UzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBFQ0MgUm9v +dCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMx +GDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3Qg +Q0EgMjAyMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWy +JGYmacCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFNSeR7T5v1 +5wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSJjy+j6CugFFR7 +81a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NWuCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGG +MAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w +7deedWo1dlJF4AIxAMeNb0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5 +Zn6g6g== +-----END CERTIFICATE----- + +Atos TrustedRoot Root CA ECC TLS 2021 +===================================== +-----BEGIN CERTIFICATE----- +MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4wLAYDVQQDDCVB +dG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9zMQswCQYD +VQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3Mg +VHJ1c3RlZFJvb3QgUm9vdCBDQSBFQ0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYT +AkRFMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6K +DP/XtXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4AjJn8ZQS +b+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2KCXWfeBmmnoJsmo7jjPX +NtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMDaAAwZQIwW5kp85wxtolrbNa9d+F851F+ +uDrNozZffPc8dz7kUK2o59JZDCaOMDtuCCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGY +a3cpetskz2VAv9LcjBHo9H1/IISpQuQo +-----END CERTIFICATE----- + +Atos TrustedRoot Root CA RSA TLS 2021 +===================================== +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBMMS4wLAYDVQQD +DCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9zMQsw +CQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0 +b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNV +BAYTAkRFMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BB +l01Z4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYvYe+W/CBG +vevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZkmGbzSoXfduP9LVq6hdK +ZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDsGY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt +0xU6kGpn8bRrZtkh68rZYnxGEFzedUlnnkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVK +PNe0OwANwI8f4UDErmwh3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMY +sluMWuPD0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzygeBY +Br3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8ANSbhqRAvNncTFd+ +rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezBc6eUWsuSZIKmAMFwoW4sKeFYV+xa +fJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lIpw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUdEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0G +CSqGSIb3DQEBDAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS +4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPso0UvFJ/1TCpl +Q3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJqM7F78PRreBrAwA0JrRUITWX +AdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuywxfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9G +slA9hGCZcbUztVdF5kJHdWoOsAgMrr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2Vkt +afcxBPTy+av5EzH4AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9q +TFsR0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuYo7Ey7Nmj +1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5dDTedk+SKlOxJTnbPP/l +PqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcEoji2jbDwN/zIIX8/syQbPYtuzE2wFg2W +HYMfRsCbvUOZ58SWLs5fyQ== +-----END CERTIFICATE----- + +TrustAsia Global Root CA G3 +=========================== +-----BEGIN CERTIFICATE----- +MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEMBQAwWjELMAkG +A1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xJDAiBgNVBAMM +G1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAeFw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEw +MTlaMFoxCzAJBgNVBAYTAkNOMSUwIwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMu +MSQwIgYDVQQDDBtUcnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNST1QY4Sxz +lZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqKAtCWHwDNBSHvBm3dIZwZ +Q0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/V +P68czH5GX6zfZBCK70bwkPAPLfSIC7Epqq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1Ag +dB4SQXMeJNnKziyhWTXAyB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm +9WAPzJMshH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gXzhqc +D0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAvkV34PmVACxmZySYg +WmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msTf9FkPz2ccEblooV7WIQn3MSAPmea +mseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jAuPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCF +TIcQcf+eQxuulXUtgQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj +7zjKsK5Xf/IhMBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E +BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4wM8zAQLpw6o1 +D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2XFNFV1pF1AWZLy4jVe5jaN/T +G3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNj +duMNhXJEIlU/HHzp/LgV6FL6qj6jITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstl +cHboCoWASzY9M/eVVHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys ++TIxxHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1onAX1daBli +2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d7XB4tmBZrOFdRWOPyN9y +aFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2NtjjgKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsAS +ZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV+Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFR +JQJ6+N1rZdVtTTDIZbpoFGWsJwt0ivKH +-----END CERTIFICATE----- + +TrustAsia Global Root CA G4 +=========================== +-----BEGIN CERTIFICATE----- +MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMwWjELMAkGA1UE +BhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xJDAiBgNVBAMMG1Ry +dXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0yMTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJa +MFoxCzAJBgNVBAYTAkNOMSUwIwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQw +IgYDVQQDDBtUcnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AATxs8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbwLxYI+hW8 +m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJijYzBhMA8GA1UdEwEB/wQF +MAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mDpm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/ +pDHel4NZg6ZvccveMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AA +bbd+NvBNEU/zy4k6LHiRUKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xk +dUfFVZDj/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA== +-----END CERTIFICATE----- + +CommScope Public Trust ECC Root-01 +================================== +-----BEGIN CERTIFICATE----- +MIICHTCCAaOgAwIBAgIUQ3CCd89NXTTxyq4yLzf39H91oJ4wCgYIKoZIzj0EAwMwTjELMAkGA1UE +BhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBUcnVz +dCBFQ0MgUm9vdC0wMTAeFw0yMTA0MjgxNzM1NDNaFw00NjA0MjgxNzM1NDJaME4xCzAJBgNVBAYT +AlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3Qg +RUNDIFJvb3QtMDEwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARLNumuV16ocNfQj3Rid8NeeqrltqLx +eP0CflfdkXmcbLlSiFS8LwS+uM32ENEp7LXQoMPwiXAZu1FlxUOcw5tjnSCDPgYLpkJEhRGnSjot +6dZoL0hOUysHP029uax3OVejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSOB2LAUN3GGQYARnQE9/OufXVNMDAKBggqhkjOPQQDAwNoADBlAjEAnDPfQeMjqEI2 +Jpc1XHvr20v4qotzVRVcrHgpD7oh2MSg2NED3W3ROT3Ek2DS43KyAjB8xX6I01D1HiXo+k515liW +pDVfG2XqYZpwI7UNo5uSUm9poIyNStDuiw7LR47QjRE= +-----END CERTIFICATE----- + +CommScope Public Trust ECC Root-02 +================================== +-----BEGIN CERTIFICATE----- +MIICHDCCAaOgAwIBAgIUKP2ZYEFHpgE6yhR7H+/5aAiDXX0wCgYIKoZIzj0EAwMwTjELMAkGA1UE +BhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBUcnVz +dCBFQ0MgUm9vdC0wMjAeFw0yMTA0MjgxNzQ0NTRaFw00NjA0MjgxNzQ0NTNaME4xCzAJBgNVBAYT +AlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3Qg +RUNDIFJvb3QtMDIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAR4MIHoYx7l63FRD/cHB8o5mXxO1Q/M +MDALj2aTPs+9xYa9+bG3tD60B8jzljHz7aRP+KNOjSkVWLjVb3/ubCK1sK9IRQq9qEmUv4RDsNuE +SgMjGWdqb8FuvAY5N9GIIvejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTmGHX/72DehKT1RsfeSlXjMjZ59TAKBggqhkjOPQQDAwNnADBkAjAmc0l6tqvmSfR9 +Uj/UQQSugEODZXW5hYA4O9Zv5JOGq4/nich/m35rChJVYaoR4HkCMHfoMXGsPHED1oQmHhS48zs7 +3u1Z/GtMMH9ZzkXpc2AVmkzw5l4lIhVtwodZ0LKOag== +-----END CERTIFICATE----- + +CommScope Public Trust RSA Root-01 +================================== +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIUPgNJgXUWdDGOTKvVxZAplsU5EN0wDQYJKoZIhvcNAQELBQAwTjELMAkG +A1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBU +cnVzdCBSU0EgUm9vdC0wMTAeFw0yMTA0MjgxNjQ1NTRaFw00NjA0MjgxNjQ1NTNaME4xCzAJBgNV +BAYTAlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1 +c3QgUlNBIFJvb3QtMDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwSGWjDR1C45Ft +nYSkYZYSwu3D2iM0GXb26v1VWvZVAVMP8syMl0+5UMuzAURWlv2bKOx7dAvnQmtVzslhsuitQDy6 +uUEKBU8bJoWPQ7VAtYXR1HHcg0Hz9kXHgKKEUJdGzqAMxGBWBB0HW0alDrJLpA6lfO741GIDuZNq +ihS4cPgugkY4Iw50x2tBt9Apo52AsH53k2NC+zSDO3OjWiE260f6GBfZumbCk6SP/F2krfxQapWs +vCQz0b2If4b19bJzKo98rwjyGpg/qYFlP8GMicWWMJoKz/TUyDTtnS+8jTiGU+6Xn6myY5QXjQ/c +Zip8UlF1y5mO6D1cv547KI2DAg+pn3LiLCuz3GaXAEDQpFSOm117RTYm1nJD68/A6g3czhLmfTif +BSeolz7pUcZsBSjBAg/pGG3svZwG1KdJ9FQFa2ww8esD1eo9anbCyxooSU1/ZOD6K9pzg4H/kQO9 +lLvkuI6cMmPNn7togbGEW682v3fuHX/3SZtS7NJ3Wn2RnU3COS3kuoL4b/JOHg9O5j9ZpSPcPYeo +KFgo0fEbNttPxP/hjFtyjMcmAyejOQoBqsCyMWCDIqFPEgkBEa801M/XrmLTBQe0MXXgDW1XT2mH ++VepuhX2yFJtocucH+X8eKg1mp9BFM6ltM6UCBwJrVbl2rZJmkrqYxhTnCwuwwIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUN12mmnQywsL5x6YVEFm4 +5P3luG0wDQYJKoZIhvcNAQELBQADggIBAK+nz97/4L1CjU3lIpbfaOp9TSp90K09FlxD533Ahuh6 +NWPxzIHIxgvoLlI1pKZJkGNRrDSsBTtXAOnTYtPZKdVUvhwQkZyybf5Z/Xn36lbQnmhUQo8mUuJM +3y+Xpi/SB5io82BdS5pYV4jvguX6r2yBS5KPQJqTRlnLX3gWsWc+QgvfKNmwrZggvkN80V4aCRck +jXtdlemrwWCrWxhkgPut4AZ9HcpZuPN4KWfGVh2vtrV0KnahP/t1MJ+UXjulYPPLXAziDslg+Mkf +Foom3ecnf+slpoq9uC02EJqxWE2aaE9gVOX2RhOOiKy8IUISrcZKiX2bwdgt6ZYD9KJ0DLwAHb/W +NyVntHKLr4W96ioDj8z7PEQkguIBpQtZtjSNMgsSDesnwv1B10A8ckYpwIzqug/xBpMu95yo9GA+ +o/E4Xo4TwbM6l4c/ksp4qRyv0LAbJh6+cOx69TOY6lz/KwsETkPdY34Op054A5U+1C0wlREQKC6/ +oAI+/15Z0wUOlV9TRe9rh9VIzRamloPh37MG88EU26fsHItdkJANclHnYfkUyq+Dj7+vsQpZXdxc +1+SWrVtgHdqul7I52Qb1dgAT+GhMIbA1xNxVssnBQVocicCMb3SgazNNtQEo/a2tiRc7ppqEvOuM +6sRxJKi6KfkIsidWNTJf6jn7MZrVGczw +-----END CERTIFICATE----- + +CommScope Public Trust RSA Root-02 +================================== +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIUVBa/O345lXGN0aoApYYNK496BU4wDQYJKoZIhvcNAQELBQAwTjELMAkG +A1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBU +cnVzdCBSU0EgUm9vdC0wMjAeFw0yMTA0MjgxNzE2NDNaFw00NjA0MjgxNzE2NDJaME4xCzAJBgNV +BAYTAlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1 +c3QgUlNBIFJvb3QtMDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDh+g77aAASyE3V +rCLENQE7xVTlWXZjpX/rwcRqmL0yjReA61260WI9JSMZNRTpf4mnG2I81lDnNJUDMrG0kyI9p+Kx +7eZ7Ti6Hmw0zdQreqjXnfuU2mKKuJZ6VszKWpCtYHu8//mI0SFHRtI1CrWDaSWqVcN3SAOLMV2MC +e5bdSZdbkk6V0/nLKR8YSvgBKtJjCW4k6YnS5cciTNxzhkcAqg2Ijq6FfUrpuzNPDlJwnZXjfG2W +Wy09X6GDRl224yW4fKcZgBzqZUPckXk2LHR88mcGyYnJ27/aaL8j7dxrrSiDeS/sOKUNNwFnJ5rp +M9kzXzehxfCrPfp4sOcsn/Y+n2Dg70jpkEUeBVF4GiwSLFworA2iI540jwXmojPOEXcT1A6kHkIf +hs1w/tkuFT0du7jyU1fbzMZ0KZwYszZ1OC4PVKH4kh+Jlk+71O6d6Ts2QrUKOyrUZHk2EOH5kQMr +eyBUzQ0ZGshBMjTRsJnhkB4BQDa1t/qp5Xd1pCKBXbCL5CcSD1SIxtuFdOa3wNemKfrb3vOTlycE +VS8KbzfFPROvCgCpLIscgSjX74Yxqa7ybrjKaixUR9gqiC6vwQcQeKwRoi9C8DfF8rhW3Q5iLc4t +Vn5V8qdE9isy9COoR+jUKgF4z2rDN6ieZdIs5fq6M8EGRPbmz6UNp2YINIos8wIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUR9DnsSL/nSz12Vdgs7Gx +cJXvYXowDQYJKoZIhvcNAQELBQADggIBAIZpsU0v6Z9PIpNojuQhmaPORVMbc0RTAIFhzTHjCLqB +KCh6krm2qMhDnscTJk3C2OVVnJJdUNjCK9v+5qiXz1I6JMNlZFxHMaNlNRPDk7n3+VGXu6TwYofF +1gbTl4MgqX67tiHCpQ2EAOHyJxCDut0DgdXdaMNmEMjRdrSzbymeAPnCKfWxkxlSaRosTKCL4BWa +MS/TiJVZbuXEs1DIFAhKm4sTg7GkcrI7djNB3NyqpgdvHSQSn8h2vS/ZjvQs7rfSOBAkNlEv41xd +gSGn2rtO/+YHqP65DSdsu3BaVXoT6fEqSWnHX4dXTEN5bTpl6TBcQe7rd6VzEojov32u5cSoHw2O +HG1QAk8mGEPej1WFsQs3BWDJVTkSBKEqz3EWnzZRSb9wO55nnPt7eck5HHisd5FUmrh1CoFSl+Nm +YWvtPjgelmFV4ZFUjO2MJB+ByRCac5krFk5yAD9UG/iNuovnFNa2RU9g7Jauwy8CTl2dlklyALKr +dVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670v64fG9PiO/yzcnMcmyiQ +iRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17Org3bhzjlP1v9mxnhMUF6cKojawHhRUzN +lM47ni3niAIi9G7oyOzWPPO5std3eqx7 +-----END CERTIFICATE----- + +Telekom Security TLS ECC Root 2020 +================================== +-----BEGIN CERTIFICATE----- +MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQswCQYDVQQGEwJE +RTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJUZWxl +a29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIwMB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIz +NTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkg +R21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqG +SM49AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/OtdKPD/M1 +2kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDPf8iAC8GXs7s1J8nCG6NC +MEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6fMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMAoGCCqGSM49BAMDA2cAMGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZ +Mo7k+5Dck2TOrbRBR2Diz6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdU +ga/sf+Rn27iQ7t0l +-----END CERTIFICATE----- + +Telekom Security TLS RSA Root 2023 +================================== +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBjMQswCQYDVQQG +EwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJU +ZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAyMDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMy +NzIzNTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJp +dHkgR21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9cUD/h3VC +KSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHVcp6R+SPWcHu79ZvB7JPP +GeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMAU6DksquDOFczJZSfvkgdmOGjup5czQRx +UX11eKvzWarE4GC+j4NSuHUaQTXtvPM6Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWo +l8hHD/BeEIvnHRz+sTugBTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9 +FIS3R/qy8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73Jco4v +zLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg8qKrBC7m8kwOFjQg +rIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8rFEz0ciD0cmfHdRHNCk+y7AO+oML +KFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7S +WWO/gLCMk3PLNaaZlSJhZQNg+y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUtqeXgj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2 +p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQpGv7qHBFfLp+ +sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm9S3ul0A8Yute1hTWjOKWi0Fp +kzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErwM807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy +/SKE8YXJN3nptT+/XOR0so8RYgDdGGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4 +mZqTuXNnQkYRIer+CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtz +aL1txKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+w6jv/naa +oqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aKL4x35bcF7DvB7L6Gs4a8 +wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+ljX273CXE2whJdV/LItM3z7gLfEdxquVeE +HVlNjM7IDiPCtyaaEBRx/pOyiriA8A4QntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0 +o82bNSQ3+pCTE4FCxpgmdTdmQRCsu/WU48IxK63nI1bMNSWSs1A= +-----END CERTIFICATE----- diff --git a/examples/esp32_pio/WebSocketClientSSLBundle/cmn_crt_authorities.csv b/examples/esp32_pio/WebSocketClientSSLBundle/cmn_crt_authorities.csv new file mode 100644 index 0000000..249ecf4 --- /dev/null +++ b/examples/esp32_pio/WebSocketClientSSLBundle/cmn_crt_authorities.csv @@ -0,0 +1,39 @@ +Owner,Common Name or Certificate Name +Amazon Trust Services,Amazon Root CA 1 +Amazon Trust Services,Amazon Root CA 2 +Amazon Trust Services,Amazon Root CA 3 +Amazon Trust Services,Amazon Root CA 4 +Amazon Trust Services,Starfield Services Root Certificate Authority - G2 +DigiCert,Baltimore CyberTrust Root +DigiCert,Cybertrust Global Root +DigiCert,DigiCert Assured ID Root CA +DigiCert,DigiCert Assured ID Root G2 +DigiCert,DigiCert Assured ID Root G3 +DigiCert,DigiCert Global Root CA +DigiCert,DigiCert Global Root G2 +DigiCert,DigiCert Global Root G3 +DigiCert,DigiCert High Assurance EV Root CA +DigiCert,DigiCert Trusted Root G4 +GlobalSign,GlobalSign ECC Root CA - R5 +GlobalSign,GlobalSign Root CA - R3 +GlobalSign,GlobalSign Root CA - R6 +GlobalSign,GlobalSign Root CA +GoDaddy,Go Daddy Class 2 CA +GoDaddy,Go Daddy Root Certificate Authority - G2 +GoDaddy,Starfield Class 2 CA +GoDaddy,Starfield Root Certificate Authority - G2 +Google Trust Services LLC (GTS),GlobalSign ECC Root CA - R4 +Google Trust Services LLC (GTS),GlobalSign Root CA - R2 +Google Trust Services LLC (GTS),GTS Root R1 +Google Trust Services LLC (GTS),GTS Root R2 +Google Trust Services LLC (GTS),GTS Root R3 +Google Trust Services LLC (GTS),GTS Root R4 +"IdenTrust Services, LLC",DST Root CA X3 +"IdenTrust Services, LLC",IdenTrust Commercial Root CA 1 +"IdenTrust Services, LLC",IdenTrust Public Sector Root CA 1 +Sectigo,Comodo AAA Services root +Sectigo,COMODO Certification Authority +Sectigo,COMODO ECC Certification Authority +Sectigo,COMODO RSA Certification Authority +Sectigo,USERTrust ECC Certification Authority +Sectigo,USERTrust RSA Certification Authority diff --git a/examples/esp32_pio/WebSocketClientSSLBundle/gen_crt_bundle.py b/examples/esp32_pio/WebSocketClientSSLBundle/gen_crt_bundle.py new file mode 100644 index 0000000..87e29e6 --- /dev/null +++ b/examples/esp32_pio/WebSocketClientSSLBundle/gen_crt_bundle.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python +# +# ESP32 x509 certificate bundle generation utility +# +# Converts PEM and DER certificates to a custom bundle format which stores just the +# subject name and public key to reduce space +# +# The bundle will have the format: number of certificates; crt 1 subject name length; crt 1 public key length; +# crt 1 subject name; crt 1 public key; crt 2... +# +# Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http:#www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import with_statement + +import argparse +import csv +import os +import re +import struct +import sys +from io import open + +try: + from cryptography import x509 + from cryptography.hazmat.backends import default_backend + from cryptography.hazmat.primitives import serialization +except ImportError: + print('The cryptography package is not installed.' + 'Please refer to the Get Started section of the ESP-IDF Programming Guide for ' + 'setting up the required packages.') + raise + +ca_bundle_bin_file = 'x509_crt_bundle' + +quiet = False + + +def status(msg): + """ Print status message to stderr """ + if not quiet: + critical(msg) + + +def critical(msg): + """ Print critical message to stderr """ + sys.stderr.write('gen_crt_bundle.py: ') + sys.stderr.write(msg) + sys.stderr.write('\n') + + +class CertificateBundle: + def __init__(self): + self.certificates = [] + self.compressed_crts = [] + + if os.path.isfile(ca_bundle_bin_file): + os.remove(ca_bundle_bin_file) + + def add_from_path(self, crts_path): + + found = False + for file_path in os.listdir(crts_path): + found |= self.add_from_file(os.path.join(crts_path, file_path)) + + if found is False: + raise InputError('No valid x509 certificates found in %s' % crts_path) + + def add_from_file(self, file_path): + try: + if file_path.endswith('.pem'): + status('Parsing certificates from %s' % file_path) + with open(file_path, 'r', encoding='utf-8') as f: + crt_str = f.read() + self.add_from_pem(crt_str) + return True + + elif file_path.endswith('.der'): + status('Parsing certificates from %s' % file_path) + with open(file_path, 'rb') as f: + crt_str = f.read() + self.add_from_der(crt_str) + return True + + except ValueError: + critical('Invalid certificate in %s' % file_path) + raise InputError('Invalid certificate') + + return False + + def add_from_pem(self, crt_str): + """ A single PEM file may have multiple certificates """ + + crt = '' + count = 0 + start = False + + for strg in crt_str.splitlines(True): + if strg == '-----BEGIN CERTIFICATE-----\n' and start is False: + crt = '' + start = True + elif strg == '-----END CERTIFICATE-----\n' and start is True: + crt += strg + '\n' + start = False + self.certificates.append(x509.load_pem_x509_certificate(crt.encode(), default_backend())) + count += 1 + if start is True: + crt += strg + + if(count == 0): + raise InputError('No certificate found') + + status('Successfully added %d certificates' % count) + + def add_from_der(self, crt_str): + self.certificates.append(x509.load_der_x509_certificate(crt_str, default_backend())) + status('Successfully added 1 certificate') + + def create_bundle(self): + # Sort certificates in order to do binary search when looking up certificates + self.certificates = sorted(self.certificates, key=lambda cert: cert.subject.public_bytes(default_backend())) + + bundle = struct.pack('>H', len(self.certificates)) + + for crt in self.certificates: + """ Read the public key as DER format """ + pub_key = crt.public_key() + pub_key_der = pub_key.public_bytes(serialization.Encoding.DER, serialization.PublicFormat.SubjectPublicKeyInfo) + + """ Read the subject name as DER format """ + sub_name_der = crt.subject.public_bytes(default_backend()) + + name_len = len(sub_name_der) + key_len = len(pub_key_der) + len_data = struct.pack('>HH', name_len, key_len) + + bundle += len_data + bundle += sub_name_der + bundle += pub_key_der + + return bundle + + def add_with_filter(self, crts_path, filter_path): + + filter_set = set() + with open(filter_path, 'r', encoding='utf-8') as f: + csv_reader = csv.reader(f, delimiter=',') + + # Skip header + next(csv_reader) + for row in csv_reader: + filter_set.add(row[1]) + + status('Parsing certificates from %s' % crts_path) + crt_str = [] + with open(crts_path, 'r', encoding='utf-8') as f: + crt_str = f.read() + + # Split all certs into a list of (name, certificate string) tuples + pem_crts = re.findall(r'(^.+?)\n(=+\n[\s\S]+?END CERTIFICATE-----\n)', crt_str, re.MULTILINE) + + filtered_crts = '' + for name, crt in pem_crts: + if name in filter_set: + filtered_crts += crt + + self.add_from_pem(filtered_crts) + + +class InputError(RuntimeError): + def __init__(self, e): + super(InputError, self).__init__(e) + + +def main(): + global quiet + + parser = argparse.ArgumentParser(description='ESP-IDF x509 certificate bundle utility') + + parser.add_argument('--quiet', '-q', help="Don't print non-critical status messages to stderr", action='store_true') + parser.add_argument('--input', '-i', nargs='+', required=True, + help='Paths to the custom certificate folders or files to parse, parses all .pem or .der files') + parser.add_argument('--filter', '-f', help='Path to CSV-file where the second columns contains the name of the certificates \ + that should be included from cacrt_all.pem') + + args = parser.parse_args() + + quiet = args.quiet + + bundle = CertificateBundle() + + for path in args.input: + if os.path.isfile(path): + if os.path.basename(path) == 'cacrt_all.pem' and args.filter: + bundle.add_with_filter(path, args.filter) + else: + bundle.add_from_file(path) + elif os.path.isdir(path): + bundle.add_from_path(path) + else: + raise InputError('Invalid --input=%s, is neither file nor folder' % args.input) + + status('Successfully added %d certificates in total' % len(bundle.certificates)) + + crt_bundle = bundle.create_bundle() + + with open(ca_bundle_bin_file, 'wb') as f: + f.write(crt_bundle) + + +if __name__ == '__main__': + try: + main() + except InputError as e: + print(e) + sys.exit(2) diff --git a/examples/esp32_pio/WebSocketClientSSLBundle/lib/README b/examples/esp32_pio/WebSocketClientSSLBundle/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/examples/esp32_pio/WebSocketClientSSLBundle/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/examples/esp32_pio/WebSocketClientSSLBundle/platformio.ini b/examples/esp32_pio/WebSocketClientSSLBundle/platformio.ini new file mode 100644 index 0000000..c4e94e4 --- /dev/null +++ b/examples/esp32_pio/WebSocketClientSSLBundle/platformio.ini @@ -0,0 +1,25 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp32dev] +platform = espressif32 +board = esp32dev +framework = arduino +monitor_speed = 115200 +upload_speed = 921600 +build_flags = + -DCORE_DEBUG_LEVEL=5 +lib_deps = ../../../src + +extra_scripts = + pre:run_gen_script.py + +board_build.embed_txtfiles = + data/cert/x509_crt_bundle.bin diff --git a/examples/esp32_pio/WebSocketClientSSLBundle/readme.md b/examples/esp32_pio/WebSocketClientSSLBundle/readme.md new file mode 100644 index 0000000..ad9c19b --- /dev/null +++ b/examples/esp32_pio/WebSocketClientSSLBundle/readme.md @@ -0,0 +1,12 @@ +This is a PlatformIO project that uses a modified WiFiClientSecure library (in `lib`) to +implement proper SSL support using root certificates as discussed +[here](https://github.com/espressif/arduino-esp32/issues/3646#issuecomment-648292677) + +It is based on the work by [meltdonw03](https://github.com/meltdown03) in that thread, and the +[BasicHttpsClient example](https://github.com/espressif/arduino-esp32/blob/1.0.4/libraries/HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino) from the arduino-esp32 project. + +Just copy `include/secrets.hpp.template` to `include/secrets.hpp` and fill in your WiFi details. +Then it should be pretty much ready to go. The local WiFiClientSecure library should take priority. +Debug is set to verbose, so you'll see a lot of noise, but there should also be this readme on success :) + +To get a current CA cert bundle download it from [curl's website](https://curl.se/docs/caextract.html). \ No newline at end of file diff --git a/examples/esp32_pio/WebSocketClientSSLBundle/run_gen_script.py b/examples/esp32_pio/WebSocketClientSSLBundle/run_gen_script.py new file mode 100644 index 0000000..88505db --- /dev/null +++ b/examples/esp32_pio/WebSocketClientSSLBundle/run_gen_script.py @@ -0,0 +1,6 @@ +Import("env") + +env.Execute("$PYTHONEXE -m pip install cryptography") +env.Execute("$PYTHONEXE gen_crt_bundle.py --input cacrt_all.pem") +env.Execute("mkdir -p data/cert") +env.Execute("mv -f x509_crt_bundle data/cert/x509_crt_bundle.bin") diff --git a/examples/esp32_pio/WebSocketClientSSLBundle/src/main.cpp b/examples/esp32_pio/WebSocketClientSSLBundle/src/main.cpp new file mode 100644 index 0000000..1765614 --- /dev/null +++ b/examples/esp32_pio/WebSocketClientSSLBundle/src/main.cpp @@ -0,0 +1,127 @@ +/* + * main.cpp + * + * Created on: 15.06.2024 + * + */ + +#include +#include +#include + +#include + +extern const uint8_t rootca_crt_bundle_start[] asm( + "_binary_data_cert_x509_crt_bundle_bin_start"); + +WiFiMulti wifiMulti; +WebSocketsClient webSocket; + +#define USE_SERIAL Serial + +void setClock() { + configTime(0, 0, "pool.ntp.org", "time.nist.gov"); + + USE_SERIAL.print(F("Waiting for NTP time sync: ")); + time_t nowSecs = time(nullptr); + while(nowSecs < 8 * 3600 * 2) { + delay(500); + USE_SERIAL.print(F(".")); + yield(); + nowSecs = time(nullptr); + } + + USE_SERIAL.println(); + struct tm timeinfo; + gmtime_r(&nowSecs, &timeinfo); + USE_SERIAL.print(F("Current time: ")); + USE_SERIAL.print(asctime(&timeinfo)); +} + +void hexdump(const void * mem, uint32_t len, uint8_t cols = 16) { + const uint8_t * src = (const uint8_t *)mem; + USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); + for(uint32_t i = 0; i < len; i++) { + if(i % cols == 0) { + USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); + } + USE_SERIAL.printf("%02X ", *src); + src++; + } + USE_SERIAL.printf("\n"); +} + +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[WSc] Disconnected!\n"); + break; + case WStype_CONNECTED: + USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); + + // send message to server when Connected + webSocket.sendTXT("Connected"); + break; + case WStype_TEXT: + USE_SERIAL.printf("[WSc] get text: %s\n", payload); + + // send message to server + // webSocket.sendTXT("message here"); + break; + case WStype_BIN: + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); + + // send data to server + // webSocket.sendBIN(payload, length); + break; + case WStype_ERROR: + case WStype_FRAGMENT_TEXT_START: + case WStype_FRAGMENT_BIN_START: + case WStype_FRAGMENT: + case WStype_FRAGMENT_FIN: + break; + } +} + +void setup() { + USE_SERIAL.begin(115200); + + USE_SERIAL.setDebugOutput(true); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + wifiMulti.addAP("SSID", "WIFI_PASSPHRASE"); + + // WiFi.disconnect(); + while(wifiMulti.run() != WL_CONNECTED) { + delay(100); + } + + setClock(); + + // server address, port and URL. This server can be flakey. + // Expected response: Request served by 0123456789abcdef + webSocket.beginSslWithBundle("echo.websocket.org", 443, "/", rootca_crt_bundle_start, ""); + + // event handler + webSocket.onEvent(webSocketEvent); + + // use HTTP Basic Authorization this is optional enable if needed + // webSocket.setAuthorization("user", "Password"); + + // try ever 5000 again if connection has failed + webSocket.setReconnectInterval(5000); +} + +void loop() { + webSocket.loop(); +} diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index f1155e0..2488dea 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -48,6 +48,9 @@ void WebSocketsClient::begin(const char * host, uint16_t port, const char * url, #if defined(HAS_SSL) _fingerprint = SSL_FINGERPRINT_NULL; _CA_cert = NULL; +#ifdef ESP32 + _CA_bundle = NULL; +#endif #endif _client.num = 0; @@ -107,6 +110,7 @@ void WebSocketsClient::beginSSL(const char * host, uint16_t port, const char * u _client.isSSL = true; _fingerprint = fingerprint; _CA_cert = NULL; + _CA_bundle = NULL; } void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String fingerprint, String protocol) { @@ -118,7 +122,16 @@ void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const ch _client.isSSL = true; _fingerprint = SSL_FINGERPRINT_NULL; _CA_cert = CA_cert; + _CA_bundle = NULL; } +void WebSocketsClient::beginSslWithBundle(const char * host, uint16_t port, const char * url, const uint8_t * CA_bundle, const char * protocol) { + begin(host, port, url, protocol); + _client.isSSL = true; + _fingerprint = SSL_FINGERPRINT_NULL; + _CA_cert = NULL; + _CA_bundle = CA_bundle; +} + #else void WebSocketsClient::beginSSL(const char * host, uint16_t port, const char * url, const uint8_t * fingerprint, const char * protocol) { begin(host, port, url, protocol); @@ -231,6 +244,11 @@ void WebSocketsClient::loop(void) { #else #error setCACert not implemented #endif +#if defined(ESP32) + } else if(_CA_bundle) { + DEBUG_WEBSOCKETS("[WS-Client] setting CA bundle"); + _client.ssl->setCACertBundle(_CA_bundle); +#endif #if defined(ESP32) } else if(!SSL_FINGERPRINT_IS_SET) { _client.ssl->setInsecure(); diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 6cc98d4..081e37e 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -53,6 +53,9 @@ class WebSocketsClient : protected WebSockets { void setSSLClientCertKey(const char * clientCert = NULL, const char * clientPrivateKey = NULL); #endif void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", const char * CA_cert = NULL, const char * protocol = "arduino"); +#ifdef ESP32 + void beginSslWithBundle(const char * host, uint16_t port, const char * url = "/", const uint8_t * CA_bundle = NULL, const char * protocol = "arduino"); +#endif #endif void beginSocketIO(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); @@ -112,6 +115,7 @@ class WebSocketsClient : protected WebSockets { #ifdef SSL_AXTLS String _fingerprint; const char * _CA_cert; + const uint8_t * _CA_bundle; #define SSL_FINGERPRINT_IS_SET (_fingerprint.length()) #define SSL_FINGERPRINT_NULL "" #else From af1b0256b9f96b1779f3b50f7f7c6c741c1dc8a8 Mon Sep 17 00:00:00 2001 From: Links2004 Date: Mon, 17 Jun 2024 16:27:08 +0200 Subject: [PATCH 327/347] bump version to 2.4.2 --- library.json | 2 +- library.properties | 2 +- src/WebSocketsVersion.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library.json b/library.json index 3647d91..2a5ed65 100644 --- a/library.json +++ b/library.json @@ -21,5 +21,5 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.4.1" + "version": "2.4.2" } \ No newline at end of file diff --git a/library.properties b/library.properties index 38aa97b..487596c 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.4.1 +version=2.4.2 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index 89dac96..11fc8b1 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -1,6 +1,6 @@ /** * @file WebSocketsVersion.h - * @date 01.05.2023 + * @date 17.06.2024 * @author Markus Sattler * * Copyright (c) 2015 Markus Sattler. All rights reserved. @@ -25,12 +25,12 @@ #ifndef WEBSOCKETSVERSION_H_ #define WEBSOCKETSVERSION_H_ -#define WEBSOCKETS_VERSION "2.4.1" +#define WEBSOCKETS_VERSION "2.4.2" #define WEBSOCKETS_VERSION_MAJOR 2 #define WEBSOCKETS_VERSION_MINOR 4 -#define WEBSOCKETS_VERSION_PATCH 1 +#define WEBSOCKETS_VERSION_PATCH 2 -#define WEBSOCKETS_VERSION_INT 2004001 +#define WEBSOCKETS_VERSION_INT 2004002 #endif /* WEBSOCKETSVERSION_H_ */ From 11cf06897ce604bf5997e8299a8742b8679c1ee9 Mon Sep 17 00:00:00 2001 From: Links2004 Date: Mon, 17 Jun 2024 16:27:43 +0200 Subject: [PATCH 328/347] update arduino-cli --- .github/workflows/main.yml | 24 ++++++++++++------------ src/WebSocketsClient.cpp | 2 +- travis/common.sh | 3 +-- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2bd0aaa..908c62e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,13 +37,13 @@ jobs: echo -en "matrix=" >> $GITHUB_OUTPUT echo -en "[" >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 0.35.0 esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 >> $GITHUB_OUTPUT + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 0.35.3 esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 >> $GITHUB_OUTPUT echo -en "," >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 0.35.0 esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 >> $GITHUB_OUTPUT + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 0.35.3 esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 >> $GITHUB_OUTPUT echo -en "," >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 0.35.0 esp32:esp32:esp32:FlashFreq=80 >> $GITHUB_OUTPUT + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 0.35.3 esp32:esp32:esp32:FlashFreq=80 >> $GITHUB_OUTPUT echo -en "]" >> $GITHUB_OUTPUT echo >> $GITHUB_OUTPUT @@ -55,7 +55,7 @@ jobs: strategy: fail-fast: false matrix: - CLI_VERSION: [0.35.0] + CLI_VERSION: [0.35.3] env: CLI_VERSION: ${{ matrix.CLI_VERSION }} ARDUINO_DIRECTORIES_DATA: /home/runner/arduino_ide @@ -63,10 +63,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Get Date - id: get-date + - name: Get hash + id: get-hash run: | - echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT + echo "hash=$(/bin/date -u "+%Y%m%d")-$(md5sum ".github/workflows/main.yml" | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT shell: bash - uses: actions/cache@v3 @@ -75,7 +75,7 @@ jobs: path: | /home/runner/arduino_ide /home/runner/Arduino - key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.CLI_VERSION }}-cli + key: ${{ runner.os }}-${{ steps.get-hash.outputs.hash }}-${{ matrix.CLI_VERSION }}-cli - name: download IDE if: steps.cache_all.outputs.cache-hit != 'true' @@ -122,10 +122,10 @@ jobs: run: | sudo apt-get install -y libgtk2.0-0 - - name: Get Date - id: get-date + - name: Get hash + id: get-hash run: | - echo "date=$(/bin/date -u "+%Y%m%d")" >> $GITHUB_OUTPUT + echo "hash=$(/bin/date -u "+%Y%m%d")-$(md5sum ".github/workflows/main.yml" | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT shell: bash - uses: actions/cache@v3 @@ -134,7 +134,7 @@ jobs: path: | /home/runner/arduino_ide /home/runner/Arduino - key: ${{ runner.os }}-${{ steps.get-date.outputs.date }}-${{ matrix.cliversion }}-cli + key: ${{ runner.os }}-${{ steps.get-hash.outputs.hash }}-${{ matrix.cliversion }}-cli - name: install python serial if: matrix.cpu == 'esp32' diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 2488dea..8578f4b 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -49,7 +49,7 @@ void WebSocketsClient::begin(const char * host, uint16_t port, const char * url, _fingerprint = SSL_FINGERPRINT_NULL; _CA_cert = NULL; #ifdef ESP32 - _CA_bundle = NULL; + _CA_bundle = NULL; #endif #endif diff --git a/travis/common.sh b/travis/common.sh index 53df57c..c5a96f5 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -1,6 +1,5 @@ #!/bin/bash - -set -x +set -e function build_sketches() { From 0e127c9a76adb1ecb2cba1fef5223f1d1ea32cd5 Mon Sep 17 00:00:00 2001 From: Links2004 Date: Mon, 17 Jun 2024 16:28:59 +0200 Subject: [PATCH 329/347] update arduino-cli to 1.0.0 --- .github/workflows/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 908c62e..64dedb0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,13 +37,13 @@ jobs: echo -en "matrix=" >> $GITHUB_OUTPUT echo -en "[" >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 0.35.3 esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 >> $GITHUB_OUTPUT + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.0.0 esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 >> $GITHUB_OUTPUT echo -en "," >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 0.35.3 esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 >> $GITHUB_OUTPUT + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.0.0 esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 >> $GITHUB_OUTPUT echo -en "," >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 0.35.3 esp32:esp32:esp32:FlashFreq=80 >> $GITHUB_OUTPUT + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.0.0 esp32:esp32:esp32:FlashFreq=80 >> $GITHUB_OUTPUT echo -en "]" >> $GITHUB_OUTPUT echo >> $GITHUB_OUTPUT @@ -55,7 +55,7 @@ jobs: strategy: fail-fast: false matrix: - CLI_VERSION: [0.35.3] + CLI_VERSION: [1.0.0] env: CLI_VERSION: ${{ matrix.CLI_VERSION }} ARDUINO_DIRECTORIES_DATA: /home/runner/arduino_ide From d5f0d3c4b5e458be5ec8efc2dd230833ed93c8ee Mon Sep 17 00:00:00 2001 From: Links2004 Date: Mon, 17 Jun 2024 16:41:53 +0200 Subject: [PATCH 330/347] remove broken rp2040 --- travis/common.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/travis/common.sh b/travis/common.sh index c5a96f5..743c460 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -105,11 +105,10 @@ function get_sketches_json_matrix() } function get_core_cli() { - export ARDUINO_BOARD_MANAGER_ADDITIONAL_URLS="https://arduino.esp8266.com/stable/package_esp8266com_index.json https://espressif.github.io/arduino-esp32/package_esp32_index.json https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json" + export ARDUINO_BOARD_MANAGER_ADDITIONAL_URLS="https://arduino.esp8266.com/stable/package_esp8266com_index.json https://espressif.github.io/arduino-esp32/package_esp32_index.json" arduino-cli core update-index arduino-cli core install esp8266:esp8266 arduino-cli core install esp32:esp32 - arduino-cli core install arduino:mbed_rp2040 } function get_core() From e364e6688455814a47f95c8ca79b27a753c0c630 Mon Sep 17 00:00:00 2001 From: Links2004 Date: Mon, 17 Jun 2024 17:07:09 +0200 Subject: [PATCH 331/347] go back to arduino-cli 0.35.3 since 1.0.0 is buggy see: https://github.com/arduino/arduino-cli/issues/2643 --- .github/workflows/main.yml | 8 ++++---- travis/common.sh | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 64dedb0..908c62e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,13 +37,13 @@ jobs: echo -en "matrix=" >> $GITHUB_OUTPUT echo -en "[" >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.0.0 esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 >> $GITHUB_OUTPUT + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 0.35.3 esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200 >> $GITHUB_OUTPUT echo -en "," >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 1.0.0 esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 >> $GITHUB_OUTPUT + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266_pico esp8266 0.35.3 esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200 >> $GITHUB_OUTPUT echo -en "," >> $GITHUB_OUTPUT - get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.0.0 esp32:esp32:esp32:FlashFreq=80 >> $GITHUB_OUTPUT + get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 0.35.3 esp32:esp32:esp32:FlashFreq=80 >> $GITHUB_OUTPUT echo -en "]" >> $GITHUB_OUTPUT echo >> $GITHUB_OUTPUT @@ -55,7 +55,7 @@ jobs: strategy: fail-fast: false matrix: - CLI_VERSION: [1.0.0] + CLI_VERSION: [0.35.3] env: CLI_VERSION: ${{ matrix.CLI_VERSION }} ARDUINO_DIRECTORIES_DATA: /home/runner/arduino_ide diff --git a/travis/common.sh b/travis/common.sh index 743c460..3c270d2 100644 --- a/travis/common.sh +++ b/travis/common.sh @@ -105,10 +105,11 @@ function get_sketches_json_matrix() } function get_core_cli() { - export ARDUINO_BOARD_MANAGER_ADDITIONAL_URLS="https://arduino.esp8266.com/stable/package_esp8266com_index.json https://espressif.github.io/arduino-esp32/package_esp32_index.json" + export ARDUINO_BOARD_MANAGER_ADDITIONAL_URLS="https://arduino.esp8266.com/stable/package_esp8266com_index.json https://espressif.github.io/arduino-esp32/package_esp32_index.json https://github.com/earlephilhower/arduino-pico/releases/download/3.9.2/package_rp2040_index.json" arduino-cli core update-index arduino-cli core install esp8266:esp8266 arduino-cli core install esp32:esp32 + arduino-cli core install rp2040:rp2040 } function get_core() From d6d4c516b38d7da89f6e4f2a242ecdfc7f627f25 Mon Sep 17 00:00:00 2001 From: Aruna Tennakoon Date: Mon, 29 Jul 2024 15:11:12 +0700 Subject: [PATCH 332/347] Support Arduino UNO WIFI 4 (#894) feat: Arduino UNO R4 WiFi support --- README.md | 1 + .../arduino_uno_r4_wifi.ino | 109 ++++++++++++++++++ library.json | 6 +- library.properties | 2 +- src/WebSockets.h | 17 +++ src/WebSocketsVersion.h | 8 +- 6 files changed, 135 insertions(+), 8 deletions(-) create mode 100644 examples/arduino_renesas/arduino_uno_r4_wifi/arduino_uno_r4_wifi.ino diff --git a/README.md b/README.md index fdc4e4c..b5930eb 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ a WebSocket Server and Client for Arduino based on RFC6455. - ATmega328 with enc28j60 (ATmega branch) - ATmega2560 with Ethernet Shield (ATmega branch) - ATmega2560 with enc28j60 (ATmega branch) + - Arduino UNO [R4 WiFi](https://github.com/arduino/ArduinoCore-renesas) ###### Note: ###### diff --git a/examples/arduino_renesas/arduino_uno_r4_wifi/arduino_uno_r4_wifi.ino b/examples/arduino_renesas/arduino_uno_r4_wifi/arduino_uno_r4_wifi.ino new file mode 100644 index 0000000..2168a62 --- /dev/null +++ b/examples/arduino_renesas/arduino_uno_r4_wifi/arduino_uno_r4_wifi.ino @@ -0,0 +1,109 @@ +#include +#include +#include + +#include "WiFiS3.h" +#include + +#define WIFI_SSID "" +#define WIFI_PASS "" + +WebSocketsClient webSocket; + +void webSocketEvent(WStype_t type, uint8_t *payload, size_t length) { + + switch (type) { + case WStype_DISCONNECTED: + Serial.println("[WSc] Disconnected!"); + break; + case WStype_CONNECTED: + Serial.println("[WSc] Connected!"); + + // send message to server when Connected + webSocket.sendTXT("Connected"); + break; + case WStype_TEXT: + Serial.print("[WSc] get text:"); + Serial.println((char *)payload); + + // send message to server + // webSocket.sendTXT("message here"); + break; + case WStype_BIN: + // send data to server + // webSocket.sendBIN(payload, length); + break; + case WStype_ERROR: + case WStype_FRAGMENT_TEXT_START: + case WStype_FRAGMENT_BIN_START: + case WStype_FRAGMENT: + case WStype_FRAGMENT_FIN: + break; + } +} + +void setup() { + Serial.begin(115200); + + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + Serial.println(); + Serial.println(); + Serial.println(); + + for (uint8_t t = 4; t > 0; t--) { + Serial.println("[SETUP] BOOT WAIT ..."); + Serial.flush(); + delay(1000); + } + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + // don't continue + while (true) + ; + } + + String fv = WiFi.firmwareVersion(); + if (fv < WIFI_FIRMWARE_LATEST_VERSION) { + Serial.println("Please upgrade the firmware"); + } + + Serial.println("[Wifi]: Connecting"); + + int status = WL_IDLE_STATUS; + + // attempt to connect to WiFi network: + while (status != WL_CONNECTED) { + Serial.print("[Wifi]: Attempting to connect to SSID: "); + Serial.println(WIFI_SSID); + + // Connect to WPA/WPA2 network. Change this line if using open or WEP network: + status = WiFi.begin(WIFI_SSID, WIFI_PASS); + + delay(1000); + } + + Serial.println("Connected!"); + + // print your board's IP address: + IPAddress ip = WiFi.localIP(); + Serial.print("IP Address: "); + Serial.println(ip); + + // server address, port and URL + webSocket.begin("192.168.0.123", 8011); + + // event handler + webSocket.onEvent(webSocketEvent); + + // try ever 5000 again if connection has failed + webSocket.setReconnectInterval(5000); +} + +void loop() { + webSocket.loop(); +} \ No newline at end of file diff --git a/library.json b/library.json index 2a5ed65..d51149f 100644 --- a/library.json +++ b/library.json @@ -16,10 +16,10 @@ "keywords": "wifi, http, web, server, client, websocket", "license": "LGPL-2.1", "name": "WebSockets", - "platforms": "atmelavr, espressif8266, espressif32, raspberrypi", + "platforms": "atmelavr, espressif8266, espressif32, raspberrypi, renesas_uno", "repository": { "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.4.2" -} \ No newline at end of file + "version": "2.5.1" +} diff --git a/library.properties b/library.properties index 487596c..462efc5 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.4.2 +version=2.5.1 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSockets.h b/src/WebSockets.h index db6c0e8..56b4988 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -93,6 +93,12 @@ #define WEBSOCKETS_YIELD() yield() #define WEBSOCKETS_YIELD_MORE() delay(1) +#elif defined(ARDUINO_UNOWIFIR4) + +#define WEBSOCKETS_MAX_DATA_SIZE (15 * 1024) +#define WEBSOCKETS_YIELD() yield() +#define WEBSOCKETS_YIELD_MORE() delay(1) + #else // atmega328p has only 2KB ram! @@ -114,6 +120,7 @@ #define NETWORK_ESP32 (4) #define NETWORK_ESP32_ETH (5) #define NETWORK_RP2040 (6) +#define NETWORK_UNOWIFIR4 (7) // max size of the WS Message Header #define WEBSOCKETS_MAX_HEADER_SIZE (14) @@ -132,6 +139,9 @@ #elif defined(ARDUINO_ARCH_RP2040) #define WEBSOCKETS_NETWORK_TYPE NETWORK_RP2040 +#elif defined(ARDUINO_UNOWIFIR4) +#define WEBSOCKETS_NETWORK_TYPE NETWORK_UNOWIFIR4 + #else #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 @@ -224,6 +234,13 @@ #define WEBSOCKETS_NETWORK_SSL_CLASS WiFiClientSecure #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_UNOWIFIR4) + +#include + +#define WEBSOCKETS_NETWORK_CLASS WiFiClient +#define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer + #else #error "no network type selected!" #endif diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index 11fc8b1..9c69078 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -25,12 +25,12 @@ #ifndef WEBSOCKETSVERSION_H_ #define WEBSOCKETSVERSION_H_ -#define WEBSOCKETS_VERSION "2.4.2" +#define WEBSOCKETS_VERSION "2.5.1" #define WEBSOCKETS_VERSION_MAJOR 2 -#define WEBSOCKETS_VERSION_MINOR 4 -#define WEBSOCKETS_VERSION_PATCH 2 +#define WEBSOCKETS_VERSION_MINOR 5 +#define WEBSOCKETS_VERSION_PATCH 1 -#define WEBSOCKETS_VERSION_INT 2004002 +#define WEBSOCKETS_VERSION_INT 2005001 #endif /* WEBSOCKETSVERSION_H_ */ From 7da1dc5c6e7a8725796726faa8b91d6749f7a726 Mon Sep 17 00:00:00 2001 From: Links2004 Date: Mon, 29 Jul 2024 13:07:27 +0200 Subject: [PATCH 333/347] bump version 2.5.2 --- README.md | 18 ++++++++---------- library.json | 4 ++-- library.properties | 2 +- src/WebSocketsVersion.h | 8 ++++---- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index b5930eb..f0b8ea9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -WebSocket Server and Client for Arduino [![Build Status](https://github.com/Links2004/arduinoWebSockets/workflows/CI/badge.svg?branch=master)](https://github.com/Links2004/arduinoWebSockets/actions?query=workflow%3ACI+branch%3Amaster) +WebSocket Server and Client for Arduino [![Build Status](https://github.com/Links2004/arduinoWebSockets/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/Links2004/arduinoWebSockets/actions?query=branch%3Amaster) =========================================== a WebSocket Server and Client for Arduino based on RFC6455. @@ -74,19 +74,19 @@ The mode can be activated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE ```c++ void begin(const char *host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); void begin(String host, uint16_t port, String url = "/", String protocol = "arduino"); - ``` +``` - `onEvent`: Callback to handle for websocket events - ```c++ +```c++ void onEvent(WebSocketClientEvent cbEvent); - ``` +``` - `WebSocketClientEvent`: Handler for websocket events - ```c++ +```c++ void (*WebSocketClientEvent)(WStype_t type, uint8_t * payload, size_t length) - ``` +``` Where `WStype_t type` is defined as: - ```c++ +```c++ typedef enum { WStype_ERROR, WStype_DISCONNECTED, @@ -100,13 +100,11 @@ Where `WStype_t type` is defined as: WStype_PING, WStype_PONG, } WStype_t; - ``` +``` ### Issues ### Submit issues to: https://github.com/Links2004/arduinoWebSockets/issues -[![Join the chat at https://gitter.im/Links2004/arduinoWebSockets](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Links2004/arduinoWebSockets?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - ### License and credits ### The library is licensed under [LGPLv2.1](https://github.com/Links2004/arduinoWebSockets/blob/master/LICENSE) diff --git a/library.json b/library.json index d51149f..6869b8c 100644 --- a/library.json +++ b/library.json @@ -21,5 +21,5 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.5.1" -} + "version": "2.5.2" +} \ No newline at end of file diff --git a/library.properties b/library.properties index 462efc5..ceb4a3f 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.5.1 +version=2.5.2 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index 9c69078..76bacef 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -1,6 +1,6 @@ /** * @file WebSocketsVersion.h - * @date 17.06.2024 + * @date 29.07.2024 * @author Markus Sattler * * Copyright (c) 2015 Markus Sattler. All rights reserved. @@ -25,12 +25,12 @@ #ifndef WEBSOCKETSVERSION_H_ #define WEBSOCKETSVERSION_H_ -#define WEBSOCKETS_VERSION "2.5.1" +#define WEBSOCKETS_VERSION "2.5.2" #define WEBSOCKETS_VERSION_MAJOR 2 #define WEBSOCKETS_VERSION_MINOR 5 -#define WEBSOCKETS_VERSION_PATCH 1 +#define WEBSOCKETS_VERSION_PATCH 2 -#define WEBSOCKETS_VERSION_INT 2005001 +#define WEBSOCKETS_VERSION_INT 2005002 #endif /* WEBSOCKETSVERSION_H_ */ From dc6fd04a9874a66a089f02ad18f5a9e7dc7c349f Mon Sep 17 00:00:00 2001 From: Links2004 Date: Sun, 4 Aug 2024 09:38:25 +0200 Subject: [PATCH 334/347] fix #896 ESP32 Arduino changed setCACertBundle args --- .../WebSocketClientSSLBundle.ino | 6 ++++++ src/WebSocketsClient.cpp | 19 ++++++++++++++++++- src/WebSocketsClient.h | 9 +++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/examples/esp32/WebSocketClientSSLBundle/WebSocketClientSSLBundle.ino b/examples/esp32/WebSocketClientSSLBundle/WebSocketClientSSLBundle.ino index b9385a7..f64cc58 100644 --- a/examples/esp32/WebSocketClientSSLBundle/WebSocketClientSSLBundle.ino +++ b/examples/esp32/WebSocketClientSSLBundle/WebSocketClientSSLBundle.ino @@ -112,7 +112,13 @@ void setup() { // server address, port and URL. This server can be flakey. // Expected response: Request served by 0123456789abcdef // webSocket.beginSslWithBundle("echo.websocket.org", 443, "/", rootca_crt_bundle_start, ""); + // ESP32 3.0.4 or higher needs the size of the bundle + // webSocket.beginSslWithBundle("echo.websocket.org", 443, "/", rootca_crt_bundle_start, sizeof(rootca_crt_bundle_start), ""); +#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 4) + webSocket.beginSslWithBundle("echo.websocket.org", 443, "/", NULL, 0, ""); +#else webSocket.beginSslWithBundle("echo.websocket.org", 443, "/", NULL, ""); +#endif // event handler webSocket.onEvent(webSocketEvent); diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 8578f4b..78512e3 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -50,6 +50,9 @@ void WebSocketsClient::begin(const char * host, uint16_t port, const char * url, _CA_cert = NULL; #ifdef ESP32 _CA_bundle = NULL; +#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 4) + _CA_bundle_size = 0; +#endif #endif #endif @@ -124,6 +127,17 @@ void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const ch _CA_cert = CA_cert; _CA_bundle = NULL; } + +#if defined(ESP32) && ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 4) +void WebSocketsClient::beginSslWithBundle(const char * host, uint16_t port, const char * url, const uint8_t * CA_bundle, size_t CA_bundle_size, const char * protocol) { + begin(host, port, url, protocol); + _client.isSSL = true; + _fingerprint = SSL_FINGERPRINT_NULL; + _CA_cert = NULL; + _CA_bundle = CA_bundle; + _CA_bundle_size = CA_bundle_size; +} +#else void WebSocketsClient::beginSslWithBundle(const char * host, uint16_t port, const char * url, const uint8_t * CA_bundle, const char * protocol) { begin(host, port, url, protocol); _client.isSSL = true; @@ -131,6 +145,7 @@ void WebSocketsClient::beginSslWithBundle(const char * host, uint16_t port, cons _CA_cert = NULL; _CA_bundle = CA_bundle; } +#endif #else void WebSocketsClient::beginSSL(const char * host, uint16_t port, const char * url, const uint8_t * fingerprint, const char * protocol) { @@ -247,9 +262,11 @@ void WebSocketsClient::loop(void) { #if defined(ESP32) } else if(_CA_bundle) { DEBUG_WEBSOCKETS("[WS-Client] setting CA bundle"); +#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 4) + _client.ssl->setCACertBundle(_CA_bundle, _CA_bundle_size); +#else _client.ssl->setCACertBundle(_CA_bundle); #endif -#if defined(ESP32) } else if(!SSL_FINGERPRINT_IS_SET) { _client.ssl->setInsecure(); #elif defined(SSL_BARESSL) diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 081e37e..c2a6b92 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -54,8 +54,12 @@ class WebSocketsClient : protected WebSockets { #endif void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", const char * CA_cert = NULL, const char * protocol = "arduino"); #ifdef ESP32 +#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 4) + void beginSslWithBundle(const char * host, uint16_t port, const char * url = "/", const uint8_t * CA_bundle = NULL, size_t CA_bundle_size = 0, const char * protocol = "arduino"); +#else void beginSslWithBundle(const char * host, uint16_t port, const char * url = "/", const uint8_t * CA_bundle = NULL, const char * protocol = "arduino"); #endif +#endif #endif void beginSocketIO(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); @@ -116,6 +120,11 @@ class WebSocketsClient : protected WebSockets { String _fingerprint; const char * _CA_cert; const uint8_t * _CA_bundle; +#if defined(ESP32) +#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 4) + size_t _CA_bundle_size; +#endif +#endif #define SSL_FINGERPRINT_IS_SET (_fingerprint.length()) #define SSL_FINGERPRINT_NULL "" #else From dcfb0df665840a43f24e7fb9aa73a6db2874fe8b Mon Sep 17 00:00:00 2001 From: Aruna Tennakoon Date: Sun, 11 Aug 2024 14:09:47 +0700 Subject: [PATCH 335/347] feat: Support Arduino Nano 33 IoT, MKR WIFI 1010 (#898) --- .github/workflows/arduino-lint.yaml | 10 ++ .../compile-arduino_wifinina-examples.yaml | 54 ++++++++++ .../workflows/compile-unor4wifi-examples.yaml | 45 ++++++++ README.md | 1 + .../arduino_wifinina/arduino_wifinina.ino | 100 ++++++++++++++++++ library.json | 4 +- library.properties | 2 +- src/WebSockets.h | 23 ++++ src/WebSocketsClient.cpp | 6 +- src/WebSocketsServer.cpp | 15 ++- src/WebSocketsVersion.h | 6 +- 11 files changed, 257 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/arduino-lint.yaml create mode 100644 .github/workflows/compile-arduino_wifinina-examples.yaml create mode 100644 .github/workflows/compile-unor4wifi-examples.yaml create mode 100644 examples/arduino_wifinina/arduino_wifinina.ino diff --git a/.github/workflows/arduino-lint.yaml b/.github/workflows/arduino-lint.yaml new file mode 100644 index 0000000..7c15bc9 --- /dev/null +++ b/.github/workflows/arduino-lint.yaml @@ -0,0 +1,10 @@ +name: Arduino library compliance (Lint) +on: [push, pull_request] +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: arduino/arduino-lint-action@v1 + with: + library-manager: update diff --git a/.github/workflows/compile-arduino_wifinina-examples.yaml b/.github/workflows/compile-arduino_wifinina-examples.yaml new file mode 100644 index 0000000..166847f --- /dev/null +++ b/.github/workflows/compile-arduino_wifinina-examples.yaml @@ -0,0 +1,54 @@ +name: Compile Arduino WiFiNINA Examples + +# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows +on: [push, pull_request] + +jobs: + build: + name: ${{ matrix.board.fqbn }} + runs-on: ubuntu-latest + + env: + SKETCHES_REPORTS_PATH: sketches-reports + + strategy: + fail-fast: false + + matrix: + board: + - fqbn: arduino:samd:mkrwifi1010 + platforms: | + - name: arduino:samd + artifact-name-suffix: arduino-samd-mkrwifi1010 + libraries: | + - name: WiFiNINA + - fqbn: arduino:samd:nano_33_iot + platforms: | + - name: arduino:samd + artifact-name-suffix: arduino-samd-nano_33_iot + libraries: | + - name: WiFiNINA + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Compile examples + uses: arduino/compile-sketches@v1 + with: + fqbn: ${{ matrix.board.fqbn }} + platforms: ${{ matrix.board.platforms }} + libraries: | + # Install the library from the local path. + - source-path: ./ + ${{ matrix.board.libraries }} + sketch-paths: | + - examples/arduino_wifinina/arduino_wifinina.ino + enable-deltas-report: true + sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} + + - name: Save sketches report as workflow artifact + uses: actions/upload-artifact@v4 + with: + if-no-files-found: error + path: ${{ env.SKETCHES_REPORTS_PATH }} + name: sketches-report-${{ matrix.board.artifact-name-suffix }} diff --git a/.github/workflows/compile-unor4wifi-examples.yaml b/.github/workflows/compile-unor4wifi-examples.yaml new file mode 100644 index 0000000..9be9878 --- /dev/null +++ b/.github/workflows/compile-unor4wifi-examples.yaml @@ -0,0 +1,45 @@ +name: Compile Arduino UNO R4 WiFi Examples + +# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows +on: [push, pull_request] + +jobs: + build: + name: ${{ matrix.board.fqbn }} + runs-on: ubuntu-latest + + env: + SKETCHES_REPORTS_PATH: sketches-reports + + strategy: + fail-fast: false + + matrix: + board: + - fqbn: arduino:renesas_uno:unor4wifi + platforms: | + - name: arduino:renesas_uno + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Compile examples + uses: arduino/compile-sketches@v1 + with: + fqbn: ${{ matrix.board.fqbn }} + platforms: ${{ matrix.board.platforms }} + libraries: | + # Install the library from the local path. + - source-path: ./ + sketch-paths: | + - examples/arduino_renesas/arduino_uno_r4_wifi + enable-deltas-report: true + sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} + + - name: Save sketches report as workflow artifact + uses: actions/upload-artifact@v4 + with: + if-no-files-found: error + path: ${{ env.SKETCHES_REPORTS_PATH }} + name: sketches-report-${{ matrix.board.artifact-name-suffix }} diff --git a/README.md b/README.md index f0b8ea9..2dcec63 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ a WebSocket Server and Client for Arduino based on RFC6455. - ATmega2560 with Ethernet Shield (ATmega branch) - ATmega2560 with enc28j60 (ATmega branch) - Arduino UNO [R4 WiFi](https://github.com/arduino/ArduinoCore-renesas) + - Arduino Nano 33 IoT, MKR WIFI 1010 ###### Note: ###### diff --git a/examples/arduino_wifinina/arduino_wifinina.ino b/examples/arduino_wifinina/arduino_wifinina.ino new file mode 100644 index 0000000..d8f6e3a --- /dev/null +++ b/examples/arduino_wifinina/arduino_wifinina.ino @@ -0,0 +1,100 @@ +#include +#include +#include +#include + +#define WIFI_SSID "" +#define WIFI_PASS "" + +int status = WL_IDLE_STATUS; +WiFiClient client; +WebSocketsClient webSocket; + +void webSocketEvent(WStype_t type, uint8_t *payload, size_t length) { + + switch (type) { + case WStype_DISCONNECTED: + Serial.println("[WSc] Disconnected!"); + break; + case WStype_CONNECTED: + Serial.println("[WSc] Connected!"); + + // send message to server when Connected + webSocket.sendTXT("Connected"); + break; + case WStype_TEXT: + Serial.print("[WSc] get text:"); + Serial.println((char *)payload); + + // send message to server + // webSocket.sendTXT("message here"); + break; + case WStype_BIN: + // send data to server + // webSocket.sendBIN(payload, length); + break; + case WStype_ERROR: + case WStype_FRAGMENT_TEXT_START: + case WStype_FRAGMENT_BIN_START: + case WStype_FRAGMENT: + case WStype_PING: + case WStype_PONG: + case WStype_FRAGMENT_FIN: + break; + } +} + +void setup() { + Serial.begin(115200); + + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + Serial.println(); + Serial.println(); + Serial.println(); + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv < WIFI_FIRMWARE_LATEST_VERSION) { + Serial.println("Please upgrade the firmware"); + } + + // attempt to connect to WiFi network: + while (status != WL_CONNECTED) { + Serial.print("Attempting to connect to SSID: "); + Serial.println(WIFI_SSID); + // Connect to WPA/WPA2 network. Change this line if using open or WEP network: + status = WiFi.begin(WIFI_SSID, WIFI_PASS); + + // wait 10 seconds for connection: + delay(10000); + } + + Serial.println("Connected to WiFi"); + + // print your board's IP address: + IPAddress ip = WiFi.localIP(); + Serial.print("IP Address: "); + Serial.println(ip); + + // server address, port and URL + webSocket.begin("192.168.0.123", 8011); + + // event handler + webSocket.onEvent(webSocketEvent); + + // try ever 5000 again if connection has failed + webSocket.setReconnectInterval(5000); +} + +void loop() { + webSocket.loop(); +} \ No newline at end of file diff --git a/library.json b/library.json index 6869b8c..56ae925 100644 --- a/library.json +++ b/library.json @@ -21,5 +21,5 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.5.2" -} \ No newline at end of file + "version": "2.5.3" +} diff --git a/library.properties b/library.properties index ceb4a3f..18c7748 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.5.2 +version=2.5.3 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSockets.h b/src/WebSockets.h index 56b4988..f0a2bf9 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -99,6 +99,12 @@ #define WEBSOCKETS_YIELD() yield() #define WEBSOCKETS_YIELD_MORE() delay(1) +#elif defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_NANO_33_IOT) + +#define WEBSOCKETS_MAX_DATA_SIZE (15 * 1024) +#define WEBSOCKETS_YIELD() yield() +#define WEBSOCKETS_YIELD_MORE() delay(1) + #else // atmega328p has only 2KB ram! @@ -121,6 +127,8 @@ #define NETWORK_ESP32_ETH (5) #define NETWORK_RP2040 (6) #define NETWORK_UNOWIFIR4 (7) +#define NETWORK_WIFI_NINA (8) + // max size of the WS Message Header #define WEBSOCKETS_MAX_HEADER_SIZE (14) @@ -142,6 +150,9 @@ #elif defined(ARDUINO_UNOWIFIR4) #define WEBSOCKETS_NETWORK_TYPE NETWORK_UNOWIFIR4 +#elif defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_NANO_33_IOT) +#define WEBSOCKETS_NETWORK_TYPE NETWORK_WIFI_NINA + #else #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 @@ -241,6 +252,18 @@ #define WEBSOCKETS_NETWORK_CLASS WiFiClient #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer +#define WEBSOCKETS_NETWORK_CLASS WiFiClient +#define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer + +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) +#if __has_include() + #include +#else + #error "Please install WiFiNINA library!" +#endif + +#define WEBSOCKETS_NETWORK_CLASS WiFiClient +#define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer #else #error "no network type selected!" #endif diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 78512e3..1b8f7a3 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -534,7 +534,11 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->status = WSC_NOT_CONNECTED; #else - delete client->tcp; + #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) + // does not support delete (no destructor) + #else + delete client->tcp; + #endif #endif client->tcp = NULL; } diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index e11e1cf..697c1d2 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -65,7 +65,11 @@ WebSocketsServerCore::~WebSocketsServerCore() { } WebSocketsServer::~WebSocketsServer() { - delete _server; + #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) + // does not support delete (no destructor) + #else + delete _server; + #endif } /** @@ -539,6 +543,8 @@ void WebSocketsServerCore::dropNativeClient(WSclient_t * client) { } #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->status = WSC_NOT_CONNECTED; +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) + // does not support delete (no destructor) #else delete client->tcp; #endif @@ -655,7 +661,12 @@ void WebSocketsServer::handleNewClients(void) { #endif // store new connection - WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->accept()); + #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) + WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); + #else + WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->accept()); + #endif + if(!tcpClient) { DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); return; diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index 76bacef..8662206 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -25,12 +25,12 @@ #ifndef WEBSOCKETSVERSION_H_ #define WEBSOCKETSVERSION_H_ -#define WEBSOCKETS_VERSION "2.5.2" +#define WEBSOCKETS_VERSION "2.5.3" #define WEBSOCKETS_VERSION_MAJOR 2 #define WEBSOCKETS_VERSION_MINOR 5 -#define WEBSOCKETS_VERSION_PATCH 2 +#define WEBSOCKETS_VERSION_PATCH 3 -#define WEBSOCKETS_VERSION_INT 2005002 +#define WEBSOCKETS_VERSION_INT 2005003 #endif /* WEBSOCKETSVERSION_H_ */ From 899cfbdbe7e5829ab49ffcf27f4a40c7336d664b Mon Sep 17 00:00:00 2001 From: Aruna Tennakoon Date: Sat, 24 Aug 2024 17:01:45 +0700 Subject: [PATCH 336/347] feat: Support Nano 33 IoT, MKR WIFI 1010, XIAO, Wio Terminal (#901) --- .../compile-arduino_wifinina-examples.yaml | 17 ++- .../compile-seeed-studio-examples.yaml | 81 ++++++++++++++ .../workflows/compile-unor4wifi-examples.yaml | 17 ++- README.md | 3 +- .../WebSocketClient/WebSocketClient.ino | 105 ++++++++++++++++++ library.json | 2 +- src/SocketIOclient.cpp | 2 +- src/SocketIOclient.h | 4 +- src/WebSockets.h | 32 +++++- src/WebSocketsClient.cpp | 26 ++++- src/WebSocketsClient.h | 9 ++ src/WebSocketsServer.cpp | 4 +- src/libb64/cdecode.c | 2 +- src/libb64/cencode.c | 2 +- 14 files changed, 286 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/compile-seeed-studio-examples.yaml create mode 100644 examples/seeed-studio/xio-wio-terminal/WebSocketClient/WebSocketClient.ino diff --git a/.github/workflows/compile-arduino_wifinina-examples.yaml b/.github/workflows/compile-arduino_wifinina-examples.yaml index 166847f..15c1773 100644 --- a/.github/workflows/compile-arduino_wifinina-examples.yaml +++ b/.github/workflows/compile-arduino_wifinina-examples.yaml @@ -1,7 +1,22 @@ name: Compile Arduino WiFiNINA Examples # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows -on: [push, pull_request] +on: + push: + paths: + - ".github/workflows/compile-arduino_wifinina-examples.yaml" + - "examples/arduino_wifinina/**" + - "src/**" + pull_request: + paths: + - ".github/workflows/compile-arduino_wifinina-examples.yaml" + - "examples/arduino_wifinina/**" + - "src/**" + schedule: + # Run every Tuesday at 8 AM UTC to catch breakage caused by changes to external resources (libraries, platforms). + - cron: "0 8 * * TUE" + workflow_dispatch: + repository_dispatch: jobs: build: diff --git a/.github/workflows/compile-seeed-studio-examples.yaml b/.github/workflows/compile-seeed-studio-examples.yaml new file mode 100644 index 0000000..859aae4 --- /dev/null +++ b/.github/workflows/compile-seeed-studio-examples.yaml @@ -0,0 +1,81 @@ +name: Compile SeedStudio Examples + +# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows +on: + push: + paths: + - ".github/workflows/compile-seeed-studio-examples.yaml" + - "examples/seeed-studio/**" + - "src/**" + pull_request: + paths: + - ".github/workflows/compile-seeed-studio-examples.yaml" + - "examples/seeed-studio/**" + - "src/**" + schedule: + # Run every Tuesday at 8 AM UTC to catch breakage caused by changes to external resources (libraries, platforms). + - cron: "0 8 * * TUE" + workflow_dispatch: + repository_dispatch: + +jobs: + build: + name: ${{ matrix.board.fqbn }} + runs-on: ubuntu-latest + + env: + SKETCHES_REPORTS_PATH: sketches-reports + + strategy: + fail-fast: false + + matrix: + board: + - fqbn: Seeeduino:samd:seeed_XIAO_m0:usbstack=arduino,debug=off + platforms: | + - name: Seeeduino:samd + source-url: https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json + libraries: | + - name: Seeed Arduino rpcWiFi + - name: Seeed Arduino rpcUnified + - name: Seeed_Arduino_mbedtls + - name: Seeed Arduino FS + - name: Seeed Arduino SFUD + artifact-name-suffix: seeeduino-xia0 + - fqbn: Seeeduino:samd:seeed_wio_terminal + platforms: | + - name: Seeeduino:samd + source-url: https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json + libraries: | + - name: Seeed Arduino rpcWiFi + - name: Seeed Arduino rpcUnified + - name: Seeed_Arduino_mbedtls + - name: Seeed Arduino FS + - name: Seeed Arduino SFUD + artifact-name-suffix: seeeduino-wio_terminal + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Compile examples + uses: arduino/compile-sketches@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + fqbn: ${{ matrix.board.fqbn }} + platforms: ${{ matrix.board.platforms }} + libraries: | + # Install the library from the local path. + - source-path: ./ + ${{ matrix.board.libraries }} + sketch-paths: | + - examples/seeed-studio/xio-wio-terminal/WebSocketClient + enable-deltas-report: true + sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} + + - name: Save sketches report as workflow artifact + uses: actions/upload-artifact@v4 + with: + if-no-files-found: error + path: ${{ env.SKETCHES_REPORTS_PATH }} + name: sketches-report-${{ matrix.board.artifact-name-suffix }} \ No newline at end of file diff --git a/.github/workflows/compile-unor4wifi-examples.yaml b/.github/workflows/compile-unor4wifi-examples.yaml index 9be9878..71b94df 100644 --- a/.github/workflows/compile-unor4wifi-examples.yaml +++ b/.github/workflows/compile-unor4wifi-examples.yaml @@ -1,7 +1,22 @@ name: Compile Arduino UNO R4 WiFi Examples # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows -on: [push, pull_request] +on: + push: + paths: + - ".github/workflows/compile-unor4wifi-examples.yaml" + - "examples/arduino_renesas/**" + - "src/**" + pull_request: + paths: + - ".github/workflows/compile-unor4wifi-examples.yaml" + - "examples/arduino_renesas/**" + - "src/**" + schedule: + # Run every Tuesday at 8 AM UTC to catch breakage caused by changes to external resources (libraries, platforms). + - cron: "0 8 * * TUE" + workflow_dispatch: + repository_dispatch: jobs: build: diff --git a/README.md b/README.md index 2dcec63..bc37c8a 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,8 @@ a WebSocket Server and Client for Arduino based on RFC6455. - ATmega2560 with Ethernet Shield (ATmega branch) - ATmega2560 with enc28j60 (ATmega branch) - Arduino UNO [R4 WiFi](https://github.com/arduino/ArduinoCore-renesas) - - Arduino Nano 33 IoT, MKR WIFI 1010 + - Arduino Nano 33 IoT, MKR WIFI 1010 (requires [WiFiNINA](https://github.com/arduino-libraries/WiFiNINA/) library) + - Seeeduino XIAO, Seeeduino Wio Terminal (requires [rpcWiFi](https://github.com/Seeed-Studio/Seeed_Arduino_rpcWiFi) library) ###### Note: ###### diff --git a/examples/seeed-studio/xio-wio-terminal/WebSocketClient/WebSocketClient.ino b/examples/seeed-studio/xio-wio-terminal/WebSocketClient/WebSocketClient.ino new file mode 100644 index 0000000..d26aac0 --- /dev/null +++ b/examples/seeed-studio/xio-wio-terminal/WebSocketClient/WebSocketClient.ino @@ -0,0 +1,105 @@ +/* + * WebSocketClient.ino + * + * Created on: 10.08.2024 + * + */ + +#include +#include +#include +#include + +WebSocketsClient webSocket; +WiFiMulti wifiMulti; + +#define USE_SERIAL Serial + +void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) { + const uint8_t* src = (const uint8_t*) mem; + USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); + for(uint32_t i = 0; i < len; i++) { + if(i % cols == 0) { + USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); + } + USE_SERIAL.printf("%02X ", *src); + src++; + } + USE_SERIAL.printf("\n"); +} + +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { + + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[WSc] Disconnected!\n"); + break; + case WStype_CONNECTED: + USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); + + // send message to server when Connected + webSocket.sendTXT("Connected"); + break; + case WStype_TEXT: + USE_SERIAL.printf("[WSc] get text: %s\n", payload); + + // send message to server + // webSocket.sendTXT("message here"); + break; + case WStype_BIN: + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); + + // send data to server + // webSocket.sendBIN(payload, length); + break; + case WStype_ERROR: + case WStype_FRAGMENT_TEXT_START: + case WStype_FRAGMENT_BIN_START: + case WStype_FRAGMENT: + case WStype_PONG: + case WStype_PING: + case WStype_FRAGMENT_FIN: + break; + } + +} + +void setup() { + // USE_SERIAL.begin(921600); + USE_SERIAL.begin(115200); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for(uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + wifiMulti.addAP("SSID", "passpasspass"); + + //WiFi.disconnect(); + while(wifiMulti.run() != WL_CONNECTED) { + delay(100); + } + + // server address, port and URL + webSocket.begin("192.168.0.123", 81, "/"); + + // event handler + webSocket.onEvent(webSocketEvent); + + // use HTTP Basic Authorization this is optional remove if not needed + webSocket.setAuthorization("user", "Password"); + + // try ever 5000 again if connection has failed + webSocket.setReconnectInterval(5000); + +} + +void loop() { + webSocket.loop(); +} diff --git a/library.json b/library.json index 56ae925..a2159dc 100644 --- a/library.json +++ b/library.json @@ -16,7 +16,7 @@ "keywords": "wifi, http, web, server, client, websocket", "license": "LGPL-2.1", "name": "WebSockets", - "platforms": "atmelavr, espressif8266, espressif32, raspberrypi, renesas_uno", + "platforms": "*", "repository": { "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" diff --git a/src/SocketIOclient.cpp b/src/SocketIOclient.cpp index 1533316..dd5037c 100644 --- a/src/SocketIOclient.cpp +++ b/src/SocketIOclient.cpp @@ -261,4 +261,4 @@ void SocketIOclient::handleCbEvent(WStype_t type, uint8_t * payload, size_t leng case WStype_PONG: break; } -} +} \ No newline at end of file diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index e33a6fd..99af80b 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -55,9 +55,11 @@ class SocketIOclient : protected WebSocketsClient { void beginSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino", uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5); #ifndef SSL_AXTLS void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino", uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5); - void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino", uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5); void setSSLClientCertKey(const char * clientCert = NULL, const char * clientPrivateKey = NULL); + #if defined(SSL_BARESSL) + void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino", uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5); void setSSLClientCertKey(BearSSL::X509List * clientCert = NULL, BearSSL::PrivateKey * clientPrivateKey = NULL); + #endif #endif #endif bool isConnected(void); diff --git a/src/WebSockets.h b/src/WebSockets.h index f0a2bf9..13a022a 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -105,6 +105,12 @@ #define WEBSOCKETS_YIELD() yield() #define WEBSOCKETS_YIELD_MORE() delay(1) +#elif defined(WIO_TERMINAL) || defined(SEEED_XIAO_M0) + +#define WEBSOCKETS_MAX_DATA_SIZE (15 * 1024) +#define WEBSOCKETS_YIELD() yield() +#define WEBSOCKETS_YIELD_MORE() delay(1) + #else // atmega328p has only 2KB ram! @@ -128,7 +134,7 @@ #define NETWORK_RP2040 (6) #define NETWORK_UNOWIFIR4 (7) #define NETWORK_WIFI_NINA (8) - +#define NETWORK_SAMD_SEED (9) // max size of the WS Message Header #define WEBSOCKETS_MAX_HEADER_SIZE (14) @@ -153,6 +159,9 @@ #elif defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_NANO_33_IOT) #define WEBSOCKETS_NETWORK_TYPE NETWORK_WIFI_NINA +#elif defined(WIO_TERMINAL) || defined(SEEED_XIAO_M0) +#define WEBSOCKETS_NETWORK_TYPE NETWORK_SAMD_SEED + #else #define WEBSOCKETS_NETWORK_TYPE NETWORK_W5100 @@ -248,10 +257,6 @@ #elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_UNOWIFIR4) #include - -#define WEBSOCKETS_NETWORK_CLASS WiFiClient -#define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer - #define WEBSOCKETS_NETWORK_CLASS WiFiClient #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer @@ -264,6 +269,23 @@ #define WEBSOCKETS_NETWORK_CLASS WiFiClient #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer +#define WEBSOCKETS_NETWORK_SSL_CLASS WiFiSSLClient + +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) +#if __has_include() && __has_include() + #include + #include +#else + #error "Please install rpcWiFi library!" +#endif + +#define WEBSOCKETS_NETWORK_CLASS WiFiClient +#define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer +#define WEBSOCKETS_NETWORK_SSL_CLASS WiFiClientSecure + +#define WEBSOCKETS_NETWORK_CLASS WiFiClient +#define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer + #else #error "no network type selected!" #endif diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 1b8f7a3..34357ab 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -155,6 +155,7 @@ void WebSocketsClient::beginSSL(const char * host, uint16_t port, const char * u _CA_cert = NULL; } +#if defined(SSL_BARESSL) void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const char * url, BearSSL::X509List * CA_cert, const char * protocol) { begin(host, port, url, protocol); _client.isSSL = true; @@ -166,14 +167,16 @@ void WebSocketsClient::beginSslWithCA(const char * host, uint16_t port, const ch beginSslWithCA(host, port, url, new BearSSL::X509List(CA_cert), protocol); } +void WebSocketsClient::setSSLClientCertKey(const char * clientCert, const char * clientPrivateKey) { + setSSLClientCertKey(new BearSSL::X509List(clientCert), new BearSSL::PrivateKey(clientPrivateKey)); +} + void WebSocketsClient::setSSLClientCertKey(BearSSL::X509List * clientCert, BearSSL::PrivateKey * clientPrivateKey) { _client_cert = clientCert; _client_key = clientPrivateKey; } +#endif // SSL_BARESSL -void WebSocketsClient::setSSLClientCertKey(const char * clientCert, const char * clientPrivateKey) { - setSSLClientCertKey(new BearSSL::X509List(clientCert), new BearSSL::PrivateKey(clientPrivateKey)); -} #endif // SSL_AXTLS #endif // HAS_SSL @@ -242,7 +245,12 @@ void WebSocketsClient::loop(void) { if(_client.isSSL) { DEBUG_WEBSOCKETS("[WS-Client] connect wss...\n"); if(_client.ssl) { - delete _client.ssl; + #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) || (WEBSOCKETS_NETWORK_TYPE ==NETWORK_UNOWIFIR4) + // does not support delete (no destructor) + #else + delete _client.ssl; + #endif + _client.ssl = NULL; _client.tcp = NULL; } @@ -256,6 +264,10 @@ void WebSocketsClient::loop(void) { _client.ssl->setCACert((const uint8_t *)_CA_cert, strlen(_CA_cert) + 1); #elif(defined(ESP8266) || defined(ARDUINO_ARCH_RP2040)) && defined(SSL_BARESSL) _client.ssl->setTrustAnchors(_CA_cert); +#elif defined(WIO_TERMINAL) || defined(SEEED_XIAO_M0) + _client.ssl->setCACert(_CA_cert); +#elif defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_NANO_33_IOT) + // no setCACert #else #error setCACert not implemented #endif @@ -283,7 +295,11 @@ void WebSocketsClient::loop(void) { } else { DEBUG_WEBSOCKETS("[WS-Client] connect ws...\n"); if(_client.tcp) { + #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) || (WEBSOCKETS_NETWORK_TYPE ==NETWORK_UNOWIFIR4) + // does not support delete (no destructor) + #else delete _client.tcp; + #endif _client.tcp = NULL; } _client.tcp = new WEBSOCKETS_NETWORK_CLASS(); @@ -534,7 +550,7 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->status = WSC_NOT_CONNECTED; #else - #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) + #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) || (WEBSOCKETS_NETWORK_TYPE ==NETWORK_UNOWIFIR4) // does not support delete (no destructor) #else delete client->tcp; diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index c2a6b92..95a126a 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -48,8 +48,10 @@ class WebSocketsClient : protected WebSockets { void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino"); #else void beginSSL(const char * host, uint16_t port, const char * url = "/", const uint8_t * fingerprint = NULL, const char * protocol = "arduino"); + #if defined(SSL_BARESSL) void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino"); void setSSLClientCertKey(BearSSL::X509List * clientCert = NULL, BearSSL::PrivateKey * clientPrivateKey = NULL); + #endif void setSSLClientCertKey(const char * clientCert = NULL, const char * clientPrivateKey = NULL); #endif void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", const char * CA_cert = NULL, const char * protocol = "arduino"); @@ -129,13 +131,20 @@ class WebSocketsClient : protected WebSockets { #define SSL_FINGERPRINT_NULL "" #else const uint8_t * _fingerprint; + #if defined(SSL_BARESSL) BearSSL::X509List * _CA_cert; BearSSL::X509List * _client_cert; BearSSL::PrivateKey * _client_key; + #endif #define SSL_FINGERPRINT_IS_SET (_fingerprint != NULL) #define SSL_FINGERPRINT_NULL NULL #endif +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) + const char * _CA_cert; + const uint8_t * _CA_bundle; +#endif + #endif WSclient_t _client; diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 697c1d2..2eccbc4 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -65,7 +65,7 @@ WebSocketsServerCore::~WebSocketsServerCore() { } WebSocketsServer::~WebSocketsServer() { - #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) + #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) // does not support delete (no destructor) #else delete _server; @@ -543,7 +543,7 @@ void WebSocketsServerCore::dropNativeClient(WSclient_t * client) { } #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->status = WSC_NOT_CONNECTED; -#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) +#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) // does not support delete (no destructor) #else delete client->tcp; diff --git a/src/libb64/cdecode.c b/src/libb64/cdecode.c index 615068a..c40d0a8 100644 --- a/src/libb64/cdecode.c +++ b/src/libb64/cdecode.c @@ -9,7 +9,7 @@ For details, see http://sourceforge.net/projects/libb64 #include #endif -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) +#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(WIO_TERMINAL) || defined(SEEED_XIAO_M0) #define CORE_HAS_LIBB64 #endif diff --git a/src/libb64/cencode.c b/src/libb64/cencode.c index cdc0f67..937474d 100644 --- a/src/libb64/cencode.c +++ b/src/libb64/cencode.c @@ -9,7 +9,7 @@ For details, see http://sourceforge.net/projects/libb64 #include #endif -#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) +#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(WIO_TERMINAL) || defined(SEEED_XIAO_M0) #define CORE_HAS_LIBB64 #endif From 0980b209baa0d7d0c500827f1969f819cce17871 Mon Sep 17 00:00:00 2001 From: Markus <974709+Links2004@users.noreply.github.com> Date: Sat, 24 Aug 2024 12:07:31 +0200 Subject: [PATCH 337/347] Create dependabot.yml --- .github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..6867e71 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" From e8006439a2b1960321dea29753aa39c5b59de120 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 24 Aug 2024 10:08:07 +0000 Subject: [PATCH 338/347] Bump actions/cache from 3 to 4 Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 908c62e..1481d62 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -69,7 +69,7 @@ jobs: echo "hash=$(/bin/date -u "+%Y%m%d")-$(md5sum ".github/workflows/main.yml" | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT shell: bash - - uses: actions/cache@v3 + - uses: actions/cache@v4 id: cache_all with: path: | @@ -128,7 +128,7 @@ jobs: echo "hash=$(/bin/date -u "+%Y%m%d")-$(md5sum ".github/workflows/main.yml" | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT shell: bash - - uses: actions/cache@v3 + - uses: actions/cache@v4 id: cache_all with: path: | From b60be0e3c587b2da1a9e5fd77edfceb9dfcfc08a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 24 Aug 2024 10:08:09 +0000 Subject: [PATCH 339/347] Bump actions/checkout from 2 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/arduino-lint.yaml | 2 +- .github/workflows/main.yml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/arduino-lint.yaml b/.github/workflows/arduino-lint.yaml index 7c15bc9..f99b9d4 100644 --- a/.github/workflows/arduino-lint.yaml +++ b/.github/workflows/arduino-lint.yaml @@ -4,7 +4,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: arduino/arduino-lint-action@v1 with: library-manager: update diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 908c62e..2f5869a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,7 +17,7 @@ jobs: check_version_files: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: check version run: | @@ -26,7 +26,7 @@ jobs: prepare_example_json: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: generate examples id: set-matrix @@ -61,7 +61,7 @@ jobs: ARDUINO_DIRECTORIES_DATA: /home/runner/arduino_ide steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Get hash id: get-hash @@ -116,7 +116,7 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: install libgtk2.0-0 run: | From d41d65ccdc3ff3b1f0d4310c0d9c2022ab9441e1 Mon Sep 17 00:00:00 2001 From: Links2004 Date: Sun, 25 Aug 2024 18:35:45 +0200 Subject: [PATCH 340/347] bump version 2.6.0 --- library.json | 4 ++-- library.properties | 2 +- src/WebSocketsVersion.h | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/library.json b/library.json index a2159dc..d101c4a 100644 --- a/library.json +++ b/library.json @@ -21,5 +21,5 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.5.3" -} + "version": "2.6.0" +} \ No newline at end of file diff --git a/library.properties b/library.properties index 18c7748..6c54794 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.5.3 +version=2.6.0 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index 8662206..7d3c46b 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -1,6 +1,6 @@ /** * @file WebSocketsVersion.h - * @date 29.07.2024 + * @date 25.08.2024 * @author Markus Sattler * * Copyright (c) 2015 Markus Sattler. All rights reserved. @@ -25,12 +25,12 @@ #ifndef WEBSOCKETSVERSION_H_ #define WEBSOCKETSVERSION_H_ -#define WEBSOCKETS_VERSION "2.5.3" +#define WEBSOCKETS_VERSION "2.6.0" #define WEBSOCKETS_VERSION_MAJOR 2 -#define WEBSOCKETS_VERSION_MINOR 5 -#define WEBSOCKETS_VERSION_PATCH 3 +#define WEBSOCKETS_VERSION_MINOR 6 +#define WEBSOCKETS_VERSION_PATCH 0 -#define WEBSOCKETS_VERSION_INT 2005003 +#define WEBSOCKETS_VERSION_INT 2006000 #endif /* WEBSOCKETSVERSION_H_ */ From 66f69c3b207578c8a2368377a691e5d399e621ec Mon Sep 17 00:00:00 2001 From: OCH <18335360+omarcostahamido@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:59:46 +0100 Subject: [PATCH 341/347] Update WebSocketServer.ino - fixed weird indentations --- .../esp32/WebSocketServer/WebSocketServer.ino | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/esp32/WebSocketServer/WebSocketServer.ino b/examples/esp32/WebSocketServer/WebSocketServer.ino index 87866ed..7e1bf19 100644 --- a/examples/esp32/WebSocketServer/WebSocketServer.ino +++ b/examples/esp32/WebSocketServer/WebSocketServer.ino @@ -42,8 +42,8 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length IPAddress ip = webSocket.remoteIP(num); USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); - // send message to client - webSocket.sendTXT(num, "Connected"); + // send message to client + webSocket.sendTXT(num, "Connected"); } break; case WStype_TEXT: @@ -62,12 +62,12 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length // send message to client // webSocket.sendBIN(num, payload, length); break; - case WStype_ERROR: - case WStype_FRAGMENT_TEXT_START: - case WStype_FRAGMENT_BIN_START: - case WStype_FRAGMENT: - case WStype_FRAGMENT_FIN: - break; + case WStype_ERROR: + case WStype_FRAGMENT_TEXT_START: + case WStype_FRAGMENT_BIN_START: + case WStype_FRAGMENT: + case WStype_FRAGMENT_FIN: + break; } } From bd011d8fd8347a5ebd7fcafba38103633f8c56a0 Mon Sep 17 00:00:00 2001 From: Links2004 Date: Fri, 6 Sep 2024 20:20:30 +0200 Subject: [PATCH 342/347] clang --- src/SocketIOclient.h | 4 ++-- src/WebSockets.h | 10 +++++----- src/WebSocketsClient.cpp | 31 +++++++++++++++---------------- src/WebSocketsClient.h | 8 ++++---- src/WebSocketsServer.cpp | 22 +++++++++++----------- 5 files changed, 37 insertions(+), 38 deletions(-) diff --git a/src/SocketIOclient.h b/src/SocketIOclient.h index 99af80b..cd5d2ec 100644 --- a/src/SocketIOclient.h +++ b/src/SocketIOclient.h @@ -56,10 +56,10 @@ class SocketIOclient : protected WebSocketsClient { #ifndef SSL_AXTLS void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino", uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5); void setSSLClientCertKey(const char * clientCert = NULL, const char * clientPrivateKey = NULL); - #if defined(SSL_BARESSL) +#if defined(SSL_BARESSL) void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino", uint32_t pingInterval = 60 * 1000, uint32_t pongTimeout = 90 * 1000, uint8_t disconnectTimeoutCount = 5); void setSSLClientCertKey(BearSSL::X509List * clientCert = NULL, BearSSL::PrivateKey * clientPrivateKey = NULL); - #endif +#endif #endif #endif bool isConnected(void); diff --git a/src/WebSockets.h b/src/WebSockets.h index 13a022a..c918c9f 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -262,9 +262,9 @@ #elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) #if __has_include() - #include +#include #else - #error "Please install WiFiNINA library!" +#error "Please install WiFiNINA library!" #endif #define WEBSOCKETS_NETWORK_CLASS WiFiClient @@ -273,10 +273,10 @@ #elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) #if __has_include() && __has_include() - #include - #include +#include +#include #else - #error "Please install rpcWiFi library!" +#error "Please install rpcWiFi library!" #endif #define WEBSOCKETS_NETWORK_CLASS WiFiClient diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index 34357ab..e8394f3 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -177,7 +177,6 @@ void WebSocketsClient::setSSLClientCertKey(BearSSL::X509List * clientCert, BearS } #endif // SSL_BARESSL - #endif // SSL_AXTLS #endif // HAS_SSL @@ -245,12 +244,12 @@ void WebSocketsClient::loop(void) { if(_client.isSSL) { DEBUG_WEBSOCKETS("[WS-Client] connect wss...\n"); if(_client.ssl) { - #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) || (WEBSOCKETS_NETWORK_TYPE ==NETWORK_UNOWIFIR4) - // does not support delete (no destructor) - #else - delete _client.ssl; - #endif - +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_UNOWIFIR4) + // does not support delete (no destructor) +#else + delete _client.ssl; +#endif + _client.ssl = NULL; _client.tcp = NULL; } @@ -295,11 +294,11 @@ void WebSocketsClient::loop(void) { } else { DEBUG_WEBSOCKETS("[WS-Client] connect ws...\n"); if(_client.tcp) { - #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) || (WEBSOCKETS_NETWORK_TYPE ==NETWORK_UNOWIFIR4) - // does not support delete (no destructor) - #else +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_UNOWIFIR4) + // does not support delete (no destructor) +#else delete _client.tcp; - #endif +#endif _client.tcp = NULL; } _client.tcp = new WEBSOCKETS_NETWORK_CLASS(); @@ -550,11 +549,11 @@ void WebSocketsClient::clientDisconnect(WSclient_t * client) { #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->status = WSC_NOT_CONNECTED; #else - #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) || (WEBSOCKETS_NETWORK_TYPE ==NETWORK_UNOWIFIR4) - // does not support delete (no destructor) - #else - delete client->tcp; - #endif +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_UNOWIFIR4) + // does not support delete (no destructor) +#else + delete client->tcp; +#endif #endif client->tcp = NULL; } diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index 95a126a..e60088b 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -48,10 +48,10 @@ class WebSocketsClient : protected WebSockets { void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino"); #else void beginSSL(const char * host, uint16_t port, const char * url = "/", const uint8_t * fingerprint = NULL, const char * protocol = "arduino"); - #if defined(SSL_BARESSL) +#if defined(SSL_BARESSL) void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino"); void setSSLClientCertKey(BearSSL::X509List * clientCert = NULL, BearSSL::PrivateKey * clientPrivateKey = NULL); - #endif +#endif void setSSLClientCertKey(const char * clientCert = NULL, const char * clientPrivateKey = NULL); #endif void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", const char * CA_cert = NULL, const char * protocol = "arduino"); @@ -131,11 +131,11 @@ class WebSocketsClient : protected WebSockets { #define SSL_FINGERPRINT_NULL "" #else const uint8_t * _fingerprint; - #if defined(SSL_BARESSL) +#if defined(SSL_BARESSL) BearSSL::X509List * _CA_cert; BearSSL::X509List * _client_cert; BearSSL::PrivateKey * _client_key; - #endif +#endif #define SSL_FINGERPRINT_IS_SET (_fingerprint != NULL) #define SSL_FINGERPRINT_NULL NULL #endif diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 2eccbc4..3f60c53 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -65,11 +65,11 @@ WebSocketsServerCore::~WebSocketsServerCore() { } WebSocketsServer::~WebSocketsServer() { - #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) - // does not support delete (no destructor) - #else - delete _server; - #endif +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) + // does not support delete (no destructor) +#else + delete _server; +#endif } /** @@ -660,12 +660,12 @@ void WebSocketsServer::handleNewClients(void) { while(_server->hasClient()) { #endif - // store new connection - #if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) - WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); - #else - WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->accept()); - #endif +// store new connection +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) + WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->available()); +#else + WEBSOCKETS_NETWORK_CLASS * tcpClient = new WEBSOCKETS_NETWORK_CLASS(_server->accept()); +#endif if(!tcpClient) { DEBUG_WEBSOCKETS("[WS-Client] creating Network class failed!"); From 87b23a48e9872b5f9fdb9b757ac44fd1b57f8d9a Mon Sep 17 00:00:00 2001 From: Links2004 Date: Fri, 6 Sep 2024 20:20:45 +0200 Subject: [PATCH 343/347] fix #907 use corect random source for newer ESP32 models --- src/WebSocketsServer.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index 3f60c53..d3857e6 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -25,6 +25,14 @@ #include "WebSockets.h" #include "WebSocketsServer.h" +#ifdef ESP32 +#if defined __has_include +#if __has_include("soc/wdev_reg.h") +#include "soc/wdev_reg.h" +#endif // __has_include +#endif // defined __has_include +#endif + WebSocketsServerCore::WebSocketsServerCore(const String & origin, const String & protocol) { _origin = origin; _protocol = protocol; @@ -87,6 +95,8 @@ void WebSocketsServerCore::begin(void) { #ifdef ESP8266 randomSeed(RANDOM_REG32); +#elif defined(ESP32) && defined(WDEV_RND_REG) + randomSeed(REG_READ(WDEV_RND_REG)); #elif defined(ESP32) #define DR_REG_RNG_BASE 0x3ff75144 randomSeed(READ_PERI_REG(DR_REG_RNG_BASE)); From 7a4c416082b80dfc2c0da10731effc8d3a69abc6 Mon Sep 17 00:00:00 2001 From: Links2004 Date: Fri, 6 Sep 2024 20:22:33 +0200 Subject: [PATCH 344/347] bump version to 2.6.1 --- library.json | 2 +- library.properties | 2 +- src/WebSocketsVersion.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library.json b/library.json index d101c4a..81fa515 100644 --- a/library.json +++ b/library.json @@ -21,5 +21,5 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.6.0" + "version": "2.6.1" } \ No newline at end of file diff --git a/library.properties b/library.properties index 6c54794..0526b57 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.6.0 +version=2.6.1 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index 7d3c46b..1cbf46b 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -1,6 +1,6 @@ /** * @file WebSocketsVersion.h - * @date 25.08.2024 + * @date 06.09.2024 * @author Markus Sattler * * Copyright (c) 2015 Markus Sattler. All rights reserved. @@ -25,12 +25,12 @@ #ifndef WEBSOCKETSVERSION_H_ #define WEBSOCKETSVERSION_H_ -#define WEBSOCKETS_VERSION "2.6.0" +#define WEBSOCKETS_VERSION "2.6.1" #define WEBSOCKETS_VERSION_MAJOR 2 #define WEBSOCKETS_VERSION_MINOR 6 -#define WEBSOCKETS_VERSION_PATCH 0 +#define WEBSOCKETS_VERSION_PATCH 1 -#define WEBSOCKETS_VERSION_INT 2006000 +#define WEBSOCKETS_VERSION_INT 2006001 #endif /* WEBSOCKETSVERSION_H_ */ From 1bea68969469a9374d355f44d2cd4dc3588b339c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 11:00:40 +0000 Subject: [PATCH 345/347] Bump arduino/arduino-lint-action from 1 to 2 Bumps [arduino/arduino-lint-action](https://github.com/arduino/arduino-lint-action) from 1 to 2. - [Release notes](https://github.com/arduino/arduino-lint-action/releases) - [Commits](https://github.com/arduino/arduino-lint-action/compare/v1...v2) --- updated-dependencies: - dependency-name: arduino/arduino-lint-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/arduino-lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/arduino-lint.yaml b/.github/workflows/arduino-lint.yaml index f99b9d4..6550c8e 100644 --- a/.github/workflows/arduino-lint.yaml +++ b/.github/workflows/arduino-lint.yaml @@ -5,6 +5,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: arduino/arduino-lint-action@v1 + - uses: arduino/arduino-lint-action@v2 with: library-manager: update From daf04b0560acba881464c1654b557c3395be9b99 Mon Sep 17 00:00:00 2001 From: OCH <18335360+omarcostahamido@users.noreply.github.com> Date: Sat, 16 Nov 2024 18:47:10 +0000 Subject: [PATCH 346/347] Update WebSocketClientSocketIOack.ino - fix some typos --- .../WebSocketClientSocketIOack.ino | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/esp32/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino b/examples/esp32/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino index af3572f..0e0fb5b 100644 --- a/examples/esp32/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino +++ b/examples/esp32/WebSocketClientSocketIOack/WebSocketClientSocketIOack.ino @@ -54,7 +54,7 @@ void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) // Message Includes a ID for a ACK (callback) if(id) { - // creat JSON message for Socket.IO (ack) + // create JSON message for Socket.IO (ack) DynamicJsonDocument docOut(1024); JsonArray array = docOut.to(); @@ -130,11 +130,11 @@ void loop() { if(now - messageTimestamp > 2000) { messageTimestamp = now; - // creat JSON message for Socket.IO (event) + // create JSON message for Socket.IO (event) DynamicJsonDocument doc(1024); JsonArray array = doc.to(); - // add evnet name + // add event name // Hint: socket.on('event_name', .... array.add("event_name"); @@ -142,7 +142,7 @@ void loop() { JsonObject param1 = array.createNestedObject(); param1["now"] = (uint32_t) now; - // JSON to String (serializion) + // JSON to String (serialization) String output; serializeJson(doc, output); From 1789a18ddb0319dc707be3a6588e26f3b3afc04f Mon Sep 17 00:00:00 2001 From: Akashdeep Deb Date: Sun, 29 Dec 2024 17:25:08 +0800 Subject: [PATCH 347/347] Update README.md (#927) * Update README.md Updating README to include ESP32 support in client mode * Update README.md --------- Co-authored-by: Markus <974709+Links2004@users.noreply.github.com> --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index bc37c8a..672c649 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ a WebSocket Server and Client for Arduino based on RFC6455. ### wss / SSL ### supported for: - wss client on the ESP8266 + - wss / SSL for ESP32 in client mode - wss / SSL is not natively supported in WebSocketsServer however it is possible to achieve secure websockets by running the device behind an SSL proxy. See [Nginx](examples/Nginx/esp8266.ssl.reverse.proxy.conf) for a sample Nginx server configuration file to enable this.