use tokio::sync::watch;
use zbus::Connection;
use crate::Result;
use crate::api::models::{Device, Network, NetworkInfo, WifiSecurity};
use crate::core::bluetooth::connect_bluetooth;
use crate::core::connection::{
connect, connect_wired, disconnect, forget_by_name_and_type, get_device_by_interface,
is_connected,
};
use crate::core::connection_settings::{
get_saved_connection_path, has_saved_connection, list_saved_connections,
};
use crate::core::device::{
is_connecting, list_bluetooth_devices, list_devices, set_wifi_enabled, wait_for_wifi_ready,
wifi_enabled, wifi_hardware_enabled,
};
use crate::core::scan::{current_network, list_networks, scan_networks};
use crate::core::vpn::{connect_vpn, disconnect_vpn, get_vpn_info, list_vpn_connections};
use crate::models::{
BluetoothDevice, BluetoothIdentity, VpnConnection, VpnConnectionInfo, VpnCredentials,
};
use crate::monitoring::device as device_monitor;
use crate::monitoring::info::show_details;
use crate::monitoring::network as network_monitor;
use crate::monitoring::wifi::{current_connection_info, current_ssid};
use crate::types::constants::device_type;
#[derive(Debug, Clone)]
pub struct NetworkManager {
conn: Connection,
timeout_config: crate::api::models::TimeoutConfig,
}
impl NetworkManager {
pub async fn new() -> Result<Self> {
let conn = Connection::system().await?;
Ok(Self {
conn,
timeout_config: crate::api::models::TimeoutConfig::default(),
})
}
pub async fn with_config(timeout_config: crate::api::models::TimeoutConfig) -> Result<Self> {
let conn = Connection::system().await?;
Ok(Self {
conn,
timeout_config,
})
}
#[must_use]
pub fn timeout_config(&self) -> crate::api::models::TimeoutConfig {
self.timeout_config
}
pub async fn list_devices(&self) -> Result<Vec<Device>> {
list_devices(&self.conn).await
}
pub async fn list_bluetooth_devices(&self) -> Result<Vec<BluetoothDevice>> {
list_bluetooth_devices(&self.conn).await
}
pub async fn list_wireless_devices(&self) -> Result<Vec<Device>> {
let devices = list_devices(&self.conn).await?;
Ok(devices.into_iter().filter(|d| d.is_wireless()).collect())
}
pub async fn list_wired_devices(&self) -> Result<Vec<Device>> {
let devices = list_devices(&self.conn).await?;
Ok(devices.into_iter().filter(|d| d.is_wired()).collect())
}
pub async fn list_networks(&self) -> Result<Vec<Network>> {
list_networks(&self.conn).await
}
pub async fn connect(&self, ssid: &str, creds: WifiSecurity) -> Result<()> {
connect(&self.conn, ssid, creds, Some(self.timeout_config)).await
}
pub async fn connect_wired(&self) -> Result<()> {
connect_wired(&self.conn, Some(self.timeout_config)).await
}
pub async fn connect_bluetooth(&self, name: &str, identity: &BluetoothIdentity) -> Result<()> {
connect_bluetooth(&self.conn, name, identity, Some(self.timeout_config)).await
}
pub async fn connect_vpn(&self, creds: VpnCredentials) -> Result<()> {
connect_vpn(&self.conn, creds, Some(self.timeout_config)).await
}
pub async fn disconnect_vpn(&self, name: &str) -> Result<()> {
disconnect_vpn(&self.conn, name).await
}
pub async fn list_vpn_connections(&self) -> Result<Vec<VpnConnection>> {
list_vpn_connections(&self.conn).await
}
pub async fn forget_vpn(&self, name: &str) -> Result<()> {
crate::core::vpn::forget_vpn(&self.conn, name).await
}
pub async fn get_vpn_info(&self, name: &str) -> Result<VpnConnectionInfo> {
get_vpn_info(&self.conn, name).await
}
pub async fn wifi_enabled(&self) -> Result<bool> {
wifi_enabled(&self.conn).await
}
pub async fn set_wifi_enabled(&self, value: bool) -> Result<()> {
set_wifi_enabled(&self.conn, value).await
}
pub async fn wifi_hardware_enabled(&self) -> Result<bool> {
wifi_hardware_enabled(&self.conn).await
}
pub async fn wait_for_wifi_ready(&self) -> Result<()> {
wait_for_wifi_ready(&self.conn).await
}
pub async fn scan_networks(&self) -> Result<()> {
scan_networks(&self.conn).await
}
pub async fn is_connecting(&self) -> Result<bool> {
is_connecting(&self.conn).await
}
pub async fn is_connected(&self, ssid: &str) -> Result<bool> {
is_connected(&self.conn, ssid).await
}
pub async fn disconnect(&self) -> Result<()> {
disconnect(&self.conn, Some(self.timeout_config)).await
}
pub async fn current_network(&self) -> Result<Option<Network>> {
current_network(&self.conn).await
}
pub async fn list_saved_connections(&self) -> Result<Vec<String>> {
list_saved_connections(&self.conn).await
}
pub async fn get_device_by_interface(&self, name: &str) -> Result<zvariant::OwnedObjectPath> {
get_device_by_interface(&self.conn, name).await
}
#[must_use]
pub async fn current_ssid(&self) -> Option<String> {
current_ssid(&self.conn).await
}
#[must_use]
pub async fn current_connection_info(&self) -> Option<(String, Option<u32>)> {
current_connection_info(&self.conn).await
}
pub async fn show_details(&self, net: &Network) -> Result<NetworkInfo> {
show_details(&self.conn, net).await
}
pub async fn has_saved_connection(&self, ssid: &str) -> Result<bool> {
has_saved_connection(&self.conn, ssid).await
}
pub async fn get_saved_connection_path(
&self,
ssid: &str,
) -> Result<Option<zvariant::OwnedObjectPath>> {
get_saved_connection_path(&self.conn, ssid).await
}
pub async fn forget(&self, ssid: &str) -> Result<()> {
forget_by_name_and_type(
&self.conn,
ssid,
Some(device_type::WIFI),
Some(self.timeout_config),
)
.await
}
pub async fn forget_bluetooth(&self, name: &str) -> Result<()> {
forget_by_name_and_type(
&self.conn,
name,
Some(device_type::BLUETOOTH),
Some(self.timeout_config),
)
.await
}
pub async fn monitor_network_changes<F>(&self, callback: F) -> Result<()>
where
F: Fn() + 'static,
{
let (_tx, rx) = watch::channel(());
network_monitor::monitor_network_changes(&self.conn, rx, callback).await
}
pub async fn monitor_device_changes<F>(&self, callback: F) -> Result<()>
where
F: Fn() + 'static,
{
let (_tx, rx) = watch::channel(());
device_monitor::monitor_device_changes(&self.conn, rx, callback).await
}
}