2026-06-27 20:00:17 -05:00
|
|
|
#include "app.h"
|
2026-06-27 15:58:42 -05:00
|
|
|
|
|
|
|
|
#include <mbedtls/md.h>
|
|
|
|
|
|
|
|
|
|
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);
|
2026-06-28 12:34:55 -05:00
|
|
|
const char *WWW_ROOT = "/www";
|
|
|
|
|
const char *LOG_DIR = "/log";
|
|
|
|
|
const char *LOG_FILE_PATH = "/log/logs.txt";
|
2026-06-27 15:58:42 -05:00
|
|
|
|
|
|
|
|
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;
|
2026-06-27 20:00:17 -05:00
|
|
|
String networkHostname;
|
|
|
|
|
bool networkDhcp = true;
|
|
|
|
|
String networkIp;
|
|
|
|
|
String networkGateway;
|
|
|
|
|
String networkSubnet;
|
|
|
|
|
String networkDns1;
|
|
|
|
|
String networkDns2;
|
2026-06-27 15:58:42 -05:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-27 20:00:17 -05:00
|
|
|
String defaultDeviceName() {
|
2026-06-27 15:58:42 -05:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-27 20:00:17 -05:00
|
|
|
String deviceName() {
|
|
|
|
|
return networkHostname.length() ? networkHostname : defaultDeviceName();
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-27 15:58:42 -05:00
|
|
|
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);
|
|
|
|
|
}
|
2026-06-27 20:00:17 -05:00
|
|
|
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);
|
2026-06-27 15:58:42 -05:00
|
|
|
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);
|
2026-06-27 20:00:17 -05:00
|
|
|
networkHostname = prefString("netHost", "");
|
|
|
|
|
networkDhcp = prefs.getBool("netDhcp", true);
|
|
|
|
|
networkIp = prefString("netIp", "");
|
|
|
|
|
networkGateway = prefString("netGw", "");
|
|
|
|
|
networkSubnet = prefString("netMask", "");
|
|
|
|
|
networkDns1 = prefString("netDns1", "");
|
|
|
|
|
networkDns2 = prefString("netDns2", "");
|
2026-06-27 15:58:42 -05:00
|
|
|
}
|