diff --git a/src/JsonSettingsIO.cpp b/src/JsonSettingsIO.cpp index 50841c10..11147884 100644 --- a/src/JsonSettingsIO.cpp +++ b/src/JsonSettingsIO.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -272,7 +273,33 @@ bool JsonSettingsIO::loadWifi(WifiCredentialStore& store, const char* json, bool } store.lastConnectedSsid = doc["lastConnectedSsid"] | std::string(""); + + const auto isValidDashedMac = [](const std::string& value) -> bool { + if (value.empty()) { + return true; + } + if (value.size() != 17) { + return false; + } + for (size_t i = 0; i < value.size(); i++) { + if (i == 2 || i == 5 || i == 8 || i == 11 || i == 14) { + if (value[i] != '-') { + return false; + } + } else if (!std::isxdigit(static_cast(value[i]))) { + return false; + } + } + return true; + }; + store.lastKnownMacAddress = doc["lastKnownMacAddress"] | std::string(""); + if (!isValidDashedMac(store.lastKnownMacAddress)) { + store.lastKnownMacAddress.clear(); + if (needsResave) { + *needsResave = true; + } + } store.credentials.clear(); JsonArray arr = doc["credentials"].as(); diff --git a/src/activities/network/WifiSelectionActivity.cpp b/src/activities/network/WifiSelectionActivity.cpp index abf36938..d4f15315 100644 --- a/src/activities/network/WifiSelectionActivity.cpp +++ b/src/activities/network/WifiSelectionActivity.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -15,15 +16,7 @@ namespace { -bool isLikelyValidMac(const uint8_t mac[6]) { - bool allZero = true; - bool allFF = true; - for (int i = 0; i < 6; i++) { - allZero = allZero && (mac[i] == 0x00); - allFF = allFF && (mac[i] == 0xFF); - } - return !allZero && !allFF; -} +void readDeviceBaseMac(uint8_t mac[6]) { esp_efuse_mac_get_default(mac); } std::string formatMacLabel(const uint8_t mac[6]) { char macStr[64]; @@ -32,6 +25,19 @@ std::string formatMacLabel(const uint8_t mac[6]) { return std::string(macStr); } +std::string formatMacDashed(const uint8_t mac[6]) { + char persistedMac[18]; + snprintf(persistedMac, sizeof(persistedMac), "%02x-%02x-%02x-%02x-%02x-%02x", mac[0], mac[1], mac[2], mac[3], mac[4], + mac[5]); + return std::string(persistedMac); +} + +String formatMacCompact(const uint8_t mac[6]) { + char compactMac[13]; + snprintf(compactMac, sizeof(compactMac), "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return String(compactMac); +} + } // namespace void WifiSelectionActivity::onEnter() { @@ -44,12 +50,10 @@ void WifiSelectionActivity::onEnter() { WIFI_STORE.loadFromFile(); } - // Show persisted MAC immediately so UI doesn't briefly display a bogus value. - if (!WIFI_STORE.getLastKnownMacAddress().empty()) { - cachedMacAddress = std::string(tr(STR_MAC_ADDRESS)) + " " + WIFI_STORE.getLastKnownMacAddress(); - } else { - cachedMacAddress = std::string(tr(STR_MAC_ADDRESS)) + " --"; - } + // Use base MAC from eFuse (stable per-device, independent of WiFi init timing). + uint8_t mac[6]; + readDeviceBaseMac(mac); + cachedMacAddress = formatMacLabel(mac); // Reset state selectedNetworkIndex = 0; @@ -64,18 +68,10 @@ void WifiSelectionActivity::onEnter() { forgetPromptSelection = 0; autoConnecting = false; - // Refresh displayed MAC from live hardware value when valid. - uint8_t mac[6]; - WiFi.macAddress(mac); - if (isLikelyValidMac(mac)) { - cachedMacAddress = formatMacLabel(mac); - char persistedMac[18]; - snprintf(persistedMac, sizeof(persistedMac), "%02x-%02x-%02x-%02x-%02x-%02x", mac[0], mac[1], mac[2], mac[3], - mac[4], mac[5]); - if (WIFI_STORE.getLastKnownMacAddress() != persistedMac) { - RenderLock lock(*this); - WIFI_STORE.setLastKnownMacAddress(persistedMac); - } + const std::string persistedMac = formatMacDashed(mac); + if (WIFI_STORE.getLastKnownMacAddress() != persistedMac) { + RenderLock lock(*this); + WIFI_STORE.setLastKnownMacAddress(persistedMac); } // Trigger first update to show scanning message @@ -256,10 +252,10 @@ void WifiSelectionActivity::attemptConnection() { WiFi.disconnect(true, true); // Abort any in-progress SDK auto-connect and clear NVS-saved SSID delay(100); - // Set hostname so routers show "CrossPoint-Reader-AABBCCDDEEFF" instead of "esp32-XXXXXXXXXXXX" - String mac = WiFi.macAddress(); - mac.replace(":", ""); - String hostname = "CrossPoint-Reader-" + mac; + // Use stable base MAC so hostname suffix is deterministic across WiFi states. + uint8_t baseMac[6]; + readDeviceBaseMac(baseMac); + String hostname = "CrossPoint-Reader-" + formatMacCompact(baseMac); WiFi.setHostname(hostname.c_str()); if (selectedRequiresPassword && !enteredPassword.empty()) {