Fix application crash on WiFi page
This commit is contained in:
+36
-8
@@ -3,6 +3,7 @@
|
||||
#include "provisioning.h"
|
||||
#include <SDL3/SDL.h>
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
void WiFiSetupPage::onPush(AppState& state) {
|
||||
@@ -123,6 +124,17 @@ void WiFiSetupPage::refreshNetworkState() {
|
||||
savedSsids_ = state_->network.savedNetworks();
|
||||
networks_ = state_->network.getScanResults();
|
||||
|
||||
if (inputMode_ != InputMode::Normal && !selectedSsid_.empty()) {
|
||||
// Pin the selection to the SSID while a password is being entered or a
|
||||
// connection is in progress, so list reordering (strength changes,
|
||||
// APs appearing/vanishing) cannot silently switch the target network.
|
||||
auto it = std::find_if(networks_.begin(), networks_.end(),
|
||||
[this](const radiantwave::network::NetworkInfo& n) { return n.ssid == selectedSsid_; });
|
||||
if (it != networks_.end()) {
|
||||
selectedIndex_ = static_cast<int>(std::distance(networks_.begin(), it));
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedIndex_ >= static_cast<int>(networks_.size())) {
|
||||
selectedIndex_ = std::max(0, static_cast<int>(networks_.size()) - 1);
|
||||
}
|
||||
@@ -136,7 +148,15 @@ void WiFiSetupPage::startConnectAsync(const std::string& ssid, const std::string
|
||||
statusMessage_ = "Connecting to " + ssid + "...";
|
||||
|
||||
connectFuture_ = std::async(std::launch::async, [this, ssid, password]() {
|
||||
return state_->network.connect(ssid, password);
|
||||
// Never let an exception escape the worker thread — a transient
|
||||
// D-Bus failure must surface as a graceful connection error, not a
|
||||
// crash when update() calls future.get().
|
||||
try {
|
||||
return state_->network.connect(ssid, password);
|
||||
} catch (const std::exception& e) {
|
||||
return radiantwave::network::ConnectResult{
|
||||
radiantwave::network::ConnectionState::Failed, e.what(), ""};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -158,9 +178,8 @@ void WiFiSetupPage::handleEvent(const SDL_Event& event) {
|
||||
if (state_->window) {
|
||||
SDL_StopTextInput(state_->window);
|
||||
}
|
||||
if (selectedIndex_ >= 0 && selectedIndex_ < static_cast<int>(networks_.size())) {
|
||||
std::string ssid = networks_[selectedIndex_].ssid;
|
||||
startConnectAsync(ssid, passwordInput_);
|
||||
if (!selectedSsid_.empty()) {
|
||||
startConnectAsync(selectedSsid_, passwordInput_);
|
||||
}
|
||||
} else if (event.key.key == SDLK_ESCAPE) {
|
||||
if (state_->window) {
|
||||
@@ -190,6 +209,7 @@ void WiFiSetupPage::handleEvent(const SDL_Event& event) {
|
||||
if (net.security == radiantwave::network::SecurityType::Open) {
|
||||
startConnectAsync(net.ssid, "");
|
||||
} else {
|
||||
selectedSsid_ = net.ssid;
|
||||
inputMode_ = InputMode::PasswordEntry;
|
||||
passwordInput_ = "";
|
||||
statusMessage_ = "Type password and press ENTER to submit";
|
||||
@@ -256,14 +276,22 @@ void WiFiSetupPage::update(float dt) {
|
||||
if (connectInProgress_ && connectFuture_.valid()) {
|
||||
auto status = connectFuture_.wait_for(std::chrono::milliseconds(0));
|
||||
if (status == std::future_status::ready) {
|
||||
auto result = connectFuture_.get();
|
||||
radiantwave::network::ConnectResult result;
|
||||
try {
|
||||
result = connectFuture_.get();
|
||||
} catch (const std::exception& e) {
|
||||
// Backstop: a stray exception must never reach the render
|
||||
// loop. Convert it to a visible, non-fatal connection error.
|
||||
result = radiantwave::network::ConnectResult{
|
||||
radiantwave::network::ConnectionState::Failed, e.what(), ""};
|
||||
}
|
||||
connectInProgress_ = false;
|
||||
|
||||
if (result.state == radiantwave::network::ConnectionState::Activated) {
|
||||
statusMessage_ = "Connected successfully!";
|
||||
inputMode_ = InputMode::Normal;
|
||||
} else {
|
||||
statusMessage_ = "Connection failed: " + (result.error_message.empty() ? "Authentication or signal error" : result.error_message);
|
||||
statusMessage_ = "Connection failed: " + (result.error_message.empty() ? "Incorrect password or authentication error" : result.error_message);
|
||||
inputMode_ = InputMode::Normal;
|
||||
}
|
||||
refreshNetworkState();
|
||||
@@ -427,8 +455,8 @@ void WiFiSetupPage::render(SDL_Renderer* renderer) {
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||
SDL_RenderRect(renderer, &boxRect);
|
||||
|
||||
if (selectedIndex_ >= 0 && selectedIndex_ < static_cast<int>(networks_.size())) {
|
||||
std::string promptStr = "Enter Password for " + networks_[selectedIndex_].ssid + ":";
|
||||
if (!selectedSsid_.empty()) {
|
||||
std::string promptStr = "Enter Password for " + selectedSsid_ + ":";
|
||||
passwordPromptText_.ensure(renderer, fontHeader_, promptStr, white);
|
||||
if (passwordPromptText_.texture) {
|
||||
SDL_FRect dst{boxX + 30.0f, boxY + 25.0f, passwordPromptText_.width, passwordPromptText_.height};
|
||||
|
||||
@@ -37,6 +37,7 @@ private:
|
||||
AppState* state_ = nullptr;
|
||||
InputMode inputMode_ = InputMode::Normal;
|
||||
int selectedIndex_ = 0;
|
||||
std::string selectedSsid_ = "";
|
||||
|
||||
std::string passwordInput_ = "";
|
||||
std::string statusMessage_ = "Press F5 to scan for available networks";
|
||||
|
||||
Reference in New Issue
Block a user