This commit is contained in:
@@ -10,7 +10,9 @@ use nmrs::raw::zvariant::OwnedObjectPath;
|
||||
use nmrs::{ActiveConnection, ConnectionError, NetworkEvent, NetworkManager, WifiSecurity};
|
||||
use std::cmp::Ordering;
|
||||
use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::sync::mpsc::UnboundedSender;
|
||||
use tokio::time::{Instant, Sleep};
|
||||
|
||||
@@ -109,8 +111,8 @@ pub enum NetworkState {
|
||||
ConnectSuccess(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NetworkBackendHandle {
|
||||
#[derive(Debug)]
|
||||
pub struct NetworkBackend {
|
||||
subscribers: Vec<Sender<NetworkState>>,
|
||||
command_tx: Option<UnboundedSender<NetworkCommand>>,
|
||||
}
|
||||
@@ -121,7 +123,7 @@ struct EventDebouncer {
|
||||
sleep: Pin<Box<Sleep>>,
|
||||
}
|
||||
|
||||
impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBackendHandle {
|
||||
impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBackend {
|
||||
fn subscribe(
|
||||
registrator: Sender<Sender<NetworkState>>,
|
||||
) -> (Receiver<NetworkState>, UnboundedSender<NetworkCommand>) {
|
||||
@@ -143,6 +145,7 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
|
||||
fn init(mut self, registration_rx: Receiver<Sender<NetworkState>>) {
|
||||
let (command_tx, mut command_rx) = tokio::sync::mpsc::unbounded_channel::<NetworkCommand>();
|
||||
self.command_tx = Some(command_tx);
|
||||
let instance = Arc::new(Mutex::new(self));
|
||||
std::thread::spawn(move || {
|
||||
let runtime = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
@@ -159,8 +162,8 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
|
||||
};
|
||||
|
||||
std::thread::spawn({
|
||||
let instance = instance.clone();
|
||||
let nm = nm.clone();
|
||||
let mut instance = self.clone();
|
||||
move || {
|
||||
let runtime = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
@@ -169,10 +172,12 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
|
||||
|
||||
runtime.block_on(async move {
|
||||
while let Ok(tx) = registration_rx.recv() {
|
||||
if tx.send(NetworkState::Init(instance.command_tx.clone().unwrap())).is_ok() {
|
||||
instance.subscribers.push(tx);
|
||||
let _ = instance.send_all_networks(&nm).await;
|
||||
let _ = instance.send_active_connection(&nm).await;
|
||||
let mut instance_guard = instance.lock().await;
|
||||
if tx.send(NetworkState::Init(instance_guard.command_tx.clone().unwrap())).is_ok() {
|
||||
instance_guard.subscribers.push(tx);
|
||||
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
|
||||
// while a potentially slow connection operation runs.
|
||||
let nm = nm.clone();
|
||||
let instance_clone = self.clone();
|
||||
let instance = instance.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
tokio::spawn(
|
||||
async move {
|
||||
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) => {
|
||||
if let Ok(saved) = nm.list_saved_connections().await {
|
||||
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 {
|
||||
match auth {
|
||||
Auth::Open => {
|
||||
@@ -218,19 +224,18 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
|
||||
&& let Some(ap) = networks.iter().find(|net| net.ssid.eq(&ssid))
|
||||
{
|
||||
if ap.security.is_open() {
|
||||
instance_clone.connect(&nm, ssid, WifiSecurity::Open).await;
|
||||
instance.lock().await.connect(&nm, ssid, WifiSecurity::Open).await;
|
||||
} 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;
|
||||
});
|
||||
}
|
||||
@@ -238,7 +243,7 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
|
||||
match event {
|
||||
Some(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:?}"),
|
||||
}
|
||||
}
|
||||
@@ -247,7 +252,7 @@ impl BackendThread<NetworkState, UnboundedSender<NetworkCommand>> for NetworkBac
|
||||
}
|
||||
_ = &mut debouncer.sleep, if debouncer.deadline.is_some() => {
|
||||
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 {
|
||||
pub fn new() -> NetworkBackendHandle {
|
||||
impl NetworkBackend {
|
||||
pub fn new() -> NetworkBackend {
|
||||
Self {
|
||||
subscribers: vec![],
|
||||
command_tx: None,
|
||||
@@ -434,44 +439,58 @@ impl NetworkBackendHandle {
|
||||
async fn send_active_connection(&self, nm: &NetworkManager) {
|
||||
trace!(&LOGGER, "Sending Active Connection");
|
||||
if let Ok(connections) = nm.list_active_connections().await {
|
||||
let connection = if let Some(primary) = Self::primary_connection(nm).await {
|
||||
connections.iter().find(|c| match c {
|
||||
ActiveConnection::Wired(c) => c.uuid.eq(&primary),
|
||||
ActiveConnection::Wifi(c) => c.uuid.eq(&primary),
|
||||
_ => false,
|
||||
})
|
||||
let Some(connection) = (if let Some(primary) = Self::primary_connection(nm).await {
|
||||
connections
|
||||
.iter()
|
||||
.find(|c| match c {
|
||||
ActiveConnection::Wired(c) => c.uuid.eq(&primary),
|
||||
ActiveConnection::Wifi(c) => c.uuid.eq(&primary),
|
||||
_ => false,
|
||||
})
|
||||
.cloned()
|
||||
} else {
|
||||
connections.first()
|
||||
};
|
||||
match connection {
|
||||
Some(conn) => {
|
||||
let mut iter = connections.into_iter();
|
||||
loop {
|
||||
let Some(conn) = iter.next() else {
|
||||
break None;
|
||||
};
|
||||
match conn {
|
||||
ActiveConnection::Wired(c) => {
|
||||
let info = NetworkInfo {
|
||||
name: c.id.clone(),
|
||||
network_type: NetworkType::Wired,
|
||||
signal: 0,
|
||||
secured: None,
|
||||
known: true,
|
||||
};
|
||||
self.publish(NetworkState::ChangeNetwork(Some(info)));
|
||||
ActiveConnection::Other(_) | ActiveConnection::Vpn(_) => continue,
|
||||
other => {
|
||||
break Some(other);
|
||||
}
|
||||
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 => {
|
||||
self.publish(NetworkState::ChangeNetwork(None));
|
||||
}) else {
|
||||
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)));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user