use crate::dbus_api::configs::dhcp4::Dhcp4Client;
use crate::dbus_api::configs::dhcp6::Dhcp6Client;
use crate::dbus_api::configs::ipv4::Ipv4Client;
use crate::dbus_api::configs::ipv6::Ipv6Client;
use crate::dbus_api::devices::Device;
use crate::dbus_api::{ActivationStateFlags, ActiveConnectionState};
use std::io::{Error, ErrorKind};
use std::sync::Arc;
use zbus::proxy::CacheProperties;
use zbus::zvariant::OwnedObjectPath;
use zbus::{Connection, Result as ZResult, proxy};
#[proxy(
interface = "org.freedesktop.NetworkManager.Connection.Active",
default_service = "org.freedesktop.NetworkManager"
)]
pub trait Connection {
#[zbus(property)]
fn connection(&self) -> ZResult<OwnedObjectPath>;
#[zbus(property)]
fn specific_object(&self) -> ZResult<OwnedObjectPath>;
#[zbus(property)]
fn id(&self) -> ZResult<String>;
#[zbus(property)]
fn uuid(&self) -> ZResult<String>;
#[zbus(property)]
fn type_(&self) -> ZResult<String>;
#[zbus(property)]
fn devices(&self) -> ZResult<Vec<OwnedObjectPath>>;
#[zbus(property)]
fn state(&self) -> ZResult<u32>;
#[zbus(property)]
fn state_flags(&self) -> ZResult<u32>;
#[zbus(property)]
fn default(&self) -> ZResult<bool>;
#[zbus(property)]
fn ip4_config(&self) -> ZResult<OwnedObjectPath>;
#[zbus(property)]
fn dhcp4_config(&self) -> ZResult<OwnedObjectPath>;
#[zbus(property)]
fn default6(&self) -> ZResult<bool>;
#[zbus(property)]
fn ip6_config(&self) -> ZResult<OwnedObjectPath>;
#[zbus(property)]
fn dhcp6_config(&self) -> ZResult<OwnedObjectPath>;
#[zbus(property)]
fn vpn(&self) -> ZResult<bool>;
#[zbus(property)]
fn master(&self) -> ZResult<OwnedObjectPath>;
}
pub struct ConnectionClient {
service_path: String,
proxy: ConnectionProxy<'static>,
}
impl ConnectionClient {
pub async fn new(connection: &Connection, service_path: String) -> Result<Self, Error> {
let proxy = ConnectionProxy::builder(connection)
.path(service_path.clone())
.map_err(|e| Error::new(ErrorKind::InvalidInput, e.to_string()))?
.cache_properties(CacheProperties::Yes)
.build()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
proxy
.id()
.await
.map_err(|e| Error::new(ErrorKind::NotFound, e.to_string()))?;
Ok(Self {
service_path,
proxy,
})
}
pub fn service_path(&self) -> &str {
&self.service_path
}
pub async fn connection(&self) -> Result<String, Error> {
self.proxy
.connection()
.await
.map(|path| path.to_string())
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn specific_object(&self) -> Result<String, Error> {
self.proxy
.specific_object()
.await
.map(|path| path.to_string())
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn id(&self) -> Result<String, Error> {
self.proxy
.id()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn uuid(&self) -> Result<String, Error> {
self.proxy
.uuid()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn type_(&self) -> Result<String, Error> {
self.proxy
.type_()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn devices(&self, connection: Arc<Connection>) -> Result<Vec<Device>, Error> {
let device_paths = self
.proxy
.devices()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
let mut devices = Vec::new();
for path in device_paths {
match Device::new(connection.clone(), path.to_string()).await {
Ok(device) => devices.push(device),
Err(_) => continue,
}
}
Ok(devices)
}
pub async fn state(&self) -> Result<ActiveConnectionState, Error> {
let state = self
.proxy
.state()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
Ok(ActiveConnectionState::from(state))
}
pub async fn state_flags(&self) -> Result<ActivationStateFlags, Error> {
let flags = self
.proxy
.state_flags()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
Ok(ActivationStateFlags::from(flags))
}
pub async fn default(&self) -> Result<bool, Error> {
self.proxy
.default()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn ip4_config(&self, connection: &Connection) -> Result<Ipv4Client, Error> {
let path = self
.proxy
.ip4_config()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
Ipv4Client::new(connection, path.to_string()).await
}
pub async fn dhcp4_config(&self, connection: &Connection) -> Result<Dhcp4Client, Error> {
let path = self
.proxy
.dhcp4_config()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
Dhcp4Client::new(connection, path.to_string()).await
}
pub async fn default6(&self) -> Result<bool, Error> {
self.proxy
.default6()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn ip6_config(&self, connection: &Connection) -> Result<Ipv6Client, Error> {
let path = self
.proxy
.ip6_config()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
Ipv6Client::new(connection, path.to_string()).await
}
pub async fn dhcp6_config(&self, connection: &Connection) -> Result<Dhcp6Client, Error> {
let path = self
.proxy
.dhcp6_config()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
Dhcp6Client::new(connection, path.to_string()).await
}
pub async fn vpn(&self) -> Result<bool, Error> {
self.proxy
.vpn()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn master(&self, connection: Arc<Connection>) -> Result<Device, Error> {
let path = self
.proxy
.master()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
Device::new(connection, path.to_string()).await
}
}