Compare commits

...

3 Commits

Author SHA1 Message Date
Deven Ducommun 0a1dce3215 fix(daemon): drain UI channel in headless mode to prevent panic
On PinePhone (headless display), the UI update receiver was dropped
immediately, causing sends from diag.rs to fail with SendError and
panic. Spawn a task that drains the channel until shutdown.

Fixes #657

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-10 11:06:34 -07:00
KAI Maintainer 2df31300e3 fix(installer): improve error message when port 4000 is already in use
Replace .unwrap() on TcpListener::bind with .with_context() so users
see a clear message about the port conflict instead of a panic.

Fixes #906
2026-06-10 00:11:43 +02:00
Brad Warren fbd8110be9 remove another instance of outdated docs 2026-05-29 13:17:32 -07:00
3 changed files with 17 additions and 11 deletions
+11 -3
View File
@@ -7,10 +7,18 @@ use crate::config;
use crate::display::DisplayState; use crate::display::DisplayState;
pub fn update_ui( pub fn update_ui(
_task_tracker: &TaskTracker, task_tracker: &TaskTracker,
_config: &config::Config, _config: &config::Config,
_shutdown_token: CancellationToken, shutdown_token: CancellationToken,
_ui_update_rx: Receiver<DisplayState>, mut ui_update_rx: Receiver<DisplayState>,
) { ) {
info!("Headless mode, not spawning UI."); info!("Headless mode, not spawning UI.");
task_tracker.spawn(async move {
loop {
tokio::select! {
_ = shutdown_token.cancelled() => break,
_ = ui_update_rx.recv() => {}
}
}
});
} }
-6
View File
@@ -61,12 +61,6 @@ On the first detection of a crash, a diagnostic snapshot is saved to `/data/rayh
If recovery fails after 5 attempts, the status will change to **failed**. A reboot of the device will reset WiFi. If recovery fails after 5 attempts, the status will change to **failed**. A reboot of the device will reset WiFi.
You can also configure WiFi during installation:
```sh
./installer orbic --admin-password 'mypassword' --wifi-ssid 'MyNetwork' --wifi-password 'networkpass'
```
## WebDAV Upload ## WebDAV Upload
Rayhunter can automatically upload finished recordings to a WebDAV server. When a `[webdav]` section is present in `config.toml`, a background worker periodically scans the recording store and uploads any closed entry that is older than `min_age_secs`. Each eligible entry uploads two files: the raw `.qmdl` capture and its `.ndjson` analysis output. After a successful upload the entry is either marked as uploaded in the manifest (and skipped on subsequent polls), or deleted locally if `delete_on_upload = true`. With no `[webdav]` section, no upload worker runs. Rayhunter can automatically upload finished recordings to a WebDAV server. When a `[webdav]` section is present in `config.toml`, a background worker periodically scans the recording store and uploads any closed entry that is older than `min_age_secs`. Each eligible entry uploads two files: the raw `.qmdl` capture and its `.ndjson` analysis output. After a successful upload the entry is either marked as uploaded in the manifest (and skipped on subsequent polls), or deleted locally if `delete_on_upload = true`. With no `[webdav]` section, no upload worker runs.
+6 -2
View File
@@ -346,9 +346,13 @@ async fn tplink_launch_telnet_v5(admin_ip: &str) -> Result<(), Error> {
admin_ip: admin_ip.to_owned(), admin_ip: admin_ip.to_owned(),
}); });
let listener = tokio::net::TcpListener::bind("127.0.0.1:4000") let bind_addr = "127.0.0.1:4000";
let listener = tokio::net::TcpListener::bind(bind_addr)
.await .await
.unwrap(); .with_context(|| format!(
"Failed to bind to {bind_addr}. Is another process using this port?\n\
Try closing any application that might be listening on port 4000 and rerun the installer."
))?;
println!("Listening on http://{}", listener.local_addr().unwrap()); println!("Listening on http://{}", listener.local_addr().unwrap());
println!("Please open above URL in your browser and log into the router to continue."); println!("Please open above URL in your browser and log into the router to continue.");