Replaced Logger usage with LOG_x (#548)

This commit is contained in:
Ken Van Hoeylandt
2026-07-04 23:49:19 +02:00
committed by GitHub
parent ecad2248d9
commit 9d5993930d
162 changed files with 1776 additions and 1842 deletions
@@ -1,15 +1,16 @@
#include <Tactility/service/ServiceRegistration.h>
#include <Tactility/Logger.h>
#include <Tactility/Mutex.h>
#include <Tactility/service/ServiceInstance.h>
#include <Tactility/service/ServiceManifest.h>
#include <string>
#include <tactility/log.h>
namespace tt::service {
static const auto LOGGER = Logger("ServiceRegistration");
constexpr auto* TAG = "ServiceRegistration";
typedef std::unordered_map<std::string, std::shared_ptr<const ServiceManifest>> ManifestMap;
typedef std::unordered_map<std::string, std::shared_ptr<ServiceInstance>> ServiceInstanceMap;
@@ -25,13 +26,13 @@ void addService(std::shared_ptr<const ServiceManifest> manifest, bool autoStart)
// We'll move the manifest pointer, but we'll need to id later
const auto& id = manifest->id;
LOGGER.info("Adding {}", id);
LOG_I(TAG, "Adding %s", id.c_str());
manifest_mutex.lock();
if (service_manifest_map[id] == nullptr) {
service_manifest_map[id] = std::move(manifest);
} else {
LOGGER.error("Service id in use: {}", id);
LOG_E(TAG, "Service id in use: %s", id.c_str());
}
manifest_mutex.unlock();
@@ -62,10 +63,10 @@ static std::shared_ptr<ServiceInstance> findServiceInstanceById(const std::strin
// TODO: Return proper error/status instead of BOOL?
bool startService(const std::string& id) {
LOGGER.info("Starting {}", id);
LOG_I(TAG, "Starting %s", id.c_str());
auto manifest = findManifestById(id);
if (manifest == nullptr) {
LOGGER.error("manifest not found for service {}", id);
LOG_E(TAG, "manifest not found for service %s", id.c_str());
return false;
}
@@ -80,14 +81,14 @@ bool startService(const std::string& id) {
if (service_instance->getService()->onStart(*service_instance)) {
service_instance->setState(State::Started);
} else {
LOGGER.error("Starting {} failed", id);
LOG_E(TAG, "Starting %s failed", id.c_str());
service_instance->setState(State::Stopped);
instance_mutex.lock();
service_instance_map.erase(manifest->id);
instance_mutex.unlock();
}
LOGGER.info("Started {}", id);
LOG_I(TAG, "Started %s", id.c_str());
return true;
}
@@ -102,10 +103,10 @@ std::shared_ptr<Service> findServiceById(const std::string& id) {
}
bool stopService(const std::string& id) {
LOGGER.info("Stopping {}", id);
LOG_I(TAG, "Stopping %s", id.c_str());
auto service_instance = findServiceInstanceById(id);
if (service_instance == nullptr) {
LOGGER.warn("Service not running: {}", id);
LOG_W(TAG, "Service not running: %s", id.c_str());
return false;
}
@@ -118,10 +119,10 @@ bool stopService(const std::string& id) {
instance_mutex.unlock();
if (service_instance.use_count() > 1) {
LOGGER.warn("Possible memory leak: service {} still has {} references", service_instance->getManifest().id, service_instance.use_count() - 1);
LOG_W(TAG, "Possible memory leak: service %s still has %d references", service_instance->getManifest().id.c_str(), (int)(service_instance.use_count() - 1));
}
LOGGER.info("Stopped {}", id);
LOG_I(TAG, "Stopped %s", id.c_str());
return true;
}
@@ -7,7 +7,6 @@
#include <Tactility/file/File.h>
#include <Tactility/network/HttpdReq.h>
#include <Tactility/network/Url.h>
#include <Tactility/Logger.h>
#include <Tactility/Paths.h>
#include <Tactility/service/development/DevelopmentSettings.h>
#include <Tactility/service/ServiceRegistration.h>
@@ -16,11 +15,13 @@
#include <ranges>
#include <sstream>
#include <tactility/log.h>
namespace tt::service::development {
extern const ServiceManifest manifest;
static const auto LOGGER = Logger("DevService");
constexpr auto* TAG = "DevService";
bool DevelopmentService::onStart(ServiceContext& service) {
std::stringstream stream;
@@ -66,26 +67,26 @@ bool DevelopmentService::isEnabled() const {
// region endpoints
esp_err_t DevelopmentService::handleGetInfo(httpd_req_t* request) {
LOGGER.info("GET /device");
LOG_I(TAG, "GET /device");
if (httpd_resp_set_type(request, "application/json") != ESP_OK) {
LOGGER.warn("Failed to send header");
LOG_W(TAG, "Failed to send header");
return ESP_FAIL;
}
auto* service = static_cast<DevelopmentService*>(request->user_ctx);
if (httpd_resp_sendstr(request, service->deviceResponse.c_str()) != ESP_OK) {
LOGGER.warn("Failed to send response body");
LOG_W(TAG, "Failed to send response body");
return ESP_FAIL;
}
LOGGER.info("[200] /device");
LOG_I(TAG, "[200] /device");
return ESP_OK;
}
esp_err_t DevelopmentService::handleAppRun(httpd_req_t* request) {
LOGGER.info("POST /app/run");
LOG_I(TAG, "POST /app/run");
std::string query;
if (!network::getQueryOrSendError(request, query)) {
@@ -95,7 +96,7 @@ esp_err_t DevelopmentService::handleAppRun(httpd_req_t* request) {
auto parameters = network::parseUrlQuery(query);
auto id_key_pos = parameters.find("id");
if (id_key_pos == parameters.end()) {
LOGGER.warn("[400] /app/run id not specified");
LOG_W(TAG, "[400] /app/run id not specified");
httpd_resp_send_err(request, HTTPD_400_BAD_REQUEST, "id not specified");
return ESP_FAIL;
}
@@ -107,14 +108,14 @@ esp_err_t DevelopmentService::handleAppRun(httpd_req_t* request) {
app::start(app_id);
LOGGER.info("[200] /app/run {}", id_key_pos->second);
LOG_I(TAG, "[200] /app/run %s", id_key_pos->second.c_str());
httpd_resp_send(request, nullptr, 0);
return ESP_OK;
}
esp_err_t DevelopmentService::handleAppInstall(httpd_req_t* request) {
LOGGER.info("PUT /app/install");
LOG_I(TAG, "PUT /app/install");
std::string boundary;
if (!network::getMultiPartBoundaryOrSendError(request, boundary)) {
@@ -175,7 +176,7 @@ esp_err_t DevelopmentService::handleAppInstall(httpd_req_t* request) {
content_left -= boundary_and_newlines_after_file.length();
if (content_left != 0) {
LOGGER.warn("We have more bytes at the end of the request parsing?!");
LOG_W(TAG, "We have more bytes at the end of the request parsing?!");
}
if (!app::install(file_path)) {
@@ -184,10 +185,10 @@ esp_err_t DevelopmentService::handleAppInstall(httpd_req_t* request) {
}
if (!file::deleteFile(file_path)) {
LOGGER.warn("Failed to delete {}", file_path);
LOG_W(TAG, "Failed to delete %s", file_path.c_str());
}
LOGGER.info("[200] /app/install -> {}", file_path);
LOG_I(TAG, "[200] /app/install -> %s", file_path.c_str());
httpd_resp_send(request, nullptr, 0);
@@ -195,7 +196,7 @@ esp_err_t DevelopmentService::handleAppInstall(httpd_req_t* request) {
}
esp_err_t DevelopmentService::handleAppUninstall(httpd_req_t* request) {
LOGGER.info("PUT /app/uninstall");
LOG_I(TAG, "PUT /app/uninstall");
std::string query;
if (!network::getQueryOrSendError(request, query)) {
@@ -205,23 +206,23 @@ esp_err_t DevelopmentService::handleAppUninstall(httpd_req_t* request) {
auto parameters = network::parseUrlQuery(query);
auto id_key_pos = parameters.find("id");
if (id_key_pos == parameters.end()) {
LOGGER.warn("[400] /app/uninstall id not specified");
LOG_W(TAG, "[400] /app/uninstall id not specified");
httpd_resp_send_err(request, HTTPD_400_BAD_REQUEST, "id not specified");
return ESP_FAIL;
}
if (!app::findAppManifestById(id_key_pos->second)) {
LOGGER.info("[200] /app/uninstall {} (app wasn't installed)", id_key_pos->second);
LOG_I(TAG, "[200] /app/uninstall %s (app wasn't installed)", id_key_pos->second.c_str());
httpd_resp_send(request, nullptr, 0);
return ESP_OK;
}
if (app::uninstall(id_key_pos->second)) {
LOGGER.info("[200] /app/uninstall {}", id_key_pos->second);
LOG_I(TAG, "[200] /app/uninstall %s", id_key_pos->second.c_str());
httpd_resp_send(request, nullptr, 0);
return ESP_OK;
} else {
LOGGER.warn("[500] /app/uninstall {}", id_key_pos->second);
LOG_W(TAG, "[500] /app/uninstall %s", id_key_pos->second.c_str());
httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to uninstall");
return ESP_FAIL;
}
@@ -1,15 +1,16 @@
#ifdef ESP_PLATFORM
#include <Tactility/file/File.h>
#include <Tactility/file/PropertiesFile.h>
#include <Tactility/Logger.h>
#include <Tactility/Paths.h>
#include <Tactility/service/development/DevelopmentSettings.h>
#include <map>
#include <string>
#include <tactility/log.h>
namespace tt::service::development {
static const auto LOGGER = Logger("DevSettings");
constexpr auto* TAG = "DevSettings";
static std::string getSettingsFilePath() {
return getUserDataPath() + "/settings/development.properties";
@@ -46,7 +47,7 @@ static bool save(const DevelopmentSettings& settings) {
map[SETTINGS_KEY_ENABLE_ON_BOOT] = settings.enableOnBoot ? "true" : "false";
auto settings_path = getSettingsFilePath();
if (!file::findOrCreateParentDirectory(settings_path, 0755)) {
LOGGER.error("Failed to create parent dir for {}", settings_path);
LOG_E(TAG, "Failed to create parent dir for %s", settings_path.c_str());
return false;
}
return file::savePropertiesFile(settings_path, map);
@@ -55,7 +56,7 @@ static bool save(const DevelopmentSettings& settings) {
void setEnableOnBoot(bool enable) {
DevelopmentSettings properties { .enableOnBoot = enable };
if (!save(properties)) {
LOGGER.error("Failed to save {}", getSettingsFilePath());
LOG_E(TAG, "Failed to save %s", getSettingsFilePath().c_str());
}
}
@@ -8,7 +8,7 @@
#include "MystifyScreensaver.h"
#include "StackChanScreensaver.h"
#include <Tactility/Logger.h>
#include <tactility/log.h>
#include <Tactility/CoreDefines.h>
#include <Tactility/hal/display/DisplayDevice.h>
#include <Tactility/lvgl/LvglSync.h>
@@ -20,7 +20,7 @@
namespace tt::service::displayidle {
static const auto LOGGER = Logger("DisplayIdle");
constexpr auto* TAG = "DisplayIdle";
constexpr uint32_t kWakeActivityThresholdMs = 100;
@@ -224,7 +224,7 @@ void DisplayIdleService::onStop(ServiceContext& service) {
}
}
if (screensaverOverlay) {
LOGGER.warn("Failed to stop screensaver during shutdown - potential resource leak");
LOG_W(TAG, "Failed to stop screensaver during shutdown - potential resource leak");
}
}
screensaver.reset();
+10 -10
View File
@@ -7,18 +7,18 @@
#include <Tactility/service/espnow/EspNow.h>
#include <Tactility/service/espnow/EspNowService.h>
#include <Tactility/Logger.h>
#include <tactility/log.h>
namespace tt::service::espnow {
static const auto LOGGER = Logger("EspNow");
constexpr auto* TAG = "EspNow";
void enable(const EspNowConfig& config) {
auto service = findService();
if (service != nullptr) {
service->enable(config);
} else {
LOGGER.error("Service not found");
LOG_E(TAG, "Service not found");
}
}
@@ -27,7 +27,7 @@ void disable() {
if (service != nullptr) {
service->disable();
} else {
LOGGER.error("Service not found");
LOG_E(TAG, "Service not found");
}
}
@@ -36,7 +36,7 @@ bool isEnabled() {
if (service != nullptr) {
return service->isEnabled();
} else {
LOGGER.error("Service not found");
LOG_E(TAG, "Service not found");
return false;
}
}
@@ -46,7 +46,7 @@ bool addPeer(const esp_now_peer_info_t& peer) {
if (service != nullptr) {
return service->addPeer(peer);
} else {
LOGGER.error("Service not found");
LOG_E(TAG, "Service not found");
return false;
}
}
@@ -56,7 +56,7 @@ bool send(const uint8_t* address, const uint8_t* buffer, size_t bufferLength) {
if (service != nullptr) {
return service->send(address, buffer, bufferLength);
} else {
LOGGER.error("Service not found");
LOG_E(TAG, "Service not found");
return false;
}
}
@@ -66,7 +66,7 @@ ReceiverSubscription subscribeReceiver(std::function<void(const esp_now_recv_inf
if (service != nullptr) {
return service->subscribeReceiver(onReceive);
} else {
LOGGER.error("Service not found");
LOG_E(TAG, "Service not found");
return -1;
}
}
@@ -76,7 +76,7 @@ void unsubscribeReceiver(ReceiverSubscription subscription) {
if (service != nullptr) {
service->unsubscribeReceiver(subscription);
} else {
LOGGER.error("Service not found");
LOG_E(TAG, "Service not found");
}
}
@@ -85,7 +85,7 @@ uint32_t getVersion() {
if (service != nullptr) {
return service->getVersion();
}
LOGGER.error("Service not found");
LOG_E(TAG, "Service not found");
return 0;
}
@@ -4,7 +4,6 @@
#if defined(CONFIG_SOC_WIFI_SUPPORTED) && !defined(CONFIG_SLAVE_SOC_WIFI_SUPPORTED)
#include <Tactility/Logger.h>
#include <Tactility/Tactility.h>
#include <Tactility/service/espnow/EspNowService.h>
#include <Tactility/service/ServiceManifest.h>
@@ -15,11 +14,13 @@
#include <esp_now.h>
#include <esp_random.h>
#include <tactility/log.h>
namespace tt::service::espnow {
extern const ServiceManifest manifest;
static const auto LOGGER = Logger("EspNowService");
constexpr auto* TAG = "EspNowService";
static uint8_t BROADCAST_MAC[ESP_NOW_ETH_ALEN];
constexpr TickType_t MAX_DELAY = 1000U / portTICK_PERIOD_MS;
@@ -60,17 +61,17 @@ void EspNowService::enableFromDispatcher(const EspNowConfig& config) {
}
if (!initWifi(config)) {
LOGGER.error("initWifi() failed");
LOG_E(TAG,"initWifi() failed");
return;
}
if (esp_now_init() != ESP_OK) {
LOGGER.error("esp_now_init() failed");
LOG_E(TAG,"esp_now_init() failed");
return;
}
if (esp_now_register_recv_cb(receiveCallback) != ESP_OK) {
LOGGER.error("esp_now_register_recv_cb() failed");
LOG_E(TAG,"esp_now_register_recv_cb() failed");
return;
}
@@ -80,15 +81,15 @@ void EspNowService::enableFromDispatcher(const EspNowConfig& config) {
//#endif
if (esp_now_set_pmk(config.masterKey) != ESP_OK) {
LOGGER.error("esp_now_set_pmk() failed");
LOG_E(TAG,"esp_now_set_pmk() failed");
return;
}
espnowVersion = 0;
if (esp_now_get_version(&espnowVersion) == ESP_OK) {
LOGGER.info("ESP-NOW version: {}.0", espnowVersion);
LOG_I(TAG, "ESP-NOW version: %u.0", (unsigned)espnowVersion);
} else {
LOGGER.warn("Failed to get ESP-NOW version");
LOG_W(TAG, "Failed to get ESP-NOW version");
}
// Add default unencrypted broadcast peer
@@ -119,11 +120,11 @@ void EspNowService::disableFromDispatcher() {
}
if (esp_now_deinit() != ESP_OK) {
LOGGER.error("esp_now_deinit() failed");
LOG_E(TAG,"esp_now_deinit() failed");
}
if (!deinitWifi()) {
LOGGER.error("deinitWifi() failed");
LOG_E(TAG,"deinitWifi() failed");
}
espnowVersion = 0;
@@ -137,7 +138,7 @@ void EspNowService::disableFromDispatcher() {
void EspNowService::receiveCallback(const esp_now_recv_info_t* receiveInfo, const uint8_t* data, int length) {
auto service = findService();
if (service == nullptr) {
LOGGER.error("Service not running");
LOG_E(TAG,"Service not running");
return;
}
service->onReceive(receiveInfo, data, length);
@@ -147,7 +148,7 @@ void EspNowService::onReceive(const esp_now_recv_info_t* receiveInfo, const uint
auto lock = mutex.asScopedLock();
lock.lock();
LOGGER.debug("Received {} bytes", length);
LOG_D(TAG, "Received %d bytes", length);
for (const auto& item: subscriptions) {
item.onReceive(receiveInfo, data, length);
@@ -164,10 +165,10 @@ bool EspNowService::isEnabled() const {
bool EspNowService::addPeer(const esp_now_peer_info_t& peer) {
if (esp_now_add_peer(&peer) != ESP_OK) {
LOGGER.error("Failed to add peer");
LOG_E(TAG,"Failed to add peer");
return false;
} else {
LOGGER.info("Peer added");
LOG_I(TAG, "Peer added");
return true;
}
}
+12 -11
View File
@@ -4,16 +4,17 @@
#if defined(CONFIG_SOC_WIFI_SUPPORTED) && !defined(CONFIG_SLAVE_SOC_WIFI_SUPPORTED)
#include <Tactility/Logger.h>
#include <Tactility/service/espnow/EspNow.h>
#include <Tactility/service/wifi/Wifi.h>
#include <esp_now.h>
#include <esp_wifi.h>
#include <tactility/log.h>
namespace tt::service::espnow {
static const auto LOGGER = Logger("EspNowService");
constexpr auto* TAG = "EspNowService";
static bool wifiStartedByEspNow = false;
bool initWifi(const EspNowConfig& config) {
@@ -32,27 +33,27 @@ bool initWifi(const EspNowConfig& config) {
if (wifiStartedByEspNow) {
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
if (esp_wifi_init(&cfg) != ESP_OK) {
LOGGER.error("esp_wifi_init() failed");
LOG_E(TAG,"esp_wifi_init() failed");
return false;
}
if (esp_wifi_set_storage(WIFI_STORAGE_RAM) != ESP_OK) {
LOGGER.error("esp_wifi_set_storage() failed");
LOG_E(TAG,"esp_wifi_set_storage() failed");
return false;
}
if (esp_wifi_set_mode(mode) != ESP_OK) {
LOGGER.error("esp_wifi_set_mode() failed");
LOG_E(TAG,"esp_wifi_set_mode() failed");
return false;
}
if (esp_wifi_start() != ESP_OK) {
LOGGER.error("esp_wifi_start() failed");
LOG_E(TAG,"esp_wifi_start() failed");
return false;
}
if (esp_wifi_set_channel(config.channel, WIFI_SECOND_CHAN_NONE) != ESP_OK) {
LOGGER.error("esp_wifi_set_channel() failed");
LOG_E(TAG,"esp_wifi_set_channel() failed");
return false;
}
}
@@ -66,11 +67,11 @@ bool initWifi(const EspNowConfig& config) {
}
if (esp_wifi_set_protocol(wifi_interface, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_LR) != ESP_OK) {
LOGGER.warn("esp_wifi_set_protocol() for long range failed");
LOG_W(TAG,"esp_wifi_set_protocol() for long range failed");
}
}
LOGGER.info("WiFi initialized for ESP-NOW (wifi already running: {})", wifi_already_running ? "yes" : "no");
LOG_I(TAG, "WiFi initialized for ESP-NOW (wifi already running: %s)", wifi_already_running ? "yes" : "no");
return true;
}
@@ -79,9 +80,9 @@ bool deinitWifi() {
esp_wifi_stop();
esp_wifi_deinit();
wifiStartedByEspNow = false;
LOGGER.info("WiFi stopped (was started by ESP-NOW)");
LOG_I(TAG, "WiFi stopped (was started by ESP-NOW)");
} else {
LOGGER.info("WiFi left running (managed by WiFi service)");
LOG_I(TAG, "WiFi left running (managed by WiFi service)");
}
return true;
}
@@ -1,25 +1,26 @@
#include <Tactility/file/ObjectFile.h>
#include <Tactility/Logger.h>
#include <Tactility/service/gps/GpsService.h>
#include <Tactility/service/ServicePaths.h>
#include <cstring>
#include <unistd.h>
#include <tactility/log.h>
using tt::hal::gps::GpsDevice;
namespace tt::service::gps {
static const auto LOGGER = Logger("GpsService");
constexpr auto* TAG = "GpsService";
bool GpsService::getConfigurationFilePath(std::string& output) const {
if (paths == nullptr) {
LOGGER.error("Can't add configuration: service not started");
LOG_E(TAG, "Can't add configuration: service not started");
return false;
}
if (!file::findOrCreateDirectory(paths->getUserDataDirectory(), 0777)) {
LOGGER.error("Failed to find or create path {}", paths->getUserDataDirectory());
LOG_E(TAG, "Failed to find or create path %s", paths->getUserDataDirectory().c_str());
return false;
}
@@ -35,21 +36,21 @@ bool GpsService::getGpsConfigurations(std::vector<hal::gps::GpsConfiguration>& c
// If file does not exist, return empty list
if (access(path.c_str(), F_OK) != 0) {
LOGGER.warn("No configurations (file not found: {})", path);
LOG_W(TAG, "No configurations (file not found: %s)", path.c_str());
return true;
}
LOGGER.info("Reading configuration file {}", path);
LOG_I(TAG, "Reading configuration file %s", path.c_str());
auto reader = file::ObjectFileReader(path, sizeof(hal::gps::GpsConfiguration));
if (!reader.open()) {
LOGGER.error("Failed to open configuration file");
LOG_E(TAG, "Failed to open configuration file");
return false;
}
hal::gps::GpsConfiguration configuration;
while (reader.hasNext()) {
if (!reader.readNext(&configuration)) {
LOGGER.error("Failed to read configuration");
LOG_E(TAG, "Failed to read configuration");
reader.close();
return false;
} else {
@@ -68,12 +69,12 @@ bool GpsService::addGpsConfiguration(hal::gps::GpsConfiguration configuration) {
auto appender = file::ObjectFileWriter(path, sizeof(hal::gps::GpsConfiguration), 1, true);
if (!appender.open()) {
LOGGER.error("Failed to open/create configuration file");
LOG_E(TAG, "Failed to open/create configuration file");
return false;
}
if (!appender.write(&configuration)) {
LOGGER.error("Failed to add configuration");
LOG_E(TAG, "Failed to add configuration");
appender.close();
return false;
}
@@ -90,7 +91,7 @@ bool GpsService::removeGpsConfiguration(hal::gps::GpsConfiguration configuration
std::vector<hal::gps::GpsConfiguration> configurations;
if (!getGpsConfigurations(configurations)) {
LOGGER.error("Failed to get gps configurations");
LOG_E(TAG, "Failed to get gps configurations");
return false;
}
@@ -102,7 +103,7 @@ bool GpsService::removeGpsConfiguration(hal::gps::GpsConfiguration configuration
auto writer = file::ObjectFileWriter(path, sizeof(hal::gps::GpsConfiguration), 1, false);
if (!writer.open()) {
LOGGER.error("Failed to open configuration file");
LOG_E(TAG, "Failed to open configuration file");
return false;
}
+14 -13
View File
@@ -1,16 +1,17 @@
#include <Tactility/service/gps/GpsService.h>
#include <Tactility/file/File.h>
#include <Tactility/Logger.h>
#include <Tactility/service/ServicePaths.h>
#include <Tactility/service/ServiceManifest.h>
#include <Tactility/service/ServiceRegistration.h>
#include <tactility/log.h>
using tt::hal::gps::GpsDevice;
namespace tt::service::gps {
static const auto LOGGER = Logger("GpsService");
constexpr auto* TAG = "GpsService";
extern const ServiceManifest manifest;
constexpr bool hasTimeElapsed(TickType_t now, TickType_t timeInThePast, TickType_t expireTimeInTicks) {
@@ -73,7 +74,7 @@ void GpsService::onStop(ServiceContext& serviceContext) {
}
bool GpsService::startGpsDevice(GpsDeviceRecord& record) {
LOGGER.info("[device {}] starting", record.device->getId());
LOG_I(TAG, "[device %u] starting", (unsigned)record.device->getId());
auto lock = mutex.asScopedLock();
lock.lock();
@@ -81,7 +82,7 @@ bool GpsService::startGpsDevice(GpsDeviceRecord& record) {
auto device = record.device;
if (!device->start()) {
LOGGER.error("[device {}] starting failed", record.device->getId());
LOG_E(TAG, "[device %u] starting failed", (unsigned)record.device->getId());
return false;
}
@@ -109,7 +110,7 @@ bool GpsService::startGpsDevice(GpsDeviceRecord& record) {
}
bool GpsService::stopGpsDevice(GpsDeviceRecord& record) {
LOGGER.info("[device {}] stopping", record.device->getId());
LOG_I(TAG, "[device %u] stopping", (unsigned)record.device->getId());
auto device = record.device;
@@ -120,7 +121,7 @@ bool GpsService::stopGpsDevice(GpsDeviceRecord& record) {
record.rmcSubscriptionId = -1;
if (!device->stop()) {
LOGGER.error("[device {}] stopping failed", record.device->getId());
LOG_E(TAG, "[device %u] stopping failed", (unsigned)record.device->getId());
return false;
}
@@ -128,10 +129,10 @@ bool GpsService::stopGpsDevice(GpsDeviceRecord& record) {
}
bool GpsService::startReceiving() {
LOGGER.info("Start receiving");
LOG_I(TAG, "Start receiving");
if (getState() != State::Off) {
LOGGER.error("Already receiving");
LOG_E(TAG, "Already receiving");
return false;
}
@@ -144,13 +145,13 @@ bool GpsService::startReceiving() {
std::vector<hal::gps::GpsConfiguration> configurations;
if (!getGpsConfigurations(configurations)) {
LOGGER.error("Failed to get GPS configurations");
LOG_E(TAG, "Failed to get GPS configurations");
setState(State::Off);
return false;
}
if (configurations.empty()) {
LOGGER.error("No GPS configurations");
LOG_E(TAG, "No GPS configurations");
setState(State::Off);
return false;
}
@@ -180,7 +181,7 @@ bool GpsService::startReceiving() {
}
void GpsService::stopReceiving() {
LOGGER.info("Stop receiving");
LOG_I(TAG, "Stop receiving");
setState(State::OffPending);
@@ -198,11 +199,11 @@ void GpsService::stopReceiving() {
}
void GpsService::onGgaSentence(hal::Device::Id deviceId, const minmea_sentence_gga& gga) {
LOGGER.debug("[device {}] LAT {} LON {}, satellites: {}", deviceId, minmea_tocoord(&gga.latitude), minmea_tocoord(&gga.longitude), gga.satellites_tracked);
LOG_D(TAG, "[device %u] LAT %f LON %f, satellites: %d", (unsigned)deviceId, minmea_tocoord(&gga.latitude), minmea_tocoord(&gga.longitude), gga.satellites_tracked);
}
void GpsService::onRmcSentence(hal::Device::Id deviceId, const minmea_sentence_rmc& rmc) {
LOGGER.debug("[device {}] LAT {} LON {}, speed: {}", deviceId, minmea_tocoord(&rmc.latitude), minmea_tocoord(&rmc.longitude), minmea_tofloat(&rmc.speed));
LOG_D(TAG, "[device %u] LAT %f LON %f, speed: %f", (unsigned)deviceId, minmea_tocoord(&rmc.latitude), minmea_tocoord(&rmc.longitude), minmea_tofloat(&rmc.speed));
}
State GpsService::getState() const {
+20 -19
View File
@@ -2,20 +2,21 @@
#include <cstring>
#include <Tactility/app/AppInstance.h>
#include <Tactility/Logger.h>
#include <Tactility/LogMessages.h>
#include <Tactility/Tactility.h>
#include <Tactility/app/AppInstance.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Tactility/lvgl/Statusbar.h>
#include <Tactility/lvgl/UsbHidInput.h>
#include <Tactility/service/loader/Loader.h>
#include <Tactility/service/ServiceRegistration.h>
#include <Tactility/Tactility.h>
#include <Tactility/service/loader/Loader.h>
#include <tactility/log.h>
namespace tt::service::gui {
extern const ServiceManifest manifest;
static const auto LOGGER = Logger("GuiService");
constexpr auto* TAG = "GuiService";
using namespace loader;
constexpr auto* GUI_TASK_NAME = "gui";
@@ -23,7 +24,7 @@ constexpr auto* GUI_TASK_NAME = "gui";
void warnIfRunningOnGuiTask(const char* context) {
const char* task_name = pcTaskGetName(nullptr);
if (strcmp(GUI_TASK_NAME, task_name) == 0) {
LOGGER.warn("{} shouldn't run on the GUI task", context);
LOG_W(TAG, "%s shouldn't run on the GUI task", context);
}
}
@@ -68,7 +69,7 @@ void GuiService::onLoaderEvent(LoaderService::Event event) {
}
if (dispatcher_dispatch(dispatcher, item, onGuiDispatch) != ERROR_NONE) {
LOGGER.error("Failed to dispatch gui event");
LOG_E(TAG, "Failed to dispatch gui event");
delete item;
}
}
@@ -77,7 +78,7 @@ int32_t GuiService::guiMain() {
auto service = findServiceById<GuiService>(manifest.id);
if (!lvgl::lock(5000)) {
LOGGER.error("LVGL guiMain start failed as LVGL couldn't be locked");
LOG_E(TAG, "LVGL guiMain start failed as LVGL couldn't be locked");
return 0;
}
@@ -86,7 +87,7 @@ int32_t GuiService::guiMain() {
auto* screen_root = lv_screen_active();
if (screen_root == nullptr) {
LOGGER.error("No display found, exiting GUI task");
LOG_E(TAG, "No display found, exiting GUI task");
lvgl::unlock();
return 0;
}
@@ -150,7 +151,7 @@ void GuiService::redraw() {
lock();
if (appRootWidget == nullptr) {
LOGGER.warn("No root widget");
LOG_W(TAG, "No root widget");
unlock();
return;
}
@@ -181,13 +182,13 @@ void GuiService::redraw() {
lv_obj_t* container = createAppViews(appRootWidget);
appToRender->getApp()->onShow(*appToRender, container);
} else {
LOGGER.warn("Nothing to draw");
LOG_W(TAG, "Nothing to draw");
}
// Unlock GUI and LVGL
lvgl::unlock();
} else {
LOGGER.error(LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "LVGL");
LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "LVGL");
}
unlock();
@@ -235,7 +236,7 @@ void GuiService::onStop(ServiceContext& service) {
auto* exit_item = new GuiDispatchItem{this, GuiDispatchType::Exit, nullptr};
if (dispatcher_dispatch(dispatcher, exit_item, onGuiDispatch) != ERROR_NONE) {
LOGGER.error("Failed to dispatch gui exit event");
LOG_E(TAG, "Failed to dispatch gui exit event");
check(false, "Failed to dispatch exit signal to thread.");
delete exit_item;
}
@@ -248,7 +249,7 @@ void GuiService::onStop(ServiceContext& service) {
}
lvgl::unlock();
} else {
LOGGER.error("Failed to lock LVGL during GUI stop");
LOG_E(TAG, "Failed to lock LVGL during GUI stop");
}
delete thread;
@@ -261,16 +262,16 @@ void GuiService::showApp(std::shared_ptr<app::AppInstance> app) {
lock.lock();
if (!isStarted) {
LOGGER.error("Failed to show app {}: GUI not started", app->getManifest().appId);
LOG_E(TAG, "Failed to show app %s: GUI not started", app->getManifest().appId.c_str());
return;
}
if (appToRender != nullptr && appToRender->getLaunchId() == app->getLaunchId()) {
LOGGER.warn("Already showing {}", app->getManifest().appId);
LOG_W(TAG, "Already showing %s", app->getManifest().appId.c_str());
return;
}
LOGGER.info("Showing {}", app->getManifest().appId);
LOG_I(TAG, "Showing %s", app->getManifest().appId.c_str());
// Ensure previous app triggers onHide() logic
if (appToRender != nullptr) {
hideApp();
@@ -285,12 +286,12 @@ void GuiService::hideApp() {
lock.lock();
if (!isStarted) {
LOGGER.error("Failed to hide app: GUI not started");
LOG_E(TAG, "Failed to hide app: GUI not started");
return;
}
if (appToRender == nullptr) {
LOGGER.warn("hideApp() called but no app is currently shown");
LOG_W(TAG, "hideApp() called but no app is currently shown");
return;
}
+22 -21
View File
@@ -3,9 +3,8 @@
#include <Tactility/app/AppManifest.h>
#include <Tactility/app/AppRegistration.h>
#include <Tactility/DispatcherThread.h>
#include <Tactility/Logger.h>
#include <Tactility/LogMessages.h>
#include <Tactility/DispatcherThread.h>
#include <Tactility/service/ServiceManifest.h>
#include <Tactility/service/ServiceRegistration.h>
@@ -16,9 +15,11 @@
#include <utility>
#endif
#include <tactility/log.h>
namespace tt::service::loader {
static const auto LOGGER = Logger("Loader");
constexpr auto* TAG = "Loader";
constexpr auto LOADER_TIMEOUT = (100 / portTICK_PERIOD_MS);
@@ -44,17 +45,17 @@ static const char* appStateToString(app::State state) {
}
void LoaderService::onStartAppMessage(const std::string& id, app::LaunchId launchId, std::shared_ptr<const Bundle> parameters) {
LOGGER.info("Start by id {}", id);
LOG_I(TAG, "Start by id %s", id.c_str());
auto app_manifest = app::findAppManifestById(id);
if (app_manifest == nullptr) {
LOGGER.error("App not found: {}", id);
LOG_E(TAG, "App not found: %s", id.c_str());
return;
}
auto lock = mutex.asScopedLock();
if (!lock.lock(LOADER_TIMEOUT)) {
LOGGER.error(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return;
}
@@ -76,14 +77,14 @@ void LoaderService::onStartAppMessage(const std::string& id, app::LaunchId launc
void LoaderService::onStopTopAppMessage(const std::string& id) {
auto lock = mutex.asScopedLock();
if (!lock.lock(LOADER_TIMEOUT)) {
LOGGER.error(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return;
}
size_t original_stack_size = appStack.size();
if (original_stack_size == 0) {
LOGGER.error("Stop app: no app running");
LOG_E(TAG, "Stop app: no app running");
return;
}
@@ -91,12 +92,12 @@ void LoaderService::onStopTopAppMessage(const std::string& id) {
auto app_to_stop = appStack[appStack.size() - 1];
if (app_to_stop->getManifest().appId != id) {
LOGGER.error("Stop app: id mismatch (wanted {} but found {} on top of stack)", id, app_to_stop->getManifest().appId);
LOG_E(TAG, "Stop app: id mismatch (wanted %s but found %s on top of stack)", id.c_str(), app_to_stop->getManifest().appId.c_str());
return;
}
if (original_stack_size == 1 && app_to_stop->getManifest().appName != "Boot") {
LOGGER.error("Stop app: can't stop root app");
LOG_E(TAG, "Stop app: can't stop root app");
return;
}
@@ -116,16 +117,16 @@ void LoaderService::onStopTopAppMessage(const std::string& id) {
// We only expect the app to be referenced within the current scope
if (app_to_stop.use_count() > 1) {
LOGGER.warn("Memory leak: Stopped {}, but use count is {}", app_to_stop->getManifest().appId, app_to_stop.use_count() - 1);
LOG_W(TAG, "Memory leak: Stopped %s, but use count is %d", app_to_stop->getManifest().appId.c_str(), (int)(app_to_stop.use_count() - 1));
}
// Refcount is expected to be 2: 1 within app_to_stop and 1 within the current scope
if (app_to_stop->getApp().use_count() > 2) {
LOGGER.warn("Memory leak: Stopped {}, but use count is {}", app_to_stop->getManifest().appId, app_to_stop->getApp().use_count() - 2);
LOG_W(TAG, "Memory leak: Stopped %s, but use count is %d", app_to_stop->getManifest().appId.c_str(), (int)(app_to_stop->getApp().use_count() - 2));
}
#ifdef ESP_PLATFORM
LOGGER.info("Free heap: {}", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
LOG_I(TAG, "Free heap: %d", (int)heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
#endif
std::shared_ptr<app::AppInstance> instance_to_resume;
@@ -182,18 +183,18 @@ int LoaderService::findAppInStack(const std::string& id) const {
void LoaderService::onStopAllAppMessage(const std::string& id) {
auto lock = mutex.asScopedLock();
if (!lock.lock(LOADER_TIMEOUT)) {
LOGGER.error(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return;
}
if (!isRunning(id)) {
LOGGER.error("Stop all: {} not running", id);
LOG_E(TAG, "Stop all: %s not running", id.c_str());
return;
}
int app_to_stop_index = findAppInStack(id);
if (app_to_stop_index < 0) {
LOGGER.error("Stop all: {} not found in stack", id);
LOG_E(TAG, "Stop all: %s not found in stack", id.c_str());
return;
}
@@ -220,7 +221,7 @@ void LoaderService::onStopAllAppMessage(const std::string& id) {
}
if (instance_to_resume != nullptr) {
LOGGER.info("Resuming {}", instance_to_resume->getManifest().appId);
LOG_I(TAG, "Resuming %s", instance_to_resume->getManifest().appId.c_str());
transitionAppToState(instance_to_resume, app::State::Showing);
instance_to_resume->getApp()->onResult(
@@ -236,8 +237,8 @@ void LoaderService::transitionAppToState(const std::shared_ptr<app::AppInstance>
const app::AppManifest& app_manifest = app->getManifest();
const app::State old_state = app->getState();
LOGGER.info( "App \"{}\" state: {} -> {}",
app_manifest.appId,
LOG_I(TAG, "App \"%s\" state: %s -> %s",
app_manifest.appId.c_str(),
appStateToString(old_state),
appStateToString(state)
);
@@ -284,14 +285,14 @@ void LoaderService::stopTop() {
}
void LoaderService::stopTop(const std::string& id) {
LOGGER.info("dispatching stopTop({})", id);
LOG_I(TAG, "dispatching stopTop(%s)", id.c_str());
dispatcherThread->dispatch([this, id] {
onStopTopAppMessage(id);
});
}
void LoaderService::stopAll(const std::string& id) {
LOGGER.info("dispatching stopAll({})", id);
LOG_I(TAG, "dispatching stopAll(%s)", id.c_str());
dispatcherThread->dispatch([this, id] {
onStopAllAppMessage(id);
});
@@ -1,14 +1,14 @@
#include <Tactility/Logger.h>
#include <Tactility/lvgl/Statusbar.h>
#include <Tactility/service/ServiceContext.h>
#include <Tactility/service/ServiceManifest.h>
#include <Tactility/service/memorychecker/MemoryCheckerService.h>
#include <tactility/lvgl_icon_statusbar.h>
#include <tactility/log.h>
namespace tt::service::memorychecker {
static const auto LOGGER = Logger("MemoryChecker");
constexpr auto* TAG = "MemoryChecker";
// Total memory (in bytes) that should be free before warnings occur
constexpr auto TOTAL_FREE_THRESHOLD = 10'000;
@@ -37,13 +37,13 @@ static bool isMemoryLow() {
bool memory_low = false;
const auto total_free = getInternalFree();
if (total_free < TOTAL_FREE_THRESHOLD) {
LOGGER.warn("Internal memory low: {} bytes", total_free);
LOG_W(TAG, "Internal memory low: %d bytes", (int)total_free);
memory_low = true;
}
const auto largest_block = getInternalLargestFreeBlock();
if (largest_block < LARGEST_FREE_BLOCK_THRESHOLD) {
LOGGER.warn("Largest free internal memory block is {} bytes", largest_block);
LOG_W(TAG, "Largest free internal memory block is %d bytes", (int)largest_block);
memory_low = true;
}
@@ -2,17 +2,18 @@
#if TT_FEATURE_SCREENSHOT_ENABLED
#include <Tactility/Logger.h>
#include <Tactility/LogMessages.h>
#include <Tactility/service/screenshot/Screenshot.h>
#include <Tactility/service/ServiceRegistration.h>
#include <Tactility/service/screenshot/Screenshot.h>
#include <lvgl.h>
#include <memory>
#include <tactility/log.h>
namespace tt::service::screenshot {
static const auto LOGGER = Logger("ScreenshotService");
constexpr auto* TAG = "ScreenshotService";
extern const ServiceManifest manifest;
@@ -23,7 +24,7 @@ std::shared_ptr<ScreenshotService> optScreenshotService() {
void ScreenshotService::startApps(const std::string& path) {
auto lock = mutex.asScopedLock();
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
LOGGER.warn(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_W(TAG,LOG_MESSAGE_MUTEX_LOCK_FAILED);
return;
}
@@ -32,14 +33,14 @@ void ScreenshotService::startApps(const std::string& path) {
mode = Mode::Apps;
task->startApps(path);
} else {
LOGGER.warn("Screenshot task already running");
LOG_W(TAG,"Screenshot task already running");
}
}
void ScreenshotService::startTimed(const std::string& path, uint8_t delayInSeconds, uint8_t amount) {
auto lock = mutex.asScopedLock();
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
LOGGER.warn(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_W(TAG,LOG_MESSAGE_MUTEX_LOCK_FAILED);
return;
}
@@ -48,13 +49,13 @@ void ScreenshotService::startTimed(const std::string& path, uint8_t delayInSecon
mode = Mode::Timed;
task->startTimed(path, delayInSeconds, amount);
} else {
LOGGER.warn("Screenshot task already running");
LOG_W(TAG,"Screenshot task already running");
}
}
bool ScreenshotService::onStart(ServiceContext& serviceContext) {
if (lv_screen_active() == nullptr) {
LOGGER.error("No display found");
LOG_E(TAG, "No display found");
return false;
}
@@ -64,7 +65,7 @@ bool ScreenshotService::onStart(ServiceContext& serviceContext) {
void ScreenshotService::stop() {
auto lock = mutex.asScopedLock();
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
LOGGER.warn(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_W(TAG,LOG_MESSAGE_MUTEX_LOCK_FAILED);
return;
}
@@ -72,14 +73,14 @@ void ScreenshotService::stop() {
task = nullptr;
mode = Mode::None;
} else {
LOGGER.warn("Screenshot task not running");
LOG_W(TAG,"Screenshot task not running");
}
}
Mode ScreenshotService::getMode() const {
auto lock = mutex.asScopedLock();
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
LOGGER.warn(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_W(TAG,LOG_MESSAGE_MUTEX_LOCK_FAILED);
return Mode::None;
}
@@ -2,21 +2,22 @@
#if TT_FEATURE_SCREENSHOT_ENABLED
#include <Tactility/CpuAffinity.h>
#include <Tactility/Logger.h>
#include <Tactility/LogMessages.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Tactility/service/screenshot/ScreenshotTask.h>
#include <Tactility/service/loader/Loader.h>
#include <Tactility/CpuAffinity.h>
#include <Tactility/TactilityCore.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Tactility/service/loader/Loader.h>
#include <Tactility/service/screenshot/ScreenshotTask.h>
#include <lv_screenshot.h>
#include <format>
#include <tactility/log.h>
namespace tt::service::screenshot {
static const auto LOGGER = Logger("ScreenshotTask");
constexpr auto* TAG = "ScreenshotTask";
ScreenshotTask::~ScreenshotTask() {
if (thread) {
@@ -27,7 +28,7 @@ ScreenshotTask::~ScreenshotTask() {
bool ScreenshotTask::isInterrupted() {
auto lock = mutex.asScopedLock();
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
LOGGER.warn(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return true;
}
return interrupted;
@@ -36,7 +37,7 @@ bool ScreenshotTask::isInterrupted() {
bool ScreenshotTask::isFinished() {
auto lock = mutex.asScopedLock();
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
LOGGER.warn(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return false;
}
return finished;
@@ -51,13 +52,13 @@ void ScreenshotTask::setFinished() {
static void makeScreenshot(const std::string& filename) {
if (lvgl::lock(50 / portTICK_PERIOD_MS)) {
if (lv_screenshot_create(lv_scr_act(), LV_100ASK_SCREENSHOT_SV_PNG, filename.c_str())) {
LOGGER.info("Screenshot saved to {}", filename);
LOG_I(TAG, "Screenshot saved to %s", filename.c_str());
} else {
LOGGER.error("Screenshot not saved to {}", filename);
LOG_E(TAG, "Screenshot not saved to %s", filename.c_str());
}
lvgl::unlock();
} else {
LOGGER.error(LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "LVGL");
LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "LVGL");
}
}
@@ -103,7 +104,7 @@ void ScreenshotTask::taskMain() {
void ScreenshotTask::taskStart() {
auto lock = mutex.asScopedLock();
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
LOGGER.error(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return;
}
@@ -123,7 +124,7 @@ void ScreenshotTask::taskStart() {
void ScreenshotTask::startApps(const std::string& path) {
auto lock = mutex.asScopedLock();
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
LOGGER.error(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return;
}
@@ -133,14 +134,14 @@ void ScreenshotTask::startApps(const std::string& path) {
work.path = path;
taskStart();
} else {
LOGGER.error("Task was already running");
LOG_E(TAG, "Task was already running");
}
}
void ScreenshotTask::startTimed(const std::string& path, uint8_t delay_in_seconds, uint8_t amount) {
auto lock = mutex.asScopedLock();
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
LOGGER.error(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return;
}
@@ -152,7 +153,7 @@ void ScreenshotTask::startTimed(const std::string& path, uint8_t delay_in_second
work.path = path;
taskStart();
} else {
LOGGER.error("Task was already running");
LOG_E(TAG, "Task was already running");
}
}
@@ -1,6 +1,5 @@
#include <Tactility/lvgl/Statusbar.h>
#include <Tactility/Logger.h>
#include <Tactility/Mutex.h>
#include <Tactility/Timer.h>
#include <Tactility/hal/power/PowerDevice.h>
@@ -27,9 +26,11 @@
#include <cstring>
#include <tactility/log.h>
namespace tt::service::statusbar {
static const auto LOGGER = Logger("StatusbarService");
constexpr auto* TAG = "StatusbarService";
// GPS
extern const ServiceManifest manifest;
@@ -302,7 +303,7 @@ public:
bool onStart(ServiceContext& serviceContext) override {
if (lv_screen_active() == nullptr) {
LOGGER.error("No display found");
LOG_E(TAG, "No display found");
return false;
}
@@ -3,7 +3,6 @@
#include <Tactility/service/webserver/AssetVersion.h>
#include <Tactility/file/File.h>
#include <Tactility/Logger.h>
#include <cJSON.h>
#include <cstdio>
@@ -12,9 +11,11 @@
#include <memory>
#include <esp_random.h>
#include <tactility/log.h>
namespace tt::service::webserver {
static const auto LOGGER = tt::Logger("AssetVersion");
constexpr auto* TAG = "AssetVersion";
constexpr auto* DATA_VERSION_FILE = "/system/app/WebServer/version.json";
constexpr auto* SD_VERSION_FILE = "/sdcard/tactility/webserver/version.json";
constexpr auto* DATA_ASSETS_DIR = "/system/app/WebServer";
@@ -22,65 +23,65 @@ constexpr auto* SD_ASSETS_DIR = "/sdcard/tactility/webserver";
static bool loadVersionFromFile(const char* path, AssetVersion& version) {
if (!file::isFile(path)) {
LOGGER.warn("Version file not found: {}", path);
LOG_W(TAG, "Version file not found: %s", path);
return false;
}
// Read file content
std::string content;
{
auto lock = file::getLock(path);
lock->lock(portMAX_DELAY);
FILE* fp = fopen(path, "r");
if (!fp) {
LOGGER.error("Failed to open version file: {}", path);
LOG_E(TAG, "Failed to open version file: %s", path);
lock->unlock();
return false;
}
char buffer[256];
size_t bytesRead = fread(buffer, 1, sizeof(buffer) - 1, fp);
bool readError = ferror(fp) != 0;
fclose(fp);
lock->unlock();
if (readError) {
LOGGER.error("Error reading version file: {}", path);
LOG_E(TAG, "Error reading version file: %s", path);
return false;
}
if (bytesRead == 0) {
LOGGER.error("Version file is empty: {}", path);
LOG_E(TAG, "Version file is empty: %s", path);
return false;
}
buffer[bytesRead] = '\0';
content = buffer;
}
// Parse JSON
cJSON* json = cJSON_Parse(content.c_str());
if (json == nullptr) {
LOGGER.error("Failed to parse version JSON: {}", path);
LOG_E(TAG, "Failed to parse version JSON: %s", path);
return false;
}
cJSON* versionItem = cJSON_GetObjectItem(json, "version");
if (versionItem == nullptr || !cJSON_IsNumber(versionItem)) {
LOGGER.error("Invalid version JSON format: {}", path);
LOG_E(TAG, "Invalid version JSON format: %s", path);
cJSON_Delete(json);
return false;
}
double versionValue = versionItem->valuedouble;
if (versionValue < 0 || versionValue > UINT32_MAX) {
LOGGER.error("Version out of valid range [0, {}]: {}", UINT32_MAX, path);
LOG_E(TAG, "Version out of valid range [0, %u]: %s", (unsigned)UINT32_MAX, path);
cJSON_Delete(json);
return false;
}
version.version = static_cast<uint32_t>(versionValue);
cJSON_Delete(json);
LOGGER.info("Loaded version {} from {}", version.version, path);
LOG_I(TAG, "Loaded version %u from %s", (unsigned)version.version, path);
return true;
}
@@ -92,23 +93,23 @@ static bool saveVersionToFile(const char* path, const AssetVersion& version) {
dirPath = dirPath.substr(0, lastSlash);
if (!file::isDirectory(dirPath.c_str())) {
if (!file::findOrCreateDirectory(dirPath.c_str(), 0755)) {
LOGGER.error("Failed to create directory: {}", dirPath);
LOG_E(TAG, "Failed to create directory: %s", dirPath.c_str());
return false;
}
}
}
// Create JSON
cJSON* json = cJSON_CreateObject();
if (json == nullptr) {
LOGGER.error("Failed to create JSON object for version");
LOG_E(TAG, "Failed to create JSON object for version");
return false;
}
cJSON_AddNumberToObject(json, "version", version.version);
char* jsonString = cJSON_Print(json);
if (jsonString == nullptr) {
LOGGER.error("Failed to serialize version JSON");
LOG_E(TAG, "Failed to serialize version JSON");
cJSON_Delete(json);
return false;
}
@@ -126,12 +127,12 @@ static bool saveVersionToFile(const char* path, const AssetVersion& version) {
success = (written == len);
if (success) {
if (fflush(fp) != 0) {
LOGGER.error("Failed to flush version file: {}", path);
LOG_E(TAG, "Failed to flush version file: %s", path);
success = false;
} else {
int fd = fileno(fp);
if (fd >= 0 && fsync(fd) != 0) {
LOGGER.error("Failed to fsync version file: {}", path);
LOG_E(TAG, "Failed to fsync version file: %s", path);
success = false;
}
}
@@ -145,9 +146,9 @@ static bool saveVersionToFile(const char* path, const AssetVersion& version) {
cJSON_Delete(json);
if (success) {
LOGGER.info("Saved version {} to {}", version.version, path);
LOG_I(TAG, "Saved version %u to %s", (unsigned)version.version, path);
} else {
LOGGER.error("Failed to write version file: {}", path);
LOG_E(TAG, "Failed to write version file: %s", path);
}
return success;
@@ -180,15 +181,15 @@ bool hasSdAssets() {
static bool copyDirectory(const char* src, const char* dst, int depth = 0) {
constexpr int MAX_DEPTH = 16;
if (depth >= MAX_DEPTH) {
LOGGER.error("Max directory depth exceeded: {}", src);
LOG_E(TAG, "Max directory depth exceeded: %s", src);
return false;
}
LOGGER.info("Copying directory: {} -> {}", src, dst);
LOG_I(TAG, "Copying directory: %s -> %s", src, dst);
// Create destination directory
if (!file::isDirectory(dst)) {
if (!file::findOrCreateDirectory(dst, 0755)) {
LOGGER.error("Failed to create destination directory: {}", dst);
LOG_E(TAG, "Failed to create destination directory: %s", dst);
return false;
}
}
@@ -216,7 +217,7 @@ static bool copyDirectory(const char* src, const char* dst, int depth = 0) {
isDir = S_ISDIR(st.st_mode);
isReg = S_ISREG(st.st_mode);
} else {
LOGGER.warn("Failed to stat entry, skipping: {}", srcPath);
LOG_W(TAG, "Failed to stat entry, skipping: %s", srcPath.c_str());
return;
}
}
@@ -233,14 +234,14 @@ static bool copyDirectory(const char* src, const char* dst, int depth = 0) {
FILE* srcFile = fopen(srcPath.c_str(), "rb");
if (!srcFile) {
LOGGER.error("Failed to open source file: {}", srcPath);
LOG_E(TAG, "Failed to open source file: %s", srcPath.c_str());
copySuccess = false;
return;
}
FILE* tempFile = fopen(tempPath.c_str(), "wb");
if (!tempFile) {
LOGGER.error("Failed to create temp file: {}", tempPath);
LOG_E(TAG, "Failed to create temp file: %s", tempPath.c_str());
fclose(srcFile);
copySuccess = false;
return;
@@ -254,7 +255,7 @@ static bool copyDirectory(const char* src, const char* dst, int depth = 0) {
while ((bytesRead = fread(buffer.get(), 1, COPY_BUF_SIZE, srcFile)) > 0) {
size_t bytesWritten = fwrite(buffer.get(), 1, bytesRead, tempFile);
if (bytesWritten != bytesRead) {
LOGGER.error("Failed to write to temp file: {}", tempPath);
LOG_E(TAG, "Failed to write to temp file: %s", tempPath.c_str());
fileCopySuccess = false;
copySuccess = false;
break;
@@ -262,7 +263,7 @@ static bool copyDirectory(const char* src, const char* dst, int depth = 0) {
}
if (fileCopySuccess && ferror(srcFile)) {
LOGGER.error("Error reading source file: {}", srcPath);
LOG_E(TAG, "Error reading source file: %s", srcPath.c_str());
fileCopySuccess = false;
copySuccess = false;
}
@@ -272,13 +273,13 @@ static bool copyDirectory(const char* src, const char* dst, int depth = 0) {
// Flush and sync temp file before closing
if (fileCopySuccess) {
if (fflush(tempFile) != 0) {
LOGGER.error("Failed to flush temp file: {}", tempPath);
LOG_E(TAG, "Failed to flush temp file: %s", tempPath.c_str());
fileCopySuccess = false;
copySuccess = false;
} else {
int fd = fileno(tempFile);
if (fd >= 0 && fsync(fd) != 0) {
LOGGER.error("Failed to fsync temp file: {}", tempPath);
LOG_E(TAG, "Failed to fsync temp file: %s", tempPath.c_str());
fileCopySuccess = false;
copySuccess = false;
}
@@ -292,7 +293,7 @@ static bool copyDirectory(const char* src, const char* dst, int depth = 0) {
remove(dstPath.c_str());
// Rename temp file to destination
if (rename(tempPath.c_str(), dstPath.c_str()) != 0) {
LOGGER.error("Failed to rename temp file {} to {}", tempPath, dstPath);
LOG_E(TAG, "Failed to rename temp file %s to %s", tempPath.c_str(), dstPath.c_str());
remove(tempPath.c_str());
fileCopySuccess = false;
copySuccess = false;
@@ -303,13 +304,13 @@ static bool copyDirectory(const char* src, const char* dst, int depth = 0) {
}
if (fileCopySuccess) {
LOGGER.info("Copied file: {}", entry.d_name);
LOG_I(TAG, "Copied file: %s", entry.d_name);
}
}
});
if (!listSuccess) {
LOGGER.error("Failed to list source directory: {}", src);
LOG_E(TAG, "Failed to list source directory: %s", src);
return false;
}
@@ -317,7 +318,7 @@ static bool copyDirectory(const char* src, const char* dst, int depth = 0) {
}
bool syncAssets() {
LOGGER.info("Starting asset synchronization...");
LOG_I(TAG, "Starting asset synchronization...");
// Check if Data partition and SD card exist
bool dataExists = hasDataAssets();
@@ -325,26 +326,26 @@ bool syncAssets() {
// FIRST BOOT SCENARIO: Data has version 0, SD card is missing
if (dataExists && !sdExists) {
LOGGER.info("First boot - Data exists but SD card backup missing");
LOGGER.warn("Skipping SD backup during boot - will be created on first settings save");
LOGGER.warn("This avoids watchdog timeout if SD card is slow or corrupted");
LOG_I(TAG, "First boot - Data exists but SD card backup missing");
LOG_W(TAG, "Skipping SD backup during boot - will be created on first settings save");
LOG_W(TAG, "This avoids watchdog timeout if SD card is slow or corrupted");
return true; // Don't block boot - defer copy to runtime
}
// NO SD CARD: Just ensure Data has default structure
if (!sdExists) {
LOGGER.warn("No SD card available - creating default Data structure if needed");
LOG_W(TAG, "No SD card available - creating default Data structure if needed");
if (!dataExists) {
if (!file::findOrCreateDirectory(DATA_ASSETS_DIR, 0755)) {
LOGGER.error("Failed to create Data assets directory");
LOG_E(TAG, "Failed to create Data assets directory");
return false;
}
AssetVersion defaultVersion(0); // Start at version 0 - SD card updates will be version 1+
if (!saveDataVersion(defaultVersion)) {
LOGGER.error("Failed to save default Data version");
LOG_E(TAG, "Failed to save default Data version");
return false;
}
LOGGER.info("Created default Data assets structure (version 0)");
LOG_I(TAG, "Created default Data assets structure (version 0)");
}
return true;
}
@@ -355,39 +356,39 @@ bool syncAssets() {
bool hasSdVer = loadSdVersion(sdVersion);
if (!hasDataVer) {
LOGGER.warn("No Data version.json - assuming version 0");
LOG_W(TAG, "No Data version.json - assuming version 0");
dataVersion.version = 0;
if (!saveDataVersion(dataVersion)) {
LOGGER.warn("Failed to save default Data version (non-fatal)");
LOG_W(TAG, "Failed to save default Data version (non-fatal)");
}
}
if (!hasSdVer) {
LOGGER.warn("No SD version.json - assuming version 0");
LOG_W(TAG, "No SD version.json - assuming version 0");
sdVersion.version = 0;
// DON'T save to SD during boot - defer to runtime
LOGGER.warn("Skipping SD version.json creation during boot - will be created on first settings save");
LOG_W(TAG, "Skipping SD version.json creation during boot - will be created on first settings save");
}
LOGGER.info("Version comparison - Data: {}, SD: {}", dataVersion.version, sdVersion.version);
LOG_I(TAG, "Version comparison - Data: %u, SD: %u", (unsigned)dataVersion.version, (unsigned)sdVersion.version);
if (sdVersion.version > dataVersion.version) {
// Firmware update - copy SD -> Data
LOGGER.info("SD card newer (v{} > v{}) - copying assets SD -> Data (firmware update)",
sdVersion.version, dataVersion.version);
LOG_I(TAG, "SD card newer (v%u > v%u) - copying assets SD -> Data (firmware update)",
(unsigned)sdVersion.version, (unsigned)dataVersion.version);
if (!copyDirectory(SD_ASSETS_DIR, DATA_ASSETS_DIR)) {
LOGGER.error("Failed to copy assets from SD to Data");
LOG_E(TAG, "Failed to copy assets from SD to Data");
return false;
}
LOGGER.info("Firmware update complete - assets updated from SD card");
LOG_I(TAG, "Firmware update complete - assets updated from SD card");
} else if (dataVersion.version > sdVersion.version) {
// User customization - backup Data -> SD
LOGGER.warn("Data newer (v{} > v{}) - deferring SD backup to avoid boot watchdog",
dataVersion.version, sdVersion.version);
LOGGER.warn("SD backup will occur on first WebServer settings save");
LOG_W(TAG, "Data newer (v%u > v%u) - deferring SD backup to avoid boot watchdog",
(unsigned)dataVersion.version, (unsigned)sdVersion.version);
LOG_W(TAG, "SD backup will occur on first WebServer settings save");
return true; // Don't block boot - defer copy to runtime
} else {
LOGGER.info("Versions match (v{}) - no sync needed", dataVersion.version);
LOG_I(TAG, "Versions match (v%u) - no sync needed", (unsigned)dataVersion.version);
}
return true;
@@ -7,7 +7,6 @@
#include <Tactility/settings/WebServerSettings.h>
#include <Tactility/MountPoints.h>
#include <Tactility/file/File.h>
#include <Tactility/Logger.h>
#include <Tactility/lvgl/Statusbar.h>
#include <Tactility/Mutex.h>
@@ -52,9 +51,11 @@
#include <mbedtls/base64.h>
#include <sstream>
#include <tactility/log.h>
namespace tt::service::webserver {
static const auto LOGGER = tt::Logger("WebServerService");
constexpr auto* TAG = "WebServerService";
// Helper to convert chip model enum to human-readable string
static const char* getChipModelName(esp_chip_model_t model) {
@@ -142,14 +143,14 @@ static esp_err_t validateRequestAuth(httpd_req_t* request, bool& authPassed) {
std::string auth_header(auth_len + 1, '\0');
if (httpd_req_get_hdr_value_str(request, "Authorization", auth_header.data(), auth_len + 1) != ESP_OK) {
LOGGER.warn("Failed to read Authorization header");
LOG_W(TAG, "Failed to read Authorization header");
return sendUnauthorized(request, "Authorization required");
}
auth_header.resize(auth_len); // Remove null terminator from string length
// Check for "Basic " prefix
if (auth_header.rfind("Basic ", 0) != 0) {
LOGGER.warn("Authorization header is not Basic auth");
LOG_W(TAG, "Authorization header is not Basic auth");
return sendUnauthorized(request, "Basic authorization required");
}
@@ -170,7 +171,7 @@ static esp_err_t validateRequestAuth(httpd_req_t* request, bool& authPassed) {
reinterpret_cast<const unsigned char*>(base64_creds.c_str()),
base64_creds.length());
if (ret != 0) {
LOGGER.warn("Failed to decode base64 credentials");
LOG_W(TAG, "Failed to decode base64 credentials");
return sendUnauthorized(request, "Invalid credentials format");
}
decoded.resize(actual_len);
@@ -178,7 +179,7 @@ static esp_err_t validateRequestAuth(httpd_req_t* request, bool& authPassed) {
// Parse username:password
size_t colon_pos = decoded.find(':');
if (colon_pos == std::string::npos) {
LOGGER.warn("Invalid credentials format (no colon separator)");
LOG_W(TAG, "Invalid credentials format (no colon separator)");
return sendUnauthorized(request, "Invalid credentials format");
}
@@ -189,7 +190,7 @@ static esp_err_t validateRequestAuth(httpd_req_t* request, bool& authPassed) {
bool usernameMatch = secureCompare(username, settings.webServerUsername);
bool passwordMatch = secureCompare(password, settings.webServerPassword);
if (!usernameMatch || !passwordMatch) {
LOGGER.warn("Invalid credentials for user '{}'", username);
LOG_W(TAG, "Invalid credentials for user '%s'", username.c_str());
return sendUnauthorized(request, "Invalid credentials");
}
@@ -198,7 +199,7 @@ static esp_err_t validateRequestAuth(httpd_req_t* request, bool& authPassed) {
}
bool WebServerService::onStart(ServiceContext& service) {
LOGGER.info("Starting WebServer service...");
LOG_I(TAG, "Starting WebServer service...");
// Register global instance
g_webServerInstance.store(this);
@@ -228,10 +229,10 @@ bool WebServerService::onStart(ServiceContext& service) {
// Start HTTP server only if enabled in settings (default: OFF to save memory)
if (serverEnabled) {
LOGGER.info("WebServer enabled in settings, starting HTTP server...");
LOG_I(TAG, "WebServer enabled in settings, starting HTTP server...");
setEnabled(true);
} else {
LOGGER.info("WebServer disabled in settings, NOT starting HTTP server (saves ~10KB RAM)");
LOG_I(TAG, "WebServer disabled in settings, NOT starting HTTP server (saves ~10KB RAM)");
setEnabled(false);
}
@@ -288,15 +289,15 @@ bool WebServerService::startApMode() {
}
if (settings.wifiMode != settings::webserver::WiFiMode::AccessPoint) {
LOGGER.info("Not in AP mode, skipping AP WiFi initialization");
LOG_I(TAG, "Not in AP mode, skipping AP WiFi initialization");
return true; // Not an error, just not needed
}
LOGGER.info("Starting WiFi in Access Point mode...");
LOG_I(TAG, "Starting WiFi in Access Point mode...");
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
if (esp_wifi_init(&cfg) != ESP_OK) {
LOGGER.error("esp_wifi_init() failed");
LOG_E(TAG, "esp_wifi_init() failed");
return false;
}
apWifiInitialized = true;
@@ -304,14 +305,14 @@ bool WebServerService::startApMode() {
// Create the AP network interface
apNetif = esp_netif_create_default_wifi_ap();
if (apNetif == nullptr) {
LOGGER.error("esp_netif_create_default_wifi_ap() failed");
LOG_E(TAG, "esp_netif_create_default_wifi_ap() failed");
esp_wifi_deinit();
apWifiInitialized = false;
return false;
}
if (esp_wifi_set_mode(WIFI_MODE_AP) != ESP_OK) {
LOGGER.error("esp_wifi_set_mode(AP) failed");
LOG_E(TAG, "esp_wifi_set_mode(AP) failed");
stopApMode();
return false;
}
@@ -324,19 +325,19 @@ bool WebServerService::startApMode() {
ip_info.netmask.addr = ipaddr_addr("255.255.255.0");
if (esp_netif_dhcps_stop(apNetif) != ESP_OK) {
LOGGER.error("esp_netif_dhcps_stop() failed");
LOG_E(TAG, "esp_netif_dhcps_stop() failed");
stopApMode();
return false;
}
if (esp_netif_set_ip_info(apNetif, &ip_info) != ESP_OK) {
LOGGER.error("esp_netif_set_ip_info() failed");
LOG_E(TAG, "esp_netif_set_ip_info() failed");
stopApMode();
return false;
}
if (esp_netif_dhcps_start(apNetif) != ESP_OK) {
LOGGER.error("esp_netif_dhcps_start() failed");
LOG_E(TAG, "esp_netif_dhcps_start() failed");
stopApMode();
return false;
}
@@ -354,36 +355,36 @@ bool WebServerService::startApMode() {
if (settings.apOpenNetwork) {
// User explicitly chose an open network
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
LOGGER.info("AP configured with OPEN authentication (user choice)");
LOG_I(TAG, "AP configured with OPEN authentication (user choice)");
} else if (settings.apPassword.length() >= 8 && settings.apPassword.length() <= 63) {
wifi_config.ap.authmode = WIFI_AUTH_WPA2_PSK;
strncpy(reinterpret_cast<char*>(wifi_config.ap.password), settings.apPassword.c_str(), sizeof(wifi_config.ap.password) - 1);
wifi_config.ap.password[sizeof(wifi_config.ap.password) - 1] = '\0';
LOGGER.info("AP configured with WPA2-PSK authentication");
LOG_I(TAG, "AP configured with WPA2-PSK authentication");
} else {
if (!settings.apPassword.empty()) {
LOGGER.warn("AP password invalid (must be 8-63 chars, got {}) - using OPEN mode", settings.apPassword.length());
LOG_W(TAG, "AP password invalid (must be 8-63 chars, got %zu) - using OPEN mode", settings.apPassword.length());
}
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
LOGGER.warn("AP configured with OPEN authentication (no password)");
LOG_W(TAG, "AP configured with OPEN authentication (no password)");
}
wifi_config.ap.max_connection = 4;
wifi_config.ap.channel = settings.apChannel;
if (esp_wifi_set_config(WIFI_IF_AP, &wifi_config) != ESP_OK) {
LOGGER.error("esp_wifi_set_config(AP) failed");
LOG_E(TAG, "esp_wifi_set_config(AP) failed");
stopApMode();
return false;
}
if (esp_wifi_start() != ESP_OK) {
LOGGER.error("esp_wifi_start() failed");
LOG_E(TAG, "esp_wifi_start() failed");
stopApMode();
return false;
}
LOGGER.info("WiFi AP started - SSID: '{}', Channel: {}, IP: 192.168.4.1", settings.apSsid, settings.apChannel);
LOG_I(TAG, "WiFi AP started - SSID: '%s', Channel: %u, IP: 192.168.4.1", settings.apSsid.c_str(), (unsigned)settings.apChannel);
return true;
}
@@ -395,15 +396,15 @@ void WebServerService::stopApMode() {
}
err = esp_wifi_stop();
if (err != ESP_OK && err != ESP_ERR_WIFI_NOT_STARTED) {
LOGGER.warn("esp_wifi_stop() in cleanup: {}", esp_err_to_name(err));
LOG_W(TAG, "esp_wifi_stop() in cleanup: %s", esp_err_to_name(err));
}
LOGGER.info("WiFi AP stopped");
LOG_I(TAG, "WiFi AP stopped");
err = esp_wifi_set_mode(WIFI_MODE_STA);
if (err != ESP_OK) {
LOGGER.warn("esp_wifi_set_mode() in cleanup: {}", esp_err_to_name(err));
LOG_W(TAG, "esp_wifi_set_mode() in cleanup: %s", esp_err_to_name(err));
}
LOGGER.info("Wifi mode set back to STA");
LOG_I(TAG, "Wifi mode set back to STA");
apWifiInitialized = false;
}
@@ -428,7 +429,7 @@ bool WebServerService::startServer() {
// Start AP mode WiFi if configured
if (settings.wifiMode == settings::webserver::WiFiMode::AccessPoint) {
if (!startApMode()) {
LOGGER.error("Failed to start AP mode WiFi - HTTP server will not start");
LOG_E(TAG, "Failed to start AP mode WiFi - HTTP server will not start");
return false;
}
}
@@ -505,19 +506,19 @@ bool WebServerService::startServer() {
httpServer->start();
if (!httpServer->isStarted()) {
LOGGER.error("Failed to start HTTP server on port {}", settings.webServerPort);
LOG_E(TAG, "Failed to start HTTP server on port %u", (unsigned)settings.webServerPort);
httpServer.reset();
return false;
}
LOGGER.info("HTTP server started successfully on port {}", settings.webServerPort);
LOG_I(TAG, "HTTP server started successfully on port %u", (unsigned)settings.webServerPort);
publish_event(this, WebServerEvent::WebServerStarted);
// Show statusbar icon
if (statusbarIconId >= 0) {
lvgl::statusbar_icon_set_image(statusbarIconId, LVGL_ICON_STATUSBAR_CLOUD);
lvgl::statusbar_icon_set_visibility(statusbarIconId, true);
LOGGER.info("WebServer statusbar icon shown ({} mode)",
LOG_I(TAG, "WebServer statusbar icon shown (%s mode)",
settings.wifiMode == settings::webserver::WiFiMode::AccessPoint ? "AP" : "Station");
}
@@ -537,7 +538,7 @@ void WebServerService::stopServer() {
stopApMode();
}
LOGGER.info("HTTP server stopped");
LOG_I(TAG, "HTTP server stopped");
publish_event(this, WebServerEvent::WebServerStopped);
if (statusbarIconId >= 0) {
@@ -550,7 +551,7 @@ void WebServerService::stopServer() {
esp_err_t WebServerService::handleRoot(httpd_req_t* request) {
LOGGER.info("GET / -> redirecting to /dashboard.html");
LOG_I(TAG, "GET / -> redirecting to /dashboard.html");
httpd_resp_set_status(request, "302 Found");
httpd_resp_set_hdr(request, "Location", "/dashboard.html");
return httpd_resp_send(request, nullptr, 0);
@@ -722,7 +723,7 @@ static bool uriMatches(const char* uri, const char* route) {
}
esp_err_t WebServerService::handleFileBrowser(httpd_req_t* request) {
LOGGER.info("GET /filebrowser -> redirecting to /dashboard.html#files");
LOG_I(TAG, "GET /filebrowser -> redirecting to /dashboard.html#files");
httpd_resp_set_status(request, "302 Found");
httpd_resp_set_hdr(request, "Location", "/dashboard.html#files");
return httpd_resp_send(request, nullptr, 0);
@@ -735,17 +736,17 @@ esp_err_t WebServerService::handleFsList(httpd_req_t* request) {
if (qlen > 1) {
std::unique_ptr<char[]> qbuf(new char[qlen]);
if (httpd_req_get_url_query_str(request, qbuf.get(), qlen) == ESP_OK) {
LOGGER.info("GET /fs/list raw query: {}", qbuf.get());
LOG_I(TAG, "GET /fs/list raw query: %s", qbuf.get());
}
}
if (!getQueryParam(request, "path", path) || path.empty()) path = "/";
std::string norm = normalizePath(path);
LOGGER.info("GET /fs/list decoded path: '{}' normalized: '{}'", path, norm);
LOG_I(TAG, "GET /fs/list decoded path: '%s' normalized: '%s'", path.c_str(), norm.c_str());
// Allow root path for listing mount points
if (!isAllowedBasePath(norm, true)) {
LOGGER.warn("GET /fs/list - invalid path requested: '{}' normalized: '{}'", path, norm);
LOG_W(TAG, "GET /fs/list - invalid path requested: '%s' normalized: '%s'", path.c_str(), norm.c_str());
httpd_resp_set_type(request, "application/json");
httpd_resp_sendstr(request, "{\"error\":\"invalid path\"}");
return ESP_OK;
@@ -811,7 +812,7 @@ esp_err_t WebServerService::handleFsDownload(httpd_req_t* request) {
}
std::string norm = normalizePath(path);
if (!isAllowedBasePath(norm) || !file::isFile(norm)) {
LOGGER.warn("GET /fs/download - not found or invalid path: '{}' normalized: '{}'", path, norm);
LOG_W(TAG, "GET /fs/download - not found or invalid path: '%s' normalized: '%s'", path.c_str(), norm.c_str());
httpd_resp_send_err(request, HTTPD_404_NOT_FOUND, "not found");
return ESP_FAIL;
}
@@ -859,7 +860,7 @@ esp_err_t WebServerService::handleFsUpload(httpd_req_t* request) {
if (qlen > 1) {
std::unique_ptr<char[]> qbuf(new char[qlen]);
if (httpd_req_get_url_query_str(request, qbuf.get(), qlen) == ESP_OK) {
LOGGER.info("POST /fs/upload raw query: {}", qbuf.get());
LOG_I(TAG, "POST /fs/upload raw query: %s", qbuf.get());
}
}
@@ -872,10 +873,10 @@ esp_err_t WebServerService::handleFsUpload(httpd_req_t* request) {
char content_type[64] = {0};
httpd_req_get_hdr_value_str(request, "Content-Type", content_type, sizeof(content_type));
std::string norm = normalizePath(path);
LOGGER.info("POST /fs/upload decoded path: '{}' normalized: '{}' Content-Length: {} Content-Type: {}", path, norm, (int)request->content_len, content_type[0] ? content_type : "(null)");
LOG_I(TAG, "POST /fs/upload decoded path: '%s' normalized: '%s' Content-Length: %d Content-Type: %s", path.c_str(), norm.c_str(), (int)request->content_len, content_type[0] ? content_type : "(null)");
if (!isAllowedBasePath(norm)) {
LOGGER.warn("POST /fs/upload - invalid path requested: '{}' normalized: '{}'", path, norm);
LOG_W(TAG, "POST /fs/upload - invalid path requested: '%s' normalized: '%s'", path.c_str(), norm.c_str());
httpd_resp_send_err(request, HTTPD_403_FORBIDDEN, "invalid path");
return ESP_FAIL;
}
@@ -902,18 +903,18 @@ esp_err_t WebServerService::handleFsUpload(httpd_req_t* request) {
// Timeout - retry with backoff
timeout_retries++;
if (timeout_retries >= MAX_TIMEOUT_RETRIES) {
LOGGER.error("Upload recv timeout after {} retries", timeout_retries);
LOG_E(TAG, "Upload recv timeout after %d retries", timeout_retries);
fclose(fp);
remove(norm.c_str()); // Clean up partial file
httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, "recv timeout");
return ESP_FAIL;
}
LOGGER.warn("Upload recv timeout, retry {}/{}", timeout_retries, MAX_TIMEOUT_RETRIES);
LOG_W(TAG, "Upload recv timeout, retry %d/%d", timeout_retries, MAX_TIMEOUT_RETRIES);
vTaskDelay(pdMS_TO_TICKS(100 * timeout_retries)); // Linear backoff
continue;
}
if (ret <= 0) {
LOGGER.error("Upload recv failed with error {}", ret);
LOG_E(TAG, "Upload recv failed with error %d", ret);
fclose(fp);
remove(norm.c_str()); // Clean up partial file
httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, "recv failed");
@@ -951,7 +952,7 @@ esp_err_t WebServerService::handleFsGenericGet(httpd_req_t* request) {
if (uriMatches(uri, "/fs/list")) return handleFsList(request);
if (uriMatches(uri, "/fs/download")) return handleFsDownload(request);
if (uriMatches(uri, "/fs/tree")) return handleFsTree(request);
LOGGER.warn("GET {} - not found in fs generic dispatcher", uri);
LOG_W(TAG, "GET %s - not found in fs generic dispatcher", uri);
httpd_resp_send_err(request, HTTPD_404_NOT_FOUND, "not found");
return ESP_FAIL;
}
@@ -970,7 +971,7 @@ esp_err_t WebServerService::handleFsGenericPost(httpd_req_t* request) {
if (uriMatches(uri, "/fs/delete")) return handleFsDelete(request);
if (uriMatches(uri, "/fs/rename")) return handleFsRename(request);
if (uriMatches(uri, "/fs/upload")) return handleFsUpload(request);
LOGGER.warn("POST {} - not found in fs generic dispatcher", uri);
LOG_W(TAG, "POST %s - not found in fs generic dispatcher", uri);
httpd_resp_send_err(request, HTTPD_404_NOT_FOUND, "not found");
return ESP_FAIL;
}
@@ -986,7 +987,7 @@ esp_err_t WebServerService::handleAdminPost(httpd_req_t* request) {
const char* uri = request->uri;
if (strncmp(uri, "/admin/reboot", 13) == 0) return handleReboot(request);
LOGGER.info("POST {} - not found in admin dispatcher", uri);
LOG_I(TAG, "POST %s - not found in admin dispatcher", uri);
httpd_resp_send_err(request, HTTPD_404_NOT_FOUND, "not found");
return ESP_FAIL;
}
@@ -1019,7 +1020,7 @@ esp_err_t WebServerService::handleApiGet(httpd_req_t* request) {
return handleApiScreenshot(request);
}
LOGGER.warn("GET {} - not found in api dispatcher", uri);
LOG_W(TAG, "GET %s - not found in api dispatcher", uri);
httpd_resp_send_err(request, HTTPD_404_NOT_FOUND, "not found");
return ESP_FAIL;
}
@@ -1040,7 +1041,7 @@ esp_err_t WebServerService::handleApiPost(httpd_req_t* request) {
return handleApiAppsUninstall(request);
}
LOGGER.warn("POST {} - not found in api dispatcher", uri);
LOG_W(TAG, "POST %s - not found in api dispatcher", uri);
httpd_resp_send_err(request, HTTPD_404_NOT_FOUND, "not found");
return ESP_FAIL;
}
@@ -1058,13 +1059,13 @@ esp_err_t WebServerService::handleApiPut(httpd_req_t* request) {
return handleApiAppsInstall(request);
}
LOGGER.warn("PUT {} - not found in api dispatcher", uri);
LOG_W(TAG, "PUT %s - not found in api dispatcher", uri);
httpd_resp_send_err(request, HTTPD_404_NOT_FOUND, "not found");
return ESP_FAIL;
}
esp_err_t WebServerService::handleApiSysinfo(httpd_req_t* request) {
LOGGER.info("GET /api/sysinfo");
LOG_I(TAG, "GET /api/sysinfo");
std::ostringstream json;
json << "{";
@@ -1214,7 +1215,7 @@ esp_err_t WebServerService::handleApiSysinfo(httpd_req_t* request) {
// GET /api/apps - List installed apps
esp_err_t WebServerService::handleApiApps(httpd_req_t* request) {
LOGGER.info("GET /api/apps");
LOG_I(TAG, "GET /api/apps");
auto manifests = app::getAppManifests();
@@ -1255,7 +1256,7 @@ esp_err_t WebServerService::handleApiApps(httpd_req_t* request) {
// POST /api/apps/run?id=xxx - Run an app
esp_err_t WebServerService::handleApiAppsRun(httpd_req_t* request) {
LOGGER.info("POST /api/apps/run");
LOG_I(TAG, "POST /api/apps/run");
std::string appId;
if (!getQueryParam(request, "id", appId) || appId.empty()) {
@@ -1276,14 +1277,14 @@ esp_err_t WebServerService::handleApiAppsRun(httpd_req_t* request) {
app::start(appId);
LOGGER.info("[200] /api/apps/run {}", appId);
LOG_I(TAG, "[200] /api/apps/run %s", appId.c_str());
httpd_resp_sendstr(request, "ok");
return ESP_OK;
}
// POST /api/apps/uninstall?id=xxx - Uninstall an app
esp_err_t WebServerService::handleApiAppsUninstall(httpd_req_t* request) {
LOGGER.info("POST /api/apps/uninstall");
LOG_I(TAG, "POST /api/apps/uninstall");
std::string appId;
if (!getQueryParam(request, "id", appId) || appId.empty()) {
@@ -1293,7 +1294,7 @@ esp_err_t WebServerService::handleApiAppsUninstall(httpd_req_t* request) {
auto manifest = app::findAppManifestById(appId);
if (!manifest) {
LOGGER.info("[200] /api/apps/uninstall {} (app wasn't installed)", appId);
LOG_I(TAG, "[200] /api/apps/uninstall %s (app wasn't installed)", appId.c_str());
httpd_resp_sendstr(request, "ok");
return ESP_OK;
}
@@ -1305,11 +1306,11 @@ esp_err_t WebServerService::handleApiAppsUninstall(httpd_req_t* request) {
}
if (app::uninstall(appId)) {
LOGGER.info("[200] /api/apps/uninstall {}", appId);
LOG_I(TAG, "[200] /api/apps/uninstall %s", appId.c_str());
httpd_resp_sendstr(request, "ok");
return ESP_OK;
} else {
LOGGER.warn("[500] /api/apps/uninstall {}", appId);
LOG_W(TAG, "[500] /api/apps/uninstall %s", appId.c_str());
httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, "uninstall failed");
return ESP_FAIL;
}
@@ -1317,7 +1318,7 @@ esp_err_t WebServerService::handleApiAppsUninstall(httpd_req_t* request) {
// PUT /api/apps/install - Install an app from multipart form upload
esp_err_t WebServerService::handleApiAppsInstall(httpd_req_t* request) {
LOGGER.info("PUT /api/apps/install");
LOG_I(TAG, "PUT /api/apps/install");
std::string boundary;
if (!network::getMultiPartBoundaryOrSendError(request, boundary)) {
@@ -1340,14 +1341,14 @@ esp_err_t WebServerService::handleApiAppsInstall(httpd_req_t* request) {
auto content_disposition_map = network::parseContentDisposition(content_headers);
if (content_disposition_map.empty()) {
LOGGER.warn("parseContentDisposition returned empty map for: {}", content_headers_data);
LOG_W(TAG, "parseContentDisposition returned empty map for: %s", content_headers_data.c_str());
httpd_resp_send_err(request, HTTPD_400_BAD_REQUEST, "invalid content disposition");
return ESP_FAIL;
}
auto filename_entry = content_disposition_map.find("filename");
if (filename_entry == content_disposition_map.end()) {
LOGGER.warn("filename not found in content disposition map");
LOG_W(TAG, "filename not found in content disposition map");
httpd_resp_send_err(request, HTTPD_400_BAD_REQUEST, "filename parameter missing");
return ESP_FAIL;
}
@@ -1402,10 +1403,10 @@ esp_err_t WebServerService::handleApiAppsInstall(httpd_req_t* request) {
// Cleanup temp file
if (!file::deleteFile(file_path)) {
LOGGER.warn("Failed to delete temp file {}", file_path);
LOG_W(TAG, "Failed to delete temp file %s", file_path.c_str());
}
LOGGER.info("[200] /api/apps/install -> {}", file_path);
LOG_I(TAG, "[200] /api/apps/install -> %s", file_path.c_str());
httpd_resp_sendstr(request, "ok");
return ESP_OK;
}
@@ -1425,7 +1426,7 @@ static const char* radioStateToJsonString(wifi::RadioState state) {
// GET /api/wifi - WiFi status
esp_err_t WebServerService::handleApiWifi(httpd_req_t* request) {
LOGGER.info("GET /api/wifi");
LOG_I(TAG, "GET /api/wifi");
auto state = wifi::getRadioState();
auto ip = wifi::getIp();
@@ -1450,7 +1451,7 @@ esp_err_t WebServerService::handleApiWifi(httpd_req_t* request) {
// GET /api/screenshot - Capture and return screenshot as PNG
// Screenshots are saved to SD card root (if available) or /data with incrementing numbers
esp_err_t WebServerService::handleApiScreenshot(httpd_req_t* request) {
LOGGER.info("GET /api/screenshot");
LOG_I(TAG, "GET /api/screenshot");
#if TT_FEATURE_SCREENSHOT_ENABLED
// Determine save location: prefer SD card root if mounted, otherwise /data
@@ -1471,7 +1472,7 @@ esp_err_t WebServerService::handleApiScreenshot(httpd_req_t* request) {
return ESP_FAIL;
}
LOGGER.info("Screenshot will be saved to: {}", screenshot_path);
LOG_I(TAG, "Screenshot will be saved to: %s", screenshot_path.c_str());
// LVGL's lodepng uses lv_fs which requires the "A:" prefix
std::string lvgl_screenshot_path = lvgl::PATH_PREFIX + screenshot_path;
@@ -1482,13 +1483,13 @@ esp_err_t WebServerService::handleApiScreenshot(httpd_req_t* request) {
lvgl::unlock();
if (!success) {
LOGGER.error("lv_screenshot_create failed for path: {}", lvgl_screenshot_path);
LOG_E(TAG, "lv_screenshot_create failed for path: %s", lvgl_screenshot_path.c_str());
httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, "screenshot capture failed");
return ESP_FAIL;
}
LOGGER.info("Screenshot captured successfully");
LOG_I(TAG, "Screenshot captured successfully");
} else {
LOGGER.error("Could not acquire LVGL lock within 100ms");
LOG_E(TAG, "Could not acquire LVGL lock within 100ms");
httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, "could not acquire LVGL lock");
return ESP_FAIL;
}
@@ -1514,7 +1515,7 @@ esp_err_t WebServerService::handleApiScreenshot(httpd_req_t* request) {
httpd_resp_send_chunk(request, nullptr, 0);
// File is kept on storage (not deleted) for user access
LOGGER.info("[200] /api/screenshot -> {}", screenshot_path);
LOG_I(TAG, "[200] /api/screenshot -> %s", screenshot_path.c_str());
return ESP_OK;
#else
httpd_resp_send_err(request, HTTPD_501_METHOD_NOT_IMPLEMENTED, "screenshot feature not enabled");
@@ -1524,7 +1525,7 @@ esp_err_t WebServerService::handleApiScreenshot(httpd_req_t* request) {
esp_err_t WebServerService::handleFsTree(httpd_req_t* request) {
LOGGER.info("GET /fs/tree");
LOG_I(TAG, "GET /fs/tree");
std::ostringstream json;
json << "{";
@@ -1569,7 +1570,7 @@ esp_err_t WebServerService::handleFsMkdir(httpd_req_t* request) {
return ESP_FAIL;
}
std::string norm = normalizePath(path);
LOGGER.info("POST /fs/mkdir requested: '{}' normalized: '{}'", path, norm);
LOG_I(TAG, "POST /fs/mkdir requested: '%s' normalized: '%s'", path.c_str(), norm.c_str());
if (!isAllowedBasePath(norm)) {
httpd_resp_send_err(request, HTTPD_403_FORBIDDEN, "invalid path");
return ESP_FAIL;
@@ -1592,7 +1593,7 @@ esp_err_t WebServerService::handleFsDelete(httpd_req_t* request) {
return ESP_FAIL;
}
std::string norm = normalizePath(path);
LOGGER.info("POST /fs/delete requested: '{}' normalized: '{}'", path, norm);
LOG_I(TAG, "POST /fs/delete requested: '%s' normalized: '%s'", path.c_str(), norm.c_str());
if (!isAllowedBasePath(norm)) {
httpd_resp_send_err(request, HTTPD_403_FORBIDDEN, "invalid path");
return ESP_FAIL;
@@ -1623,7 +1624,7 @@ esp_err_t WebServerService::handleFsRename(httpd_req_t* request) {
return ESP_FAIL;
}
std::string norm = normalizePath(path);
LOGGER.info("POST /fs/rename requested: '{}' normalized: '{}' -> newName: '{}'", path.c_str(), norm.c_str(), newName.c_str());
LOG_I(TAG, "POST /fs/rename requested: '%s' normalized: '%s' -> newName: '%s'", path.c_str(), norm.c_str(), newName.c_str());
if (!isAllowedBasePath(norm)) {
httpd_resp_send_err(request, HTTPD_403_FORBIDDEN, "invalid path");
return ESP_FAIL;
@@ -1662,7 +1663,7 @@ esp_err_t WebServerService::handleFsRename(httpd_req_t* request) {
int r = rename(norm.c_str(), target.c_str());
if (r != 0) {
int e = errno;
LOGGER.warn("rename failed errno={} ({}) -> {} -> {}", e, strerror(e), norm, target);
LOG_W(TAG, "rename failed errno=%d (%s) -> %s -> %s", e, strerror(e), norm.c_str(), target.c_str());
// Return errno string to client to aid debugging
std::string msg = std::string("rename failed: ") + strerror(e);
httpd_resp_send_err(request, HTTPD_500_INTERNAL_SERVER_ERROR, msg.c_str());
@@ -1676,7 +1677,7 @@ esp_err_t WebServerService::handleFsRename(httpd_req_t* request) {
esp_err_t WebServerService::handleReboot(httpd_req_t* request) {
LOGGER.info("POST /reboot");
LOG_I(TAG, "POST /reboot");
httpd_resp_sendstr(request, "Rebooting...");
// Reboot after a short delay to allow response to be sent
@@ -1695,7 +1696,7 @@ esp_err_t WebServerService::handleAssets(httpd_req_t* request) {
}
const char* uri = request->uri;
LOGGER.info("GET {}", uri);
LOG_I(TAG, "GET %s", uri);
// Special case: serve favicon from system assets
if (strcmp(uri, "/favicon.ico") == 0) {
@@ -1721,7 +1722,7 @@ esp_err_t WebServerService::handleAssets(httpd_req_t* request) {
fclose(fp);
lock->unlock();
httpd_resp_send_chunk(request, nullptr, 0);
LOGGER.info("[200] {} (favicon)", uri);
LOG_I(TAG, "[200] %s (favicon)", uri);
return ESP_OK;
}
lock->unlock();
@@ -1745,7 +1746,7 @@ esp_err_t WebServerService::handleAssets(httpd_req_t* request) {
std::string dataPath = std::string("/system/app/WebServer") + requestedPath;
if (requestedPath == "/dashboard.html" && !file::isFile(dataPath.c_str())) {
LOGGER.info("dashboard.html not found, serving default.html");
LOG_I(TAG, "dashboard.html not found, serving default.html");
}
// Try to serve from Data partition first
@@ -1771,7 +1772,7 @@ esp_err_t WebServerService::handleAssets(httpd_req_t* request) {
lock->unlock();
httpd_resp_send_chunk(request, nullptr, 0); // End of chunks
LOGGER.info("[200] {} (from Data)", uri);
LOG_I(TAG, "[200] %s (from Data)", uri);
return ESP_OK;
}
lock->unlock();
@@ -1800,14 +1801,14 @@ esp_err_t WebServerService::handleAssets(httpd_req_t* request) {
lock->unlock();
httpd_resp_send_chunk(request, nullptr, 0); // End of chunks
LOGGER.info("[200] {} (from SD)", uri);
LOG_I(TAG, "[200] %s (from SD)", uri);
return ESP_OK;
}
lock->unlock();
}
// File not found
LOGGER.warn("[404] {}", uri);
LOG_W(TAG, "[404] %s", uri);
httpd_resp_send_err(request, HTTPD_404_NOT_FOUND, "File not found");
return ESP_FAIL;
}
@@ -1823,7 +1824,7 @@ void setWebServerEnabled(bool enabled) {
instance->setEnabled(enabled);
// Don't log here - startServer()/stopServer() already log the actual result
} else {
LOGGER.warn("WebServer service not available, cannot {}", enabled ? "start" : "stop");
LOG_W(TAG, "WebServer service not available, cannot %s", enabled ? "start" : "stop");
}
}
@@ -4,9 +4,11 @@
#include <Tactility/crypt/Crypt.h>
#include <Tactility/file/File.h>
#include <Tactility/Logger.h>
#include <Tactility/service/ServicePaths.h>
#include <tactility/log.h>
#include <format>
#include <iomanip>
#include <ranges>
@@ -15,7 +17,7 @@
namespace tt::service::wifi::settings {
static const auto LOGGER = Logger("WifiApSettings");
constexpr auto* TAG = "WifiApSettings";
constexpr auto* AP_SETTINGS_FORMAT = "{}/{}.ap.properties";
@@ -34,7 +36,7 @@ std::string toHexString(const uint8_t *data, int length) {
bool readHex(const std::string& input, uint8_t* buffer, int length) {
if (input.size() / 2 != length) {
LOGGER.error("readHex() length mismatch");
LOG_E(TAG, "readHex() length mismatch");
return false;
}
@@ -64,7 +66,7 @@ static bool encrypt(const std::string& ssidInput, std::string& ssidOutput) {
crypt::getIv(ssidInput.c_str(), ssidInput.size(), iv);
if (crypt::encrypt(iv, reinterpret_cast<const uint8_t*>(ssidInput.c_str()), buffer, encrypted_length) != 0) {
LOGGER.error("Failed to encrypt");
LOG_E(TAG, "Failed to encrypt");
free(buffer);
return false;
}
@@ -80,7 +82,7 @@ static bool decrypt(const std::string& ssidInput, std::string& ssidOutput) {
assert(ssidInput.size() % 2 == 0);
auto* data = static_cast<uint8_t*>(malloc(ssidInput.size() / 2));
if (!readHex(ssidInput, data, ssidInput.size() / 2)) {
LOGGER.error("Failed to read hex");
LOG_E(TAG, "Failed to read hex");
return false;
}
@@ -102,7 +104,7 @@ static bool decrypt(const std::string& ssidInput, std::string& ssidOutput) {
free(data);
if (decrypt_result != 0) {
LOGGER.error("Failed to decrypt credentials for \"{}s\": {}", ssidInput, decrypt_result);
LOG_E(TAG, "Failed to decrypt credentials for \"%ss\": %d", ssidInput.c_str(), decrypt_result);
free(result);
return false;
}
@@ -186,7 +188,7 @@ bool save(const WifiApSettings& apSettings) {
const auto file_path = getApPropertiesFilePath(service_context->getPaths(), apSettings.ssid);
if (!file::findOrCreateParentDirectory(file_path, 0755)) {
LOGGER.error("Failed to create {}", file_path);
LOG_E(TAG, "Failed to create %s", file_path.c_str());
return false;
}
@@ -7,11 +7,13 @@
#include <Tactility/MountPoints.h>
#include <Tactility/file/File.h>
#include <Tactility/Logger.h>
#include <Tactility/service/wifi/WifiApSettings.h>
#include <Tactility/Paths.h>
#include <Tactility/Tactility.h>
#include <tactility/log.h>
#include <dirent.h>
#include <format>
#include <map>
@@ -20,7 +22,7 @@
namespace tt::service::wifi {
static const auto LOGGER = Logger("WifiBootSplashInit");
constexpr auto* TAG = "WifiBootSplashInit";
constexpr auto* AP_PROPERTIES_KEY_SSID = "ssid";
constexpr auto* AP_PROPERTIES_KEY_PASSWORD = "password";
@@ -39,13 +41,13 @@ struct ApProperties {
static void importWifiAp(const std::string& filePath) {
std::map<std::string, std::string> map;
if (!file::loadPropertiesFile(filePath, map)) {
LOGGER.error("Failed to load AP properties at {}", filePath);
LOG_E(TAG, "Failed to load AP properties at %s", filePath.c_str());
return;
}
const auto ssid_iterator = map.find(AP_PROPERTIES_KEY_SSID);
if (ssid_iterator == map.end()) {
LOGGER.error("{} is missing ssid", filePath);
LOG_E(TAG, "%s is missing ssid", filePath.c_str());
return;
}
const auto ssid = ssid_iterator->second;
@@ -69,18 +71,18 @@ static void importWifiAp(const std::string& filePath) {
);
if (!settings::save(settings)) {
LOGGER.error("Failed to save settings for {}", ssid);
LOG_E(TAG, "Failed to save settings for %s", ssid.c_str());
} else {
LOGGER.info("Imported {} from {}", ssid, filePath);
LOG_I(TAG, "Imported %s from %s", ssid.c_str(), filePath.c_str());
}
}
const auto auto_remove_iterator = map.find(AP_PROPERTIES_KEY_AUTO_REMOVE);
if (auto_remove_iterator != map.end() && auto_remove_iterator->second == "true") {
if (!remove(filePath.c_str())) {
LOGGER.error("Failed to auto-remove {}", filePath);
LOG_E(TAG, "Failed to auto-remove %s", filePath.c_str());
} else {
LOGGER.info("Auto-removed {}", filePath);
LOG_I(TAG, "Auto-removed %s", filePath.c_str());
}
}
}
@@ -109,7 +111,7 @@ static void importWifiApSettingsFromDir(const std::string& path) {
}
if (dirent_list.empty()) {
LOGGER.warn("No AP files found at {}", path);
LOG_W(TAG, "No AP files found at %s", path.c_str());
return;
}
@@ -120,24 +122,24 @@ static void importWifiApSettingsFromDir(const std::string& path) {
}
void bootSplashInit() {
LOGGER.info("bootSplashInit dispatch");
LOG_I(TAG, "bootSplashInit dispatch");
getMainDispatcher().dispatch([] {
LOGGER.info("bootSplashInit dispatch begin");
LOG_I(TAG, "bootSplashInit dispatch begin");
// Import any provisioning files placed on the system data partition.
const std::string provisioning_path = file::getChildPath(getUserDataPath(), "provisioning");
if (file::isDirectory(provisioning_path)) {
importWifiApSettingsFromDir(provisioning_path);
} else {
LOGGER.info("Skip provisioning: no files at {}", provisioning_path);
LOG_I(TAG, "Skip provisioning: no files at %s", provisioning_path.c_str());
}
// Dispatch WiFi on
if (settings::shouldEnableOnBoot()) {
LOGGER.info("Auto-enabling WiFi");
LOG_I(TAG, "Auto-enabling WiFi");
getMainDispatcher().dispatch([] -> void { setEnabled(true); });
}
LOGGER.info("bootSplashInit dispatch end");
LOG_I(TAG, "bootSplashInit dispatch end");
});
}
+75 -74
View File
@@ -6,10 +6,8 @@
#include <Tactility/service/wifi/Wifi.h>
#include <tactility/check.h>
#include <Tactility/EventGroup.h>
#include <Tactility/Logger.h>
#include <Tactility/LogMessages.h>
#include <Tactility/EventGroup.h>
#include <Tactility/RecursiveMutex.h>
#include <Tactility/Tactility.h>
#include <Tactility/Timer.h>
@@ -19,6 +17,9 @@
#include <Tactility/service/wifi/WifiGlobals.h>
#include <Tactility/service/wifi/WifiSettings.h>
#include <tactility/check.h>
#include <tactility/log.h>
#include <esp_wifi_default.h>
#include <lwip/esp_netif_net_stack.h>
#include <freertos/FreeRTOS.h>
@@ -28,7 +29,7 @@
namespace tt::service::wifi {
static const auto LOGGER = Logger("WifiService");
constexpr auto* TAG = "WifiService";
constexpr auto WIFI_CONNECTED_BIT = BIT0;
constexpr auto WIFI_FAIL_BIT = BIT1;
@@ -155,7 +156,7 @@ std::string getConnectionTarget() {
}
void scan() {
LOGGER.info("scan()");
LOG_I(TAG, "scan()");
auto wifi = wifi_singleton;
if (wifi == nullptr) {
return;
@@ -174,7 +175,7 @@ bool isScanning() {
}
void connect(const settings::WifiApSettings& ap, bool remember) {
LOGGER.info("connect({}, {})", ap.ssid, remember);
LOG_I(TAG, "connect(%s, %d)", ap.ssid.c_str(), (int)remember);
auto wifi = wifi_singleton;
if (wifi == nullptr) {
return;
@@ -198,7 +199,7 @@ void connect(const settings::WifiApSettings& ap, bool remember) {
}
void disconnect() {
LOGGER.info("disconnect()");
LOG_I(TAG, "disconnect()");
auto wifi = wifi_singleton;
if (wifi == nullptr) {
return;
@@ -229,7 +230,7 @@ void clearIp() {
memset(&wifi->ip_info, 0, sizeof(esp_netif_ip_info_t));
}
void setScanRecords(uint16_t records) {
LOGGER.info("setScanRecords({})", records);
LOG_I(TAG, "setScanRecords(%u)", records);
auto wifi = wifi_singleton;
if (wifi == nullptr) {
return;
@@ -247,7 +248,7 @@ void setScanRecords(uint16_t records) {
}
std::vector<ApRecord> getScanResults() {
LOGGER.info("getScanResults()");
LOG_I(TAG, "getScanResults()");
auto wifi = wifi_singleton;
std::vector<ApRecord> records;
@@ -278,7 +279,7 @@ std::vector<ApRecord> getScanResults() {
}
void setEnabled(bool enabled) {
LOGGER.info("setEnabled({})", enabled);
LOG_I(TAG, "setEnabled(%d)", (int)enabled);
auto wifi = wifi_singleton;
if (wifi == nullptr) {
return;
@@ -370,7 +371,7 @@ static bool copy_scan_list(std::shared_ptr<Wifi> wifi) {
wifi->isScanActive();
if (!can_fetch_results) {
LOGGER.info("Skip scan result fetching");
LOG_I(TAG, "Skip scan result fetching");
return false;
}
@@ -387,11 +388,11 @@ static bool copy_scan_list(std::shared_ptr<Wifi> wifi) {
if (scan_result == ESP_OK) {
uint16_t safe_record_count = std::min(wifi->scan_list_limit, record_count);
wifi->scan_list_count = safe_record_count;
LOGGER.info("Scanned {} APs. Showing {}:", record_count, safe_record_count);
LOG_I(TAG, "Scanned %u APs. Showing %u:", record_count, safe_record_count);
for (uint16_t i = 0; i < safe_record_count; i++) {
wifi_ap_record_t* record = &wifi->scan_list[i];
if (record->ssid[0] != 0 && record->primary != 0) {
LOGGER.info(" - SSID {}, RSSI {}, channel {}, BSSID {:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
LOG_I(TAG, " - SSID %s, RSSI %d, channel %u, BSSID %02x:%02x:%02x:%02x:%02x:%02x",
reinterpret_cast<const char*>(record->ssid),
record->rssi,
record->primary,
@@ -403,18 +404,18 @@ static bool copy_scan_list(std::shared_ptr<Wifi> wifi) {
record->bssid[5]
);
} else {
LOGGER.info(" - (missing channel info)"); // Behaviour on on P4 with C6
LOG_I(TAG, " - (missing channel info)"); // Behaviour on on P4 with C6
}
}
return true;
} else {
LOGGER.info("Failed to get scanned records: {}", esp_err_to_name(scan_result));
LOG_I(TAG, "Failed to get scanned records: %s", esp_err_to_name(scan_result));
return false;
}
}
static bool find_auto_connect_ap(std::shared_ptr<Wifi> wifi, settings::WifiApSettings& settings) {
LOGGER.info("find_auto_connect_ap()");
LOG_I(TAG, "find_auto_connect_ap()");
auto lock = wifi->dataMutex.asScopedLock();
if (lock.lock(10 / portTICK_PERIOD_MS)) {
for (int i = 0; i < wifi->scan_list_count; ++i) {
@@ -426,7 +427,7 @@ static bool find_auto_connect_ap(std::shared_ptr<Wifi> wifi, settings::WifiApSet
return true;
}
} else {
LOGGER.error("Failed to load credentials for ssid {}", ssid);
LOG_E(TAG, "Failed to load credentials for ssid %s", ssid);
}
break;
}
@@ -437,11 +438,11 @@ static bool find_auto_connect_ap(std::shared_ptr<Wifi> wifi, settings::WifiApSet
}
static void dispatchAutoConnect(std::shared_ptr<Wifi> wifi) {
LOGGER.info("dispatchAutoConnect()");
LOG_I(TAG, "dispatchAutoConnect()");
settings::WifiApSettings settings;
if (find_auto_connect_ap(wifi, settings)) {
LOGGER.info("Auto-connecting to {}", settings.ssid);
LOG_I(TAG, "Auto-connecting to %s", settings.ssid.c_str());
connect(settings, false);
// TODO: We currently have to manually reset it because connect() sets it.
// connect() assumes it's only being called by the user and not internally, so it disables auto-connect
@@ -452,23 +453,23 @@ static void dispatchAutoConnect(std::shared_ptr<Wifi> wifi) {
static void eventHandler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
auto wifi = wifi_singleton;
if (wifi == nullptr) {
LOGGER.error("eventHandler: no wifi instance");
LOG_E(TAG, "eventHandler: no wifi instance");
return;
}
if (event_base == WIFI_EVENT) {
LOGGER.info("eventHandler: WIFI_EVENT {}", event_id);
LOG_I(TAG, "eventHandler: WIFI_EVENT %d", (int)event_id);
} else if (event_base == IP_EVENT) {
LOGGER.info("eventHandler: IP_EVENT {}", event_id);
LOG_I(TAG, "eventHandler: IP_EVENT %d", (int)event_id);
}
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
LOGGER.info("eventHandler: STA_START");
LOG_I(TAG, "eventHandler: STA_START");
if (wifi->getRadioState() == RadioState::ConnectionPending) {
esp_wifi_connect();
}
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
LOGGER.info("eventHandler: STA_DISCONNECTED");
LOG_I(TAG, "eventHandler: STA_DISCONNECTED");
clearIp();
switch (wifi->getRadioState()) {
case RadioState::ConnectionPending:
@@ -487,7 +488,7 @@ static void eventHandler(void* arg, esp_event_base_t event_base, int32_t event_i
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
auto* event = static_cast<ip_event_got_ip_t*>(event_data);
memcpy(&wifi->ip_info, &event->ip_info, sizeof(esp_netif_ip_info_t));
LOGGER.info("eventHandler: got ip: {}.{}.{}.{}", IP2STR(&event->ip_info.ip));
LOG_I(TAG, "eventHandler: got ip: %d.%d.%d.%d", IP2STR(&event->ip_info.ip));
if (wifi->getRadioState() == RadioState::ConnectionPending) {
wifi->connection_wait_flags.set(WIFI_CONNECTED_BIT);
// We resume auto-connecting only when there was an explicit request by the user for the connection
@@ -497,7 +498,7 @@ static void eventHandler(void* arg, esp_event_base_t event_base, int32_t event_i
kernel::publishSystemEvent(kernel::SystemEvent::NetworkConnected);
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) {
auto* event = static_cast<wifi_event_sta_scan_done_t*>(event_data);
LOGGER.info("eventHandler: wifi scanning done (scan id {})", event->scan_id);
LOG_I(TAG, "eventHandler: wifi scanning done (scan id %u)", event->scan_id);
bool copied_list = copy_scan_list(wifi);
auto state = wifi->getRadioState();
@@ -510,7 +511,7 @@ static void eventHandler(void* arg, esp_event_base_t event_base, int32_t event_i
}
publish_event(wifi_singleton, WifiEvent::ScanFinished);
LOGGER.info("eventHandler: Finished scan");
LOG_I(TAG, "eventHandler: Finished scan");
if (copied_list && wifi_singleton->getRadioState() == RadioState::On && !wifi->pause_auto_connect) {
getMainDispatcher().dispatch([wifi]() { dispatchAutoConnect(wifi); });
@@ -519,7 +520,7 @@ static void eventHandler(void* arg, esp_event_base_t event_base, int32_t event_i
}
static void dispatchEnable(std::shared_ptr<Wifi> wifi) {
LOGGER.info("dispatchEnable()");
LOG_I(TAG, "dispatchEnable()");
RadioState state = wifi->getRadioState();
if (
@@ -527,13 +528,13 @@ static void dispatchEnable(std::shared_ptr<Wifi> wifi) {
state == RadioState::OnPending ||
state == RadioState::OffPending
) {
LOGGER.warn("Can't enable from current state");
LOG_W(TAG, "Can't enable from current state");
return;
}
auto lock = wifi->radioMutex.asScopedLock();
if (lock.lock(50 / portTICK_PERIOD_MS)) {
LOGGER.info("Enabling");
LOG_I(TAG, "Enabling");
wifi->setRadioState(RadioState::OnPending);
publish_event(wifi, WifiEvent::RadioStateOnPending);
@@ -548,9 +549,9 @@ static void dispatchEnable(std::shared_ptr<Wifi> wifi) {
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
esp_err_t init_result = esp_wifi_init(&config);
if (init_result != ESP_OK) {
LOGGER.error("Wifi init failed");
LOG_E(TAG, "Wifi init failed");
if (init_result == ESP_ERR_NO_MEM) {
LOGGER.error("Insufficient memory");
LOG_E(TAG, "Insufficient memory");
}
wifi->setRadioState(RadioState::Off);
publish_event(wifi, WifiEvent::RadioStateOff);
@@ -578,7 +579,7 @@ static void dispatchEnable(std::shared_ptr<Wifi> wifi) {
));
if (esp_wifi_set_mode(WIFI_MODE_STA) != ESP_OK) {
LOGGER.error("Wifi mode setting failed");
LOG_E(TAG, "Wifi mode setting failed");
wifi->setRadioState(RadioState::Off);
esp_wifi_deinit();
publish_event(wifi, WifiEvent::RadioStateOff);
@@ -587,9 +588,9 @@ static void dispatchEnable(std::shared_ptr<Wifi> wifi) {
esp_err_t start_result = esp_wifi_start();
if (start_result != ESP_OK) {
LOGGER.error("Wifi start failed");
LOG_E(TAG, "Wifi start failed");
if (start_result == ESP_ERR_NO_MEM) {
LOGGER.error("Insufficient memory");
LOG_E(TAG, "Insufficient memory");
}
wifi->setRadioState(RadioState::Off);
esp_wifi_set_mode(WIFI_MODE_NULL);
@@ -603,18 +604,18 @@ static void dispatchEnable(std::shared_ptr<Wifi> wifi) {
wifi->pause_auto_connect = false;
LOGGER.info("Enabled");
LOG_I(TAG, "Enabled");
} else {
LOGGER.error(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
}
}
static void dispatchDisable(std::shared_ptr<Wifi> wifi) {
LOGGER.info("dispatchDisable()");
LOG_I(TAG, "dispatchDisable()");
auto lock = wifi->radioMutex.asScopedLock();
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
LOGGER.error(LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "disable()");
LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "disable()");
return;
}
@@ -624,11 +625,11 @@ static void dispatchDisable(std::shared_ptr<Wifi> wifi) {
state == RadioState::OffPending ||
state == RadioState::OnPending
) {
LOGGER.warn("Can't disable from current state");
LOG_W(TAG, "Can't disable from current state");
return;
}
LOGGER.info("Disabling");
LOG_I(TAG, "Disabling");
wifi->setRadioState(RadioState::OffPending);
publish_event(wifi, WifiEvent::RadioStateOffPending);
@@ -649,11 +650,11 @@ static void dispatchDisable(std::shared_ptr<Wifi> wifi) {
// event handlers and subsequent disable attempts would behave incorrectly.
// If stop fails, continue the teardown anyway so we end in a clean Off state.
if (esp_wifi_stop() != ESP_OK) {
LOGGER.error("Failed to stop radio - continuing teardown");
LOG_E(TAG, "Failed to stop radio - continuing teardown");
}
if (esp_wifi_set_mode(WIFI_MODE_NULL) != ESP_OK) {
LOGGER.error("Failed to unset mode");
LOG_E(TAG, "Failed to unset mode");
}
if (esp_event_handler_instance_unregister(
@@ -661,7 +662,7 @@ static void dispatchDisable(std::shared_ptr<Wifi> wifi) {
ESP_EVENT_ANY_ID,
wifi->event_handler_any_id
) != ESP_OK) {
LOGGER.error("Failed to unregister id event handler");
LOG_E(TAG, "Failed to unregister id event handler");
}
if (esp_event_handler_instance_unregister(
@@ -669,11 +670,11 @@ static void dispatchDisable(std::shared_ptr<Wifi> wifi) {
IP_EVENT_STA_GOT_IP,
wifi->event_handler_got_ip
) != ESP_OK) {
LOGGER.error("Failed to unregister ip event handler");
LOG_E(TAG, "Failed to unregister ip event handler");
}
if (esp_wifi_deinit() != ESP_OK) {
LOGGER.error("Failed to deinit");
LOG_E(TAG, "Failed to deinit");
}
assert(wifi->netif != nullptr);
@@ -682,26 +683,26 @@ static void dispatchDisable(std::shared_ptr<Wifi> wifi) {
wifi->setScanActive(false);
wifi->setRadioState(RadioState::Off);
publish_event(wifi, WifiEvent::RadioStateOff);
LOGGER.info("Disabled");
LOG_I(TAG, "Disabled");
}
static void dispatchScan(std::shared_ptr<Wifi> wifi) {
LOGGER.info("dispatchScan()");
LOG_I(TAG, "dispatchScan()");
auto lock = wifi->radioMutex.asScopedLock();
if (!lock.lock(10 / portTICK_PERIOD_MS)) {
LOGGER.error(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return;
}
RadioState state = wifi->getRadioState();
if (state != RadioState::On && state != RadioState::ConnectionActive && state != RadioState::ConnectionPending) {
LOGGER.warn("Scan unavailable: wifi not enabled");
LOG_W(TAG, "Scan unavailable: wifi not enabled");
return;
}
if (wifi->isScanActive()) {
LOGGER.warn("Scan already pending");
LOG_W(TAG, "Scan already pending");
return;
}
@@ -709,25 +710,25 @@ static void dispatchScan(std::shared_ptr<Wifi> wifi) {
wifi->last_scan_time = tt::kernel::getTicks();
if (esp_wifi_scan_start(nullptr, false) != ESP_OK) {
LOGGER.info("Can't start scan");
LOG_I(TAG, "Can't start scan");
return;
}
LOGGER.info("Starting scan");
LOG_I(TAG, "Starting scan");
wifi->setScanActive(true);
publish_event(wifi, WifiEvent::ScanStarted);
}
static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
LOGGER.info("dispatchConnect()");
LOG_I(TAG, "dispatchConnect()");
auto lock = wifi->radioMutex.asScopedLock();
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
LOGGER.error(LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "dispatchConnect()");
LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT, "dispatchConnect()");
return;
}
LOGGER.info("Connecting to {}", wifi->connection_target.ssid);
LOG_I(TAG, "Connecting to %s", wifi->connection_target.ssid.c_str());
// Stop radio first, if needed
RadioState radio_state = wifi->getRadioState();
@@ -736,11 +737,11 @@ static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
radio_state == RadioState::ConnectionActive ||
radio_state == RadioState::ConnectionPending
) {
LOGGER.info("Connecting: Stopping radio first");
LOG_I(TAG, "Connecting: Stopping radio first");
esp_err_t stop_result = esp_wifi_stop();
wifi->setScanActive(false);
if (stop_result != ESP_OK) {
LOGGER.error("Connecting: Failed to disconnect ({})", esp_err_to_name(stop_result));
LOG_E(TAG, "Connecting: Failed to disconnect (%s)", esp_err_to_name(stop_result));
return;
}
}
@@ -766,20 +767,20 @@ static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
}
LOGGER.info("esp_wifi_set_config()");
LOG_I(TAG, "esp_wifi_set_config()");
esp_err_t set_config_result = esp_wifi_set_config(WIFI_IF_STA, &config);
if (set_config_result != ESP_OK) {
wifi->setRadioState(RadioState::On);
LOGGER.error("Failed to set wifi config ({})", esp_err_to_name(set_config_result));
LOG_E(TAG, "Failed to set wifi config (%s)", esp_err_to_name(set_config_result));
publish_event(wifi, WifiEvent::ConnectionFailed);
return;
}
LOGGER.info("esp_wifi_start()");
LOG_I(TAG, "esp_wifi_start()");
esp_err_t wifi_start_result = esp_wifi_start();
if (wifi_start_result != ESP_OK) {
wifi->setRadioState(RadioState::On);
LOGGER.error("Failed to start wifi to begin connecting ({})", esp_err_to_name(wifi_start_result));
LOG_E(TAG, "Failed to start wifi to begin connecting (%s)", esp_err_to_name(wifi_start_result));
publish_event(wifi, WifiEvent::ConnectionFailed);
return;
}
@@ -789,28 +790,28 @@ static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
* The bits are set by wifi_event_handler() */
uint32_t flags;
if (wifi_singleton->connection_wait_flags.wait(WIFI_FAIL_BIT | WIFI_CONNECTED_BIT, false, true, &flags, kernel::MAX_TICKS)) {
LOGGER.info("Waiting for EventGroup by event_handler()");
LOG_I(TAG, "Waiting for EventGroup by event_handler()");
if (flags & WIFI_CONNECTED_BIT) {
wifi->setSecureConnection(config.sta.password[0] != 0x00U);
wifi->setRadioState(RadioState::ConnectionActive);
publish_event(wifi, WifiEvent::ConnectionSuccess);
LOGGER.info("Connected to {}", wifi->connection_target.ssid.c_str());
LOG_I(TAG, "Connected to %s", wifi->connection_target.ssid.c_str());
if (wifi->connection_target_remember) {
if (!settings::save(wifi->connection_target)) {
LOGGER.error("Failed to store credentials");
LOG_E(TAG, "Failed to store credentials");
} else {
LOGGER.info("Stored credentials");
LOG_I(TAG, "Stored credentials");
}
}
} else if (flags & WIFI_FAIL_BIT) {
wifi->setRadioState(RadioState::On);
publish_event(wifi, WifiEvent::ConnectionFailed);
LOGGER.info("Failed to connect to {}", wifi->connection_target.ssid.c_str());
LOG_I(TAG, "Failed to connect to %s", wifi->connection_target.ssid.c_str());
} else {
wifi->setRadioState(RadioState::On);
publish_event(wifi, WifiEvent::ConnectionFailed);
LOGGER.error("UNEXPECTED EVENT");
LOG_E(TAG, "UNEXPECTED EVENT");
}
wifi_singleton->connection_wait_flags.clear(WIFI_FAIL_BIT | WIFI_CONNECTED_BIT);
@@ -818,17 +819,17 @@ static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
}
static void dispatchDisconnectButKeepActive(std::shared_ptr<Wifi> wifi) {
LOGGER.info("dispatchDisconnectButKeepActive()");
LOG_I(TAG, "dispatchDisconnectButKeepActive()");
auto lock = wifi->radioMutex.asScopedLock();
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
LOGGER.error(LOG_MESSAGE_MUTEX_LOCK_FAILED);
LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
return;
}
esp_err_t stop_result = esp_wifi_stop();
if (stop_result != ESP_OK) {
LOGGER.error("Failed to disconnect ({})", esp_err_to_name(stop_result));
LOG_E(TAG, "Failed to disconnect (%s)", esp_err_to_name(stop_result));
return;
}
@@ -844,7 +845,7 @@ static void dispatchDisconnectButKeepActive(std::shared_ptr<Wifi> wifi) {
if (set_config_result != ESP_OK) {
// TODO: disable radio, because radio state is in limbo between off and on
wifi->setRadioState(RadioState::Off);
LOGGER.error("failed to set wifi config ({})", esp_err_to_name(set_config_result));
LOG_E(TAG, "failed to set wifi config (%s)", esp_err_to_name(set_config_result));
publish_event(wifi, WifiEvent::RadioStateOff);
return;
}
@@ -853,14 +854,14 @@ static void dispatchDisconnectButKeepActive(std::shared_ptr<Wifi> wifi) {
if (wifi_start_result != ESP_OK) {
// TODO: disable radio, because radio state is in limbo between off and on
wifi->setRadioState(RadioState::Off);
LOGGER.error("failed to start wifi to begin connecting ({})", esp_err_to_name(wifi_start_result));
LOG_E(TAG, "failed to start wifi to begin connecting (%s)", esp_err_to_name(wifi_start_result));
publish_event(wifi, WifiEvent::RadioStateOff);
return;
}
wifi->setRadioState(RadioState::On);
publish_event(wifi, WifiEvent::Disconnected);
LOGGER.info("Disconnected");
LOG_I(TAG, "Disconnected");
}
static bool shouldScanForAutoConnect(std::shared_ptr<Wifi> wifi) {
@@ -2,13 +2,14 @@
#include <Tactility/file/File.h>
#include <Tactility/file/PropertiesFile.h>
#include <Tactility/Logger.h>
#include <Tactility/service/ServicePaths.h>
#include <Tactility/service/wifi/WifiPrivate.h>
#include <tactility/log.h>
namespace tt::service::wifi::settings {
static const auto LOGGER = Logger("WifiSettings");
constexpr auto* TAG = "WifiSettings";
constexpr auto* SETTINGS_KEY_ENABLE_ON_BOOT = "enableOnBoot";
struct WifiSettings {
@@ -47,7 +48,7 @@ static bool save(std::shared_ptr<ServiceContext> context, const WifiSettings& se
map[SETTINGS_KEY_ENABLE_ON_BOOT] = settings.enableOnBoot ? "true" : "false";
std::string settings_path = context->getPaths()->getUserDataPath("settings.properties");
if (!file::findOrCreateParentDirectory(settings_path, 0755)) {
LOGGER.error("Failed to create {}", settings_path);
LOG_E(TAG, "Failed to create %s", settings_path.c_str());
return false;
}
return file::savePropertiesFile(settings_path, map);
@@ -60,7 +61,7 @@ WifiSettings getCachedOrLoad() {
if (load(context, cachedSettings)) {
cached = true;
} else {
LOGGER.info("Failed to load settings, using defaults");
LOG_I(TAG, "Failed to load settings, using defaults");
}
}
}
@@ -72,7 +73,7 @@ void setEnableOnBoot(bool enable) {
cachedSettings.enableOnBoot = enable;
auto context = findServiceContext();
if (context && !save(context, cachedSettings)) {
LOGGER.error("Failed to save settings");
LOG_E(TAG, "Failed to save settings");
}
}