Fix application crash on WiFi page
This commit is contained in:
+35
-7
@@ -3,6 +3,7 @@
|
|||||||
#include "provisioning.h"
|
#include "provisioning.h"
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <exception>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
void WiFiSetupPage::onPush(AppState& state) {
|
void WiFiSetupPage::onPush(AppState& state) {
|
||||||
@@ -123,6 +124,17 @@ void WiFiSetupPage::refreshNetworkState() {
|
|||||||
savedSsids_ = state_->network.savedNetworks();
|
savedSsids_ = state_->network.savedNetworks();
|
||||||
networks_ = state_->network.getScanResults();
|
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())) {
|
if (selectedIndex_ >= static_cast<int>(networks_.size())) {
|
||||||
selectedIndex_ = std::max(0, static_cast<int>(networks_.size()) - 1);
|
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 + "...";
|
statusMessage_ = "Connecting to " + ssid + "...";
|
||||||
|
|
||||||
connectFuture_ = std::async(std::launch::async, [this, ssid, password]() {
|
connectFuture_ = std::async(std::launch::async, [this, 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);
|
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) {
|
if (state_->window) {
|
||||||
SDL_StopTextInput(state_->window);
|
SDL_StopTextInput(state_->window);
|
||||||
}
|
}
|
||||||
if (selectedIndex_ >= 0 && selectedIndex_ < static_cast<int>(networks_.size())) {
|
if (!selectedSsid_.empty()) {
|
||||||
std::string ssid = networks_[selectedIndex_].ssid;
|
startConnectAsync(selectedSsid_, passwordInput_);
|
||||||
startConnectAsync(ssid, passwordInput_);
|
|
||||||
}
|
}
|
||||||
} else if (event.key.key == SDLK_ESCAPE) {
|
} else if (event.key.key == SDLK_ESCAPE) {
|
||||||
if (state_->window) {
|
if (state_->window) {
|
||||||
@@ -190,6 +209,7 @@ void WiFiSetupPage::handleEvent(const SDL_Event& event) {
|
|||||||
if (net.security == radiantwave::network::SecurityType::Open) {
|
if (net.security == radiantwave::network::SecurityType::Open) {
|
||||||
startConnectAsync(net.ssid, "");
|
startConnectAsync(net.ssid, "");
|
||||||
} else {
|
} else {
|
||||||
|
selectedSsid_ = net.ssid;
|
||||||
inputMode_ = InputMode::PasswordEntry;
|
inputMode_ = InputMode::PasswordEntry;
|
||||||
passwordInput_ = "";
|
passwordInput_ = "";
|
||||||
statusMessage_ = "Type password and press ENTER to submit";
|
statusMessage_ = "Type password and press ENTER to submit";
|
||||||
@@ -256,14 +276,22 @@ void WiFiSetupPage::update(float dt) {
|
|||||||
if (connectInProgress_ && connectFuture_.valid()) {
|
if (connectInProgress_ && connectFuture_.valid()) {
|
||||||
auto status = connectFuture_.wait_for(std::chrono::milliseconds(0));
|
auto status = connectFuture_.wait_for(std::chrono::milliseconds(0));
|
||||||
if (status == std::future_status::ready) {
|
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;
|
connectInProgress_ = false;
|
||||||
|
|
||||||
if (result.state == radiantwave::network::ConnectionState::Activated) {
|
if (result.state == radiantwave::network::ConnectionState::Activated) {
|
||||||
statusMessage_ = "Connected successfully!";
|
statusMessage_ = "Connected successfully!";
|
||||||
inputMode_ = InputMode::Normal;
|
inputMode_ = InputMode::Normal;
|
||||||
} else {
|
} 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;
|
inputMode_ = InputMode::Normal;
|
||||||
}
|
}
|
||||||
refreshNetworkState();
|
refreshNetworkState();
|
||||||
@@ -427,8 +455,8 @@ void WiFiSetupPage::render(SDL_Renderer* renderer) {
|
|||||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||||
SDL_RenderRect(renderer, &boxRect);
|
SDL_RenderRect(renderer, &boxRect);
|
||||||
|
|
||||||
if (selectedIndex_ >= 0 && selectedIndex_ < static_cast<int>(networks_.size())) {
|
if (!selectedSsid_.empty()) {
|
||||||
std::string promptStr = "Enter Password for " + networks_[selectedIndex_].ssid + ":";
|
std::string promptStr = "Enter Password for " + selectedSsid_ + ":";
|
||||||
passwordPromptText_.ensure(renderer, fontHeader_, promptStr, white);
|
passwordPromptText_.ensure(renderer, fontHeader_, promptStr, white);
|
||||||
if (passwordPromptText_.texture) {
|
if (passwordPromptText_.texture) {
|
||||||
SDL_FRect dst{boxX + 30.0f, boxY + 25.0f, passwordPromptText_.width, passwordPromptText_.height};
|
SDL_FRect dst{boxX + 30.0f, boxY + 25.0f, passwordPromptText_.width, passwordPromptText_.height};
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ private:
|
|||||||
AppState* state_ = nullptr;
|
AppState* state_ = nullptr;
|
||||||
InputMode inputMode_ = InputMode::Normal;
|
InputMode inputMode_ = InputMode::Normal;
|
||||||
int selectedIndex_ = 0;
|
int selectedIndex_ = 0;
|
||||||
|
std::string selectedSsid_ = "";
|
||||||
|
|
||||||
std::string passwordInput_ = "";
|
std::string passwordInput_ = "";
|
||||||
std::string statusMessage_ = "Press F5 to scan for available networks";
|
std::string statusMessage_ = "Press F5 to scan for available networks";
|
||||||
|
|||||||
Reference in New Issue
Block a user