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/src/WebSockets.h b/src/WebSockets.h index c918c9f..d5d08e1 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) @@ -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 @@ -368,7 +377,7 @@ typedef struct { #if defined(HAS_SSL) bool isSSL = false; ///< run in ssl mode - WEBSOCKETS_NETWORK_SSL_CLASS * ssl; + WEBSOCKETS_NETWORK_SSL_CLASS * ssl = nullptr; #endif String cUrl; ///< http url diff --git a/src/WebSocketsClient.cpp b/src/WebSocketsClient.cpp index e8394f3..a9b3865 100644 --- a/src/WebSocketsClient.cpp +++ b/src/WebSocketsClient.cpp @@ -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) +#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_RP2040) || (WEBSOCKETS_NETWORK_TYPE == NETWORK_CUSTOM) if(client->isSSL && client->ssl) { if(client->ssl->connected()) { client->ssl->flush(); 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); +};