Various improvements (#264)
- Replace C function pointers with C++ `std::function` in `Thread`, `Timer` and `DispatcherThread` - Rename `SystemEvent`-related functions - WiFi: fix auto-connect when WiFi disconnects from bad signal - WiFi: fix auto-connect when WiFi fails to auto-connect - WiFi: implement disconnect() when tapping connected WiFi ap in WiFi management app
This commit is contained in:
committed by
GitHub
parent
d72852a6e2
commit
3f1bfee3f5
@@ -38,20 +38,9 @@ void EspNowService::onStop(ServiceContext& service) {
|
||||
// region Enable
|
||||
|
||||
void EspNowService::enable(const EspNowConfig& config) {
|
||||
auto enable_context = std::make_shared<EspNowConfig>(config);
|
||||
getMainDispatcher().dispatch(enableFromDispatcher, enable_context);
|
||||
}
|
||||
|
||||
void EspNowService::enableFromDispatcher(std::shared_ptr<void> context) {
|
||||
auto service = findService();
|
||||
if (service == nullptr) {
|
||||
TT_LOG_E(TAG, "Service not running");
|
||||
return;
|
||||
}
|
||||
|
||||
auto config = std::static_pointer_cast<EspNowConfig>(context);
|
||||
|
||||
service->enableFromDispatcher(*config);
|
||||
getMainDispatcher().dispatch([this, config]() {
|
||||
enableFromDispatcher(config);
|
||||
});
|
||||
}
|
||||
|
||||
void EspNowService::enableFromDispatcher(const EspNowConfig& config) {
|
||||
@@ -101,17 +90,9 @@ void EspNowService::enableFromDispatcher(const EspNowConfig& config) {
|
||||
// region Disable
|
||||
|
||||
void EspNowService::disable() {
|
||||
getMainDispatcher().dispatch(disableFromDispatcher, nullptr);
|
||||
}
|
||||
|
||||
void EspNowService::disableFromDispatcher(TT_UNUSED std::shared_ptr<void> context) {
|
||||
auto service = findService();
|
||||
if (service == nullptr) {
|
||||
TT_LOG_E(TAG, "Service not running");
|
||||
return;
|
||||
}
|
||||
|
||||
service->disableFromDispatcher();
|
||||
getMainDispatcher().dispatch([this]() {
|
||||
disableFromDispatcher();
|
||||
});
|
||||
}
|
||||
|
||||
void EspNowService::disableFromDispatcher() {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "Tactility/app/AppManifest.h"
|
||||
#include "Tactility/app/ManifestRegistry.h"
|
||||
#include "Tactility/service/gui/Gui.h"
|
||||
#include "Tactility/service/loader/Loader_i.h"
|
||||
|
||||
#include <Tactility/service/ServiceManifest.h>
|
||||
@@ -54,9 +53,6 @@ private:
|
||||
*/
|
||||
std::unique_ptr<DispatcherThread> dispatcherThread = std::make_unique<DispatcherThread>("loader_dispatcher", 6144); // Files app requires ~5k
|
||||
|
||||
static void onStartAppMessageCallback(std::shared_ptr<void> message);
|
||||
static void onStopAppMessageCallback(std::shared_ptr<void> message);
|
||||
|
||||
void onStartAppMessage(const std::string& id, std::shared_ptr<const Bundle> parameters);
|
||||
void onStopAppMessage(const std::string& id);
|
||||
|
||||
@@ -86,14 +82,6 @@ std::shared_ptr<LoaderService> _Nullable optScreenshotService() {
|
||||
return service::findServiceById<LoaderService>(manifest.id);
|
||||
}
|
||||
|
||||
void LoaderService::onStartAppMessageCallback(std::shared_ptr<void> message) {
|
||||
auto start_message = std::reinterpret_pointer_cast<LoaderMessageAppStart>(message);
|
||||
auto& id = start_message->id;
|
||||
auto& parameters = start_message->parameters;
|
||||
|
||||
optScreenshotService()->onStartAppMessage(id, parameters);
|
||||
}
|
||||
|
||||
void LoaderService::onStartAppMessage(const std::string& id, std::shared_ptr<const Bundle> parameters) {
|
||||
|
||||
TT_LOG_I(TAG, "Start by id %s", id.c_str());
|
||||
@@ -130,12 +118,6 @@ void LoaderService::onStartAppMessage(const std::string& id, std::shared_ptr<con
|
||||
pubsubExternal->publish(&event_external);
|
||||
}
|
||||
|
||||
void LoaderService::onStopAppMessageCallback(std::shared_ptr<void> message) {
|
||||
TT_LOG_I(TAG, "OnStopAppMessageCallback");
|
||||
auto stop_message = std::reinterpret_pointer_cast<LoaderMessageAppStop>(message);
|
||||
optScreenshotService()->onStopAppMessage(stop_message->id);
|
||||
}
|
||||
|
||||
void LoaderService::onStopAppMessage(const std::string& id) {
|
||||
|
||||
auto lock = mutex.asScopedLock();
|
||||
@@ -271,14 +253,17 @@ void LoaderService::transitionAppToState(const std::shared_ptr<app::AppInstance>
|
||||
|
||||
void LoaderService::startApp(const std::string& id, std::shared_ptr<const Bundle> parameters) {
|
||||
auto message = std::make_shared<LoaderMessageAppStart>(id, std::move(parameters));
|
||||
dispatcherThread->dispatch(onStartAppMessageCallback, message);
|
||||
dispatcherThread->dispatch([this, id, parameters]() {
|
||||
onStartAppMessage(id, parameters);
|
||||
});
|
||||
}
|
||||
|
||||
void LoaderService::stopApp() {
|
||||
TT_LOG_I(TAG, "stopApp()");
|
||||
auto id = getCurrentAppContext()->getManifest().id;
|
||||
auto message = std::make_shared<LoaderMessageAppStop>(id);
|
||||
dispatcherThread->dispatch(onStopAppMessageCallback, message);
|
||||
dispatcherThread->dispatch([this, id]() {
|
||||
onStopAppMessage(id);
|
||||
});
|
||||
TT_LOG_I(TAG, "dispatched");
|
||||
}
|
||||
|
||||
|
||||
@@ -49,17 +49,14 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
static void onUpdate(std::shared_ptr<void> context) {
|
||||
auto service = std::static_pointer_cast<SdCardService>(context);
|
||||
service->update();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void onStart(ServiceContext& serviceContext) final {
|
||||
if (hal::getConfiguration()->sdcard != nullptr) {
|
||||
auto service = findServiceById(manifest.id);
|
||||
updateTimer = std::make_unique<Timer>(Timer::Type::Periodic, onUpdate, service);
|
||||
auto service = findServiceById<SdCardService>(manifest.id);
|
||||
updateTimer = std::make_unique<Timer>(Timer::Type::Periodic, [service]() {
|
||||
service->update();
|
||||
});
|
||||
// We want to try and scan more often in case of startup or scan lock failure
|
||||
updateTimer->start(1000);
|
||||
} else {
|
||||
|
||||
@@ -223,8 +223,7 @@ private:
|
||||
updatePowerStatusIcon();
|
||||
}
|
||||
|
||||
static void onUpdate(std::shared_ptr<void> parameter) {
|
||||
auto service = std::static_pointer_cast<StatusbarService>(parameter);
|
||||
static void onUpdate(const std::shared_ptr<StatusbarService>& service) {
|
||||
service->update();
|
||||
}
|
||||
|
||||
@@ -242,11 +241,14 @@ public:
|
||||
// TODO: Make thread-safe for LVGL
|
||||
lvgl::statusbar_icon_set_visibility(wifi_icon_id, true);
|
||||
|
||||
auto service = findServiceById(manifest.id);
|
||||
auto service = findServiceById<StatusbarService>(manifest.id);
|
||||
assert(service);
|
||||
onUpdate(service);
|
||||
|
||||
updateTimer = std::make_unique<Timer>(Timer::Type::Periodic, onUpdate, service);
|
||||
updateTimer = std::make_unique<Timer>(Timer::Type::Periodic, [service]() {
|
||||
onUpdate(service);
|
||||
});
|
||||
|
||||
// We want to try and scan more often in case of startup or scan lock failure
|
||||
updateTimer->start(1000);
|
||||
}
|
||||
|
||||
@@ -25,12 +25,12 @@ namespace tt::service::wifi {
|
||||
class Wifi;
|
||||
static void scan_list_free_safely(std::shared_ptr<Wifi> wifi);
|
||||
// Methods for main thread dispatcher
|
||||
static void dispatchAutoConnect(std::shared_ptr<void> context);
|
||||
static void dispatchEnable(std::shared_ptr<void> context);
|
||||
static void dispatchDisable(std::shared_ptr<void> context);
|
||||
static void dispatchScan(std::shared_ptr<void> context);
|
||||
static void dispatchConnect(std::shared_ptr<void> context);
|
||||
static void dispatchDisconnectButKeepActive(std::shared_ptr<void> context);
|
||||
static void dispatchAutoConnect(std::shared_ptr<Wifi> wifi);
|
||||
static void dispatchEnable(std::shared_ptr<Wifi> wifi);
|
||||
static void dispatchDisable(std::shared_ptr<Wifi> wifi);
|
||||
static void dispatchScan(std::shared_ptr<Wifi> wifi);
|
||||
static void dispatchConnect(std::shared_ptr<Wifi> wifi);
|
||||
static void dispatchDisconnectButKeepActive(std::shared_ptr<Wifi> wifi);
|
||||
|
||||
class Wifi {
|
||||
|
||||
@@ -172,7 +172,7 @@ void scan() {
|
||||
return;
|
||||
}
|
||||
|
||||
getMainDispatcher().dispatch(dispatchScan, wifi);
|
||||
getMainDispatcher().dispatch([wifi]() { dispatchScan(wifi); });
|
||||
}
|
||||
|
||||
bool isScanning() {
|
||||
@@ -202,10 +202,10 @@ void connect(const settings::WifiApSettings* ap, bool remember) {
|
||||
wifi->connection_target_remember = remember;
|
||||
|
||||
if (wifi->getRadioState() == RadioState::Off) {
|
||||
getMainDispatcher().dispatch(dispatchEnable, wifi);
|
||||
getMainDispatcher().dispatch([wifi]() { dispatchEnable(wifi); });
|
||||
}
|
||||
|
||||
getMainDispatcher().dispatch(dispatchConnect, wifi);
|
||||
getMainDispatcher().dispatch([wifi]() { dispatchConnect(wifi); });
|
||||
}
|
||||
|
||||
void disconnect() {
|
||||
@@ -227,7 +227,7 @@ void disconnect() {
|
||||
};
|
||||
// Manual disconnect (e.g. via app) should stop auto-connecting until a new connection is established
|
||||
wifi->pause_auto_connect = true;
|
||||
getMainDispatcher().dispatch(dispatchDisconnectButKeepActive, wifi);
|
||||
getMainDispatcher().dispatch([wifi]() { dispatchDisconnectButKeepActive(wifi); });
|
||||
}
|
||||
|
||||
void setScanRecords(uint16_t records) {
|
||||
@@ -291,10 +291,11 @@ void setEnabled(bool enabled) {
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
getMainDispatcher().dispatch(dispatchEnable, wifi);
|
||||
getMainDispatcher().dispatch([wifi]() { dispatchEnable(wifi); });
|
||||
} else {
|
||||
getMainDispatcher().dispatch(dispatchDisable, wifi);
|
||||
getMainDispatcher().dispatch([wifi]() { dispatchDisable(wifi); });
|
||||
}
|
||||
|
||||
wifi->pause_auto_connect = false;
|
||||
wifi->last_scan_time = 0;
|
||||
}
|
||||
@@ -405,8 +406,7 @@ static bool copy_scan_list(std::shared_ptr<Wifi> wifi) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool find_auto_connect_ap(std::shared_ptr<void> context, settings::WifiApSettings& settings) {
|
||||
auto wifi = std::static_pointer_cast<Wifi>(context);
|
||||
static bool find_auto_connect_ap(std::shared_ptr<Wifi> wifi, settings::WifiApSettings& settings) {
|
||||
auto lock = wifi->dataMutex.asScopedLock();
|
||||
|
||||
if (lock.lock(10 / portTICK_PERIOD_MS)) {
|
||||
@@ -430,14 +430,16 @@ static bool find_auto_connect_ap(std::shared_ptr<void> context, settings::WifiAp
|
||||
return false;
|
||||
}
|
||||
|
||||
static void dispatchAutoConnect(std::shared_ptr<void> context) {
|
||||
static void dispatchAutoConnect(std::shared_ptr<Wifi> wifi) {
|
||||
TT_LOG_I(TAG, "dispatchAutoConnect()");
|
||||
auto wifi = std::static_pointer_cast<Wifi>(context);
|
||||
|
||||
settings::WifiApSettings settings;
|
||||
if (find_auto_connect_ap(context, settings)) {
|
||||
if (find_auto_connect_ap(wifi, settings)) {
|
||||
TT_LOG_I(TAG, "Auto-connecting to %s", settings.ssid);
|
||||
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
|
||||
wifi->pause_auto_connect = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,8 +463,16 @@ static void eventHandler(TT_UNUSED void* arg, esp_event_base_t event_base, int32
|
||||
}
|
||||
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||
TT_LOG_I(TAG, "eventHandler: disconnected");
|
||||
if (wifi->getRadioState() == RadioState::ConnectionPending) {
|
||||
wifi->connection_wait_flags.set(WIFI_FAIL_BIT);
|
||||
switch (wifi->getRadioState()) {
|
||||
case RadioState::ConnectionPending:
|
||||
wifi->connection_wait_flags.set(WIFI_FAIL_BIT);
|
||||
break;
|
||||
case RadioState::On:
|
||||
// Ensure we can reconnect again
|
||||
wifi->pause_auto_connect = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
wifi->setRadioState(RadioState::On);
|
||||
publish_event_simple(wifi, EventType::Disconnected);
|
||||
@@ -493,14 +503,13 @@ static void eventHandler(TT_UNUSED void* arg, esp_event_base_t event_base, int32
|
||||
TT_LOG_I(TAG, "eventHandler: Finished scan");
|
||||
|
||||
if (copied_list && wifi_singleton->getRadioState() == RadioState::On && !wifi->pause_auto_connect) {
|
||||
getMainDispatcher().dispatch(dispatchAutoConnect, wifi);
|
||||
getMainDispatcher().dispatch([wifi]() { dispatchAutoConnect(wifi); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dispatchEnable(std::shared_ptr<void> context) {
|
||||
static void dispatchEnable(std::shared_ptr<Wifi> wifi) {
|
||||
TT_LOG_I(TAG, "dispatchEnable()");
|
||||
auto wifi = std::static_pointer_cast<Wifi>(context);
|
||||
|
||||
RadioState state = wifi->getRadioState();
|
||||
if (
|
||||
@@ -580,15 +589,17 @@ static void dispatchEnable(std::shared_ptr<void> context) {
|
||||
|
||||
wifi->setRadioState(RadioState::On);
|
||||
publish_event_simple(wifi, EventType::RadioStateOn);
|
||||
|
||||
wifi->pause_auto_connect = false;
|
||||
|
||||
TT_LOG_I(TAG, "Enabled");
|
||||
} else {
|
||||
TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
static void dispatchDisable(std::shared_ptr<void> context) {
|
||||
static void dispatchDisable(std::shared_ptr<Wifi> wifi) {
|
||||
TT_LOG_I(TAG, "dispatchDisable()");
|
||||
auto wifi = std::static_pointer_cast<Wifi>(context);
|
||||
auto lock = wifi->radioMutex.asScopedLock();
|
||||
|
||||
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
|
||||
@@ -653,9 +664,8 @@ static void dispatchDisable(std::shared_ptr<void> context) {
|
||||
TT_LOG_I(TAG, "Disabled");
|
||||
}
|
||||
|
||||
static void dispatchScan(std::shared_ptr<void> context) {
|
||||
static void dispatchScan(std::shared_ptr<Wifi> wifi) {
|
||||
TT_LOG_I(TAG, "dispatchScan()");
|
||||
auto wifi = std::static_pointer_cast<Wifi>(context);
|
||||
auto lock = wifi->radioMutex.asScopedLock();
|
||||
|
||||
if (!lock.lock(10 / portTICK_PERIOD_MS)) {
|
||||
@@ -687,9 +697,8 @@ static void dispatchScan(std::shared_ptr<void> context) {
|
||||
publish_event_simple(wifi, EventType::ScanStarted);
|
||||
}
|
||||
|
||||
static void dispatchConnect(std::shared_ptr<void> context) {
|
||||
static void dispatchConnect(std::shared_ptr<Wifi> wifi) {
|
||||
TT_LOG_I(TAG, "dispatchConnect()");
|
||||
auto wifi = std::static_pointer_cast<Wifi>(context);
|
||||
auto lock = wifi->radioMutex.asScopedLock();
|
||||
|
||||
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
|
||||
@@ -786,9 +795,8 @@ static void dispatchConnect(std::shared_ptr<void> context) {
|
||||
wifi_singleton->connection_wait_flags.clear(WIFI_FAIL_BIT | WIFI_CONNECTED_BIT);
|
||||
}
|
||||
|
||||
static void dispatchDisconnectButKeepActive(std::shared_ptr<void> context) {
|
||||
static void dispatchDisconnectButKeepActive(std::shared_ptr<Wifi> wifi) {
|
||||
TT_LOG_I(TAG, "dispatchDisconnectButKeepActive()");
|
||||
auto wifi = std::static_pointer_cast<Wifi>(context);
|
||||
auto lock = wifi->radioMutex.asScopedLock();
|
||||
|
||||
if (!lock.lock(50 / portTICK_PERIOD_MS)) {
|
||||
@@ -836,6 +844,7 @@ static void dispatchDisconnectButKeepActive(std::shared_ptr<void> context) {
|
||||
static bool shouldScanForAutoConnect(std::shared_ptr<Wifi> wifi) {
|
||||
auto lock = wifi->dataMutex.asScopedLock();
|
||||
if (!lock.lock(100)) {
|
||||
TT_LOG_W(TAG, "Auto-connect can't lock");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -844,6 +853,7 @@ static bool shouldScanForAutoConnect(std::shared_ptr<Wifi> wifi) {
|
||||
!wifi->pause_auto_connect;
|
||||
|
||||
if (!is_radio_in_scannable_state) {
|
||||
TT_LOG_W(TAG, "Auto-connect: radio state not ok (%d, %d, %d)", (int)wifi->getRadioState(), wifi->isScanActive(), wifi->pause_auto_connect);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -851,15 +861,19 @@ static bool shouldScanForAutoConnect(std::shared_ptr<Wifi> wifi) {
|
||||
bool scan_time_has_looped = (current_time < wifi->last_scan_time);
|
||||
bool no_recent_scan = (current_time - wifi->last_scan_time) > (AUTO_SCAN_INTERVAL / portTICK_PERIOD_MS);
|
||||
|
||||
if (!scan_time_has_looped && !no_recent_scan) {
|
||||
TT_LOG_W(TAG, "Auto-connect: scan time looped = %d, no recent scan = %d", scan_time_has_looped, no_recent_scan);
|
||||
}
|
||||
|
||||
return scan_time_has_looped || no_recent_scan;
|
||||
}
|
||||
|
||||
void onAutoConnectTimer(std::shared_ptr<void> context) {
|
||||
void onAutoConnectTimer() {
|
||||
auto wifi = std::static_pointer_cast<Wifi>(wifi_singleton);
|
||||
// Automatic scanning is done so we can automatically connect to access points
|
||||
bool should_auto_scan = shouldScanForAutoConnect(wifi);
|
||||
if (should_auto_scan) {
|
||||
getMainDispatcher().dispatch(dispatchScan, wifi);
|
||||
getMainDispatcher().dispatch([wifi]() { dispatchScan(wifi); });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -871,13 +885,13 @@ public:
|
||||
assert(wifi_singleton == nullptr);
|
||||
wifi_singleton = std::make_shared<Wifi>();
|
||||
|
||||
wifi_singleton->autoConnectTimer = std::make_unique<Timer>(Timer::Type::Periodic, onAutoConnectTimer, wifi_singleton);
|
||||
wifi_singleton->autoConnectTimer = std::make_unique<Timer>(Timer::Type::Periodic, []() { onAutoConnectTimer(); });
|
||||
// We want to try and scan more often in case of startup or scan lock failure
|
||||
wifi_singleton->autoConnectTimer->start(std::min(2000, AUTO_SCAN_INTERVAL));
|
||||
|
||||
if (settings::shouldEnableOnBoot()) {
|
||||
TT_LOG_I(TAG, "Auto-enabling due to setting");
|
||||
getMainDispatcher().dispatch(dispatchEnable, wifi_singleton);
|
||||
getMainDispatcher().dispatch([]() { dispatchEnable(wifi_singleton); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user