Skip to content

Commit ab91b27

Browse files
committed
Fix setHostname() after WiFi is already initilised
by @willmmiles
1 parent a247b9b commit ab91b27

4 files changed

Lines changed: 37 additions & 7 deletions

File tree

wled00/cfg.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
162162
// apply WiFi options from above (regardless of fromFS or not)
163163
#ifdef ARDUINO_ARCH_ESP32
164164
WiFi.setSleep(!noWifiSleep);
165-
WiFi.setHostname(hostName);
165+
WiFi.setHostname(hostName); // Sets the hostName in the wifi lib; does not necessarily propagate it to the network interface
166+
set_esp_interface_hostname(ESP_IF_WIFI_STA, hostName); // ensure hostName propagates to network interface for DHCP and mDNS
166167
#else
167168
WiFi.setPhyMode(force802_3g ? WIFI_PHY_MODE_11G : WIFI_PHY_MODE_11N);
168169
wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T);

wled00/network.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,16 @@ void fillStr2MAC(uint8_t *mac, const char *str) {
302302
for (int i = 0; i < 6; i++) { *--mac = MAC & 0xFF; MAC >>= 8; }
303303
}
304304

305+
#ifdef ARDUINO_ARCH_ESP32
306+
// Shim class to allow access to protected members of WiFiScanClass so we can extend the timeout
307+
namespace {
308+
struct WifiScanAccessor : public WiFiScanClass {
309+
static uint32_t& scanStarted() { return WiFiScanClass::_scanStarted; }
310+
static uint32_t& scanTimeout() { return WiFiScanClass::_scanTimeout; }
311+
static uint16_t& scanCount() { return WiFiScanClass::_scanCount; };
312+
};
313+
}
314+
#endif
305315

306316
#ifndef WLED_DISABLE_ESPNOW
307317
void initESPNow(bool resetAP) {
@@ -389,28 +399,39 @@ int findWiFi(bool doScan) {
389399

390400
if (doScan || status == WIFI_SCAN_FAILED) {
391401
DEBUG_PRINTF_P(PSTR("WiFi: Scan started. @ %lus\n"), millis()/1000);
392-
WiFi.scanNetworks(true); // start scanning in asynchronous mode (will delete old scan)
393-
} else if (status > 0) { // status contains number of found networks (including duplicate SSIDs with different BSSID)
402+
WiFi.disconnect(); // make sure we're not trying to reconnect to a network while scanning
403+
status = WiFi.scanNetworks(true); // start scanning in asynchronous mode (will delete old scan)
404+
#ifdef ARDUINO_ARCH_ESP32
405+
// the Arduino core can be overly aggressive with its scan timeout if we're busy with the CPU. Be more generous.
406+
if (status == WIFI_SCAN_RUNNING) {
407+
WifiScanAccessor::scanTimeout() += 5000;
408+
}
409+
#endif
410+
}
411+
412+
if (status >= 0) { // status contains number of found networks (including duplicate SSIDs with different BSSID)
394413
DEBUG_PRINTF_P(PSTR("WiFi: Found %d SSIDs. @ %lus\n"), status, millis()/1000);
395414
int rssi = -9999;
396415
int selected = selectedWiFi;
397416
for (int o = 0; o < status; o++) {
398417
DEBUG_PRINTF_P(PSTR(" SSID: %s (BSSID: %s) RSSI: %ddB\n"), WiFi.SSID(o).c_str(), WiFi.BSSIDstr(o).c_str(), WiFi.RSSI(o));
399-
for (unsigned n = 0; n < multiWiFi.size(); n++)
418+
for (unsigned n = 0; n < multiWiFi.size(); n++) {
400419
if (!strcmp(WiFi.SSID(o).c_str(), multiWiFi[n].clientSSID)) {
401420
bool foundBSSID = memcmp(multiWiFi[n].bssid, WiFi.BSSID(o), 6) == 0;
402421
// find the WiFi with the strongest signal (but keep priority of entry if signal difference is not big)
403-
if (foundBSSID || ((int)n < selected && WiFi.RSSI(o) > rssi-10) || WiFi.RSSI(o) > rssi) {
422+
// essentially give a bonus to higher priority wifis
423+
if (foundBSSID || ((WiFi.RSSI(o) + ((int)n < selected ? 10 : 0)) > rssi)) {
404424
rssi = foundBSSID ? 0 : WiFi.RSSI(o); // RSSI is only ever negative
405425
selected = n;
406426
}
407427
break;
408428
}
429+
}
409430
}
410431
DEBUG_PRINTF_P(PSTR("WiFi: Selected SSID: %s RSSI: %ddB\n"), multiWiFi[selected].clientSSID, rssi);
411432
return selected+1;
412433
}
413-
//DEBUG_PRINT(F("WiFi scan running."));
434+
//DEBUG_PRINTF_P(PSTR("WiFi scan running: %d. @ %lus\n"), status, millis()/1000);
414435
return status; // scan is still running or there was an error
415436
}
416437

wled00/network.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
#ifndef WLED_NETWORK_H
44
#define WLED_NETWORK_H
55

6+
#ifdef ARDUINO_ARCH_ESP32
7+
// Declare internal Arduino library function to work around the fact that WiFi.setHostname() does not propagate the
8+
// hostname to the network interface if it's been previously used. The underlying ESP-IDF layer supports this just
9+
// fine; it's an oversight in the Arduino layer that we can work around by calling the internal function directly.
10+
esp_err_t set_esp_interface_hostname(esp_interface_t interface, const char * hostname);
11+
#endif
12+
613
#ifndef WLED_DISABLE_ESPNOW
714
typedef struct {
815
char magic[4]; // enough to store "WLED"

wled00/set.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
7373
#ifdef WLED_USE_ETHERNET
7474
ETH.setHostname(hostName);
7575
#endif
76-
WiFi.setHostname(hostName);
76+
WiFi.setHostname(hostName); // Sets the hostName in the wifi lib; does not necessarily propagate it to the network interface
77+
set_esp_interface_hostname(ESP_IF_WIFI_STA, hostName); // ensure hostName propagates to network interface for DHCP and mDNS
7778
#else
7879
WiFi.hostname(hostName);
7980
#endif

0 commit comments

Comments
 (0)