diff --git a/code/espurna/config/general.h b/code/espurna/config/general.h index c1957336..05b66868 100644 --- a/code/espurna/config/general.h +++ b/code/espurna/config/general.h @@ -416,7 +416,12 @@ PROGMEM const char* const custom_reset_string[] = { #endif #ifndef SSDP_SUPPORT -#define SSDP_SUPPORT 0 // Publish device using SSDP protocol by default (3.32Kb) +#define SSDP_SUPPORT 1 // Publish device using SSDP protocol by default (4.59Kb) +#endif + +#ifndef SSDP_DEVICE_TYPE +#define SSDP_DEVICE_TYPE "upnp:rootdevice" +//#define SSDP_DEVICE_TYPE "urn:schemas-upnp-org:device:BinaryLight:1" #endif #if WEB_SUPPORT == 0 diff --git a/code/espurna/libs/SSDPDevice.cpp b/code/espurna/libs/SSDPDevice.cpp deleted file mode 100644 index 22bab48d..00000000 --- a/code/espurna/libs/SSDPDevice.cpp +++ /dev/null @@ -1,376 +0,0 @@ -#if SSDP_SUPPORT - -#include "SSDPDevice.h" -#include "lwip/igmp.h" - -SSDPDeviceClass::SSDPDeviceClass() : - m_server(0), - m_port(80), - m_ttl(SSDP_MULTICAST_TTL) -{ - m_uuid[0] = '\0'; - m_modelNumber[0] = '\0'; - sprintf(m_deviceType, "urn:schemas-upnp-org:device:Basic:1"); - m_friendlyName[0] = '\0'; - m_presentationURL[0] = '\0'; - m_serialNumber[0] = '\0'; - m_modelName[0] = '\0'; - m_modelURL[0] = '\0'; - m_manufacturer[0] = '\0'; - m_manufacturerURL[0] = '\0'; - sprintf(m_schemaURL, "ssdp/schema.xml"); - - uint32_t chipId = ESP.getChipId(); - - sprintf(m_uuid, "38323636-4558-4dda-9188-cda0e6%02x%02x%02x", - (uint16_t)((chipId >> 16) & 0xff), - (uint16_t)((chipId >> 8) & 0xff), - (uint16_t)chipId & 0xff); - - for (int i = 0; i < SSDP_QUEUE_SIZE; i++) { - m_queue[i].time = 0; - } -} - -void SSDPDeviceClass::update() { - postNotifyUpdate(); -} - -bool SSDPDeviceClass::readLine(String &value) { - char buffer[65]; - int bufferPos = 0; - - while (1) { - int c = m_server->read(); - - if (c < 0) { - buffer[bufferPos] = '\0'; - - break; - } - if (c == '\r' && m_server->peek() == '\n') { - m_server->read(); - - buffer[bufferPos] = '\0'; - - break; - } - if (bufferPos < 64) { - buffer[bufferPos++] = c; - } - } - - value = String(buffer); - - return bufferPos > 0; -} - -bool SSDPDeviceClass::readKeyValue(String &key, String &value) { - char buffer[65]; - int bufferPos = 0; - - while (1) { - int c = m_server->read(); - - if (c < 0) { - if (bufferPos == 0) return false; - - buffer[bufferPos] = '\0'; - - break; - } - if (c == ':') { - buffer[bufferPos] = '\0'; - - while (m_server->peek() == ' ') m_server->read(); - - break; - } - else if (c == '\r' && m_server->peek() == '\n') { - m_server->read(); - - if (bufferPos == 0) return false; - - buffer[bufferPos] = '\0'; - - key = String(); - value = String(buffer); - - return true; - } - if (bufferPos < 64) { - buffer[bufferPos++] = c; - } - } - - key = String(buffer); - - readLine(value); - - return true; -} - -void SSDPDeviceClass::postNotifyALive() { - unsigned long time = millis(); - - post(NOTIFY_ALIVE_INIT, ROOT_FOR_ALL, SSDP_MULTICAST_ADDR, SSDP_PORT, time + 10); - post(NOTIFY_ALIVE_INIT, ROOT_BY_UUID, SSDP_MULTICAST_ADDR, SSDP_PORT, time + 55); - post(NOTIFY_ALIVE_INIT, ROOT_BY_TYPE, SSDP_MULTICAST_ADDR, SSDP_PORT, time + 80); - - post(NOTIFY_ALIVE_INIT, ROOT_FOR_ALL, SSDP_MULTICAST_ADDR, SSDP_PORT, time + 210); - post(NOTIFY_ALIVE_INIT, ROOT_BY_UUID, SSDP_MULTICAST_ADDR, SSDP_PORT, time + 255); - post(NOTIFY_ALIVE_INIT, ROOT_BY_TYPE, SSDP_MULTICAST_ADDR, SSDP_PORT, time + 280); - - post(NOTIFY_ALIVE, ROOT_FOR_ALL, SSDP_MULTICAST_ADDR, SSDP_PORT, time + 610); - post(NOTIFY_ALIVE, ROOT_BY_UUID, SSDP_MULTICAST_ADDR, SSDP_PORT, time + 655); - post(NOTIFY_ALIVE, ROOT_BY_TYPE, SSDP_MULTICAST_ADDR, SSDP_PORT, time + 680); -} - -void SSDPDeviceClass::postNotifyUpdate() { - unsigned long time = millis(); - - post(NOTIFY_UPDATE, ROOT_FOR_ALL, SSDP_MULTICAST_ADDR, SSDP_PORT, time + 10); - post(NOTIFY_UPDATE, ROOT_BY_UUID, SSDP_MULTICAST_ADDR, SSDP_PORT, time + 55); - post(NOTIFY_UPDATE, ROOT_BY_TYPE, SSDP_MULTICAST_ADDR, SSDP_PORT, time + 80); -} - -void SSDPDeviceClass::postResponse(long mx) { - unsigned long time = millis(); - unsigned long delay = random(0, mx) * 900L; // 1000 ms - 100 ms - - IPAddress address = m_server->remoteIP(); - uint16_t port = m_server->remotePort(); - - post(RESPONSE, ROOT_FOR_ALL, address, port, time + delay / 3); - post(RESPONSE, ROOT_BY_UUID, address, port, time + delay / 3 * 2); - post(RESPONSE, ROOT_BY_TYPE, address, port, time + delay); -} - -void SSDPDeviceClass::postResponse(ssdp_udn_t udn, long mx) { - post(RESPONSE, udn, m_server->remoteIP(), m_server->remotePort(), millis() + random(0, mx) * 900L); // 1000 ms - 100 ms -} - -void SSDPDeviceClass::post(ssdp_message_t type, ssdp_udn_t udn, IPAddress address, uint16_t port, unsigned long time) { - for (int i = 0; i < SSDP_QUEUE_SIZE; i++) { - if (m_queue[i].time == 0) { - m_queue[i].type = type; - m_queue[i].udn = udn; - m_queue[i].address = address; - m_queue[i].port = port; - m_queue[i].time = time; - - break; - } - } -} - -void SSDPDeviceClass::send(ssdp_send_parameters_t *parameters) { - char buffer[1460]; - unsigned int ip = WiFi.localIP(); - - const char *typeTemplate; - const char *uri, *usn1, *usn2, *usn3; - - switch (parameters->type) { - case NOTIFY_ALIVE_INIT: - case NOTIFY_ALIVE: - typeTemplate = SSDP_NOTIFY_ALIVE_TEMPLATE; - break; - case NOTIFY_UPDATE: - typeTemplate = SSDP_NOTIFY_UPDATE_TEMPLATE; - break; - default: // RESPONSE - typeTemplate = SSDP_RESPONSE_TEMPLATE; - break; - } - - String uuid = "uuid:" + String(m_uuid); - - switch (parameters->udn) { - case ROOT_FOR_ALL: - uri = "upnp:rootdevice"; - usn1 = uuid.c_str(); - usn2 = "::"; - usn3 = "upnp:rootdevice"; - break; - case ROOT_BY_UUID: - uri = uuid.c_str(); - usn1 = uuid.c_str(); - usn2 = ""; - usn3 = ""; - break; - case ROOT_BY_TYPE: - uri = m_deviceType; - usn1 = uuid.c_str(); - usn2 = "::"; - usn3 = m_deviceType; - break; - } - - int len = snprintf_P(buffer, sizeof(buffer), - SSDP_PACKET_TEMPLATE, typeTemplate, - SSDP_INTERVAL, m_modelName, m_modelNumber, usn1, usn2, usn3, parameters->type == RESPONSE ? "ST" : "NT", uri, - IP2STR(&ip), m_port, m_schemaURL - ); - - if (parameters->address == SSDP_MULTICAST_ADDR) { - m_server->beginPacketMulticast(parameters->address, parameters->port, m_ttl); - } - else { - m_server->beginPacket(parameters->address, parameters->port); - } - - m_server->write(buffer, len); - m_server->endPacket(); - - parameters->time = parameters->type == NOTIFY_ALIVE ? parameters->time + SSDP_INTERVAL * 900L : 0; // 1000 ms - 100 ms -} - -String SSDPDeviceClass::schema() { - char buffer[1024]; - uint32_t ip = WiFi.localIP(); - snprintf(buffer, sizeof(buffer), SSDP_SCHEMA_TEMPLATE, - IP2STR(&ip), m_port, m_schemaURL, - m_deviceType, - m_friendlyName, - m_presentationURL, - m_serialNumber, - m_modelName, - m_modelNumber, - m_modelURL, - m_manufacturer, - m_manufacturerURL, - m_uuid - ); - return String(buffer); -} - -void SSDPDeviceClass::handleClient() { - IPAddress current = WiFi.localIP(); - - if (m_last != current) { - m_last = current; - - for (int i = 0; i < SSDP_QUEUE_SIZE; i++) { - m_queue[i].time = 0; - } - - if (current != INADDR_NONE) { - if (!m_server) m_server = new WiFiUDP(); - - m_server->beginMulticast(current, SSDP_MULTICAST_ADDR, SSDP_PORT); - - postNotifyALive(); - } - else if (m_server) { - m_server->stop(); - } - } - - if (m_server && m_server->parsePacket()) { - String value; - - if (readLine(value) && value.equalsIgnoreCase("M-SEARCH * HTTP/1.1")) { - String key, st; - bool host = false, man = false; - long mx = 0; - - while (readKeyValue(key, value)) { - if (key.equalsIgnoreCase("HOST") && value.equals("239.255.255.250:1900")) { - host = true; - } - else if (key.equalsIgnoreCase("MAN") && value.equals("\"ssdp:discover\"")) { - man = true; - } - else if (key.equalsIgnoreCase("ST")) { - st = value; - } - else if (key.equalsIgnoreCase("MX")) { - mx = value.toInt(); - } - } - - if (host && man && mx > 0) { - if (st.equals("ssdp:all")) { - postResponse(mx); - } - else if (st.equals("upnp:rootdevice")) { - postResponse(ROOT_FOR_ALL, mx); - } - else if (st.equals("uuid:" + String(m_uuid))) { - postResponse(ROOT_BY_UUID, mx); - } - else if (st.equals(m_deviceType)) { - postResponse(ROOT_BY_TYPE, mx); - } - } - } - - m_server->flush(); - } - else { - unsigned long time = millis(); - - for (int i = 0; i < SSDP_QUEUE_SIZE; i++) { - if (m_queue[i].time > 0 && m_queue[i].time < time) { - send(&m_queue[i]); - } - } - } -} - -void SSDPDeviceClass::setSchemaURL(const char *url) { - strlcpy(m_schemaURL, url, sizeof(m_schemaURL)); -} - -void SSDPDeviceClass::setHTTPPort(uint16_t port) { - m_port = port; -} - -void SSDPDeviceClass::setDeviceType(const char *deviceType) { - strlcpy(m_deviceType, deviceType, sizeof(m_deviceType)); -} - -void SSDPDeviceClass::setName(const char *name) { - strlcpy(m_friendlyName, name, sizeof(m_friendlyName)); -} - -void SSDPDeviceClass::setURL(const char *url) { - strlcpy(m_presentationURL, url, sizeof(m_presentationURL)); -} - -void SSDPDeviceClass::setSerialNumber(const char *serialNumber) { - strlcpy(m_serialNumber, serialNumber, sizeof(m_serialNumber)); -} - -void SSDPDeviceClass::setSerialNumber(const uint32_t serialNumber) { - snprintf(m_serialNumber, sizeof(uint32_t) * 2 + 1, "%08X", serialNumber); -} - -void SSDPDeviceClass::setModelName(const char *name) { - strlcpy(m_modelName, name, sizeof(m_modelName)); -} - -void SSDPDeviceClass::setModelNumber(const char *num) { - strlcpy(m_modelNumber, num, sizeof(m_modelNumber)); -} - -void SSDPDeviceClass::setModelURL(const char *url) { - strlcpy(m_modelURL, url, sizeof(m_modelURL)); -} - -void SSDPDeviceClass::setManufacturer(const char *name) { - strlcpy(m_manufacturer, name, sizeof(m_manufacturer)); -} - -void SSDPDeviceClass::setManufacturerURL(const char *url) { - strlcpy(m_manufacturerURL, url, sizeof(m_manufacturerURL)); -} - -void SSDPDeviceClass::setTTL(const uint8_t ttl) { - m_ttl = ttl; -} - -SSDPDeviceClass SSDPDevice; - -#endif diff --git a/code/espurna/libs/SSDPDevice.h b/code/espurna/libs/SSDPDevice.h deleted file mode 100644 index 0a3bd796..00000000 --- a/code/espurna/libs/SSDPDevice.h +++ /dev/null @@ -1,198 +0,0 @@ -#if SSDP_SUPPORT // SSDP_SUPPORT - -#ifndef _SSDPDEVICE_h -#define _SSDPDEVICE_h - -#if defined(ARDUINO) && ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif - -#include -#include - -#define SSDP_INTERVAL 1200 -#define SSDP_PORT 1900 -//#define SSDP_METHOD_SIZE 10 -//#define SSDP_URI_SIZE 2 -//#define SSDP_BUFFER_SIZE 64 -#define SSDP_MULTICAST_TTL 2 - -#define SSDP_QUEUE_SIZE 21 - -static const IPAddress SSDP_MULTICAST_ADDR(239, 255, 255, 250); - -#define SSDP_UUID_SIZE 37 -#define SSDP_SCHEMA_URL_SIZE 64 -#define SSDP_DEVICE_TYPE_SIZE 64 -#define SSDP_FRIENDLY_NAME_SIZE 64 -#define SSDP_SERIAL_NUMBER_SIZE 32 -#define SSDP_PRESENTATION_URL_SIZE 128 -#define SSDP_MODEL_NAME_SIZE 64 -#define SSDP_MODEL_URL_SIZE 128 -#define SSDP_MODEL_VERSION_SIZE 32 -#define SSDP_MANUFACTURER_SIZE 64 -#define SSDP_MANUFACTURER_URL_SIZE 128 - -static const char* PROGMEM SSDP_RESPONSE_TEMPLATE = - "HTTP/1.1 200 OK\r\n" - "EXT:\r\n"; - -static const char* PROGMEM SSDP_NOTIFY_ALIVE_TEMPLATE = - "NOTIFY * HTTP/1.1\r\n" - "HOST: 239.255.255.250:1900\r\n" - "NTS: ssdp:alive\r\n"; - -static const char* PROGMEM SSDP_NOTIFY_UPDATE_TEMPLATE = - "NOTIFY * HTTP/1.1\r\n" - "HOST: 239.255.255.250:1900\r\n" - "NTS: ssdp:update\r\n"; - -static const char* PROGMEM SSDP_PACKET_TEMPLATE = - "%s" // _ssdp_response_template / _ssdp_notify_template - "CACHE-CONTROL: max-age=%u\r\n" // SSDP_INTERVAL - "SERVER: UPNP/1.1 %s/%s\r\n" // m_modelName, m_modelNumber - "USN: %s%s%s\r\n" // m_uuid - "%s: %s\r\n" // "NT" or "ST", m_deviceType - "LOCATION: http://%u.%u.%u.%u:%u/%s\r\n" // WiFi.localIP(), m_port, m_schemaURL - "\r\n"; - -static const char* PROGMEM SSDP_SCHEMA_TEMPLATE = - "HTTP/1.1 200 OK\r\n" - "Content-Type: text/xml\r\n" - "Connection: close\r\n" - "Access-Control-Allow-Origin: *\r\n" - "\r\n" - "" - "" - "" - "1" - "0" - "" - "http://%u.%u.%u.%u:%u/%s" // WiFi.localIP(), _port - "" - "%s" - "%s" - "%s" - "%s" - "%s" - "%s" - "%s" - "%s" - "%s" - "uuid:%s" - "" -// "" -// "" -// "image/png" -// "48" -// "48" -// "24" -// "icon48.png" -// "" -// "" -// "image/png" -// "120" -// "120" -// "24" -// "icon120.png" -// "" -// "" - "\r\n" - "\r\n"; - -typedef enum { - NOTIFY_ALIVE_INIT, - NOTIFY_ALIVE, - NOTIFY_UPDATE, - RESPONSE -} ssdp_message_t; - -typedef enum { - ROOT_FOR_ALL, - ROOT_BY_UUID, - ROOT_BY_TYPE -} ssdp_udn_t; - -typedef struct { - unsigned long time; - - ssdp_message_t type; - ssdp_udn_t udn; - uint32_t address; - uint16_t port; -} ssdp_send_parameters_t; - -class SSDPDeviceClass { -private: - WiFiUDP *m_server; - - IPAddress m_last; - - char m_schemaURL[SSDP_SCHEMA_URL_SIZE]; - char m_uuid[SSDP_UUID_SIZE]; - char m_deviceType[SSDP_DEVICE_TYPE_SIZE]; - char m_friendlyName[SSDP_FRIENDLY_NAME_SIZE]; - char m_serialNumber[SSDP_SERIAL_NUMBER_SIZE]; - char m_presentationURL[SSDP_PRESENTATION_URL_SIZE]; - char m_manufacturer[SSDP_MANUFACTURER_SIZE]; - char m_manufacturerURL[SSDP_MANUFACTURER_URL_SIZE]; - char m_modelName[SSDP_MODEL_NAME_SIZE]; - char m_modelURL[SSDP_MODEL_URL_SIZE]; - char m_modelNumber[SSDP_MODEL_VERSION_SIZE]; - - uint16_t m_port; - uint8_t m_ttl; - - ssdp_send_parameters_t m_queue[SSDP_QUEUE_SIZE]; -protected: - bool readLine(String &value); - bool readKeyValue(String &key, String &value); - - void postNotifyALive(); - void postNotifyUpdate(); - void postResponse(long mx); - void postResponse(ssdp_udn_t udn, long mx); - void post(ssdp_message_t type, ssdp_udn_t udn, IPAddress address, uint16_t port, unsigned long time); - - void send(ssdp_send_parameters_t *parameters); -public: - SSDPDeviceClass(); - - void update(); - - String schema(); - - void handleClient(); - - void setDeviceType(const String& deviceType) { setDeviceType(deviceType.c_str()); } - void setDeviceType(const char *deviceType); - void setName(const String& name) { setName(name.c_str()); } - void setName(const char *name); - void setURL(const String& url) { setURL(url.c_str()); } - void setURL(const char *url); - void setSchemaURL(const String& url) { setSchemaURL(url.c_str()); } - void setSchemaURL(const char *url); - void setSerialNumber(const String& serialNumber) { setSerialNumber(serialNumber.c_str()); } - void setSerialNumber(const char *serialNumber); - void setSerialNumber(const uint32_t serialNumber); - void setModelName(const String& name) { setModelName(name.c_str()); } - void setModelName(const char *name); - void setModelNumber(const String& num) { setModelNumber(num.c_str()); } - void setModelNumber(const char *num); - void setModelURL(const String& url) { setModelURL(url.c_str()); } - void setModelURL(const char *url); - void setManufacturer(const String& name) { setManufacturer(name.c_str()); } - void setManufacturer(const char *name); - void setManufacturerURL(const String& url) { setManufacturerURL(url.c_str()); } - void setManufacturerURL(const char *url); - void setHTTPPort(uint16_t port); - void setTTL(uint8_t ttl); -}; - -extern SSDPDeviceClass SSDPDevice; - -#endif - -#endif // SSDP_SUPPORT diff --git a/code/espurna/ssdp.ino b/code/espurna/ssdp.ino index 80f2817e..6ecf0f58 100644 --- a/code/espurna/ssdp.ino +++ b/code/espurna/ssdp.ino @@ -10,34 +10,74 @@ https://github.com/esp8266/Arduino/issues/2283#issuecomment-299635604 #if SSDP_SUPPORT -#include +#include + +const char _ssdp_template[] PROGMEM = + "" + "" + "" + "1" + "0" + "" + "http://%s:%u/" + "" + "%s" + "%s" + "/" + "%u" + "%s" + "%s" + "%s" + "%s" + "%s" + "uuid:38323636-4558-4dda-9188-cda0e6%06x" + "" + "\r\n" + "\r\n"; void ssdpSetup() { - SSDPDevice.setName(getSetting("hostname")); - SSDPDevice.setDeviceType("urn:schemas-upnp-org:device:BinaryLight:1"); - SSDPDevice.setSchemaURL("description.xml"); - SSDPDevice.setSerialNumber(ESP.getChipId()); - SSDPDevice.setURL("/"); - SSDPDevice.setModelName(DEVICE); - SSDPDevice.setModelNumber(""); - SSDPDevice.setManufacturer(MANUFACTURER); - - #if WEB_SUPPORT - webServer()->on("/description.xml", HTTP_GET, [](AsyncWebServerRequest *request) { - DEBUG_MSG_P(PSTR("[SSDP] Schema request\n")); - String schema = SSDPDevice.schema(); - request->send(200, "application/xml", schema.c_str()); - }); - #endif - - // Register loop - espurnaRegisterLoop(ssdpLoop); + webServer()->on("/description.xml", HTTP_GET, [](AsyncWebServerRequest *request) { -} + DEBUG_MSG_P(PSTR("[SSDP] Schema request\n")); + + IPAddress ip = WiFi.localIP(); + uint32_t chipId = ESP.getChipId(); + + char response[strlen_P(_ssdp_template) + 100]; + snprintf_P(response, sizeof(response), _ssdp_template, + WiFi.localIP().toString().c_str(), // ip + webPort(), // port + SSDP_DEVICE_TYPE, // device type + getSetting("hostname").c_str(), // friendlyName + chipId, // serialNumber + APP_NAME, // modelName + APP_VERSION, // modelNumber + APP_WEBSITE, // modelURL + DEVICE_NAME, // manufacturer + "", // manufacturerURL + chipId // UUID + ); + + request->send(200, "text/xml", response); + + }); + + SSDP.setSchemaURL("description.xml"); + SSDP.setHTTPPort(webPort()); + SSDP.setDeviceType(SSDP_DEVICE_TYPE); //https://github.com/esp8266/Arduino/issues/2283 + SSDP.setName(getSetting("hostname")); + SSDP.setSerialNumber(String(ESP.getChipId())); + SSDP.setModelName(APP_NAME); + SSDP.setModelNumber(APP_VERSION); + SSDP.setModelURL(APP_WEBSITE); + SSDP.setManufacturer(DEVICE_NAME); + SSDP.setManufacturerURL(""); + SSDP.setURL("/"); + SSDP.begin(); + + DEBUG_MSG_P(PSTR("[SSDP] Started\n")); -void ssdpLoop() { - SSDPDevice.handleClient(); } #endif // SSDP_SUPPORT diff --git a/code/espurna/web.ino b/code/espurna/web.ino index dfb9c75f..a7e371fb 100644 --- a/code/espurna/web.ino +++ b/code/espurna/web.ino @@ -277,6 +277,14 @@ AsyncWebServer * webServer() { return _server; } +unsigned int webPort() { + #if ASYNC_TCP_SSL_ENABLED & WEB_SSL_ENABLED + return 443; + #else + return getSetting("webPort", WEB_PORT).toInt(); + #endif +} + void webLog(AsyncWebServerRequest *request) { DEBUG_MSG_P(PSTR("[WEBSERVER] Request: %s %s\n"), request->methodToString(), request->url().c_str()); } @@ -287,11 +295,7 @@ void webSetup() { snprintf_P(_last_modified, sizeof(_last_modified), PSTR("%s %s GMT"), __DATE__, __TIME__); // Create server - #if ASYNC_TCP_SSL_ENABLED & WEB_SSL_ENABLED - unsigned int port = 443; - #else - unsigned int port = getSetting("webPort", WEB_PORT).toInt(); - #endif + unsigned int port = webPort(); _server = new AsyncWebServer(port); // Rewrites @@ -323,12 +327,12 @@ void webSetup() { // Run server #if ASYNC_TCP_SSL_ENABLED & WEB_SSL_ENABLED - _server->onSslFileRequest(_onCertificate, NULL); - _server->beginSecure("server.cer", "server.key", NULL); + _server->onSslFileRequest(_onCertificate, NULL); + _server->beginSecure("server.cer", "server.key", NULL); #else - _server->begin(); + _server->begin(); #endif - DEBUG_MSG_P(PSTR("[WEBSERVER] Webserver running on port %d\n"), port); + DEBUG_MSG_P(PSTR("[WEBSERVER] Webserver running on port %u\n"), port); }