#include "app.h" #include const char *APP_VERSION = "0.1.0"; const char *PROJECT_NAME_VALUE = PROJECT_NAME; const char *DEFAULT_ADMIN = "admin"; const char *DEFAULT_UPDATE_URL = "http://example.com/update.tslpkg"; const uint32_t FACTORY_RESET_HOLD_MS = 10000; const size_t MAX_USERS = 8; const size_t MAX_TOKENS = 8; const bool DEFAULT_LED_INVERTED = true; const byte DNS_PORT = 53; const IPAddress SETUP_AP_IP(192, 168, 1, 1); const IPAddress SETUP_AP_GATEWAY(192, 168, 1, 1); const IPAddress SETUP_AP_SUBNET(255, 255, 255, 0); WebServer server(80); DNSServer dnsServer; Preferences prefs; Token tokens[8]; LogLevel currentLogLevel = LOG_INFO; size_t maxLogBytes = 50 * 1024; bool setupMode = false; uint8_t ledBrightness = 0; bool ledInverted = DEFAULT_LED_INVERTED; String updateUrl = DEFAULT_UPDATE_URL; String networkHostname; bool networkDhcp = true; String networkIp; String networkGateway; String networkSubnet; String networkDns1; String networkDns2; String chipId() { uint64_t mac = ESP.getEfuseMac(); char buf[13]; snprintf(buf, sizeof(buf), "%04X%08X", (uint16_t)(mac >> 32), (uint32_t)mac); return String(buf); } String defaultDeviceName() { String suffix = chipId().substring(6); String base = PROJECT_NAME_VALUE; base.trim(); for (size_t i = 0; i < base.length(); i++) { char c = base[i]; if (!(isalnum(c) || c == '-')) base.setCharAt(i, '-'); } while (base.startsWith("-")) base.remove(0, 1); while (base.endsWith("-")) base.remove(base.length() - 1); if (!base.length()) base = "ESP32C3"; const size_t maxHostnameLength = 31; size_t maxBaseLength = maxHostnameLength - 1 - suffix.length(); if (base.length() > maxBaseLength) base = base.substring(0, maxBaseLength); while (base.endsWith("-")) base.remove(base.length() - 1); return base + "-" + suffix; } String deviceName() { return networkHostname.length() ? networkHostname : defaultDeviceName(); } String sha256(const String &input) { uint8_t digest[32]; mbedtls_md_context_t ctx; mbedtls_md_init(&ctx); mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 0); mbedtls_md_starts(&ctx); mbedtls_md_update(&ctx, (const unsigned char *)input.c_str(), input.length()); mbedtls_md_finish(&ctx, digest); mbedtls_md_free(&ctx); char out[65]; for (int i = 0; i < 32; i++) snprintf(out + (i * 2), 3, "%02x", digest[i]); out[64] = 0; return String(out); } String passwordHash(const String &password) { return sha256(chipId() + ":" + password); } String prefString(const char *key, const String &fallback) { return prefs.isKey(key) ? prefs.getString(key, fallback) : fallback; } void loadSettings() { prefs.begin("boiler", false); if (!prefs.getBool("ledPolV2", false)) { prefs.putBool("ledInv", DEFAULT_LED_INVERTED); prefs.putBool("ledPolV2", true); } uint8_t rawLogLevel = prefs.getUChar("logLevel", LOG_INFO); if (!prefs.getBool("logLevelV2", false)) { if (prefs.isKey("logLevel") && rawLogLevel >= 2) rawLogLevel++; rawLogLevel = constrain(rawLogLevel, 0, 4); prefs.putUChar("logLevel", rawLogLevel); prefs.putBool("logLevelV2", true); } currentLogLevel = (LogLevel)constrain(rawLogLevel, 0, 4); maxLogBytes = prefs.getUInt("logMax", 50 * 1024); ledInverted = prefs.getBool("ledInv", DEFAULT_LED_INVERTED); ledBrightness = constrain(prefs.getUChar("ledBright", 0), 0, 100); updateUrl = prefString("updateUrl", DEFAULT_UPDATE_URL); networkHostname = prefString("netHost", ""); networkDhcp = prefs.getBool("netDhcp", true); networkIp = prefString("netIp", ""); networkGateway = prefString("netGw", ""); networkSubnet = prefString("netMask", ""); networkDns1 = prefString("netDns1", ""); networkDns2 = prefString("netDns2", ""); }