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:
Ken Van Hoeylandt
2025-03-30 21:59:31 +02:00
committed by GitHub
parent d72852a6e2
commit 3f1bfee3f5
37 changed files with 239 additions and 322 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ private:
static int32_t bootThreadCallback(TT_UNUSED void* context) {
TickType_t start_time = kernel::getTicks();
kernel::systemEventPublish(kernel::SystemEvent::BootSplash);
kernel::publishSystemEvent(kernel::SystemEvent::BootSplash);
auto hal_display = getHalDisplay();
assert(hal_display != nullptr);
+9 -16
View File
@@ -21,7 +21,7 @@ private:
Mutex mutex;
static lv_obj_t* createGpioRowWrapper(lv_obj_t* parent);
static void onTimer(TT_UNUSED std::shared_ptr<void> context);
void onTimer();
public:
@@ -49,9 +49,9 @@ void GpioApp::updatePinStates() {
}
void GpioApp::updatePinWidgets() {
auto scoped_lvgl_lock = lvgl::getSyncLock()->scoped();
auto scoped_lvgl_lock = lvgl::getSyncLock()->asScopedLock();
auto scoped_gpio_lock = mutex.asScopedLock();
if (scoped_gpio_lock.lock() && scoped_lvgl_lock->lock(100)) {
if (scoped_gpio_lock.lock() && scoped_lvgl_lock.lock(lvgl::defaultLockTime)) {
for (int j = 0; j < GPIO_NUM_MAX; ++j) {
int level = pinStates[j];
lv_obj_t* label = lvPins[j];
@@ -79,24 +79,17 @@ lv_obj_t* GpioApp::createGpioRowWrapper(lv_obj_t* parent) {
// region Task
void GpioApp::onTimer(TT_UNUSED std::shared_ptr<void> context) {
auto appContext = getCurrentAppContext();
if (appContext->getManifest().id == manifest.id) {
auto app = std::static_pointer_cast<GpioApp>(appContext->getApp());
if (app != nullptr) {
app->updatePinStates();
app->updatePinWidgets();
}
}
void GpioApp::onTimer() {
updatePinStates();
updatePinWidgets();
}
void GpioApp::startTask() {
mutex.lock();
assert(timer == nullptr);
timer = std::make_unique<Timer>(
Timer::Type::Periodic,
&onTimer
);
timer = std::make_unique<Timer>(Timer::Type::Periodic, [this]() {
onTimer();
});
timer->start(100 / portTICK_PERIOD_MS);
mutex.unlock();
}
@@ -39,12 +39,6 @@ private:
PubSub::SubscriptionHandle serviceStateSubscription = nullptr;
std::shared_ptr<service::gps::GpsService> service;
static void onUpdateCallback(TT_UNUSED std::shared_ptr<void> context) {
auto appPtr = std::static_pointer_cast<GpsSettingsApp*>(context);
auto app = *appPtr;
app->updateViews();
}
static void onServiceStateChangedCallback(const void* data, void* context) {
auto* app = (GpsSettingsApp*)context;
app->onServiceStateChanged();
@@ -266,13 +260,13 @@ private:
if (wants_on != is_on) {
// start/stop are potentially blocking calls, so we use a dispatcher to not block the UI
if (wants_on) {
getMainDispatcher().dispatch([](auto service) {
std::static_pointer_cast<service::gps::GpsService>(service)->startReceiving();
}, service);
getMainDispatcher().dispatch([this]() {
service->startReceiving();
});
} else {
getMainDispatcher().dispatch([](auto service) {
std::static_pointer_cast<service::gps::GpsService>(service)->stopReceiving();
}, service);
getMainDispatcher().dispatch([this]() {
service->stopReceiving();
});
}
}
}
@@ -280,7 +274,9 @@ private:
public:
GpsSettingsApp() {
timer = std::make_unique<Timer>(Timer::Type::Periodic, onUpdateCallback, appReference);
timer = std::make_unique<Timer>(Timer::Type::Periodic, [this]() {
updateViews();
});
service = service::gps::findGpsService();
}
@@ -45,7 +45,7 @@ private:
static void onSelectBusCallback(lv_event_t* event);
static void onPressScanCallback(lv_event_t* event);
static void onScanTimerCallback(std::shared_ptr<void> context);
static void onScanTimerCallback();
void onSelectBus(lv_event_t* event);
void onPressScan(lv_event_t* event);
@@ -180,7 +180,7 @@ void I2cScannerApp::onPressScanCallback(lv_event_t* event) {
}
}
void I2cScannerApp::onScanTimerCallback(TT_UNUSED std::shared_ptr<void> context) {
void I2cScannerApp::onScanTimerCallback() {
auto app = optApp();
if (app != nullptr) {
app->onScanTimer();
@@ -284,10 +284,9 @@ void I2cScannerApp::startScanning() {
lv_obj_clean(scanListWidget);
scanState = ScanStateScanning;
scanTimer = std::make_unique<Timer>(
Timer::Type::Once,
onScanTimerCallback
);
scanTimer = std::make_unique<Timer>(Timer::Type::Once, [](){
onScanTimerCallback();
});
scanTimer->start(10);
mutex.unlock();
} else {
+2 -2
View File
@@ -33,7 +33,7 @@ class PowerApp : public App {
private:
Timer update_timer = Timer(Timer::Type::Periodic, &onTimer, nullptr);
Timer update_timer = Timer(Timer::Type::Periodic, []() { onTimer(); });
std::shared_ptr<hal::power::PowerDevice> power;
@@ -44,7 +44,7 @@ private:
lv_obj_t* chargeLevelLabel = nullptr;
lv_obj_t* currentLabel = nullptr;
static void onTimer(TT_UNUSED std::shared_ptr<void> context) {
static void onTimer() {
auto app = optApp();
if (app != nullptr) {
app->updateUi();
+5 -10
View File
@@ -72,15 +72,10 @@ static void onModeSetCallback(TT_UNUSED lv_event_t* event) {
}
}
static void onTimerCallback(TT_UNUSED std::shared_ptr<void> context) {
auto app = optApp();
if (app != nullptr) {
app->onTimerTick();
}
}
ScreenshotApp::ScreenshotApp() {
updateTimer = std::make_unique<Timer>(Timer::Type::Periodic, onTimerCallback, nullptr);
updateTimer = std::make_unique<Timer>(Timer::Type::Periodic, [this]() {
onTimerTick();
});
}
ScreenshotApp::~ScreenshotApp() {
@@ -90,8 +85,8 @@ ScreenshotApp::~ScreenshotApp() {
}
void ScreenshotApp::onTimerTick() {
auto lvgl_lock = lvgl::getSyncLock()->scoped();
if (lvgl_lock->lock(50 / portTICK_PERIOD_MS)) {
auto lock = lvgl::getSyncLock()->asScopedLock();
if (lock.lock(lvgl::defaultLockTime)) {
updateScreenshotMode();
}
}
+2 -2
View File
@@ -117,7 +117,7 @@ private:
lv_obj_add_event_cb(btn, &onListItemSelectedCallback, LV_EVENT_SHORT_CLICKED, (void*)index);
}
static void updateTimerCallback(std::shared_ptr<void> context) {
static void updateTimerCallback() {
auto appContext = getCurrentAppContext();
if (appContext != nullptr && appContext->getManifest().id == manifest.id) {
auto app = std::static_pointer_cast<TimeZoneApp>(appContext->getApp());
@@ -231,7 +231,7 @@ public:
}
void onCreate(AppContext& app) override {
updateTimer = std::make_unique<Timer>(Timer::Type::Once, updateTimerCallback, nullptr);
updateTimer = std::make_unique<Timer>(Timer::Type::Once, []() { updateTimerCallback(); });
}
};
+7 -1
View File
@@ -69,7 +69,13 @@ static void connect(lv_event_t* event) {
if (ssid != nullptr) {
TT_LOG_I(TAG, "Clicked AP: %s", ssid);
auto* bindings = (Bindings*)lv_event_get_user_data(event);
bindings->onConnectSsid(ssid);
std::string connection_target = service::wifi::getConnectionTarget();
if (connection_target == ssid) {
bindings->onDisconnect();
} else {
bindings->onConnectSsid(ssid);
}
}
}
+8 -8
View File
@@ -15,19 +15,19 @@
namespace tt::hal {
void init(const Configuration& configuration) {
kernel::systemEventPublish(kernel::SystemEvent::BootInitHalBegin);
kernel::publishSystemEvent(kernel::SystemEvent::BootInitHalBegin);
kernel::systemEventPublish(kernel::SystemEvent::BootInitI2cBegin);
kernel::publishSystemEvent(kernel::SystemEvent::BootInitI2cBegin);
tt_check(i2c::init(configuration.i2c), "I2C init failed");
kernel::systemEventPublish(kernel::SystemEvent::BootInitI2cEnd);
kernel::publishSystemEvent(kernel::SystemEvent::BootInitI2cEnd);
kernel::systemEventPublish(kernel::SystemEvent::BootInitSpiBegin);
kernel::publishSystemEvent(kernel::SystemEvent::BootInitSpiBegin);
tt_check(spi::init(configuration.spi), "SPI init failed");
kernel::systemEventPublish(kernel::SystemEvent::BootInitSpiEnd);
kernel::publishSystemEvent(kernel::SystemEvent::BootInitSpiEnd);
kernel::systemEventPublish(kernel::SystemEvent::BootInitUartBegin);
kernel::publishSystemEvent(kernel::SystemEvent::BootInitUartBegin);
tt_check(uart::init(configuration.uart), "UART init failed");
kernel::systemEventPublish(kernel::SystemEvent::BootInitUartEnd);
kernel::publishSystemEvent(kernel::SystemEvent::BootInitUartEnd);
if (configuration.initBoot != nullptr) {
TT_LOG_I(TAG, "Init power");
@@ -47,7 +47,7 @@ void init(const Configuration& configuration) {
hal::registerDevice(power);
}
kernel::systemEventPublish(kernel::SystemEvent::BootInitHalEnd);
kernel::publishSystemEvent(kernel::SystemEvent::BootInitHalEnd);
}
} // namespace
+3 -7
View File
@@ -10,11 +10,6 @@ namespace tt::hal::gps {
constexpr uint32_t GPS_UART_BUFFER_SIZE = 256;
constexpr const char* TAG = "GpsDevice";
int32_t GpsDevice::threadMainStatic(void* parameter) {
auto* gps_device = (GpsDevice*)parameter;
return gps_device->threadMain();
}
int32_t GpsDevice::threadMain() {
uint8_t buffer[GPS_UART_BUFFER_SIZE];
@@ -125,8 +120,9 @@ bool GpsDevice::start() {
thread = std::make_unique<Thread>(
"gps",
4096,
threadMainStatic,
this
[this]() {
return this->threadMain();
}
);
thread->setPriority(tt::Thread::Priority::High);
thread->start();
+3 -3
View File
@@ -55,7 +55,7 @@ static const char* getEventName(SystemEvent event) {
tt_crash(); // Missing case above
}
void systemEventPublish(SystemEvent event) {
void publishSystemEvent(SystemEvent event) {
TT_LOG_I(TAG, "%s", getEventName(event));
if (mutex.lock(portMAX_DELAY)) {
@@ -69,7 +69,7 @@ void systemEventPublish(SystemEvent event) {
}
}
SystemEventSubscription systemEventAddListener(SystemEvent event, std::function<void(SystemEvent)> handler) {
SystemEventSubscription subscribeSystemEvent(SystemEvent event, OnSystemEvent handler) {
if (mutex.lock(portMAX_DELAY)) {
auto id = ++subscriptionCounter;
@@ -86,7 +86,7 @@ SystemEventSubscription systemEventAddListener(SystemEvent event, std::function<
}
}
void systemEventRemoveListener(SystemEventSubscription subscription) {
void unsubscribeSystemEvent(SystemEventSubscription subscription) {
if (mutex.lock(portMAX_DELAY)) {
std::erase_if(subscriptions, [subscription](auto& item) {
return (item.id == subscription);
+2 -2
View File
@@ -84,7 +84,7 @@ static bool initKeyboard(const std::shared_ptr<hal::display::DisplayDevice>& dis
void init(const hal::Configuration& config) {
TT_LOG_I(TAG, "Starting");
kernel::systemEventPublish(kernel::SystemEvent::BootInitLvglBegin);
kernel::publishSystemEvent(kernel::SystemEvent::BootInitLvglBegin);
#ifdef ESP_PLATFORM
if (config.lvglInit == hal::LvglInit::Default && !initEspLvglPort()) {
@@ -114,7 +114,7 @@ void init(const hal::Configuration& config) {
TT_LOG_I(TAG, "Finished");
kernel::systemEventPublish(kernel::SystemEvent::BootInitLvglEnd);
kernel::publishSystemEvent(kernel::SystemEvent::BootInitLvglEnd);
}
} // namespace
+4 -4
View File
@@ -18,7 +18,7 @@ namespace tt::lvgl {
#define TAG "statusbar"
static void onUpdateTime(TT_UNUSED std::shared_ptr<void> context);
static void onUpdateTime();
struct StatusbarIcon {
std::string image;
@@ -30,7 +30,7 @@ struct StatusbarData {
Mutex mutex = Mutex(Mutex::Type::Recursive);
std::shared_ptr<PubSub> pubsub = std::make_shared<PubSub>();
StatusbarIcon icons[STATUSBAR_ICON_LIMIT] = {};
Timer* time_update_timer = new Timer(Timer::Type::Once, onUpdateTime, nullptr);
Timer* time_update_timer = new Timer(Timer::Type::Once, []() { onUpdateTime(); });
uint8_t time_hours = 0;
uint8_t time_minutes = 0;
bool time_set = false;
@@ -70,7 +70,7 @@ static TickType_t getNextUpdateTime() {
return pdMS_TO_TICKS(seconds_to_wait * 1000U);
}
static void onUpdateTime(TT_UNUSED std::shared_ptr<void> context) {
static void onUpdateTime() {
time_t now = ::time(nullptr);
struct tm* tm_struct = localtime(&now);
@@ -137,7 +137,7 @@ static void statusbar_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj)
if (!statusbar_data.time_update_timer->isRunning()) {
statusbar_data.time_update_timer->start(50 / portTICK_PERIOD_MS);
statusbar_data.systemEventSubscription = kernel::systemEventAddListener(
statusbar_data.systemEventSubscription = kernel::subscribeSystemEvent(
kernel::SystemEvent::Time,
onNetworkConnected
);
+1 -1
View File
@@ -15,7 +15,7 @@ namespace tt::network::ntp {
static void onTimeSynced(struct timeval* tv) {
TT_LOG_I(TAG, "Time synced (%llu)", tv->tv_sec);
kernel::systemEventPublish(kernel::SystemEvent::Time);
kernel::publishSystemEvent(kernel::SystemEvent::Time);
}
void init() {
@@ -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() {
+6 -21
View File
@@ -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");
}
+4 -7
View File
@@ -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);
}
+48 -34
View File
@@ -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); });
}
}
+4 -4
View File
@@ -32,7 +32,7 @@ void setTimeZone(const std::string& name, const std::string& code) {
setenv("TZ", code.c_str(), 1);
tzset();
kernel::systemEventPublish(kernel::SystemEvent::Time);
kernel::publishSystemEvent(kernel::SystemEvent::Time);
}
std::string getTimeZoneName() {
@@ -65,7 +65,7 @@ bool isTimeFormat24Hour() {
void setTimeFormat24Hour(bool show24Hour) {
Preferences preferences(TIME_SETTINGS_NAMESPACE);
preferences.putBool(TIMEZONE_PREFERENCES_KEY_TIME24, show24Hour);
kernel::systemEventPublish(kernel::SystemEvent::Time);
kernel::publishSystemEvent(kernel::SystemEvent::Time);
}
#else
@@ -79,7 +79,7 @@ void init() {}
void setTimeZone(const std::string& name, const std::string& code) {
timeZoneName = name;
timeZoneCode = code;
kernel::systemEventPublish(kernel::SystemEvent::Time);
kernel::publishSystemEvent(kernel::SystemEvent::Time);
}
std::string getTimeZoneName() {
@@ -96,7 +96,7 @@ bool isTimeFormat24Hour() {
void setTimeFormat24Hour(bool enabled) {
show24Hour = enabled;
kernel::systemEventPublish(kernel::SystemEvent::Time);
kernel::publishSystemEvent(kernel::SystemEvent::Time);
}
#endif