Merge develop into main (#313)
- Add app path get() functions to `TactilityC` - Improved `Dispatcher` and `DispatcherThread` - Improved `PubSub` (type safety) - Created test for `DispatcherThread` and `PubSub` - Save properties files on app exit (various apps) by posting it to the main dispatcher (fixes UI hanging briefly on app exit) - Fixed bug with `SystemSettings` being read from the wrong file path. - `loadPropertiesFile()` now uses `file::readLines()` instead of doing that manually - Increased timer task stack size (required due to issues when reading a properties file for the very first time) - General cleanup - Created `EstimatedPower` driver that uses an ADC pin to measure voltage and estimate the battery charge that is left. - Cleanup of T-Deck board (updated to new style)
This commit is contained in:
committed by
GitHub
parent
5cc5b50694
commit
0f8380e8fe
@@ -1,28 +1,46 @@
|
||||
#include <Tactility/Tactility.h>
|
||||
#include <Tactility/TactilityConfig.h>
|
||||
|
||||
#include <Tactility/app/AppRegistration.h>
|
||||
#include <Tactility/TactilityConfig.h>
|
||||
#include <Tactility/TactilityHeadless.h>
|
||||
#include <Tactility/DispatcherThread.h>
|
||||
#include <Tactility/hal/HalPrivate.h>
|
||||
#include <Tactility/hal/sdcard/SdCardMounting.h>
|
||||
#include <Tactility/lvgl/LvglPrivate.h>
|
||||
#include <Tactility/network/NtpPrivate.h>
|
||||
#include <Tactility/service/ServiceManifest.h>
|
||||
#include <Tactility/service/ServiceRegistration.h>
|
||||
#include <Tactility/service/loader/Loader.h>
|
||||
#include <Tactility/settings/TimePrivate.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include <Tactility/InitEsp.h>
|
||||
#endif
|
||||
|
||||
namespace tt {
|
||||
|
||||
#define TAG "Tactility"
|
||||
constexpr auto* TAG = "Tactility";
|
||||
|
||||
static const Configuration* config_instance = nullptr;
|
||||
static Dispatcher mainDispatcher;
|
||||
|
||||
// region Default services
|
||||
|
||||
namespace service {
|
||||
// Primary
|
||||
namespace gps { extern const ServiceManifest manifest; }
|
||||
namespace wifi { extern const ServiceManifest manifest; }
|
||||
namespace sdcard { extern const ServiceManifest manifest; }
|
||||
#ifdef ESP_PLATFORM
|
||||
namespace development { extern const ServiceManifest manifest; }
|
||||
namespace espnow { extern const ServiceManifest manifest; }
|
||||
#endif
|
||||
// Secondary (UI)
|
||||
namespace gui { extern const ServiceManifest manifest; }
|
||||
namespace loader { extern const ServiceManifest manifest; }
|
||||
namespace statusbar { extern const ServiceManifest manifest; }
|
||||
#if TT_FEATURE_SCREENSHOT_ENABLED
|
||||
namespace screenshot { extern const ServiceManifest manifest; }
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// endregion
|
||||
@@ -127,7 +145,7 @@ static void registerUserApps(const std::vector<const app::AppManifest*>& apps) {
|
||||
}
|
||||
}
|
||||
|
||||
static void registerAndStartSystemServices() {
|
||||
static void registerAndStartSecondaryServices() {
|
||||
TT_LOG_I(TAG, "Registering and starting system services");
|
||||
addService(service::loader::manifest);
|
||||
addService(service::gui::manifest);
|
||||
@@ -137,6 +155,17 @@ static void registerAndStartSystemServices() {
|
||||
#endif
|
||||
}
|
||||
|
||||
static void registerAndStartPrimaryServices() {
|
||||
TT_LOG_I(TAG, "Registering and starting system services");
|
||||
addService(service::gps::manifest);
|
||||
addService(service::sdcard::manifest);
|
||||
addService(service::wifi::manifest);
|
||||
#ifdef ESP_PLATFORM
|
||||
addService(service::development::manifest);
|
||||
addService(service::espnow::manifest);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void registerAndStartUserServices(const std::vector<const service::ServiceManifest*>& manifests) {
|
||||
TT_LOG_I(TAG, "Registering and starting user services");
|
||||
for (auto* manifest : manifests) {
|
||||
@@ -165,11 +194,18 @@ void run(const Configuration& config) {
|
||||
// Assign early so starting services can use it
|
||||
config_instance = &config;
|
||||
|
||||
initHeadless(hardware);
|
||||
TT_LOG_I(TAG, "Tactility v%s on %s (%s)", TT_VERSION, CONFIG_TT_BOARD_NAME, CONFIG_TT_BOARD_ID);
|
||||
#ifdef ESP_PLATFORM
|
||||
initEsp();
|
||||
#endif
|
||||
settings::initTimeZone();
|
||||
hal::init(*config.hardware);
|
||||
hal::sdcard::mountAll();
|
||||
network::ntp::init();
|
||||
|
||||
registerAndStartPrimaryServices();
|
||||
lvgl::init(hardware);
|
||||
|
||||
registerAndStartSystemServices();
|
||||
registerAndStartSecondaryServices();
|
||||
|
||||
TT_LOG_I(TAG, "starting boot app");
|
||||
// The boot app takes care of registering system apps, user services and user apps
|
||||
@@ -180,7 +216,7 @@ void run(const Configuration& config) {
|
||||
|
||||
TT_LOG_I(TAG, "Processing main dispatcher");
|
||||
while (true) {
|
||||
getMainDispatcher().consume();
|
||||
mainDispatcher.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,4 +224,8 @@ const Configuration* _Nullable getConfiguration() {
|
||||
return config_instance;
|
||||
}
|
||||
|
||||
Dispatcher& getMainDispatcher() {
|
||||
return mainDispatcher;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
#include "Tactility/TactilityHeadless.h"
|
||||
#include "Tactility/hal/Configuration.h"
|
||||
#include "Tactility/hal/Hal_i.h"
|
||||
#include "Tactility/network/NtpPrivate.h"
|
||||
#include "Tactility/service/ServiceManifest.h"
|
||||
#include "Tactility/service/ServiceRegistration.h"
|
||||
|
||||
#include <Tactility/Dispatcher.h>
|
||||
#include <Tactility/hal/sdcard/SdCardMounting.h>
|
||||
#include <Tactility/settings/TimePrivate.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "Tactility/InitEsp.h"
|
||||
#endif
|
||||
|
||||
namespace tt {
|
||||
|
||||
constexpr auto* TAG = "Tactility";
|
||||
|
||||
namespace service::gps { extern const ServiceManifest manifest; }
|
||||
namespace service::wifi { extern const ServiceManifest manifest; }
|
||||
namespace service::sdcard { extern const ServiceManifest manifest; }
|
||||
#ifdef ESP_PLATFORM
|
||||
namespace service::development { extern const ServiceManifest manifest; }
|
||||
namespace service::espnow { extern const ServiceManifest manifest; }
|
||||
#endif
|
||||
|
||||
static Dispatcher mainDispatcher;
|
||||
|
||||
static const hal::Configuration* hardwareConfig = nullptr;
|
||||
|
||||
static void registerAndStartSystemServices() {
|
||||
TT_LOG_I(TAG, "Registering and starting system services");
|
||||
addService(service::gps::manifest);
|
||||
addService(service::sdcard::manifest);
|
||||
addService(service::wifi::manifest);
|
||||
#ifdef ESP_PLATFORM
|
||||
addService(service::development::manifest);
|
||||
addService(service::espnow::manifest);
|
||||
#endif
|
||||
}
|
||||
|
||||
void initHeadless(const hal::Configuration& config) {
|
||||
TT_LOG_I(TAG, "Tactility v%s on %s (%s)", TT_VERSION, CONFIG_TT_BOARD_NAME, CONFIG_TT_BOARD_ID);
|
||||
#ifdef ESP_PLATFORM
|
||||
initEsp();
|
||||
#endif
|
||||
hardwareConfig = &config;
|
||||
settings::initTimeZone();
|
||||
hal::init(config);
|
||||
hal::sdcard::mountAll();
|
||||
network::ntp::init();
|
||||
registerAndStartSystemServices();
|
||||
}
|
||||
|
||||
Dispatcher& getMainDispatcher() {
|
||||
return mainDispatcher;
|
||||
}
|
||||
|
||||
namespace hal {
|
||||
|
||||
const Configuration* getConfiguration() {
|
||||
return hardwareConfig;
|
||||
}
|
||||
|
||||
} // namespace hal
|
||||
|
||||
} // namespace tt
|
||||
@@ -32,7 +32,7 @@ class BootApp : public App {
|
||||
|
||||
Thread thread = Thread(
|
||||
"boot",
|
||||
4096,
|
||||
5120,
|
||||
[] { return bootThreadCallback(); },
|
||||
getCpuAffinityConfiguration().system
|
||||
);
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include <Tactility/Tactility.h>
|
||||
|
||||
#include <Tactility/app/AppManifest.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
#include <Tactility/lvgl/Style.h>
|
||||
#include <Tactility/lvgl/Toolbar.h>
|
||||
#include <Tactility/service/development/DevelopmentService.h>
|
||||
#include <Tactility/service/development/DevelopmentSettings.h>
|
||||
#include <Tactility/service/loader/Loader.h>
|
||||
#include <Tactility/service/wifi/Wifi.h>
|
||||
#include <Tactility/Timer.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <lvgl.h>
|
||||
#include <Tactility/service/development/DevelopmentSettings.h>
|
||||
|
||||
namespace tt::app::development {
|
||||
|
||||
@@ -51,7 +53,10 @@ class DevelopmentApp final : public App {
|
||||
bool is_on = lv_obj_has_state(widget, LV_STATE_CHECKED);
|
||||
bool is_changed = is_on != service::development::shouldEnableOnBoot();
|
||||
if (is_changed) {
|
||||
service::development::setEnableOnBoot(is_on);
|
||||
// Dispatch it, so file IO doesn't block the UI
|
||||
getMainDispatcher().dispatch([is_on] {
|
||||
service::development::setEnableOnBoot(is_on);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include <Tactility/Tactility.h>
|
||||
|
||||
#include <Tactility/settings/DisplaySettings.h>
|
||||
#include <Tactility/Assets.h>
|
||||
#include <Tactility/hal/display/DisplayDevice.h>
|
||||
#include <Tactility/lvgl/Toolbar.h>
|
||||
#include <Tactility/Tactility.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
@@ -139,7 +140,11 @@ public:
|
||||
|
||||
void onHide(TT_UNUSED AppContext& app) override {
|
||||
if (displaySettingsUpdated) {
|
||||
settings::display::save(displaySettings);
|
||||
// Dispatch it, so file IO doesn't block the UI
|
||||
const settings::display::DisplaySettings settings_to_save = displaySettings;
|
||||
getMainDispatcher().dispatch([settings_to_save] {
|
||||
settings::display::save(settings_to_save);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#include "Tactility/TactilityHeadless.h"
|
||||
#include "Tactility/Timer.h"
|
||||
#include "Tactility/app/AppManifest.h"
|
||||
#include "Tactility/app/alertdialog/AlertDialog.h"
|
||||
#include "Tactility/lvgl/LvglSync.h"
|
||||
#include "Tactility/lvgl/Toolbar.h"
|
||||
#include "Tactility/service/gps/GpsUtil.h"
|
||||
#include "Tactility/service/loader/Loader.h"
|
||||
#include <Tactility/Tactility.h>
|
||||
|
||||
#include <Tactility/app/AppManifest.h>
|
||||
#include <Tactility/app/alertdialog/AlertDialog.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
#include <Tactility/lvgl/Toolbar.h>
|
||||
#include <Tactility/service/gps/GpsService.h>
|
||||
#include <Tactility/service/gps/GpsState.h>
|
||||
#include <Tactility/service/loader/Loader.h>
|
||||
#include <Tactility/Timer.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <format>
|
||||
@@ -34,14 +35,9 @@ class GpsSettingsApp final : public App {
|
||||
lv_obj_t* gpsConfigWrapper = nullptr;
|
||||
lv_obj_t* addGpsWrapper = nullptr;
|
||||
bool hasSetInfo = false;
|
||||
PubSub::SubscriptionHandle serviceStateSubscription = nullptr;
|
||||
PubSub<service::gps::State>::SubscriptionHandle serviceStateSubscription = nullptr;
|
||||
std::shared_ptr<service::gps::GpsService> service;
|
||||
|
||||
static void onServiceStateChangedCallback(const void* data, void* context) {
|
||||
auto* app = (GpsSettingsApp*)context;
|
||||
app->onServiceStateChanged();
|
||||
}
|
||||
|
||||
void onServiceStateChanged() {
|
||||
auto lock = lvgl::getSyncLock()->asScopedLock();
|
||||
if (lock.lock(100 / portTICK_PERIOD_MS)) {
|
||||
@@ -313,7 +309,9 @@ public:
|
||||
lv_obj_set_style_pad_all(infoContainerWidget, 0, 0);
|
||||
hasSetInfo = false;
|
||||
|
||||
serviceStateSubscription = service->getStatePubsub()->subscribe(onServiceStateChangedCallback, this);
|
||||
serviceStateSubscription = service->getStatePubsub()->subscribe([this](auto) {
|
||||
onServiceStateChanged();
|
||||
});
|
||||
|
||||
gpsConfigWrapper = lv_obj_create(main_wrapper);
|
||||
lv_obj_set_size(gpsConfigWrapper, LV_PCT(100), LV_SIZE_CONTENT);
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
#include "Tactility/TactilityConfig.h"
|
||||
#include <Tactility/Tactility.h>
|
||||
#include <Tactility/TactilityConfig.h>
|
||||
|
||||
#include <Tactility/Timer.h>
|
||||
#include <Tactility/kernel/Kernel.h>
|
||||
|
||||
#if TT_FEATURE_SCREENSHOT_ENABLED
|
||||
|
||||
#include "Tactility/app/App.h"
|
||||
#include "Tactility/app/AppManifest.h"
|
||||
#include "Tactility/lvgl/LvglSync.h"
|
||||
#include "Tactility/lvgl/Toolbar.h"
|
||||
#include "Tactility/service/screenshot/Screenshot.h"
|
||||
#include <Tactility/app/App.h>
|
||||
#include <Tactility/app/AppManifest.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
#include <Tactility/lvgl/Toolbar.h>
|
||||
#include <Tactility/service/screenshot/Screenshot.h>
|
||||
|
||||
#include <Tactility/TactilityHeadless.h>
|
||||
|
||||
#define TAG "screenshot"
|
||||
constexpr auto* TAG = "Screenshot";
|
||||
|
||||
namespace tt::app::screenshot {
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#include "Tactility/app/wificonnect/State.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <Tactility/app/wificonnect/State.h>
|
||||
|
||||
namespace tt::app::wificonnect {
|
||||
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
#include "Tactility/app/wificonnect/View.h"
|
||||
#include "Tactility/app/wificonnect/WifiConnect.h"
|
||||
|
||||
#include "Tactility/lvgl/Toolbar.h"
|
||||
#include "Tactility/lvgl/Spinner.h"
|
||||
|
||||
#include <Tactility/TactilityCore.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <cstring>
|
||||
#include <Tactility/app/wificonnect/View.h>
|
||||
#include <Tactility/app/wificonnect/WifiConnect.h>
|
||||
#include <Tactility/lvgl/Toolbar.h>
|
||||
#include <Tactility/lvgl/Spinner.h>
|
||||
#include <Tactility/service/wifi/WifiApSettings.h>
|
||||
#include <Tactility/service/wifi/WifiGlobals.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace tt::app::wificonnect {
|
||||
|
||||
#define TAG "wifi_connect"
|
||||
constexpr auto* TAG = "WifiConnect";
|
||||
|
||||
void View::resetErrors() {
|
||||
lv_obj_add_flag(password_error, LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
@@ -1,41 +1,18 @@
|
||||
#include "Tactility/app/wificonnect/WifiConnect.h"
|
||||
#include <Tactility/app/wificonnect/WifiConnect.h>
|
||||
|
||||
#include "Tactility/app/AppContext.h"
|
||||
#include "Tactility/service/loader/Loader.h"
|
||||
#include "Tactility/service/wifi/Wifi.h"
|
||||
#include "Tactility/lvgl/LvglSync.h"
|
||||
#include <Tactility/app/AppContext.h>
|
||||
#include <Tactility/service/loader/Loader.h>
|
||||
#include <Tactility/service/wifi/Wifi.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
|
||||
namespace tt::app::wificonnect {
|
||||
#define TAG "wifi_connect"
|
||||
#define WIFI_CONNECT_PARAM_SSID "ssid" // String
|
||||
#define WIFI_CONNECT_PARAM_PASSWORD "password" // String
|
||||
|
||||
constexpr auto* TAG = "WifiConnect";
|
||||
constexpr auto* WIFI_CONNECT_PARAM_SSID = "ssid"; // String
|
||||
constexpr auto* WIFI_CONNECT_PARAM_PASSWORD = "password"; // String
|
||||
|
||||
extern const AppManifest manifest;
|
||||
|
||||
static void eventCallback(const void* message, void* context) {
|
||||
auto* event = static_cast<const service::wifi::Event*>(message);
|
||||
auto* wifi = static_cast<WifiConnect*>(context);
|
||||
State& state = wifi->getState();
|
||||
switch (event->type) {
|
||||
case service::wifi::EventType::ConnectionFailed:
|
||||
if (state.isConnecting()) {
|
||||
state.setConnecting(false);
|
||||
state.setConnectionError(true);
|
||||
wifi->requestViewUpdate();
|
||||
}
|
||||
break;
|
||||
case service::wifi::EventType::ConnectionSuccess:
|
||||
if (wifi->getState().isConnecting()) {
|
||||
state.setConnecting(false);
|
||||
service::loader::stopApp();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
wifi->requestViewUpdate();
|
||||
}
|
||||
|
||||
static void onConnect(const service::wifi::settings::WifiApSettings& ap_settings, bool remember, TT_UNUSED void* parameter) {
|
||||
auto* wifi = static_cast<WifiConnect*>(parameter);
|
||||
wifi->getState().setApSettings(ap_settings);
|
||||
@@ -43,8 +20,33 @@ static void onConnect(const service::wifi::settings::WifiApSettings& ap_settings
|
||||
service::wifi::connect(ap_settings, remember);
|
||||
}
|
||||
|
||||
void WifiConnect::onWifiEvent(service::wifi::WifiEvent event) {
|
||||
State& state = getState();
|
||||
switch (event) {
|
||||
case service::wifi::WifiEvent::ConnectionFailed:
|
||||
if (state.isConnecting()) {
|
||||
state.setConnecting(false);
|
||||
state.setConnectionError(true);
|
||||
requestViewUpdate();
|
||||
}
|
||||
break;
|
||||
case service::wifi::WifiEvent::ConnectionSuccess:
|
||||
if (getState().isConnecting()) {
|
||||
state.setConnecting(false);
|
||||
service::loader::stopApp();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
requestViewUpdate();
|
||||
}
|
||||
|
||||
WifiConnect::WifiConnect() {
|
||||
wifiSubscription = service::wifi::getPubsub()->subscribe(&eventCallback, this);
|
||||
wifiSubscription = service::wifi::getPubsub()->subscribe([this](auto event) {
|
||||
onWifiEvent(event);
|
||||
});
|
||||
|
||||
bindings = (Bindings) {
|
||||
.onConnectSsid = onConnect,
|
||||
.onConnectSsidContext = this,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "Tactility/app/wifimanage/WifiManagePrivate.h"
|
||||
#include <Tactility/app/wifimanage/WifiManagePrivate.h>
|
||||
|
||||
namespace tt::app::wifimanage {
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#include "Tactility/app/wifimanage/View.h"
|
||||
#include "Tactility/app/wifimanage/WifiManagePrivate.h"
|
||||
#include <Tactility/app/wifimanage/View.h>
|
||||
|
||||
#include "Tactility/lvgl/Style.h"
|
||||
#include "Tactility/lvgl/Toolbar.h"
|
||||
#include "Tactility/lvgl/Spinner.h"
|
||||
#include <Tactility/Tactility.h>
|
||||
#include <Tactility/app/wifimanage/WifiManagePrivate.h>
|
||||
|
||||
#include <Tactility/lvgl/Style.h>
|
||||
#include <Tactility/lvgl/Toolbar.h>
|
||||
#include <Tactility/lvgl/Spinner.h>
|
||||
|
||||
#include <Tactility/Log.h>
|
||||
#include <Tactility/service/wifi/Wifi.h>
|
||||
@@ -15,7 +17,7 @@
|
||||
|
||||
namespace tt::app::wifimanage {
|
||||
|
||||
#define TAG "wifi_main_view"
|
||||
constexpr auto* TAG = "WifiManageView";
|
||||
|
||||
std::shared_ptr<WifiManage> _Nullable optWifiManage();
|
||||
|
||||
@@ -49,7 +51,10 @@ static void on_enable_on_boot_switch_changed(lv_event_t* event) {
|
||||
auto* enable_switch = static_cast<lv_obj_t*>(lv_event_get_target(event));
|
||||
if (code == LV_EVENT_VALUE_CHANGED) {
|
||||
bool is_on = lv_obj_has_state(enable_switch, LV_STATE_CHECKED);
|
||||
service::wifi::settings::setEnableOnBoot(is_on);
|
||||
// Dispatch it, so file IO doesn't block the UI
|
||||
getMainDispatcher().dispatch([is_on] {
|
||||
service::wifi::settings::setEnableOnBoot(is_on);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
#include "Tactility/app/wifimanage/WifiManagePrivate.h"
|
||||
#include "Tactility/app/wifimanage/View.h"
|
||||
#include <Tactility/app/wifimanage/WifiManagePrivate.h>
|
||||
#include <Tactility/app/wifimanage/View.h>
|
||||
|
||||
#include "Tactility/app/AppContext.h"
|
||||
#include "Tactility/app/wifiapsettings/WifiApSettings.h"
|
||||
#include "Tactility/service/loader/Loader.h"
|
||||
#include "Tactility/service/wifi/WifiSettings.h"
|
||||
#include "Tactility/lvgl/LvglSync.h"
|
||||
#include "Tactility/app/wificonnect/WifiConnect.h"
|
||||
#include <Tactility/app/AppContext.h>
|
||||
#include <Tactility/app/wifiapsettings/WifiApSettings.h>
|
||||
#include <Tactility/app/wificonnect/WifiConnect.h>
|
||||
#include <Tactility/lvgl/LvglSync.h>
|
||||
#include <Tactility/service/loader/Loader.h>
|
||||
|
||||
namespace tt::app::wifimanage {
|
||||
|
||||
#define TAG "wifi_manage"
|
||||
constexpr auto TAG = "WifiManage";
|
||||
|
||||
extern const AppManifest manifest;
|
||||
|
||||
@@ -72,20 +71,18 @@ void WifiManage::requestViewUpdate() {
|
||||
unlock();
|
||||
}
|
||||
|
||||
static void wifiManageEventCallback(const void* message, void* context) {
|
||||
auto* event = (service::wifi::Event*)message;
|
||||
auto* wifi = (WifiManage*)context;
|
||||
void WifiManage::onWifiEvent(service::wifi::WifiEvent event) {
|
||||
auto radio_state = service::wifi::getRadioState();
|
||||
TT_LOG_I(TAG, "Update with state %s", service::wifi::radioStateToString(radio_state));
|
||||
wifi->getState().setRadioState(radio_state);
|
||||
switch (event->type) {
|
||||
using enum tt::service::wifi::EventType;
|
||||
getState().setRadioState(radio_state);
|
||||
switch (event) {
|
||||
using enum service::wifi::WifiEvent;
|
||||
case ScanStarted:
|
||||
wifi->getState().setScanning(true);
|
||||
getState().setScanning(true);
|
||||
break;
|
||||
case ScanFinished:
|
||||
wifi->getState().setScanning(false);
|
||||
wifi->getState().updateApRecords();
|
||||
getState().setScanning(false);
|
||||
getState().updateApRecords();
|
||||
break;
|
||||
case RadioStateOn:
|
||||
if (!service::wifi::isScanning()) {
|
||||
@@ -96,11 +93,13 @@ static void wifiManageEventCallback(const void* message, void* context) {
|
||||
break;
|
||||
}
|
||||
|
||||
wifi->requestViewUpdate();
|
||||
requestViewUpdate();
|
||||
}
|
||||
|
||||
void WifiManage::onShow(AppContext& app, lv_obj_t* parent) {
|
||||
wifiSubscription = service::wifi::getPubsub()->subscribe(&wifiManageEventCallback, this);
|
||||
wifiSubscription = service::wifi::getPubsub()->subscribe([this](auto event) {
|
||||
onWifiEvent(event);
|
||||
});
|
||||
|
||||
// State update (it has its own locking)
|
||||
state.setRadioState(service::wifi::getRadioState());
|
||||
|
||||
@@ -21,31 +21,21 @@ bool getKeyValuePair(const std::string& input, std::string& key, std::string& va
|
||||
bool loadPropertiesFile(const std::string& filePath, std::function<void(const std::string& key, const std::string& value)> callback) {
|
||||
return file::withLock<bool>(filePath, [&filePath, &callback] {
|
||||
TT_LOG_I(TAG, "Reading properties file %s", filePath.c_str());
|
||||
const auto input = readString(filePath);
|
||||
if (input == nullptr) {
|
||||
TT_LOG_E(TAG, "Failed to read file contents of %s", filePath.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto* input_start = reinterpret_cast<const char*>(input.get());
|
||||
const std::string input_string = input_start;
|
||||
|
||||
uint16_t line_count = 0;
|
||||
// TODO: Rewrite to use file::readLines()
|
||||
string::split(input_string, "\n", [&line_count, &filePath, &callback](auto token) {
|
||||
return readLines(filePath, true, [&line_count, &filePath, &callback](const std::string& line) {
|
||||
line_count++;
|
||||
std::string key, value;
|
||||
auto trimmed_token = string::trim(token, " \t");
|
||||
if (!trimmed_token.starts_with("#")) {
|
||||
if (getKeyValuePair(token, key, value)) {
|
||||
auto trimmed_line = string::trim(line, " \t");
|
||||
if (!trimmed_line.starts_with("#")) {
|
||||
if (getKeyValuePair(trimmed_line, key, value)) {
|
||||
std::string trimmed_key = string::trim(key, " \t");
|
||||
std::string trimmed_value = string::trim(value, " \t");
|
||||
callback(trimmed_key, trimmed_value);
|
||||
} else { TT_LOG_E(TAG, "Failed to parse line %d of %s", line_count, filePath.c_str()); }
|
||||
} else {
|
||||
TT_LOG_E(TAG, "Failed to parse line %d of %s", line_count, filePath.c_str());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "Tactility/Tactility.h"
|
||||
#include "Tactility/hal/Configuration.h"
|
||||
#include "Tactility/hal/Device.h"
|
||||
#include "Tactility/hal/gps/GpsInit.h"
|
||||
@@ -10,7 +11,7 @@
|
||||
|
||||
namespace tt::hal {
|
||||
|
||||
constexpr auto* TAG = "hal";
|
||||
constexpr auto* TAG = "Hal";
|
||||
|
||||
void registerDevices(const Configuration& configuration) {
|
||||
TT_LOG_I(TAG, "Registering devices");
|
||||
@@ -62,4 +63,8 @@ void init(const Configuration& configuration) {
|
||||
kernel::publishSystemEvent(kernel::SystemEvent::BootInitHalEnd);
|
||||
}
|
||||
|
||||
const Configuration* getConfiguration() {
|
||||
return tt::getConfiguration()->hardware;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
#include <ranges>
|
||||
#include <cstring>
|
||||
#include <Tactility/TactilityHeadless.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "Tactility/TactilityHeadless.h"
|
||||
#include "Tactility/hal/uart/UartEsp.h"
|
||||
#include <Tactility/hal/uart/UartEsp.h>
|
||||
#include <esp_check.h>
|
||||
#else
|
||||
#include "Tactility/hal/uart/UartPosix.h"
|
||||
#include <Tactility/hal/uart/UartPosix.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,7 @@ struct UartEntry {
|
||||
static std::vector<UartEntry> uartEntries = {};
|
||||
static uint32_t lastUartId = uartIdNotInUse;
|
||||
|
||||
bool init(const std::vector<uart::Configuration>& configurations) {
|
||||
bool init(const std::vector<Configuration>& configurations) {
|
||||
TT_LOG_I(TAG, "Init");
|
||||
for (const auto& configuration: configurations) {
|
||||
uartEntries.push_back({
|
||||
@@ -142,7 +142,7 @@ void close(uint32_t uartId) {
|
||||
std::vector<std::string> getNames() {
|
||||
std::vector<std::string> names;
|
||||
#ifdef ESP_PLATFORM
|
||||
for (auto& config : getConfiguration()->uart) {
|
||||
for (auto& config : hal::getConfiguration()->uart) {
|
||||
names.push_back(config.name);
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include "Tactility/hal/usb/Usb.h"
|
||||
#include "Tactility/TactilityHeadless.h"
|
||||
#include "Tactility/hal/sdcard/SpiSdCardDevice.h"
|
||||
#include "Tactility/hal/usb/UsbTusb.h"
|
||||
#include <Tactility/hal/usb/Usb.h>
|
||||
#include <Tactility/hal/sdcard/SpiSdCardDevice.h>
|
||||
#include <Tactility/hal/usb/UsbTusb.h>
|
||||
|
||||
#include <Tactility/Log.h>
|
||||
|
||||
namespace tt::hal::usb {
|
||||
|
||||
#define TAG "usb"
|
||||
|
||||
#define BOOT_FLAG 42
|
||||
constexpr auto* TAG = "usb";
|
||||
constexpr auto BOOT_FLAG = 42;
|
||||
|
||||
struct BootMode {
|
||||
uint32_t flag = 0;
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <Tactility/kernel/SystemEvents.h>
|
||||
#include <Tactility/service/ServiceRegistration.h>
|
||||
#include <Tactility/settings/DisplaySettings.h>
|
||||
#include <Tactility/TactilityHeadless.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include <Tactility/lvgl/EspLvglPort.h>
|
||||
|
||||
@@ -28,9 +28,9 @@ struct StatusbarIcon {
|
||||
|
||||
struct StatusbarData {
|
||||
Mutex mutex = Mutex(Mutex::Type::Recursive);
|
||||
std::shared_ptr<PubSub> pubsub = std::make_shared<PubSub>();
|
||||
std::shared_ptr<PubSub<void*>> pubsub = std::make_shared<PubSub<void*>>();
|
||||
StatusbarIcon icons[STATUSBAR_ICON_LIMIT] = {};
|
||||
Timer* time_update_timer = new Timer(Timer::Type::Once, []() { onUpdateTime(); });
|
||||
Timer* time_update_timer = new Timer(Timer::Type::Once, [] { onUpdateTime(); });
|
||||
uint8_t time_hours = 0;
|
||||
uint8_t time_minutes = 0;
|
||||
bool time_set = false;
|
||||
@@ -44,7 +44,7 @@ typedef struct {
|
||||
lv_obj_t* time;
|
||||
lv_obj_t* icons[STATUSBAR_ICON_LIMIT];
|
||||
lv_obj_t* battery_icon;
|
||||
PubSub::SubscriptionHandle pubsub_subscription;
|
||||
PubSub<void*>::SubscriptionHandle pubsub_subscription;
|
||||
} Statusbar;
|
||||
|
||||
static bool statusbar_lock(TickType_t timeoutTicks = portMAX_DELAY) {
|
||||
@@ -108,9 +108,8 @@ static const lv_obj_class_t statusbar_class = {
|
||||
.theme_inheritable = false
|
||||
};
|
||||
|
||||
static void statusbar_pubsub_event(TT_UNUSED const void* message, void* obj) {
|
||||
TT_LOG_D(TAG, "event");
|
||||
auto* statusbar = static_cast<Statusbar*>(obj);
|
||||
static void statusbar_pubsub_event(Statusbar* statusbar) {
|
||||
TT_LOG_D(TAG, "Update event");
|
||||
if (lock(portMAX_DELAY)) {
|
||||
update_main(statusbar);
|
||||
lv_obj_invalidate(&statusbar->obj);
|
||||
@@ -133,7 +132,9 @@ static void statusbar_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
|
||||
lv_obj_remove_flag(obj, LV_OBJ_FLAG_SCROLLABLE);
|
||||
LV_TRACE_OBJ_CREATE("finished");
|
||||
auto* statusbar = (Statusbar*)obj;
|
||||
statusbar->pubsub_subscription = statusbar_data.pubsub->subscribe(&statusbar_pubsub_event, statusbar);
|
||||
statusbar->pubsub_subscription = statusbar_data.pubsub->subscribe([statusbar](auto) {
|
||||
statusbar_pubsub_event(statusbar);
|
||||
});
|
||||
|
||||
if (!statusbar_data.time_update_timer->isRunning()) {
|
||||
statusbar_data.time_update_timer->start(200 / portTICK_PERIOD_MS);
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <Tactility/service/ServiceRegistration.h>
|
||||
#include <Tactility/service/wifi/Wifi.h>
|
||||
#include <Tactility/StringUtils.h>
|
||||
#include <Tactility/TactilityHeadless.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <esp_wifi.h>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include "Tactility/service/espnow/EspNowService.h"
|
||||
#include "Tactility/TactilityHeadless.h"
|
||||
#include "Tactility/service/ServiceManifest.h"
|
||||
#include "Tactility/service/ServiceRegistration.h"
|
||||
#include "Tactility/service/espnow/EspNowWifi.h"
|
||||
#include <Tactility/Tactility.h>
|
||||
#include <Tactility/service/espnow/EspNowService.h>
|
||||
#include <Tactility/service/ServiceManifest.h>
|
||||
#include <Tactility/service/ServiceRegistration.h>
|
||||
#include <Tactility/service/espnow/EspNowWifi.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <esp_now.h>
|
||||
#include <esp_random.h>
|
||||
|
||||
@@ -208,7 +208,7 @@ void GpsService::setState(State newState) {
|
||||
lock.lock();
|
||||
state = newState;
|
||||
lock.unlock();
|
||||
statePubSub->publish(&state);
|
||||
statePubSub->publish(state);
|
||||
}
|
||||
|
||||
bool GpsService::hasCoordinates() const {
|
||||
|
||||
@@ -12,22 +12,16 @@ namespace tt::service::gui {
|
||||
|
||||
extern const ServiceManifest manifest;
|
||||
|
||||
constexpr const char* TAG = "gui";
|
||||
constexpr auto* TAG = "GuiService";
|
||||
|
||||
// region AppManifest
|
||||
|
||||
void GuiService::onLoaderMessage(const void* message, TT_UNUSED void* context) {
|
||||
auto service = findService();
|
||||
if (service == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* event = static_cast<const loader::LoaderEvent*>(message);
|
||||
if (event->type == loader::LoaderEventTypeApplicationShowing) {
|
||||
void GuiService::onLoaderEvent(loader::LoaderEvent event) {
|
||||
if (event == loader::LoaderEvent::ApplicationShowing) {
|
||||
auto app_instance = app::getCurrentAppContext();
|
||||
service->showApp(app_instance);
|
||||
} else if (event->type == loader::LoaderEventTypeApplicationHiding) {
|
||||
service->hideApp();
|
||||
showApp(app_instance);
|
||||
} else if (event == loader::LoaderEvent::ApplicationHiding) {
|
||||
hideApp();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +118,12 @@ void GuiService::onStart(TT_UNUSED ServiceContext& service) {
|
||||
4096, // Last known minimum was 2800 for launching desktop
|
||||
[]() { return guiMain(); }
|
||||
);
|
||||
loader_pubsub_subscription = loader::getPubsub()->subscribe(&onLoaderMessage, nullptr);
|
||||
|
||||
loader_pubsub_subscription = loader::getPubsub()->subscribe([this](auto event) {
|
||||
onLoaderEvent(event);
|
||||
});
|
||||
|
||||
|
||||
tt_check(lvgl::lock(1000 / portTICK_PERIOD_MS));
|
||||
keyboardGroup = lv_group_create();
|
||||
auto* screen_root = lv_screen_active();
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "Tactility/app/AppManifest.h"
|
||||
#include "Tactility/app/AppRegistration.h"
|
||||
|
||||
#include <Tactility/RtosCompat.h>
|
||||
#include <Tactility/DispatcherThread.h>
|
||||
#include <Tactility/service/ServiceManifest.h>
|
||||
#include <Tactility/service/ServiceRegistration.h>
|
||||
@@ -11,7 +10,6 @@
|
||||
#include <stack>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include <Tactility/TactilityHeadless.h>
|
||||
#include <esp_heap_caps.h>
|
||||
#include <utility>
|
||||
#else
|
||||
@@ -20,8 +18,8 @@
|
||||
|
||||
namespace tt::service::loader {
|
||||
|
||||
#define TAG "loader"
|
||||
#define LOADER_TIMEOUT (100 / portTICK_PERIOD_MS)
|
||||
constexpr auto* TAG = "Loader";
|
||||
constexpr auto LOADER_TIMEOUT = (100 / portTICK_PERIOD_MS);
|
||||
|
||||
extern const ServiceManifest manifest;
|
||||
|
||||
@@ -47,7 +45,7 @@ static const char* appStateToString(app::State state) {
|
||||
|
||||
class LoaderService final : public Service {
|
||||
|
||||
std::shared_ptr<PubSub> pubsubExternal = std::make_shared<PubSub>();
|
||||
std::shared_ptr<PubSub<LoaderEvent>> pubsubExternal = std::make_shared<PubSub<LoaderEvent>>();
|
||||
Mutex mutex = Mutex(Mutex::Type::Recursive);
|
||||
std::stack<std::shared_ptr<app::AppInstance>> appStack;
|
||||
app::LaunchId nextLaunchId = 0;
|
||||
@@ -64,13 +62,13 @@ class LoaderService final : public Service {
|
||||
|
||||
public:
|
||||
|
||||
void onStart(TT_UNUSED ServiceContext& service) final {
|
||||
void onStart(TT_UNUSED ServiceContext& service) override {
|
||||
dispatcherThread->start();
|
||||
}
|
||||
|
||||
void onStop(TT_UNUSED ServiceContext& service) final {
|
||||
void onStop(TT_UNUSED ServiceContext& service) override {
|
||||
// Send stop signal to thread and wait for thread to finish
|
||||
mutex.withLock([this]() {
|
||||
mutex.withLock([this] {
|
||||
dispatcherThread->stop();
|
||||
});
|
||||
}
|
||||
@@ -79,7 +77,7 @@ public:
|
||||
void stopApp();
|
||||
std::shared_ptr<app::AppContext> _Nullable getCurrentAppContext();
|
||||
|
||||
std::shared_ptr<PubSub> getPubsub() const { return pubsubExternal; }
|
||||
std::shared_ptr<PubSub<LoaderEvent>> getPubsub() const { return pubsubExternal; }
|
||||
};
|
||||
|
||||
std::shared_ptr<LoaderService> _Nullable optScreenshotService() {
|
||||
@@ -117,8 +115,7 @@ void LoaderService::onStartAppMessage(const std::string& id, app::LaunchId launc
|
||||
|
||||
transitionAppToState(new_app, app::State::Showing);
|
||||
|
||||
LoaderEvent event_external = { .type = LoaderEventTypeApplicationStarted };
|
||||
pubsubExternal->publish(&event_external);
|
||||
pubsubExternal->publish(LoaderEvent::ApplicationStarted);
|
||||
}
|
||||
|
||||
void LoaderService::onStopAppMessage(const std::string& id) {
|
||||
@@ -188,8 +185,7 @@ void LoaderService::onStopAppMessage(const std::string& id) {
|
||||
lock.unlock();
|
||||
// WARNING: After this point we cannot change the app states from this method directly anymore as we don't have a lock!
|
||||
|
||||
LoaderEvent event_external = { .type = LoaderEventTypeApplicationStopped };
|
||||
pubsubExternal->publish(&event_external);
|
||||
pubsubExternal->publish(LoaderEvent::ApplicationStopped);
|
||||
|
||||
if (instance_to_resume != nullptr) {
|
||||
if (result_set) {
|
||||
@@ -240,13 +236,11 @@ void LoaderService::transitionAppToState(const std::shared_ptr<app::AppInstance>
|
||||
app->getApp()->onCreate(*app);
|
||||
break;
|
||||
case Showing: {
|
||||
LoaderEvent event_showing = { .type = LoaderEventTypeApplicationShowing };
|
||||
pubsubExternal->publish(&event_showing);
|
||||
pubsubExternal->publish(LoaderEvent::ApplicationShowing);
|
||||
break;
|
||||
}
|
||||
case Hiding: {
|
||||
LoaderEvent event_hiding = { .type = LoaderEventTypeApplicationHiding };
|
||||
pubsubExternal->publish(&event_hiding);
|
||||
pubsubExternal->publish(LoaderEvent::ApplicationHiding);
|
||||
break;
|
||||
}
|
||||
case Stopped:
|
||||
@@ -307,7 +301,7 @@ std::shared_ptr<app::App> _Nullable getCurrentApp() {
|
||||
return app_context != nullptr ? app_context->getApp() : nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<PubSub> getPubsub() {
|
||||
std::shared_ptr<PubSub<LoaderEvent>> getPubsub() {
|
||||
auto service = optScreenshotService();
|
||||
assert(service);
|
||||
return service->getPubsub();
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#include "Tactility/service/ServiceContext.h"
|
||||
#include "Tactility/TactilityHeadless.h"
|
||||
#include "Tactility/service/ServiceRegistration.h"
|
||||
#include <Tactility/service/ServiceContext.h>
|
||||
#include <Tactility/service/ServiceRegistration.h>
|
||||
|
||||
#include <Tactility/Mutex.h>
|
||||
#include <Tactility/Timer.h>
|
||||
|
||||
#define TAG "sdcard_service"
|
||||
#include <Tactility/hal/sdcard/SdCardDevice.h>
|
||||
|
||||
namespace tt::service::sdcard {
|
||||
|
||||
constexpr auto* TAG = "SdcardService";
|
||||
|
||||
extern const ServiceManifest manifest;
|
||||
|
||||
class SdCardService final : public Service {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "Tactility/service/gps/GpsService.h"
|
||||
#include <Tactility/Mutex.h>
|
||||
#include <Tactility/Tactility.h>
|
||||
#include <Tactility/TactilityHeadless.h>
|
||||
#include <Tactility/Timer.h>
|
||||
#include <Tactility/service/ServiceContext.h>
|
||||
#include <Tactility/service/ServiceRegistration.h>
|
||||
@@ -14,7 +13,7 @@
|
||||
|
||||
namespace tt::service::statusbar {
|
||||
|
||||
#define TAG "statusbar_service"
|
||||
constexpr auto* TAG = "StatusbarService";
|
||||
|
||||
// SD card status
|
||||
#define STATUSBAR_ICON_SDCARD "sdcard.png"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include "Tactility/service/wifi/Wifi.h"
|
||||
|
||||
#include "Tactility/TactilityHeadless.h"
|
||||
#include "Tactility/service/ServiceContext.h"
|
||||
#include "Tactility/service/wifi/WifiGlobals.h"
|
||||
#include "Tactility/service/wifi/WifiSettings.h"
|
||||
#include "Tactility/service/wifi/WifiBootSplashInit.h"
|
||||
#include <Tactility/service/wifi/Wifi.h>
|
||||
|
||||
#include <Tactility/EventFlag.h>
|
||||
#include <Tactility/Tactility.h>
|
||||
#include <Tactility/kernel/SystemEvents.h>
|
||||
#include <Tactility/service/ServiceContext.h>
|
||||
#include <Tactility/service/wifi/WifiGlobals.h>
|
||||
#include <Tactility/service/wifi/WifiSettings.h>
|
||||
#include <Tactility/service/wifi/WifiBootSplashInit.h>
|
||||
#include <Tactility/Timer.h>
|
||||
|
||||
#include <lwip/esp_netif_net_stack.h>
|
||||
@@ -19,10 +19,10 @@
|
||||
|
||||
namespace tt::service::wifi {
|
||||
|
||||
#define TAG "wifi_service"
|
||||
#define WIFI_CONNECTED_BIT BIT0
|
||||
#define WIFI_FAIL_BIT BIT1
|
||||
#define AUTO_SCAN_INTERVAL 10000 // ms
|
||||
constexpr auto* TAG = "WifiService";
|
||||
constexpr auto WIFI_CONNECTED_BIT = BIT0;
|
||||
constexpr auto WIFI_FAIL_BIT = BIT1;
|
||||
constexpr auto AUTO_SCAN_INTERVAL = 10000; // ms
|
||||
|
||||
// Forward declarations
|
||||
class Wifi;
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
Mutex dataMutex = Mutex(Mutex::Type::Recursive);
|
||||
std::unique_ptr<Timer> autoConnectTimer;
|
||||
/** @brief The public event bus */
|
||||
std::shared_ptr<PubSub> pubsub = std::make_shared<PubSub>();
|
||||
std::shared_ptr<PubSub<WifiEvent>> pubsub = std::make_shared<PubSub<WifiEvent>>();
|
||||
// TODO: Deal with messages that come in while an action is ongoing
|
||||
// for example: when scanning and you turn off the radio, the scan should probably stop or turning off
|
||||
// the radio should disable the on/off button in the app as it is pending.
|
||||
@@ -129,7 +129,7 @@ static std::shared_ptr<Wifi> wifi_singleton;
|
||||
|
||||
// region Public functions
|
||||
|
||||
std::shared_ptr<PubSub> getPubsub() {
|
||||
std::shared_ptr<PubSub<WifiEvent>> getPubsub() {
|
||||
auto wifi = wifi_singleton;
|
||||
if (wifi == nullptr) {
|
||||
tt_crash("Service not running");
|
||||
@@ -371,11 +371,10 @@ static void scan_list_free_safely(std::shared_ptr<Wifi> wifi) {
|
||||
}
|
||||
}
|
||||
|
||||
static void publish_event_simple(std::shared_ptr<Wifi> wifi, EventType type) {
|
||||
static void publish_event(std::shared_ptr<Wifi> wifi, WifiEvent event) {
|
||||
auto lock = wifi->dataMutex.asScopedLock();
|
||||
if (lock.lock()) {
|
||||
Event turning_on_event = {.type = type};
|
||||
wifi->pubsub->publish(&turning_on_event);
|
||||
wifi->pubsub->publish(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -484,7 +483,7 @@ static void eventHandler(TT_UNUSED void* arg, esp_event_base_t event_base, int32
|
||||
break;
|
||||
}
|
||||
wifi->setRadioState(RadioState::On);
|
||||
publish_event_simple(wifi, EventType::Disconnected);
|
||||
publish_event(wifi, WifiEvent::Disconnected);
|
||||
kernel::publishSystemEvent(kernel::SystemEvent::NetworkDisconnected);
|
||||
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||
auto* event = static_cast<ip_event_got_ip_t*>(event_data);
|
||||
@@ -511,7 +510,7 @@ static void eventHandler(TT_UNUSED void* arg, esp_event_base_t event_base, int32
|
||||
esp_wifi_scan_stop();
|
||||
}
|
||||
|
||||
publish_event_simple(wifi_singleton, EventType::ScanFinished);
|
||||
publish_event(wifi_singleton, WifiEvent::ScanFinished);
|
||||
TT_LOG_I(TAG, "eventHandler: Finished scan");
|
||||
|
||||
if (copied_list && wifi_singleton->getRadioState() == RadioState::On && !wifi->pause_auto_connect) {
|
||||
@@ -537,7 +536,7 @@ static void dispatchEnable(std::shared_ptr<Wifi> wifi) {
|
||||
if (lock.lock(50 / portTICK_PERIOD_MS)) {
|
||||
TT_LOG_I(TAG, "Enabling");
|
||||
wifi->setRadioState(RadioState::OnPending);
|
||||
publish_event_simple(wifi, EventType::RadioStateOnPending);
|
||||
publish_event(wifi, WifiEvent::RadioStateOnPending);
|
||||
|
||||
if (wifi->netif != nullptr) {
|
||||
esp_netif_destroy(wifi->netif);
|
||||
@@ -554,7 +553,7 @@ static void dispatchEnable(std::shared_ptr<Wifi> wifi) {
|
||||
TT_LOG_E(TAG, "Insufficient memory");
|
||||
}
|
||||
wifi->setRadioState(RadioState::Off);
|
||||
publish_event_simple(wifi, EventType::RadioStateOff);
|
||||
publish_event(wifi, WifiEvent::RadioStateOff);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -582,7 +581,7 @@ static void dispatchEnable(std::shared_ptr<Wifi> wifi) {
|
||||
TT_LOG_E(TAG, "Wifi mode setting failed");
|
||||
wifi->setRadioState(RadioState::Off);
|
||||
esp_wifi_deinit();
|
||||
publish_event_simple(wifi, EventType::RadioStateOff);
|
||||
publish_event(wifi, WifiEvent::RadioStateOff);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -595,12 +594,12 @@ static void dispatchEnable(std::shared_ptr<Wifi> wifi) {
|
||||
wifi->setRadioState(RadioState::Off);
|
||||
esp_wifi_set_mode(WIFI_MODE_NULL);
|
||||
esp_wifi_deinit();
|
||||
publish_event_simple(wifi, EventType::RadioStateOff);
|
||||
publish_event(wifi, WifiEvent::RadioStateOff);
|
||||
return;
|
||||
}
|
||||
|
||||
wifi->setRadioState(RadioState::On);
|
||||
publish_event_simple(wifi, EventType::RadioStateOn);
|
||||
publish_event(wifi, WifiEvent::RadioStateOn);
|
||||
|
||||
wifi->pause_auto_connect = false;
|
||||
|
||||
@@ -631,7 +630,7 @@ static void dispatchDisable(std::shared_ptr<Wifi> wifi) {
|
||||
|
||||
TT_LOG_I(TAG, "Disabling");
|
||||
wifi->setRadioState(RadioState::OffPending);
|
||||
publish_event_simple(wifi, EventType::RadioStateOffPending);
|
||||
publish_event(wifi, WifiEvent::RadioStateOffPending);
|
||||
|
||||
// Free up scan list memory
|
||||
scan_list_free_safely(wifi_singleton);
|
||||
@@ -639,7 +638,7 @@ static void dispatchDisable(std::shared_ptr<Wifi> wifi) {
|
||||
if (esp_wifi_stop() != ESP_OK) {
|
||||
TT_LOG_E(TAG, "Failed to stop radio");
|
||||
wifi->setRadioState(RadioState::On);
|
||||
publish_event_simple(wifi, EventType::RadioStateOn);
|
||||
publish_event(wifi, WifiEvent::RadioStateOn);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -672,7 +671,7 @@ static void dispatchDisable(std::shared_ptr<Wifi> wifi) {
|
||||
wifi->netif = nullptr;
|
||||
wifi->setScanActive(false);
|
||||
wifi->setRadioState(RadioState::Off);
|
||||
publish_event_simple(wifi, EventType::RadioStateOff);
|
||||
publish_event(wifi, WifiEvent::RadioStateOff);
|
||||
TT_LOG_I(TAG, "Disabled");
|
||||
}
|
||||
|
||||
@@ -706,7 +705,7 @@ static void dispatchScan(std::shared_ptr<Wifi> wifi) {
|
||||
|
||||
TT_LOG_I(TAG, "Starting scan");
|
||||
wifi->setScanActive(true);
|
||||
publish_event_simple(wifi, EventType::ScanStarted);
|
||||
publish_event(wifi, WifiEvent::ScanStarted);
|
||||
}
|
||||
|
||||
static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
|
||||
@@ -740,7 +739,7 @@ static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
|
||||
|
||||
wifi->setRadioState(RadioState::ConnectionPending);
|
||||
|
||||
publish_event_simple(wifi, EventType::ConnectionPending);
|
||||
publish_event(wifi, WifiEvent::ConnectionPending);
|
||||
|
||||
wifi_config_t config;
|
||||
memset(&config, 0, sizeof(wifi_config_t));
|
||||
@@ -762,7 +761,7 @@ static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
|
||||
if (set_config_result != ESP_OK) {
|
||||
wifi->setRadioState(RadioState::On);
|
||||
TT_LOG_E(TAG, "Failed to set wifi config (%s)", esp_err_to_name(set_config_result));
|
||||
publish_event_simple(wifi, EventType::ConnectionFailed);
|
||||
publish_event(wifi, WifiEvent::ConnectionFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -771,7 +770,7 @@ static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
|
||||
if (wifi_start_result != ESP_OK) {
|
||||
wifi->setRadioState(RadioState::On);
|
||||
TT_LOG_E(TAG, "Failed to start wifi to begin connecting (%s)", esp_err_to_name(wifi_start_result));
|
||||
publish_event_simple(wifi, EventType::ConnectionFailed);
|
||||
publish_event(wifi, WifiEvent::ConnectionFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -784,7 +783,7 @@ static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
|
||||
if (bits & WIFI_CONNECTED_BIT) {
|
||||
wifi->setSecureConnection(config.sta.password[0] != 0x00U);
|
||||
wifi->setRadioState(RadioState::ConnectionActive);
|
||||
publish_event_simple(wifi, EventType::ConnectionSuccess);
|
||||
publish_event(wifi, WifiEvent::ConnectionSuccess);
|
||||
TT_LOG_I(TAG, "Connected to %s", wifi->connection_target.ssid.c_str());
|
||||
if (wifi->connection_target_remember) {
|
||||
if (!settings::save(wifi->connection_target)) {
|
||||
@@ -795,11 +794,11 @@ static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
|
||||
}
|
||||
} else if (bits & WIFI_FAIL_BIT) {
|
||||
wifi->setRadioState(RadioState::On);
|
||||
publish_event_simple(wifi, EventType::ConnectionFailed);
|
||||
publish_event(wifi, WifiEvent::ConnectionFailed);
|
||||
TT_LOG_I(TAG, "Failed to connect to %s", wifi->connection_target.ssid.c_str());
|
||||
} else {
|
||||
wifi->setRadioState(RadioState::On);
|
||||
publish_event_simple(wifi, EventType::ConnectionFailed);
|
||||
publish_event(wifi, WifiEvent::ConnectionFailed);
|
||||
TT_LOG_E(TAG, "UNEXPECTED EVENT");
|
||||
}
|
||||
|
||||
@@ -834,7 +833,7 @@ static void dispatchDisconnectButKeepActive(std::shared_ptr<Wifi> wifi) {
|
||||
// TODO: disable radio, because radio state is in limbo between off and on
|
||||
wifi->setRadioState(RadioState::Off);
|
||||
TT_LOG_E(TAG, "failed to set wifi config (%s)", esp_err_to_name(set_config_result));
|
||||
publish_event_simple(wifi, EventType::RadioStateOff);
|
||||
publish_event(wifi, WifiEvent::RadioStateOff);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -843,12 +842,12 @@ static void dispatchDisconnectButKeepActive(std::shared_ptr<Wifi> wifi) {
|
||||
// TODO: disable radio, because radio state is in limbo between off and on
|
||||
wifi->setRadioState(RadioState::Off);
|
||||
TT_LOG_E(TAG, "failed to start wifi to begin connecting (%s)", esp_err_to_name(wifi_start_result));
|
||||
publish_event_simple(wifi, EventType::RadioStateOff);
|
||||
publish_event(wifi, WifiEvent::RadioStateOff);
|
||||
return;
|
||||
}
|
||||
|
||||
wifi->setRadioState(RadioState::On);
|
||||
publish_event_simple(wifi, EventType::Disconnected);
|
||||
publish_event(wifi, WifiEvent::Disconnected);
|
||||
TT_LOG_I(TAG, "Disconnected");
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ struct Wifi {
|
||||
/** @brief Locking mechanism for modifying the Wifi instance */
|
||||
Mutex mutex = Mutex(Mutex::Type::Recursive);
|
||||
/** @brief The public event bus */
|
||||
std::shared_ptr<PubSub> pubsub = std::make_shared<PubSub>();
|
||||
std::shared_ptr<PubSub<WifiEvent>> pubsub = std::make_shared<PubSub<WifiEvent>>();
|
||||
/** @brief The internal message queue */
|
||||
bool scan_active = false;
|
||||
bool secure_connection = false;
|
||||
@@ -34,16 +34,15 @@ static Wifi* wifi = nullptr;
|
||||
|
||||
// region Static
|
||||
|
||||
static void publish_event_simple(Wifi* wifi, EventType type) {
|
||||
Event turning_on_event = { .type = type };
|
||||
wifi->pubsub->publish(&turning_on_event);
|
||||
static void publish_event(WifiEvent event) {
|
||||
wifi->pubsub->publish(event);
|
||||
}
|
||||
|
||||
// endregion Static
|
||||
|
||||
// region Public functions
|
||||
|
||||
std::shared_ptr<PubSub> getPubsub() {
|
||||
std::shared_ptr<PubSub<WifiEvent>> getPubsub() {
|
||||
assert(wifi);
|
||||
return wifi->pubsub;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
#include "Tactility/service/wifi/WifiSettings.h"
|
||||
#include "Tactility/Preferences.h"
|
||||
#include "Tactility/file/PropertiesFile.h"
|
||||
#include <Tactility/service/wifi/WifiSettings.h>
|
||||
|
||||
#include <Tactility/Log.h>
|
||||
#include <Tactility/file/File.h>
|
||||
#include <Tactility/file/PropertiesFile.h>
|
||||
#include <Tactility/Log.h>
|
||||
|
||||
namespace tt::service::wifi::settings {
|
||||
|
||||
@@ -15,6 +14,12 @@ struct WifiSettings {
|
||||
bool enableOnBoot;
|
||||
};
|
||||
|
||||
static WifiSettings cachedSettings {
|
||||
.enableOnBoot = false
|
||||
};
|
||||
|
||||
static bool cached = false;
|
||||
|
||||
static bool load(WifiSettings& settings) {
|
||||
std::map<std::string, std::string> map;
|
||||
if (!file::loadPropertiesFile(SETTINGS_FILE, map)) {
|
||||
@@ -36,19 +41,27 @@ static bool save(const WifiSettings& settings) {
|
||||
return file::savePropertiesFile(SETTINGS_FILE, map);
|
||||
}
|
||||
|
||||
WifiSettings getCachedOrLoad() {
|
||||
if (!cached) {
|
||||
if (!load(cachedSettings)) {
|
||||
TT_LOG_E(TAG, "Failed to load %s", SETTINGS_FILE);
|
||||
} else {
|
||||
cached = true;
|
||||
}
|
||||
}
|
||||
|
||||
return cachedSettings;
|
||||
}
|
||||
|
||||
void setEnableOnBoot(bool enable) {
|
||||
WifiSettings settings { .enableOnBoot = enable };
|
||||
if (!save(settings)) {
|
||||
cachedSettings.enableOnBoot = enable;
|
||||
if (!save(cachedSettings)) {
|
||||
TT_LOG_E(TAG, "Failed to save %s", SETTINGS_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldEnableOnBoot() {
|
||||
WifiSettings settings;
|
||||
if (!load(settings)) {
|
||||
return false;
|
||||
}
|
||||
return settings.enableOnBoot;
|
||||
return getCachedOrLoad().enableOnBoot;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
namespace tt::settings {
|
||||
|
||||
constexpr auto* TAG = "SystemSettings";
|
||||
constexpr auto* FILE_PATH = "/data/system.properties";
|
||||
constexpr auto* FILE_PATH = "/data/settings/system.properties";
|
||||
|
||||
static Mutex mutex = Mutex();
|
||||
static bool cached = false;
|
||||
static SystemSettings cachedProperties;
|
||||
static SystemSettings cachedSettings;
|
||||
|
||||
static bool loadSystemSettingsFromFile(SystemSettings& properties) {
|
||||
std::map<std::string, std::string> map;
|
||||
@@ -44,13 +44,13 @@ bool loadSystemSettings(SystemSettings& properties) {
|
||||
scoped_lock.lock();
|
||||
|
||||
if (!cached) {
|
||||
if (!loadSystemSettingsFromFile(cachedProperties)) {
|
||||
if (!loadSystemSettingsFromFile(cachedSettings)) {
|
||||
return false;
|
||||
}
|
||||
cached = true;
|
||||
}
|
||||
|
||||
properties = cachedProperties;
|
||||
properties = cachedSettings;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ bool saveSystemSettings(const SystemSettings& properties) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cachedProperties = properties;
|
||||
cachedSettings = properties;
|
||||
cached = true;
|
||||
return true;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user