2dc216fb7b
- McpSettings was hardcoded to /data/service/mcp/settings.properties, but ES3C28P uses storage.userDataLocation=SD so user data lives on /sdcard/tactility/. Settings appeared to save but on reload returned default false -> "enable and when I go back shows disabled". Fixed to use getUserDataPath()+"/settings/mcp.properties" pattern consistent with DisplaySettings/WebServerSettings, with findOrCreateParentDirectory() and isFile() guard. - HttpServer ctrl_port collision: ESP-IDF default 32768 used by both WebServer (80) and DevelopmentService (6666). Second httpd_start() failed silently -> dashboard up but /api/mcp 404 and :6666 refused. Fixed with unique ctrl_port = 32768 + (port % 1000). Added CONFIG_HTTPD_MAX_URI_HANDLERS=20 (default 8 < 9 needed for 7 handlers + 2 internal). - DevService stack 5120 -> 8192 for /app/install handling. - McpSystem video stream task stack 4096 -> 8192 and idle yield 50ms (was 5ms always) to avoid CPU starvation blocking httpd tasks. On RLCD, timer must always run: DisplayIdle early return on !supportsBacklightDuty() broke MCP manual activation (cachedSettings not loaded, backlight duty 0). Fixed to always load settings + start timer, log RLCD detection, guard setBacklightDuty with supportsBacklightDuty() and fallback duty 255. - DisplaySettings: add disableScreensaverWhenCharging bool, persisted, with UI toggle in Display app (Settings->Display) using PowerDevice::IsCharging check via findDevices callback. When charging and flag enabled, screensaver activation skipped, and if already dimmed, wake on charging. - ES3C28P Power driver: GPIO9 ADC1_CH8 2x divider 2500-4200mV spec from ~/Downloads official docs, TP4054 CHRG not connected to GPIO, so IsCharging inferred via voltage thresholds (<500mV no battery USB or >5000mV wall powered, >=4150mV high) + rising trend. Verified: flashed es3c28p to /dev/cu.usbmodem101 (192.168.68.113), WiFi FamReynaMesh RSSI -59, dashboard 200, :6666/info now works, /api/mcp returns disabled correctly until enabled, persists to SD.
84 lines
2.1 KiB
C++
84 lines
2.1 KiB
C++
#ifdef ESP_PLATFORM
|
|
|
|
#include <Tactility/network/HttpServer.h>
|
|
|
|
#include <Tactility/Logger.h>
|
|
#include <Tactility/service/wifi/Wifi.h>
|
|
|
|
namespace tt::network {
|
|
|
|
static const auto LOGGER = Logger("HttpServer");
|
|
|
|
static constexpr size_t INTERNAL_URI_HANDLER_COUNT = 2;
|
|
|
|
bool HttpServer::startInternal() {
|
|
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
|
config.stack_size = stackSize;
|
|
config.server_port = port;
|
|
config.uri_match_fn = matchUri;
|
|
config.max_uri_handlers = handlers.size() + INTERNAL_URI_HANDLER_COUNT;
|
|
// Assign unique ctrl port based on server port to avoid collision when
|
|
// multiple HTTP servers (e.g. WebServer 80 + DevServer 6666) start simultaneously.
|
|
// ESP-IDF default ctrl_port is 32768; we offset by server port.
|
|
config.ctrl_port = static_cast<uint16_t>(32768 + (port % 1000));
|
|
|
|
if (httpd_start(&server, &config) != ESP_OK) {
|
|
LOGGER.error("Failed to start http server on port {} (ctrl_port {})", port, config.ctrl_port);
|
|
return false;
|
|
}
|
|
|
|
bool allRegistered = true;
|
|
for (std::vector<httpd_uri_t>::reference handler : handlers) {
|
|
if (httpd_register_uri_handler(server, &handler) != ESP_OK) {
|
|
LOGGER.error("Failed to register URI handler: {}", handler.uri);
|
|
allRegistered = false;
|
|
}
|
|
}
|
|
if (!allRegistered) {
|
|
httpd_stop(server);
|
|
server = nullptr;
|
|
return false;
|
|
}
|
|
|
|
LOGGER.info("Started on port {}", config.server_port);
|
|
return true;
|
|
}
|
|
|
|
void HttpServer::stopInternal() {
|
|
LOGGER.info("Stopping server");
|
|
if (server != nullptr) {
|
|
if (httpd_stop(server) == ESP_OK) {
|
|
server = nullptr;
|
|
} else {
|
|
LOGGER.warn("Error while stopping");
|
|
}
|
|
}
|
|
}
|
|
|
|
bool HttpServer::start() {
|
|
auto lock = mutex.asScopedLock();
|
|
lock.lock();
|
|
|
|
if (isStarted()) {
|
|
LOGGER.warn("Already started");
|
|
return true;
|
|
}
|
|
|
|
return startInternal();
|
|
}
|
|
|
|
void HttpServer::stop() {
|
|
auto lock = mutex.asScopedLock();
|
|
lock.lock();
|
|
|
|
if (!isStarted()) {
|
|
LOGGER.warn("Not started");
|
|
return;
|
|
}
|
|
|
|
stopInternal();
|
|
}
|
|
|
|
}
|
|
|
|
#endif |