mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-09-17 08:44:23 +00:00
Make Indicator WiFi setup state actionable
This commit is contained in:
@@ -45,6 +45,7 @@ enum class CompanionWiFiPowerSaveResult : uint8_t {
|
||||
// from the main loop so a button callback never tears down an active server.
|
||||
bool toggleCompanionWiFi();
|
||||
bool isCompanionWiFiEnabled();
|
||||
bool hasCompanionWiFiCredentials();
|
||||
// Display-facing station state. Arduino's cached WL status can briefly lag the
|
||||
// ESP-IDF association record, so accept either source while the AP link is
|
||||
// live. Unlike localIP(), the driver record is cleared on a real disconnect.
|
||||
@@ -55,6 +56,7 @@ enum class CompanionWiFiDisplayState : uint8_t {
|
||||
Setup,
|
||||
Off,
|
||||
Ready,
|
||||
NotConfigured,
|
||||
Connecting,
|
||||
};
|
||||
|
||||
@@ -64,6 +66,11 @@ enum class CompanionWiFiDisplayState : uint8_t {
|
||||
void noteCompanionWiFiDisplayState(CompanionWiFiDisplayState state);
|
||||
void formatCompanionWiFiDisplayStatus(char* reply, size_t reply_size);
|
||||
|
||||
// A display callback only queues this request. The main loop owns the actual
|
||||
// WebConfig/WiFi transition so touch handling never tears down network services
|
||||
// from the UI task.
|
||||
void requestCompanionWiFiSetup();
|
||||
|
||||
// Reload saved credentials after a text-terminal update. The reconnect is
|
||||
// deferred so the command reply can leave USB/TCP before WiFi is restarted.
|
||||
void scheduleCompanionWiFiCredentialReload();
|
||||
|
||||
@@ -818,6 +818,7 @@ void halt() {
|
||||
static bool companion_wifi_active = false;
|
||||
static bool companion_wifi_disable_in_progress = false;
|
||||
static bool companion_wifi_services_stopped = false;
|
||||
static volatile bool companion_wifi_setup_requested = false;
|
||||
static bool companion_wifi_credential_reload_pending = false;
|
||||
static unsigned long companion_wifi_credential_reload_at = 0;
|
||||
static bool companion_wifi_power_save_loaded = false;
|
||||
@@ -1149,6 +1150,10 @@ void halt() {
|
||||
return companion_wifi_requested;
|
||||
}
|
||||
|
||||
bool hasCompanionWiFiCredentials() {
|
||||
return companion_wifi_has_credentials;
|
||||
}
|
||||
|
||||
bool isCompanionWiFiConnected() {
|
||||
// The display describes the station link, not the lifecycle of the
|
||||
// Companion TCP services. A valid station association remains the source
|
||||
@@ -1167,7 +1172,8 @@ void halt() {
|
||||
void formatCompanionWiFiDisplayStatus(char* reply, size_t reply_size) {
|
||||
if (reply == nullptr || reply_size == 0) return;
|
||||
static const char* const names[] = {
|
||||
"not-rendered", "setup", "off", "ready", "connecting",
|
||||
"not-rendered", "setup", "off", "ready", "not-configured",
|
||||
"connecting",
|
||||
};
|
||||
uint8_t state = static_cast<uint8_t>(companion_wifi_display_state);
|
||||
if (state >= sizeof(names) / sizeof(names[0])) state = 0;
|
||||
@@ -1186,6 +1192,10 @@ void halt() {
|
||||
WiFi.localIP().toString().c_str());
|
||||
}
|
||||
|
||||
void requestCompanionWiFiSetup() {
|
||||
companion_wifi_setup_requested = true;
|
||||
}
|
||||
|
||||
bool toggleCompanionWiFi() {
|
||||
#if defined(COMPANION_EXCLUSIVE_WIFI_BLE)
|
||||
const CompanionTransportMode current = getCompanionTransportMode();
|
||||
@@ -2156,6 +2166,15 @@ void loop() {
|
||||
#if defined(ESP32) && defined(WIFI_SSID)
|
||||
#ifdef WITH_WEBCONFIG
|
||||
the_mesh.serviceWebConfig();
|
||||
if (companion_wifi_setup_requested) {
|
||||
companion_wifi_setup_requested = false;
|
||||
if (companion_wifi_requested) {
|
||||
char web_reply[160];
|
||||
if (!the_mesh.startWebConfig(true, web_reply)) {
|
||||
WIFI_DEBUG_PRINTLN("Display WiFi setup request: %s", web_reply);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
serviceCompanionWiFiCredentialReload();
|
||||
serviceCompanionWiFiState();
|
||||
|
||||
@@ -125,13 +125,16 @@ static void drawCompanionWiFiSetupPage(DisplayDriver& display) {
|
||||
setup_ssid, sizeof(setup_ssid), setup_ip, sizeof(setup_ip));
|
||||
const bool wifi_enabled = isCompanionWiFiEnabled();
|
||||
const bool wifi_connected = isCompanionWiFiConnected();
|
||||
const bool wifi_configured = hasCompanionWiFiCredentials();
|
||||
const CompanionWiFiDisplayState state = setup_active
|
||||
? CompanionWiFiDisplayState::Setup
|
||||
: !wifi_enabled
|
||||
? CompanionWiFiDisplayState::Off
|
||||
: wifi_connected
|
||||
? CompanionWiFiDisplayState::Ready
|
||||
: CompanionWiFiDisplayState::Connecting;
|
||||
: !wifi_configured
|
||||
? CompanionWiFiDisplayState::NotConfigured
|
||||
: CompanionWiFiDisplayState::Connecting;
|
||||
static CompanionWiFiDisplayState previous_state =
|
||||
CompanionWiFiDisplayState::NotRendered;
|
||||
|
||||
@@ -189,6 +192,12 @@ static void drawCompanionWiFiSetupPage(DisplayDriver& display) {
|
||||
display.drawTextEllipsized(4, 60, display.width() - 8, ssid.c_str());
|
||||
const String ip = WiFi.localIP().toString();
|
||||
display.drawTextCentered(display.width() / 2, 95, ip.c_str());
|
||||
} else if (!wifi_configured) {
|
||||
display.setTextSize(3);
|
||||
display.drawTextCentered(display.width() / 2, 45, "WIFI SETUP");
|
||||
display.setTextSize(2);
|
||||
display.setColor(UIColor::secondary_txt);
|
||||
display.drawTextCentered(display.width() / 2, 90, "TAP TO START");
|
||||
} else {
|
||||
display.setTextSize(3);
|
||||
display.drawTextCentered(display.width() / 2, 45, "WIFI");
|
||||
@@ -558,12 +567,16 @@ public:
|
||||
"tap center: inbox");
|
||||
|
||||
#ifdef WIFI_SSID
|
||||
if (isCompanionWiFiEnabled()) {
|
||||
if (!isCompanionWiFiEnabled()) {
|
||||
strcpy(tmp, "WiFi: OFF");
|
||||
} else if (isCompanionWiFiConnected()) {
|
||||
IPAddress ip = WiFi.localIP();
|
||||
snprintf(tmp, sizeof(tmp), "IP: %d.%d.%d.%d",
|
||||
ip[0], ip[1], ip[2], ip[3]);
|
||||
} else if (hasCompanionWiFiCredentials()) {
|
||||
strcpy(tmp, "WiFi: CONNECTING");
|
||||
} else {
|
||||
strcpy(tmp, "WiFi: OFF");
|
||||
strcpy(tmp, "WiFi: SETUP");
|
||||
}
|
||||
display.setTextSize(1);
|
||||
mesh::ui::drawTextCenteredEllipsized(
|
||||
@@ -607,14 +620,20 @@ public:
|
||||
mesh::ui::drawTextCenteredEllipsized(
|
||||
display, layout.pairing, layout.pairing_label_y, "TAP");
|
||||
#ifdef WIFI_SSID
|
||||
if (isCompanionWiFiEnabled()) {
|
||||
if (!isCompanionWiFiEnabled()) {
|
||||
strcpy(tmp, "OFF");
|
||||
display.setTextSize(3);
|
||||
} else if (isCompanionWiFiConnected()) {
|
||||
IPAddress ip = WiFi.localIP();
|
||||
snprintf(tmp, sizeof(tmp), "IP: %d.%d.%d.%d",
|
||||
ip[0], ip[1], ip[2], ip[3]);
|
||||
display.setTextSize(1);
|
||||
} else {
|
||||
strcpy(tmp, "OFF");
|
||||
} else if (hasCompanionWiFiCredentials()) {
|
||||
strcpy(tmp, "WAIT");
|
||||
display.setTextSize(3);
|
||||
} else {
|
||||
strcpy(tmp, "SETUP");
|
||||
display.setTextSize(2);
|
||||
}
|
||||
mesh::ui::drawTextCenteredEllipsized(
|
||||
display, layout.pairing, layout.pairing_value_y, tmp);
|
||||
@@ -677,12 +696,16 @@ public:
|
||||
#endif
|
||||
|
||||
#ifdef WIFI_SSID
|
||||
if (isCompanionWiFiEnabled()) {
|
||||
if (!isCompanionWiFiEnabled()) {
|
||||
strcpy(tmp, "WiFi: OFF");
|
||||
} else if (isCompanionWiFiConnected()) {
|
||||
IPAddress ip = WiFi.localIP();
|
||||
snprintf(tmp, sizeof(tmp), "IP: %d.%d.%d.%d",
|
||||
ip[0], ip[1], ip[2], ip[3]);
|
||||
} else if (hasCompanionWiFiCredentials()) {
|
||||
strcpy(tmp, "WiFi: CONNECTING");
|
||||
} else {
|
||||
strcpy(tmp, "WiFi: OFF");
|
||||
strcpy(tmp, "WiFi: SETUP");
|
||||
}
|
||||
display.setTextSize(1);
|
||||
display.drawTextCentered(display.width() / 2, 54, tmp);
|
||||
@@ -1026,6 +1049,16 @@ public:
|
||||
_task->showMessages();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#if UI_WIFI_SETUP_HOME_PAGE == 1
|
||||
if (c == KEY_ENTER && _page == HomePage::WIFI_SETUP) {
|
||||
if (isCompanionWiFiEnabled() && !isCompanionWiFiConnected()
|
||||
&& !WebConfigServer::getSetupInfo(nullptr, 0, nullptr, 0)) {
|
||||
requestCompanionWiFiSetup();
|
||||
_task->showAlert("Starting WiFi setup", 1000);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
if (c == KEY_ENTER && _page == HomePage::ADVERT) {
|
||||
_task->notify(UIEventType::ack);
|
||||
|
||||
@@ -177,6 +177,9 @@ int main() {
|
||||
self.assertIn("if (_page == HomePage::WIFI_SETUP) return 1000;", ui)
|
||||
self.assertIn("wifi_setup_active && !_wifi_setup_was_active", ui)
|
||||
self.assertIn("isCompanionWiFiConnected()", page)
|
||||
self.assertIn("hasCompanionWiFiCredentials()", page)
|
||||
self.assertIn("CompanionWiFiDisplayState::NotConfigured", page)
|
||||
self.assertIn('"TAP TO START"', page)
|
||||
self.assertIn("wifi_connected != _wifi_was_connected", ui)
|
||||
self.assertIn("CompanionWiFiDisplayState::Ready", page)
|
||||
self.assertIn("display.clear()", page)
|
||||
@@ -191,6 +194,9 @@ int main() {
|
||||
mesh = (ROOT / "examples/companion_radio/MyMesh.cpp").read_text()
|
||||
self.assertIn('strcmp(command, "get display.wifi")', mesh)
|
||||
self.assertIn("_task->gotoHomeScreen();", ui)
|
||||
self.assertIn("requestCompanionWiFiSetup();", ui)
|
||||
self.assertIn('strcpy(tmp, "WiFi: SETUP");', ui)
|
||||
self.assertIn('strcpy(tmp, "SETUP");', ui)
|
||||
|
||||
main = MAIN.read_text(encoding="utf-8")
|
||||
loop = main[main.index("\nvoid loop()") :]
|
||||
@@ -199,6 +205,8 @@ int main() {
|
||||
self.assertIn("&& UI_WIFI_SETUP_HOME_PAGE != 1", display_dispatch)
|
||||
self.assertIn("renderCompanionSetupDisplay();", display_dispatch)
|
||||
self.assertIn("#else\n ui_task.loop();", display_dispatch)
|
||||
self.assertIn('"not-configured"', main)
|
||||
self.assertIn("companion_wifi_setup_requested", loop)
|
||||
|
||||
def test_wifi_qr_payload_is_standard_and_escaped(self):
|
||||
setup = WIFI_QR_PAYLOAD.read_text(encoding="utf-8")
|
||||
|
||||
Reference in New Issue
Block a user