use crate::dbus_api::NMConnection;
use crate::dbus_api::active_connection::ActiveConnectionClient;
use crate::dbus_api::devices::Device;
use std::collections::HashMap;
use std::io::{Error, ErrorKind};
use std::sync::Arc;
use zbus::proxy::CacheProperties;
use zbus::zvariant::{ObjectPath, OwnedObjectPath, OwnedValue, Value};
use zbus::{Connection, Result as ZResult, proxy};
#[proxy(
interface = "org.freedesktop.NetworkManager",
default_service = "org.freedesktop.NetworkManager",
default_path = "/org/freedesktop/NetworkManager"
)]
pub trait NetworkManager {
fn reload(&self, flags: u32) -> ZResult<()>;
fn get_devices(&self) -> ZResult<Vec<OwnedObjectPath>>;
fn get_all_devices(&self) -> ZResult<Vec<OwnedObjectPath>>;
fn get_device_by_ip_iface(&self, iface: &str) -> ZResult<OwnedObjectPath>;
fn activate_connection(
&self,
connection: ObjectPath<'_>,
device: ObjectPath<'_>,
specific_object: ObjectPath<'_>,
) -> ZResult<OwnedObjectPath>;
fn add_and_activate_connection(
&self,
connection: NMConnection,
device: ObjectPath<'_>,
specific_object: ObjectPath<'_>,
) -> ZResult<(OwnedObjectPath, OwnedObjectPath)>;
fn add_and_activate_connection2(
&self,
connection: NMConnection,
device: ObjectPath<'_>,
specific_object: ObjectPath<'_>,
options: HashMap<&str, Value<'_>>,
) -> ZResult<(
OwnedObjectPath,
OwnedObjectPath,
HashMap<String, OwnedValue>,
)>;
fn deactivate_connection(&self, active_connection: ObjectPath<'_>) -> ZResult<()>;
fn sleep(&self, sleep: bool) -> ZResult<()>;
fn enable(&self, enable: bool) -> ZResult<()>;
fn get_permissions(&self) -> ZResult<HashMap<String, String>>;
fn set_logging(&self, level: &str, domains: &str) -> ZResult<()>;
fn get_logging(&self) -> ZResult<(String, String)>;
fn check_connectivity(&self) -> ZResult<u32>;
fn state(&self) -> ZResult<u32>;
fn checkpoint_create(
&self,
devices: Vec<&str>,
rollback_timeout: u32,
flags: u32,
) -> ZResult<OwnedObjectPath>;
fn checkpoint_destroy(&self, checkpoint: &str) -> ZResult<()>;
fn checkpoint_rollback(&self, checkpoint: &str) -> ZResult<HashMap<String, u32>>;
fn checkpoint_adjust_rollback_timeout(&self, checkpoint: &str, add_timeout: u32)
-> ZResult<()>;
#[zbus(property)]
fn devices(&self) -> ZResult<Vec<OwnedObjectPath>>;
#[zbus(property)]
fn all_devices(&self) -> ZResult<Vec<OwnedObjectPath>>;
#[zbus(property)]
fn checkpoints(&self) -> ZResult<Vec<OwnedObjectPath>>;
#[zbus(property)]
fn networking_enabled(&self) -> ZResult<bool>;
#[zbus(property)]
fn wireless_enabled(&self) -> ZResult<bool>;
#[zbus(property)]
fn set_wireless_enabled(&self, value: bool) -> ZResult<()>;
#[zbus(property)]
fn wireless_hardware_enabled(&self) -> ZResult<bool>;
#[zbus(property)]
fn wwan_enabled(&self) -> ZResult<bool>;
#[zbus(property)]
fn set_wwan_enabled(&self, value: bool) -> ZResult<()>;
#[zbus(property)]
fn wwan_hardware_enabled(&self) -> ZResult<bool>;
#[zbus(property)]
fn wimax_enabled(&self) -> ZResult<bool>;
#[zbus(property)]
fn set_wimax_enabled(&self, value: bool) -> ZResult<()>;
#[zbus(property)]
fn wimax_hardware_enabled(&self) -> ZResult<bool>;
#[zbus(property)]
fn active_connections(&self) -> ZResult<Vec<OwnedObjectPath>>;
#[zbus(property)]
fn primary_connection(&self) -> ZResult<OwnedObjectPath>;
#[zbus(property)]
fn primary_connection_type(&self) -> ZResult<String>;
#[zbus(property)]
fn metered(&self) -> ZResult<u32>;
#[zbus(property)]
fn activating_connection(&self) -> ZResult<OwnedObjectPath>;
#[zbus(property)]
fn startup(&self) -> ZResult<bool>;
#[zbus(property)]
fn version(&self) -> ZResult<String>;
#[zbus(property)]
fn capabilities(&self) -> ZResult<Vec<u32>>;
#[zbus(property)]
fn connectivity(&self) -> ZResult<u32>;
#[zbus(property)]
fn connectivity_check_available(&self) -> ZResult<bool>;
#[zbus(property)]
fn connectivity_check_enabled(&self) -> ZResult<bool>;
#[zbus(property)]
fn set_connectivity_check_enabled(&self, value: bool) -> ZResult<()>;
#[zbus(property)]
fn connectivity_check_uri(&self) -> ZResult<String>;
#[zbus(property)]
fn global_dns_configuration(&self) -> ZResult<HashMap<String, OwnedValue>>;
#[zbus(property)]
fn set_global_dns_configuration(&self, value: HashMap<&str, Value<'_>>) -> ZResult<()>;
}
pub struct NetworkManagerClient {
connection: Arc<Connection>,
proxy: NetworkManagerProxy<'static>,
}
impl NetworkManagerClient {
pub async fn new() -> Result<Self, Error> {
let connection = Arc::new(
Connection::system()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?,
);
let proxy = NetworkManagerProxy::builder(&connection)
.cache_properties(CacheProperties::Yes)
.build()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
Ok(Self { connection, proxy })
}
pub fn connection(&self) -> Arc<Connection> {
self.connection.clone()
}
pub async fn get_devices(&self) -> Result<Vec<Device>, Error> {
let paths = self
.proxy
.get_devices()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
let mut devices = Vec::new();
for path in paths {
match Device::new(self.connection.clone(), path.to_string()).await {
Ok(device) => devices.push(device),
Err(_) => continue,
}
}
Ok(devices)
}
pub async fn get_all_devices(&self) -> Result<Vec<Device>, Error> {
let paths = self
.proxy
.get_all_devices()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
let mut devices = Vec::new();
for path in paths {
match Device::new(self.connection.clone(), path.to_string()).await {
Ok(device) => devices.push(device),
Err(_) => continue,
}
}
Ok(devices)
}
pub async fn get_device_by_ip_iface(&self, iface: &str) -> Result<Device, Error> {
let device_path = self
.proxy
.get_device_by_ip_iface(iface)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
Device::new(self.connection.clone(), device_path.to_string()).await
}
pub async fn networking_enabled(&self) -> Result<bool, Error> {
self.proxy
.networking_enabled()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn wireless_enabled(&self) -> Result<bool, Error> {
self.proxy
.wireless_enabled()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn set_wireless_enabled(&self, value: bool) -> Result<(), Error> {
self.proxy
.set_wireless_enabled(value)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn wireless_hardware_enabled(&self) -> Result<bool, Error> {
self.proxy
.wireless_hardware_enabled()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn wwan_enabled(&self) -> Result<bool, Error> {
self.proxy
.wwan_enabled()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn set_wwan_enabled(&self, value: bool) -> Result<(), Error> {
self.proxy
.set_wwan_enabled(value)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn wwan_hardware_enabled(&self) -> Result<bool, Error> {
self.proxy
.wwan_hardware_enabled()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn wimax_enabled(&self) -> Result<bool, Error> {
self.proxy
.wimax_enabled()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn set_wimax_enabled(&self, value: bool) -> Result<(), Error> {
self.proxy
.set_wimax_enabled(value)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn wimax_hardware_enabled(&self) -> Result<bool, Error> {
self.proxy
.wimax_hardware_enabled()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn startup(&self) -> Result<bool, Error> {
self.proxy
.startup()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn reload(&self, flags: u32) -> Result<(), Error> {
self.proxy
.reload(flags)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn activate_connection(
&self,
connection_path: &str,
device_path: &str,
specific_object_path: &str,
) -> Result<String, Error> {
let connection_path = ObjectPath::try_from(connection_path)
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
let device_path = ObjectPath::try_from(device_path)
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
let specific_object_path = ObjectPath::try_from(specific_object_path)
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
self.proxy
.activate_connection(connection_path, device_path, specific_object_path)
.await
.map(|path| path.to_string())
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn add_and_activate_connection(
&self,
connection: NMConnection,
device_path: &str,
specific_object_path: &str,
) -> Result<(String, String), Error> {
let device_path = ObjectPath::try_from(device_path)
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
let specific_object_path = ObjectPath::try_from(specific_object_path)
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
self.proxy
.add_and_activate_connection(connection, device_path, specific_object_path)
.await
.map(|(con_path, act_con_path)| (con_path.to_string(), act_con_path.to_string()))
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn add_and_activate_connection2(
&self,
connection: NMConnection,
device_path: &str,
specific_object_path: &str,
options: HashMap<&str, Value<'_>>,
) -> Result<(String, String, HashMap<String, OwnedValue>), Error> {
let device_path = ObjectPath::try_from(device_path)
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
let specific_object_path = ObjectPath::try_from(specific_object_path)
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
self.proxy
.add_and_activate_connection2(connection, device_path, specific_object_path, options)
.await
.map(|(con_path, act_con_path, options)| {
(con_path.to_string(), act_con_path.to_string(), options)
})
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn deactivate_connection(&self, active_connection_path: &str) -> Result<(), Error> {
let active_connection_path = ObjectPath::try_from(active_connection_path)
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
self.proxy
.deactivate_connection(active_connection_path)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn sleep(&self, sleep: bool) -> Result<(), Error> {
self.proxy
.sleep(sleep)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn enable(&self, enable: bool) -> Result<(), Error> {
self.proxy
.enable(enable)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn get_permissions(&self) -> Result<HashMap<String, String>, Error> {
self.proxy
.get_permissions()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn set_logging(&self, level: &str, domains: &str) -> Result<(), Error> {
self.proxy
.set_logging(level, domains)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn get_logging(&self) -> Result<(String, String), Error> {
self.proxy
.get_logging()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn check_connectivity(&self) -> Result<u32, Error> {
self.proxy
.check_connectivity()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn active_connections(&self) -> Result<Vec<ActiveConnectionClient>, Error> {
let paths = self
.proxy
.active_connections()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
let mut connections = Vec::new();
for path in paths {
match ActiveConnectionClient::new(self.connection.clone(), path.to_string()).await {
Ok(conn) => connections.push(conn),
Err(_) => continue,
}
}
Ok(connections)
}
pub async fn primary_connection(&self) -> Result<String, Error> {
self.proxy
.primary_connection()
.await
.map(|path| path.to_string())
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn primary_connection_type(&self) -> Result<String, Error> {
self.proxy
.primary_connection_type()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn metered(&self) -> Result<u32, Error> {
self.proxy
.metered()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn activating_connection(&self) -> Result<String, Error> {
self.proxy
.activating_connection()
.await
.map(|path| path.to_string())
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn version(&self) -> Result<String, Error> {
self.proxy
.version()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn capabilities(&self) -> Result<Vec<u32>, Error> {
self.proxy
.capabilities()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn state(&self) -> Result<u32, Error> {
self.proxy
.state()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn connectivity(&self) -> Result<u32, Error> {
self.proxy
.connectivity()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn connectivity_check_available(&self) -> Result<bool, Error> {
self.proxy
.connectivity_check_available()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn connectivity_check_enabled(&self) -> Result<bool, Error> {
self.proxy
.connectivity_check_enabled()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn set_connectivity_check_enabled(&self, value: bool) -> Result<(), Error> {
self.proxy
.set_connectivity_check_enabled(value)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn connectivity_check_uri(&self) -> Result<String, Error> {
self.proxy
.connectivity_check_uri()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn global_dns_configuration(&self) -> Result<HashMap<String, OwnedValue>, Error> {
self.proxy
.global_dns_configuration()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn set_global_dns_configuration(
&self,
value: HashMap<&str, Value<'_>>,
) -> Result<(), Error> {
self.proxy
.set_global_dns_configuration(value)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn checkpoint_create(
&self,
devices: Vec<&str>,
rollback_timeout: u32,
flags: u32,
) -> Result<String, Error> {
self.proxy
.checkpoint_create(devices, rollback_timeout, flags)
.await
.map(|path| path.to_string())
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn checkpoint_destroy(&self, checkpoint: &str) -> Result<(), Error> {
self.proxy
.checkpoint_destroy(checkpoint)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn checkpoint_rollback(
&self,
checkpoint: &str,
) -> Result<HashMap<String, u32>, Error> {
self.proxy
.checkpoint_rollback(checkpoint)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn checkpoint_adjust_rollback_timeout(
&self,
checkpoint: &str,
add_timeout: u32,
) -> Result<(), Error> {
self.proxy
.checkpoint_adjust_rollback_timeout(checkpoint, add_timeout)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
}