diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index a9c1eccde..712cf2058 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -57,10 +57,21 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { #endif JsonObject id = doc["id"]; - getStringFromJson(cmDNS, id[F("mdns")], 33); - getStringFromJson(serverDescription, id[F("name")], 33); + getStringFromJson(cmDNS, id[F("mdns")], sizeof(cmDNS)); + // fill in unique mDNS name if not set (cmDNS can be empty meaning no mDNS is used) + if (strcmp(cmDNS, DEFAULT_MDNS_NAME) == 0) sprintf_P(cmDNS, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6); + getStringFromJson(serverDescription, id[F("name")], sizeof(serverDescription)); + if (!fromFS) { + char hostname[25]; + prepareHostname(hostname, sizeof(hostname)-1); + #ifdef ARDUINO_ARCH_ESP32 + WiFi.setHostname(hostname); + #else + WiFi.hostname(hostname); + #endif + } #ifndef WLED_DISABLE_ALEXA - getStringFromJson(alexaInvocationName, id[F("inv")], 33); + getStringFromJson(alexaInvocationName, id[F("inv")], sizeof(alexaInvocationName)); #endif CJSON(simplifiedUI, id[F("sui")]); @@ -637,8 +648,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { getStringFromJson(mqttUser, if_mqtt[F("user")], 41); getStringFromJson(mqttPass, if_mqtt["psk"], 65); //normally not present due to security getStringFromJson(mqttClientID, if_mqtt[F("cid")], 41); - + if (mqttClientID[0] == 0) sprintf_P(mqttClientID, PSTR("WLED-%*s"), 6, escapedMac.c_str() + 6); getStringFromJson(mqttDeviceTopic, if_mqtt[F("topics")][F("device")], MQTT_MAX_TOPIC_LEN+1); // "wled/test" + if (mqttDeviceTopic[0] == 0) sprintf_P(mqttDeviceTopic, PSTR("wled/%*s"), 6, escapedMac.c_str() + 6); getStringFromJson(mqttGroupTopic, if_mqtt[F("topics")][F("group")], MQTT_MAX_TOPIC_LEN+1); // "" CJSON(retainMqttMsg, if_mqtt[F("rtn")]); #endif diff --git a/wled00/data/settings_wifi.htm b/wled00/data/settings_wifi.htm index d2d7c66c4..e4a63dd59 100644 --- a/wled00/data/settings_wifi.htm +++ b/wled00/data/settings_wifi.htm @@ -144,6 +144,7 @@ Static subnet mask:
function tE() { // keep the hidden input with MAC addresses, only toggle visibility of the list UI gId('rlc').style.display = d.Sf.RE.checked ? 'block' : 'none'; + if (d.Sf.RE.checked) d.Sf.ETH.selectedIndex = 0; // disable Ethernet if ESPNOW is enabled } // reset remotes: initialize empty list (called from xml.cpp) function rstR() { @@ -176,7 +177,9 @@ Static subnet mask:
rC++; gId('+').style.display = gId("rml").childElementCount < 10 ? 'inline' : 'none'; // can't append to list anymore, hide button } - + function vI(i) { + i.style.color = (i.value.match(/^[a-zA-Z0-9_\-]*$/)) ? 'white' : 'red'; + } @@ -187,6 +190,9 @@ Static subnet mask:

WiFi setup

+ Hostname/mDNS address (empty for no mDNS):
+ http://.local
+ Client IP: Not connected

Connect to existing network


@@ -198,14 +204,10 @@ Static subnet mask:
DNS server address:
...
-
- mDNS address (leave empty for no mDNS):
- http:// .local
- Client IP: Not connected

Configure Access Point

- AP SSID (leave empty for no AP):

+ AP SSID (empty for no AP):

Hide AP name:
- AP password (leave empty for open):

+ AP password (empty for open):

Access Point WiFi channel:
AP opens: +

+
+ ESP-NOW is incompatible with Ethernet.
diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index d2f62870d..f2fea119c 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -505,7 +505,7 @@ size_t printSetFormValue(Print& settingsScript, const char* key, int val); size_t printSetFormValue(Print& settingsScript, const char* key, const char* val); size_t printSetFormIndex(Print& settingsScript, const char* key, int index); size_t printSetClassElementHTML(Print& settingsScript, const char* key, const int index, const char* val); -void prepareHostname(char* hostname); +void prepareHostname(char* hostname, size_t maxLen = 32); [[gnu::pure]] bool isAsterisksOnly(const char* str, byte maxLen); bool requestJSONBufferLock(uint8_t moduleID=255); void releaseJSONBufferLock(); diff --git a/wled00/network.cpp b/wled00/network.cpp index 79209ff5e..d06ce2b46 100644 --- a/wled00/network.cpp +++ b/wled00/network.cpp @@ -386,7 +386,7 @@ void WiFiEvent(WiFiEvent_t event) case ARDUINO_EVENT_WIFI_AP_STOP: DEBUG_PRINTLN(F("WiFi-E: AP Stopped")); break; - #if defined(WLED_USE_ETHERNET) + #ifdef WLED_USE_ETHERNET case ARDUINO_EVENT_ETH_START: DEBUG_PRINTLN(F("ETH-E: Started")); break; @@ -402,8 +402,8 @@ void WiFiEvent(WiFiEvent_t event) ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE); } // convert the "serverDescription" into a valid DNS hostname (alphanumeric) - char hostname[64]; - prepareHostname(hostname); + char hostname[33]; + prepareHostname(hostname, sizeof(hostname)-1); ETH.setHostname(hostname); showWelcomePage = false; break; diff --git a/wled00/set.cpp b/wled00/set.cpp index 9fa84d7aa..742e69371 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -63,16 +63,23 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) dnsAddress = IPAddress(request->arg(F("D0")).toInt(),request->arg(F("D1")).toInt(),request->arg(F("D2")).toInt(),request->arg(F("D3")).toInt()); } - strlcpy(cmDNS, request->arg(F("CM")).c_str(), 33); + strlcpy(cmDNS, request->arg(F("CM")).c_str(), sizeof(cmDNS)); + char hostname[25]; + prepareHostname(hostname, sizeof(hostname)-1); + #ifdef ARDUINO_ARCH_ESP32 + WiFi.setHostname(hostname); + #else + WiFi.hostname(hostname); + #endif apBehavior = request->arg(F("AB")).toInt(); char oldSSID[33]; strcpy(oldSSID, apSSID); - strlcpy(apSSID, request->arg(F("AS")).c_str(), 33); + strlcpy(apSSID, request->arg(F("AS")).c_str(), sizeof(apSSID)); if (!strcmp(oldSSID, apSSID) && apActive) forceReconnect = true; apHide = request->hasArg(F("AH")); int passlen = request->arg(F("AP")).length(); - if (passlen == 0 || (passlen > 7 && !isAsterisksOnly(request->arg(F("AP")).c_str(), 65))) { - strlcpy(apPass, request->arg(F("AP")).c_str(), 65); + if (passlen == 0 || (passlen > 7 && !isAsterisksOnly(request->arg(F("AP")).c_str(), sizeof(apPass)))) { + strlcpy(apPass, request->arg(F("AP")).c_str(), sizeof(apPass)); forceReconnect = true; } int t = request->arg(F("AC")).toInt(); @@ -368,6 +375,13 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) if (subPage == SUBPAGE_UI) { strlcpy(serverDescription, request->arg(F("DS")).c_str(), 33); + char hostname[25]; + prepareHostname(hostname, sizeof(hostname)-1); + #ifdef ARDUINO_ARCH_ESP32 + WiFi.setHostname(hostname); + #else + WiFi.hostname(hostname); + #endif //syncToggleReceive = request->hasArg(F("ST")); simplifiedUI = request->hasArg(F("SU")); DEBUG_PRINTLN(F("Enumerating ledmaps")); diff --git a/wled00/util.cpp b/wled00/util.cpp index 97e1e3b03..7f41102b9 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -114,28 +114,30 @@ size_t printSetClassElementHTML(Print& settingsScript, const char* key, const in } - -void prepareHostname(char* hostname) +// prepare a unique hostname based on the last 6 digits of the MAC address +// if no mDNS name or serverDescription is set, otherwise use cmDNS or serverDescription +// the hostname will be at most 24 characters long, starting with "wled-" +// and containing only alphanumeric characters and hyphens +// the hostname will not end with a hyphen and will be null-terminated +void prepareHostname(char* hostname, size_t maxLen) { + // create a unique hostname based on the last 6 digits of the MAC address if no mDNS name or serverDescription is set sprintf_P(hostname, PSTR("wled-%*s"), 6, escapedMac.c_str() + 6); - const char *pC = serverDescription; - unsigned pos = 5; // keep "wled-" - while (*pC && pos < 24) { // while !null and not over length - if (isalnum(*pC)) { // if the current char is alpha-numeric append it to the hostname - hostname[pos] = *pC; - pos++; + const char *pC = cmDNS; // use cmDNS as hostname if set + if (strlen(pC) == 0) pC = serverDescription; // else use serverDescription + unsigned pos = 5; // keep "wled-" from unique name + while (*pC && pos < maxLen) { // while !null and not over length + if (isalnum(*pC)) { // if the current char is alpha-numeric append it to the hostname + hostname[pos++] = *pC; } else if (*pC == ' ' || *pC == '_' || *pC == '-' || *pC == '+' || *pC == '!' || *pC == '?' || *pC == '*') { - hostname[pos] = '-'; - pos++; + hostname[pos++] = '-'; } // else do nothing - no leading hyphens and do not include hyphens for all other characters. pC++; } - //last character must not be hyphen - if (pos > 5) { - while (pos > 4 && hostname[pos -1] == '-') pos--; - hostname[pos] = '\0'; // terminate string (leave at least "wled") - } + // last character must not be hyphen + while (pos > 4 && hostname[pos-1] == '-') pos--; + hostname[pos] = '\0'; // terminate string (leave at least "wled") }