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 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. 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); diff --git a/examples/esp32_pio/CustomNetworkClient/.clang-format b/examples/esp32_pio/CustomNetworkClient/.clang-format new file mode 100644 index 0000000..2593ef5 --- /dev/null +++ b/examples/esp32_pio/CustomNetworkClient/.clang-format @@ -0,0 +1 @@ +BasedOnStyle: Google \ No newline at end of file diff --git a/examples/esp32_pio/CustomNetworkClient/.gitignore b/examples/esp32_pio/CustomNetworkClient/.gitignore new file mode 100644 index 0000000..b9f3806 --- /dev/null +++ b/examples/esp32_pio/CustomNetworkClient/.gitignore @@ -0,0 +1,2 @@ +.pio +.vscode diff --git a/examples/esp32_pio/CustomNetworkClient/lib/README b/examples/esp32_pio/CustomNetworkClient/lib/README new file mode 100644 index 0000000..e69de29 diff --git a/examples/esp32_pio/CustomNetworkClient/platformio.ini b/examples/esp32_pio/CustomNetworkClient/platformio.ini new file mode 100644 index 0000000..dfbcf7d --- /dev/null +++ b/examples/esp32_pio/CustomNetworkClient/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@6.11.0 +board = esp32dev +framework = arduino +monitor_speed = 115200 +upload_speed = 921600 +build_flags = + -DCORE_DEBUG_LEVEL=5 + -D WEBSOCKETS_NETWORK_TYPE=10 + -D TINY_GSM_MODEM_SIM7600 +lib_deps = + digitaldragon/SSLClient@^1.3.2 + vshymanskyy/StreamDebugger@^1.0.1 + vshymanskyy/TinyGSM@^0.12.0 + symlink://../../.. diff --git a/examples/esp32_pio/CustomNetworkClient/readme.md b/examples/esp32_pio/CustomNetworkClient/readme.md new file mode 100644 index 0000000..947e225 --- /dev/null +++ b/examples/esp32_pio/CustomNetworkClient/readme.md @@ -0,0 +1,3 @@ +This example project shows how to use a custom NetworkClient class to switch between two underlying network interfaces. + +In this case it shows how a board can support Wi-Fi as well as GSM/LTE connectivity. It uses a shim to switch between the two network interfaces, thereby allowing a single binary to handle both interfaces without needing to reboot. This example can be extended to cover other network interfaces that conform to the Client() class interface. diff --git a/examples/esp32_pio/CustomNetworkClient/src/main.cpp b/examples/esp32_pio/CustomNetworkClient/src/main.cpp new file mode 100644 index 0000000..d90c916 --- /dev/null +++ b/examples/esp32_pio/CustomNetworkClient/src/main.cpp @@ -0,0 +1,126 @@ +/* + * main.cpp + * + * Created on: 15.06.2024 + * + */ + +#include +#include +#include + +#include "network_client_impl.h" + +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("Berge", "BlauerHimmel!"); + + // WiFi.disconnect(); + while (wifiMulti.run() != WL_CONNECTED) { + delay(100); + } + + // Call to enable WiFi interface to be used by the webSocketClient + WebSocketsNetworkClient::Impl::enableWifi(); + + setClock(); + + // server address, port and URL. This server can be flakey. + // Expected response: Request served by 0123456789abcdef + webSocket.beginSSL("echo.websocket.org", 443, "/"); + + // 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/CustomNetworkClient/src/network_client.cpp b/examples/esp32_pio/CustomNetworkClient/src/network_client.cpp new file mode 100644 index 0000000..3150d09 --- /dev/null +++ b/examples/esp32_pio/CustomNetworkClient/src/network_client.cpp @@ -0,0 +1,148 @@ +#include "network_client_impl.h" + +WebSocketsNetworkClient::WebSocketsNetworkClient() + : _impl(new WebSocketsNetworkClient::Impl()) {} +WebSocketsNetworkClient::WebSocketsNetworkClient(WiFiClient wifi_client) + : _impl(new WebSocketsNetworkClient::Impl()) {} +WebSocketsNetworkClient::~WebSocketsNetworkClient() {} + +int WebSocketsNetworkClient::connect(IPAddress ip, uint16_t port) { + if (_impl->gsm_client_) { + return _impl->gsm_client_->connect(ip, port); + } else if (_impl->wifi_client_) { + return _impl->wifi_client_->connect(ip, port); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +int WebSocketsNetworkClient::connect(const char *host, uint16_t port) { + if (_impl->gsm_client_) { + return _impl->gsm_client_->connect(host, port); + } else if (_impl->wifi_client_) { + return _impl->wifi_client_->connect(host, port); + } + Serial.println(_impl->no_interface_error_); + return 0; +} +int WebSocketsNetworkClient::connect(const char *host, uint16_t port, + int32_t timeout_ms) { + if (_impl->gsm_client_) { + return _impl->gsm_client_->connect(host, port, timeout_ms); + } else if (_impl->wifi_client_) { + return _impl->wifi_client_->connect(host, port, timeout_ms); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +size_t WebSocketsNetworkClient::write(uint8_t data) { + if (_impl->gsm_client_) { + return _impl->gsm_client_->write(data); + } else if (_impl->wifi_client_) { + return _impl->wifi_client_->write(data); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +size_t WebSocketsNetworkClient::write(const uint8_t *buf, size_t size) { + Serial.printf("Send_: %zu\n", size); + if (_impl->gsm_client_) { + return _impl->gsm_client_->write(buf, size); + } else if (_impl->wifi_client_) { + return _impl->wifi_client_->write(buf, size); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +size_t WebSocketsNetworkClient::write(const char *str) { + const int size = strlen(str); + Serial.printf("Send: %zu\n", size); + if (_impl->gsm_client_) { + return _impl->gsm_client_->write((const uint8_t *)str, size); + } else if (_impl->wifi_client_) { + return _impl->wifi_client_->write((const uint8_t *)str, size); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +int WebSocketsNetworkClient::available() { + if (_impl->gsm_client_) { + return _impl->gsm_client_->available(); + } else if (_impl->wifi_client_) { + return _impl->wifi_client_->available(); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +int WebSocketsNetworkClient::read() { + if (_impl->gsm_client_) { + return _impl->gsm_client_->read(); + } else if (_impl->wifi_client_) { + return _impl->wifi_client_->read(); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +int WebSocketsNetworkClient::read(uint8_t *buf, size_t size) { + if (_impl->gsm_client_) { + return _impl->gsm_client_->read(buf, size); + } else if (_impl->wifi_client_) { + return _impl->wifi_client_->read(buf, size); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +int WebSocketsNetworkClient::peek() { + if (_impl->gsm_client_) { + return _impl->gsm_client_->peek(); + } else if (_impl->wifi_client_) { + return _impl->wifi_client_->peek(); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +void WebSocketsNetworkClient::flush() { + if (_impl->gsm_client_) { + return _impl->gsm_client_->flush(); + } else if (_impl->wifi_client_) { + return _impl->wifi_client_->flush(); + } + Serial.println(_impl->no_interface_error_); +} + +void WebSocketsNetworkClient::stop() { + if (_impl->gsm_client_) { + return _impl->gsm_client_->stop(); + } else if (_impl->wifi_client_) { + return _impl->wifi_client_->stop(); + } + Serial.println(_impl->no_interface_error_); +} + +uint8_t WebSocketsNetworkClient::connected() { + if (_impl->gsm_client_) { + return _impl->gsm_client_->connected(); + } else if (_impl->wifi_client_) { + return _impl->wifi_client_->connected(); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +WebSocketsNetworkClient::operator bool() { + if (_impl->gsm_client_) { + return _impl->gsm_client_->operator bool(); + } else if (_impl->wifi_client_) { + return _impl->wifi_client_->operator bool(); + } + Serial.println(_impl->no_interface_error_); + return 0; +} diff --git a/examples/esp32_pio/CustomNetworkClient/src/network_client_impl.cpp b/examples/esp32_pio/CustomNetworkClient/src/network_client_impl.cpp new file mode 100644 index 0000000..cf8d22f --- /dev/null +++ b/examples/esp32_pio/CustomNetworkClient/src/network_client_impl.cpp @@ -0,0 +1,8 @@ +#include "network_client_impl.h" + +std::unique_ptr WebSocketsNetworkClient::Impl::wifi_client_ = nullptr; +std::unique_ptr WebSocketsNetworkClient::Impl::wifi_client_secure_ = + nullptr; +std::unique_ptr WebSocketsNetworkClient::Impl::gsm_client_ = nullptr; +std::unique_ptr WebSocketsNetworkClient::Impl::gsm_client_secure_ = nullptr; +const char *WebSocketsNetworkClient::Impl::no_interface_error_ = "No interface"; diff --git a/examples/esp32_pio/CustomNetworkClient/src/network_client_impl.h b/examples/esp32_pio/CustomNetworkClient/src/network_client_impl.h new file mode 100644 index 0000000..4a62302 --- /dev/null +++ b/examples/esp32_pio/CustomNetworkClient/src/network_client_impl.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include +#include + +struct WebSocketsNetworkClient::Impl { + static void enableWifi() { + // Do nothing if already enabled + if (wifi_client_ && wifi_client_secure_) { + return; + } + wifi_client_ = std::unique_ptr(new WiFiClient()); + wifi_client_secure_ = + std::unique_ptr(new WiFiClientSecure()); + } + static void disableWifi() { + wifi_client_ = nullptr; + wifi_client_secure_ = nullptr; + } + static void enableGsm(TinyGsm* tiny_gsm) { + // Do nothing if already enabled + if (gsm_client_ && gsm_client_secure_) { + return; + } + gsm_client_ = std::unique_ptr(new TinyGsmClient(*tiny_gsm)); + gsm_client_secure_ = + std::unique_ptr(new SSLClient(gsm_client_.get())); + } + static void disableGsm() { + if (gsm_client_secure_) { + gsm_client_secure_->stop(); + } + gsm_client_secure_ = nullptr; + gsm_client_ = nullptr; + } + + static std::unique_ptr wifi_client_; + static std::unique_ptr wifi_client_secure_; + static std::unique_ptr gsm_client_; + static std::unique_ptr gsm_client_secure_; + + static const char* no_interface_error_; +}; \ No newline at end of file diff --git a/examples/esp32_pio/CustomNetworkClient/src/network_client_secure.cpp b/examples/esp32_pio/CustomNetworkClient/src/network_client_secure.cpp new file mode 100644 index 0000000..a2e78a2 --- /dev/null +++ b/examples/esp32_pio/CustomNetworkClient/src/network_client_secure.cpp @@ -0,0 +1,191 @@ +#include "network_client_impl.h" + +WebSocketsNetworkClientSecure::WebSocketsNetworkClientSecure() {} +WebSocketsNetworkClientSecure::WebSocketsNetworkClientSecure( + WiFiClient wifi_client) {} +WebSocketsNetworkClientSecure::~WebSocketsNetworkClientSecure() { + if (_impl->gsm_client_secure_) { + _impl->gsm_client_secure_->stop(); + } +} + +int WebSocketsNetworkClientSecure::connect(IPAddress ip, uint16_t port) { + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->connect(ip, port); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->connect(ip, port); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +int WebSocketsNetworkClientSecure::connect(const char *host, uint16_t port) { + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->connect(host, port); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->connect(host, port); + } + Serial.println(_impl->no_interface_error_); + return 0; +} +int WebSocketsNetworkClientSecure::connect(const char *host, uint16_t port, + int32_t timeout_ms) { + if (_impl->gsm_client_secure_) { + // Ignore timeout as will cause read() to block for specified time + return _impl->gsm_client_secure_->connect(host, port); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->connect(host, port, timeout_ms); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +size_t WebSocketsNetworkClientSecure::write(uint8_t data) { + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->write(data); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->write(data); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +size_t WebSocketsNetworkClientSecure::write(const uint8_t *buf, size_t size) { + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->write(buf, size); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->write(buf, size); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +size_t WebSocketsNetworkClientSecure::write(const char *str) { + const int size = strlen(str); + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->write((const uint8_t *)str, size); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->write((const uint8_t *)str, size); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +int WebSocketsNetworkClientSecure::available() { + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->available(); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->available(); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +int WebSocketsNetworkClientSecure::read() { + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->read(); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->read(); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +int WebSocketsNetworkClientSecure::read(uint8_t *buf, size_t size) { + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->read(buf, size); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->read(buf, size); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +int WebSocketsNetworkClientSecure::peek() { + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->peek(); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->peek(); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +void WebSocketsNetworkClientSecure::flush() { + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->flush(); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->flush(); + } + Serial.println(_impl->no_interface_error_); +} + +void WebSocketsNetworkClientSecure::stop() { + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->stop(); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->stop(); + } + Serial.println(_impl->no_interface_error_); +} + +uint8_t WebSocketsNetworkClientSecure::connected() { + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->connected(); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->connected(); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +WebSocketsNetworkClientSecure::operator bool() { + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->operator bool(); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->operator bool(); + } + Serial.println(_impl->no_interface_error_); + return 0; +} + +void WebSocketsNetworkClientSecure::setCACert(const char *rootCA) { + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->setCertificate(rootCA); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->setCACert(rootCA); + } + Serial.println(_impl->no_interface_error_); +} + +void WebSocketsNetworkClientSecure::setCACertBundle(const uint8_t *bundle) { + if (_impl->gsm_client_secure_) { + return _impl->gsm_client_secure_->setCACertBundle(bundle); + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->setCACertBundle(bundle); + } + Serial.println(_impl->no_interface_error_); +} + +void WebSocketsNetworkClientSecure::setInsecure() { + if (_impl->gsm_client_secure_) { + _impl->gsm_client_secure_->setInsecure(); + } else if (_impl->wifi_client_secure_) { + _impl->wifi_client_secure_->setInsecure(); + } + Serial.println(_impl->no_interface_error_); +} + +bool WebSocketsNetworkClientSecure::verify(const char *fingerprint, + const char *domain_name) { + if (_impl->gsm_client_secure_) { + // Simply calling SSLClient::verify() will break TLS handshake + // Can be skipped as verification is done by SSLClient itself, + // ArduinoWebSockets need not call it + return true; + } else if (_impl->wifi_client_secure_) { + return _impl->wifi_client_secure_->verify(fingerprint, domain_name); + } + Serial.println(_impl->no_interface_error_); + return false; +} diff --git a/library.json b/library.json index 81fa515..1df003f 100644 --- a/library.json +++ b/library.json @@ -21,5 +21,5 @@ "type": "git", "url": "https://github.com/Links2004/arduinoWebSockets.git" }, - "version": "2.6.1" + "version": "2.7.0" } \ No newline at end of file diff --git a/library.properties b/library.properties index 0526b57..370182d 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=WebSockets -version=2.6.1 +version=2.7.0 author=Markus Sattler maintainer=Markus Sattler sentence=WebSockets for Arduino (Server + Client) diff --git a/src/WebSockets.cpp b/src/WebSockets.cpp index 2d3a254..9b9ca8f 100644 --- a/src/WebSockets.cpp +++ b/src/WebSockets.cpp @@ -42,7 +42,7 @@ extern "C" { #include #if ESP_IDF_VERSION_MAJOR >= 4 -#if(ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(1, 0, 6)) +#if (ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(1, 0, 6)) #include "sha/sha_parallel_engine.h" #else #include @@ -328,7 +328,7 @@ void WebSockets::headerDone(WSclient_t * client) { 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 @@ -525,7 +525,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 @@ -594,7 +594,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; } diff --git a/src/WebSockets.h b/src/WebSockets.h index c918c9f..51ee3ef 100644 --- a/src/WebSockets.h +++ b/src/WebSockets.h @@ -135,6 +135,7 @@ #define NETWORK_UNOWIFIR4 (7) #define NETWORK_WIFI_NINA (8) #define NETWORK_SAMD_SEED (9) +#define NETWORK_CUSTOM (10) // max size of the WS Message Header #define WEBSOCKETS_MAX_HEADER_SIZE (14) @@ -169,7 +170,7 @@ #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 @@ -192,7 +193,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!" @@ -212,7 +213,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 @@ -224,13 +225,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 @@ -239,13 +240,13 @@ #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 #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer -#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) #include #include @@ -254,13 +255,13 @@ #define WEBSOCKETS_NETWORK_SSL_CLASS WiFiClientSecure #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer -#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_UNOWIFIR4) +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_UNOWIFIR4) #include #define WEBSOCKETS_NETWORK_CLASS WiFiClient #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer -#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) #if __has_include() #include #else @@ -271,7 +272,7 @@ #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer #define WEBSOCKETS_NETWORK_SSL_CLASS WiFiSSLClient -#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) #if __has_include() && __has_include() #include #include @@ -286,6 +287,14 @@ #define WEBSOCKETS_NETWORK_CLASS WiFiClient #define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_CUSTOM) +#include +#include + +#define SSL_AXTLS +#define WEBSOCKETS_NETWORK_CLASS WebSocketsNetworkClient +#define WEBSOCKETS_NETWORK_SSL_CLASS WebSocketsNetworkClientSecure +#define WEBSOCKETS_NETWORK_SERVER_CLASS WiFiServer #else #error "no network type selected!" #endif @@ -367,8 +376,8 @@ typedef struct { bool isSocketIO = false; ///< client for socket.io server #if defined(HAS_SSL) - bool isSSL = false; ///< run in ssl mode - WEBSOCKETS_NETWORK_SSL_CLASS * ssl; + bool isSSL = false; ///< run in ssl mode + WEBSOCKETS_NETWORK_SSL_CLASS * ssl = nullptr; #endif String cUrl; ///< http url @@ -404,7 +413,7 @@ typedef struct { 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) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) String cHttpLine; ///< HTTP header lines #endif diff --git a/src/WebSockets4WebServer.h b/src/WebSockets4WebServer.h index 595f38b..b2eddcc 100644 --- a/src/WebSockets4WebServer.h +++ b/src/WebSockets4WebServer.h @@ -28,7 +28,7 @@ #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) diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index e8394f3..60a47d3 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -88,7 +88,7 @@ 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 @@ -225,7 +225,7 @@ void WebSocketsClient::beginSocketIOSSLWithCA(const char * host, uint16_t port, #endif -#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * called in arduino loop */ @@ -244,7 +244,7 @@ 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) +#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; @@ -261,7 +261,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); #elif defined(WIO_TERMINAL) || defined(SEEED_XIAO_M0) _client.ssl->setCACert(_CA_cert); @@ -294,7 +294,7 @@ 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) +#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; @@ -525,7 +525,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) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) +#ifdef HAS_SSL if(client->isSSL && client->ssl) { if(client->ssl->connected()) { client->ssl->flush(); @@ -540,16 +540,16 @@ 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 -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_UNOWIFIR4) +#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; @@ -605,7 +605,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 */ @@ -726,7 +726,7 @@ void WebSocketsClient::sendHeader(WSclient_t * client) { 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 @@ -801,7 +801,7 @@ 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 { @@ -871,7 +871,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) +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) } else if(client->isSocketIO) { if(client->cSessionId.length() > 0) { DEBUG_WEBSOCKETS("[WS-Client][handleHeader] found cSessionId\n"); @@ -899,7 +899,7 @@ 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; @@ -915,12 +915,12 @@ void WebSocketsClient::connectedCb() { _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) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) _client.tcp->setNoDelay(true); #endif @@ -950,7 +950,7 @@ 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"); diff --git a/src/WebSocketsClient.h b/src/WebSocketsClient.h index e60088b..8294b3c 100644 --- a/src/WebSocketsClient.h +++ b/src/WebSocketsClient.h @@ -77,7 +77,7 @@ class WebSocketsClient : protected WebSockets { #endif #endif -#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void loop(void); #else // Async interface not need a loop call @@ -140,7 +140,7 @@ class WebSocketsClient : protected WebSockets { #define SSL_FINGERPRINT_NULL NULL #endif -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) const char * _CA_cert; const uint8_t * _CA_bundle; #endif @@ -159,7 +159,7 @@ class WebSocketsClient : protected WebSockets { void clientDisconnect(WSclient_t * client); bool clientIsConnected(WSclient_t * client); -#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void handleClientData(void); #endif @@ -171,7 +171,7 @@ class WebSocketsClient : protected WebSockets { void handleHBPing(); // send ping in specified intervals -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) void asyncConnect(); #endif diff --git a/src/WebSocketsNetworkClient.h b/src/WebSocketsNetworkClient.h new file mode 100644 index 0000000..7003a61 --- /dev/null +++ b/src/WebSocketsNetworkClient.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +class WebSocketsNetworkClient : public Client { + public: + struct Impl; + std::unique_ptr _impl; + + WebSocketsNetworkClient(); + WebSocketsNetworkClient(WiFiClient wifi_client); + virtual ~WebSocketsNetworkClient(); + + virtual int connect(IPAddress ip, uint16_t port); + virtual int connect(const char * host, uint16_t port); + virtual int connect(const char * host, uint16_t port, int32_t timeout); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t * buf, size_t size); + virtual size_t write(const char * str); + virtual int available(); + virtual int read(); + virtual int read(uint8_t * buf, size_t size); + virtual int peek(); + virtual void flush(); + virtual void stop(); + virtual uint8_t connected(); + virtual operator bool(); +}; diff --git a/src/WebSocketsNetworkClientSecure.h b/src/WebSocketsNetworkClientSecure.h new file mode 100644 index 0000000..efa9cd1 --- /dev/null +++ b/src/WebSocketsNetworkClientSecure.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +class WebSocketsNetworkClientSecure : public WebSocketsNetworkClient { + public: + WebSocketsNetworkClientSecure(); + WebSocketsNetworkClientSecure(WiFiClient wifi_client); + virtual ~WebSocketsNetworkClientSecure(); + + int connect(IPAddress ip, uint16_t port) override; + int connect(const char * host, uint16_t port) override; + int connect(const char * host, uint16_t port, int32_t timeout) override; + size_t write(uint8_t) override; + size_t write(const uint8_t * buf, size_t size) override; + size_t write(const char * str) override; + int available() override; + int read() override; + int read(uint8_t * buf, size_t size) override; + int peek() override; + void flush() override; + void stop() override; + uint8_t connected() override; + operator bool() override; + + void setCACert(const char * rootCA); + void setCACertBundle(const uint8_t * bundle); + void setInsecure(); + bool verify(const char * fingerprint, const char * domain_name); +}; diff --git a/src/WebSocketsServer.cpp b/src/WebSocketsServer.cpp index d3857e6..9d64c3a 100644 --- a/src/WebSocketsServer.cpp +++ b/src/WebSocketsServer.cpp @@ -54,7 +54,7 @@ WebSocketsServer::WebSocketsServer(uint16_t port, const String & origin, const S _server = new WEBSOCKETS_NETWORK_SERVER_CLASS(port); -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) _server->onClient([](void * s, AsyncClient * c) { ((WebSocketsServerCore *)s)->newClient(new AsyncTCPbuffer(c)); }, @@ -73,7 +73,7 @@ WebSocketsServerCore::~WebSocketsServerCore() { } WebSocketsServer::~WebSocketsServer() { -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) // does not support delete (no destructor) #else delete _server; @@ -411,7 +411,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) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) +#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 @@ -445,7 +445,7 @@ WSclient_t * WebSocketsServerCore::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclien // look for match to existing socket before creating a new one if(clientIsConnected(client)) { -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_W5100) +#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; @@ -455,16 +455,16 @@ WSclient_t * WebSocketsServerCore::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclien // state is not connected or tcp connection is lost 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) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) +#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 @@ -473,7 +473,7 @@ WSclient_t * WebSocketsServerCore::newClient(WEBSOCKETS_NETWORK_CLASS * TCPclien 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([](WebSocketsServerCore * server, AsyncTCPbuffer * obj, WSclient_t * client) -> bool { DEBUG_WEBSOCKETS("[WS-Server][%d] Disconnect client\n", client->num); @@ -546,14 +546,14 @@ 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) && (WEBSOCKETS_NETWORK_TYPE != NETWORK_RP2040) +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) && (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP32) && (WEBSOCKETS_NETWORK_TYPE != NETWORK_RP2040) 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; -#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) +#elif (WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_SAMD_SEED) // does not support delete (no destructor) #else delete client->tcp; @@ -567,7 +567,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) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) +#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(); @@ -590,7 +590,7 @@ void WebSocketsServerCore::clientDisconnect(WSclient_t * client) { client->cWsRXsize = 0; -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) client->cHttpLine = ""; #endif @@ -632,7 +632,7 @@ bool WebSocketsServerCore::clientIsConnected(WSclient_t * client) { return false; } -#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) /** * Handle incoming Connection Request */ @@ -641,7 +641,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) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) #ifndef NODEBUG_WEBSOCKETS IPAddress ip = tcpClient->remoteIP(); #endif @@ -666,12 +666,12 @@ 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) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) while(_server->hasClient()) { #endif // store new connection -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_WIFI_NINA) +#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()); @@ -684,7 +684,7 @@ void WebSocketsServer::handleNewClients(void) { handleNewClient(tcpClient); -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) +#if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) } #endif } @@ -798,7 +798,7 @@ void WebSocketsServerCore::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(&WebSocketsServerCore::handleHeader, this, client, &(client->cHttpLine))); #endif } else { @@ -955,16 +955,16 @@ void WebSocketsServer::begin(void) { void WebSocketsServer::close(void) { WebSocketsServerCore::close(); -#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) +#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) +#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 */ diff --git a/src/WebSocketsServer.h b/src/WebSocketsServer.h index 197c37f..25b0427 100644 --- a/src/WebSocketsServer.h +++ b/src/WebSocketsServer.h @@ -90,11 +90,11 @@ 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) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) +#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 -#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void loop(void); // handle client data only #endif @@ -123,7 +123,7 @@ class WebSocketsServerCore : protected WebSockets { void clientDisconnect(WSclient_t * client); bool clientIsConnected(WSclient_t * client); -#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void handleClientData(void); #endif @@ -199,7 +199,7 @@ class WebSocketsServerCore : protected WebSockets { return true; } -#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) WSclient_t * handleNewClient(WEBSOCKETS_NETWORK_CLASS * tcpClient); #endif @@ -224,7 +224,7 @@ class WebSocketsServer : public WebSocketsServerCore { void begin(void); void close(void); -#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void loop(void); // handle incoming client and client data #else // Async interface not need a loop call @@ -232,7 +232,7 @@ class WebSocketsServer : public WebSocketsServerCore { #endif protected: -#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) +#if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) void handleNewClients(void); #endif diff --git a/src/WebSocketsVersion.h b/src/WebSocketsVersion.h index 1cbf46b..99f7471 100644 --- a/src/WebSocketsVersion.h +++ b/src/WebSocketsVersion.h @@ -1,6 +1,6 @@ /** * @file WebSocketsVersion.h - * @date 06.09.2024 + * @date 13.08.2025 * @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.1" +#define WEBSOCKETS_VERSION "2.7.0" #define WEBSOCKETS_VERSION_MAJOR 2 -#define WEBSOCKETS_VERSION_MINOR 6 -#define WEBSOCKETS_VERSION_PATCH 1 +#define WEBSOCKETS_VERSION_MINOR 7 +#define WEBSOCKETS_VERSION_PATCH 0 -#define WEBSOCKETS_VERSION_INT 2006001 +#define WEBSOCKETS_VERSION_INT 2007000 #endif /* WEBSOCKETSVERSION_H_ */ diff --git a/travis/version.py b/travis/version.py index 71454ab..441fd33 100755 --- a/travis/version.py +++ b/travis/version.py @@ -73,7 +73,7 @@ def get_library_json_version(): def get_header_versions(): data = {} - define = re.compile('^#define WEBSOCKETS_VERSION_?(.*) "?([0-9\.]*)"?$') + 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)