Change workflow
Some checks failed
Build Project / Build Linux (push) Failing after 6s

This commit is contained in:
jmb05
2026-11-03 01:03:48 +01:00
parent daf865423f
commit 61a4e136ed

View File

@@ -10,7 +10,9 @@ use nmrs::raw::zvariant::OwnedObjectPath;
use nmrs::{ActiveConnection, ConnectionError, NetworkEvent, NetworkManager, WifiSecurity}; use nmrs::{ActiveConnection, ConnectionError, NetworkEvent, NetworkManager, WifiSecurity};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::pin::Pin; use std::pin::Pin;
use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use tokio::sync::Mutex;
use tokio::sync::mpsc::UnboundedSender; use tokio::sync::mpsc::UnboundedSender;
use tokio::time::{Instant, Sleep}; use tokio::time::{Instant, Sleep};
@@ -109,8 +111,8 @@ pub enum NetworkState {
ConnectSuccess(String), ConnectSuccess(String),
} }
#[derive(Debug, Clone)] #[derive(Debug)]
pub struct NetworkBackendHandle { pub struct NetworkBackend {
subscribers: Vec<Sender<NetworkState>>, subscribers: Vec<Sender<NetworkState>>,
command_tx: Option<UnboundedSender<NetworkCommand>>, command_tx: Option<UnboundedSender<NetworkCommand>>,
} }
@@ -121,7 +123,7 @@ struct EventDebouncer {
sleep: Pin<Box<Sleep>>, sleep: Pin<Box<Sleep>>,
} }
impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBackendHandle { impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBackend {
fn subscribe( fn subscribe(
registrator: Sender<Sender<NetworkState>>, registrator: Sender<Sender<NetworkState>>,
) -> (Receiver<NetworkState>, UnboundedSender<NetworkCommand>) { ) -> (Receiver<NetworkState>, UnboundedSender<NetworkCommand>) {
@@ -143,6 +145,7 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
fn init(mut self, registration_rx: Receiver<Sender<NetworkState>>) { fn init(mut self, registration_rx: Receiver<Sender<NetworkState>>) {
let (command_tx, mut command_rx) = tokio::sync::mpsc::unbounded_channel::<NetworkCommand>(); let (command_tx, mut command_rx) = tokio::sync::mpsc::unbounded_channel::<NetworkCommand>();
self.command_tx = Some(command_tx); self.command_tx = Some(command_tx);
let instance = Arc::new(Mutex::new(self));
std::thread::spawn(move || { std::thread::spawn(move || {
let runtime = tokio::runtime::Builder::new_current_thread() let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all() .enable_all()
@@ -159,8 +162,8 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
}; };
std::thread::spawn({ std::thread::spawn({
let instance = instance.clone();
let nm = nm.clone(); let nm = nm.clone();
let mut instance = self.clone();
move || { move || {
let runtime = tokio::runtime::Builder::new_current_thread() let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all() .enable_all()
@@ -169,10 +172,12 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
runtime.block_on(async move { runtime.block_on(async move {
while let Ok(tx) = registration_rx.recv() { while let Ok(tx) = registration_rx.recv() {
if tx.send(NetworkState::Init(instance.command_tx.clone().unwrap())).is_ok() { let mut instance_guard = instance.lock().await;
instance.subscribers.push(tx); if tx.send(NetworkState::Init(instance_guard.command_tx.clone().unwrap())).is_ok() {
let _ = instance.send_all_networks(&nm).await; instance_guard.subscribers.push(tx);
let _ = instance.send_active_connection(&nm).await; println!("Added subscriber: {:?}", instance_guard.subscribers);
let _ = instance_guard.send_all_networks(&nm).await;
let _ = instance_guard.send_active_connection(&nm).await;
} }
} }
}); });
@@ -202,15 +207,16 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
// Run the command without stopping event processing // Run the command without stopping event processing
// while a potentially slow connection operation runs. // while a potentially slow connection operation runs.
let nm = nm.clone(); let nm = nm.clone();
let instance_clone = self.clone(); let instance = instance.clone();
tokio::spawn(async move { tokio::spawn(
async move {
match command { match command {
NetworkCommand::ToggleVpn(profile) => instance_clone.toggle_vpn(profile, &nm).await, NetworkCommand::ToggleVpn(profile) => instance.lock().await.toggle_vpn(profile, &nm).await,
NetworkCommand::Connect(ssid, auth) => { NetworkCommand::Connect(ssid, auth) => {
if let Ok(saved) = nm.list_saved_connections().await { if let Ok(saved) = nm.list_saved_connections().await {
if saved.iter().find(|c| c.id.eq(&ssid)).is_some() { if saved.iter().find(|c| c.id.eq(&ssid)).is_some() {
instance_clone.connect(&nm, ssid, WifiSecurity::Open).await; instance.lock().await.connect(&nm, ssid, WifiSecurity::Open).await;
} else { } else {
match auth { match auth {
Auth::Open => { Auth::Open => {
@@ -218,19 +224,18 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
&& let Some(ap) = networks.iter().find(|net| net.ssid.eq(&ssid)) && let Some(ap) = networks.iter().find(|net| net.ssid.eq(&ssid))
{ {
if ap.security.is_open() { if ap.security.is_open() {
instance_clone.connect(&nm, ssid, WifiSecurity::Open).await; instance.lock().await.connect(&nm, ssid, WifiSecurity::Open).await;
} else { } else {
instance_clone.publish(NetworkState::Auth(ssid, AuthType::Password)); instance.lock().await.publish(NetworkState::Auth(ssid, AuthType::Password));
} }
} }
} }
Auth::Password(password) => instance_clone.connect(&nm, ssid, WifiSecurity::WpaPsk { psk: password }).await, Auth::Password(password) => instance.lock().await.connect(&nm, ssid, WifiSecurity::WpaPsk { psk: password }).await,
} }
} }
} }
} }
}; };
let _ = nm; let _ = nm;
}); });
} }
@@ -238,7 +243,7 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
match event { match event {
Some(event_res) => { Some(event_res) => {
match event_res { match event_res {
Ok(event) => self.handle_event(&nm, event, &mut debouncer).await, Ok(event) => instance.lock().await.handle_event(&nm, event, &mut debouncer).await,
Err(err) => error!(&LOGGER, "Error: {err:?}"), Err(err) => error!(&LOGGER, "Error: {err:?}"),
} }
} }
@@ -247,7 +252,7 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
} }
_ = &mut debouncer.sleep, if debouncer.deadline.is_some() => { _ = &mut debouncer.sleep, if debouncer.deadline.is_some() => {
debouncer.deadline = None; debouncer.deadline = None;
let _ = self.send_all_networks(&nm).await; let _ = instance.lock().await.send_all_networks(&nm).await;
} }
} }
} }
@@ -256,8 +261,8 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
} }
} }
impl NetworkBackendHandle { impl NetworkBackend {
pub fn new() -> NetworkBackendHandle { pub fn new() -> NetworkBackend {
Self { Self {
subscribers: vec![], subscribers: vec![],
command_tx: None, command_tx: None,
@@ -434,44 +439,58 @@ impl NetworkBackendHandle {
async fn send_active_connection(&self, nm: &NetworkManager) { async fn send_active_connection(&self, nm: &NetworkManager) {
trace!(&LOGGER, "Sending Active Connection"); trace!(&LOGGER, "Sending Active Connection");
if let Ok(connections) = nm.list_active_connections().await { if let Ok(connections) = nm.list_active_connections().await {
let connection = if let Some(primary) = Self::primary_connection(nm).await { let Some(connection) = (if let Some(primary) = Self::primary_connection(nm).await {
connections.iter().find(|c| match c { connections
ActiveConnection::Wired(c) => c.uuid.eq(&primary), .iter()
ActiveConnection::Wifi(c) => c.uuid.eq(&primary), .find(|c| match c {
_ => false, ActiveConnection::Wired(c) => c.uuid.eq(&primary),
}) ActiveConnection::Wifi(c) => c.uuid.eq(&primary),
_ => false,
})
.cloned()
} else { } else {
connections.first() let mut iter = connections.into_iter();
}; loop {
match connection { let Some(conn) = iter.next() else {
Some(conn) => { break None;
};
match conn { match conn {
ActiveConnection::Wired(c) => { ActiveConnection::Other(_) | ActiveConnection::Vpn(_) => continue,
let info = NetworkInfo { other => {
name: c.id.clone(), break Some(other);
network_type: NetworkType::Wired,
signal: 0,
secured: None,
known: true,
};
self.publish(NetworkState::ChangeNetwork(Some(info)));
} }
ActiveConnection::Wifi(c) => {
let info = NetworkInfo {
name: c.ssid.clone(),
network_type: NetworkType::Wifi,
signal: c.strength.unwrap_or(0),
secured: None, // Not relevant here
known: true,
};
self.publish(NetworkState::ChangeNetwork(Some(info)));
}
_ => {}
} }
} }
None => { }) else {
self.publish(NetworkState::ChangeNetwork(None)); debug!(&LOGGER, "Disconnected from all Networks");
self.publish(NetworkState::ChangeNetwork(None));
return;
};
debug!(&LOGGER, "Found active connection: {connection:#?}");
match connection {
ActiveConnection::Wired(c) => {
let info = NetworkInfo {
name: c.id.clone(),
network_type: NetworkType::Wired,
signal: 0,
secured: None,
known: true,
};
debug!(&LOGGER, "Connected to wired network");
self.publish(NetworkState::ChangeNetwork(Some(info)));
} }
ActiveConnection::Wifi(c) => {
let info = NetworkInfo {
name: c.ssid.clone(),
network_type: NetworkType::Wifi,
signal: c.strength.unwrap_or(0),
secured: None, // Not relevant here
known: true,
};
debug!(&LOGGER, "Connected to wireless network");
self.publish(NetworkState::ChangeNetwork(Some(info)));
}
_ => {}
} }
} }
} }