ESP-NOW bridge for P4 (#573)

This commit is contained in:
Shadowtrance
2026-07-19 17:23:20 +10:00
committed by GitHub
parent bd30aa046a
commit 2d768ef3a1
40 changed files with 1343 additions and 182 deletions
+29 -5
View File
@@ -17,8 +17,10 @@
#include <tactility/device.h>
#include <tactility/drivers/wifi.h>
#include <tactility/log.h>
#include <tactility/wifi_auto_scan.h>
#include <algorithm>
#include <atomic>
namespace tt::service::wifi {
@@ -63,7 +65,14 @@ struct WifiServiceState {
std::shared_ptr<PubSub<WifiEvent>> pubsub = std::make_shared<PubSub<WifiEvent>>();
RecursiveMutex mutex;
bool secureConnection = false;
// Internal: set by connect()/disconnect() while a manual attempt is in flight, cleared on
// connection success/failure. Distinct from externalScanPause below - the two must not
// clobber each other, otherwise a caller's explicit pause (e.g. AutoScanPauseGuard during a
// co-processor OTA) can be silently cleared by an unrelated connect/disconnect finishing.
bool pauseAutoConnect = false;
// External: only setAutoScanPaused() may set/clear this. Read alongside pauseAutoConnect to
// gate scan scheduling (both must be false to scan).
std::atomic<bool> externalScanPause{false};
bool connectionTargetRemember = false;
settings::WifiApSettings connectionTarget;
uint16_t scanRecordLimit = TT_WIFI_SCAN_RECORD_LIMIT;
@@ -224,11 +233,12 @@ bool findAutoConnectAp(settings::WifiApSettings& out) {
void dispatchAutoConnect() {
LOG_I(TAG, "dispatchAutoConnect()");
if (state.pauseAutoConnect) {
if (state.pauseAutoConnect || state.externalScanPause.load()) {
// A manual disconnect() or an in-progress manual connect() has paused
// auto-connect. This is called on every SCAN_FINISHED, not just the
// auto-connect timer's own scans (e.g. WifiManage re-scans on show),
// so it must honor the pause instead of reconnecting unconditionally.
// auto-connect, or a caller (e.g. AutoScanPauseGuard) has externally paused it.
// This is called on every SCAN_FINISHED, not just the auto-connect timer's own
// scans (e.g. WifiManage re-scans on show), so it must honor the pause instead of
// reconnecting unconditionally.
return;
}
RadioState radio_state = getRadioState();
@@ -249,7 +259,8 @@ void dispatchAutoConnect() {
}
bool shouldScanForAutoConnect() {
bool radio_scannable = getRadioState() == RadioState::On && !isScanning() && !state.pauseAutoConnect;
bool radio_scannable = getRadioState() == RadioState::On && !isScanning() &&
!state.pauseAutoConnect && !state.externalScanPause.load();
if (!radio_scannable) return false;
TickType_t current_time = kernel::getTicks();
@@ -328,6 +339,11 @@ void onWifiDeviceEvent(Device* /*device*/, void* /*context*/, ::WifiEvent event)
publish(event);
}
void autoScanSetPaused(bool paused) {
LOG_I(TAG, "autoScanSetPaused(%d)", (int)paused);
state.externalScanPause = paused;
}
} // namespace
// region Public functions
@@ -416,6 +432,10 @@ void disconnect() {
getMainDispatcher().dispatch([] { dispatchDisconnect(); });
}
void setAutoScanPaused(bool paused) {
autoScanSetPaused(paused);
}
void setScanRecords(uint16_t records) {
LOG_I(TAG, "setScanRecords(%u)", records);
if (!started) return;
@@ -479,6 +499,8 @@ public:
bool onStart(ServiceContext& /*service*/) override {
check(!started);
wifi_auto_scan_set_paused_function(autoScanSetPaused);
state.device = wifi_find_first_registered_device();
if (state.device == nullptr) {
LOG_W(TAG, "No WiFi device found");
@@ -515,6 +537,8 @@ public:
state.secureConnection = false;
state.pauseAutoConnect = false;
state.device = nullptr;
wifi_auto_scan_set_paused_function(nullptr);
}
};