use crate::dbus_api::active_connection::ActiveConnectionClient;
use crate::dbus_api::devices::adsl::AdslClient;
use crate::dbus_api::devices::bluetooth::BluetoothClient;
use crate::dbus_api::devices::bond::BondClient;
use crate::dbus_api::devices::bridge::BridgeClient;
use crate::dbus_api::devices::dummy::DummyClient;
use crate::dbus_api::devices::generic::GenericClient;
use crate::dbus_api::devices::infiniband::InfinibandClient;
use crate::dbus_api::devices::ip_tunnel::IPTunnelClient;
use crate::dbus_api::devices::lowpan::LowpanClient;
use crate::dbus_api::devices::macsec::MacsecClient;
use crate::dbus_api::devices::macvlan::MacvlanClient;
use crate::dbus_api::devices::modem::ModemClient;
use crate::dbus_api::devices::olpc_mesh::OlpcMeshClient;
use crate::dbus_api::devices::statistics::DeviceStatistics;
use crate::dbus_api::devices::team::TeamClient;
use crate::dbus_api::devices::tun::TunClient;
use crate::dbus_api::devices::veth::VethClient;
use crate::dbus_api::devices::wifi_p2p::WifiP2PClient;
use crate::dbus_api::devices::wimax::WiMaxClient;
use crate::dbus_api::devices::wired::WiredClient;
use crate::dbus_api::devices::wireless::WirelessClient;
use crate::dbus_api::devices::wpan::WpanClient;
use crate::dbus_api::{DeviceType, NMConnection};
use std::collections::HashMap;
use std::io::{Error, ErrorKind};
use std::sync::Arc;
use zbus::proxy::CacheProperties;
use zbus::zvariant::{OwnedObjectPath, OwnedValue, Value};
use zbus::{Connection, Result as ZResult, proxy};
pub mod adsl;
pub mod bluetooth;
pub mod bond;
pub mod bridge;
pub mod dummy;
pub mod generic;
pub mod infiniband;
pub mod ip_tunnel;
pub mod lowpan;
pub mod macsec;
pub mod macvlan;
pub mod modem;
pub mod olpc_mesh;
pub mod ovs_bridge;
pub mod ovs_interface;
pub mod ovs_port;
pub mod ppp;
pub mod statistics;
pub mod team;
pub mod tun;
pub mod veth;
pub mod vlan;
pub mod vrf;
pub mod vxlan;
pub mod wifi_p2p;
pub mod wimax;
pub mod wired;
pub mod wireguard;
pub mod wireless;
pub mod wpan;
#[proxy(
interface = "org.freedesktop.NetworkManager.Device",
default_service = "org.freedesktop.NetworkManager"
)]
pub trait Device {
fn reapply(
&self,
connection: HashMap<&str, HashMap<&str, Value<'_>>>,
version_id: u64,
flags: u32,
) -> ZResult<()>;
fn get_applied_connection(&self, flags: u32) -> ZResult<(NMConnection, u64)>;
fn disconnect(&self) -> ZResult<()>;
fn delete(&self) -> ZResult<()>;
#[zbus(property)]
fn udi(&self) -> ZResult<String>;
#[zbus(property)]
fn interface(&self) -> ZResult<String>;
#[zbus(property)]
fn ip_interface(&self) -> ZResult<String>;
#[zbus(property)]
fn driver(&self) -> ZResult<String>;
#[zbus(property)]
fn driver_version(&self) -> ZResult<String>;
#[zbus(property)]
fn firmware_version(&self) -> ZResult<String>;
#[zbus(property)]
fn capabilities(&self) -> ZResult<u32>;
#[zbus(property)]
fn ip4_address(&self) -> ZResult<u32>;
#[zbus(property)]
fn state(&self) -> ZResult<u32>;
#[zbus(property)]
fn state_reason(&self) -> ZResult<(u32, u32)>;
#[zbus(property)]
fn active_connection(&self) -> ZResult<OwnedObjectPath>;
#[zbus(property)]
fn ip4_config(&self) -> ZResult<OwnedObjectPath>;
#[zbus(property)]
fn dhcp4_config(&self) -> ZResult<OwnedObjectPath>;
#[zbus(property)]
fn ip6_config(&self) -> ZResult<OwnedObjectPath>;
#[zbus(property)]
fn dhcp6_config(&self) -> ZResult<OwnedObjectPath>;
#[zbus(property)]
fn managed(&self) -> ZResult<bool>;
#[zbus(property)]
fn set_managed(&self, value: bool) -> ZResult<()>;
#[zbus(property)]
fn autoconnect(&self) -> ZResult<bool>;
#[zbus(property)]
fn set_autoconnect(&self, value: bool) -> ZResult<()>;
#[zbus(property)]
fn firmware_missing(&self) -> ZResult<bool>;
#[zbus(property)]
fn nm_plugin_missing(&self) -> ZResult<bool>;
#[zbus(property)]
fn device_type(&self) -> ZResult<u32>;
#[zbus(property)]
fn available_connections(&self) -> ZResult<Vec<OwnedObjectPath>>;
#[zbus(property)]
fn physical_port_id(&self) -> ZResult<String>;
#[zbus(property)]
fn mtu(&self) -> ZResult<u32>;
#[zbus(property)]
fn metered(&self) -> ZResult<u32>;
#[zbus(property)]
fn lldp_neighbors(&self) -> ZResult<Vec<HashMap<String, OwnedValue>>>;
#[zbus(property)]
fn real(&self) -> ZResult<bool>;
#[zbus(property)]
fn ip4_connectivity(&self) -> ZResult<u32>;
#[zbus(property)]
fn ip6_connectivity(&self) -> ZResult<u32>;
#[zbus(property)]
fn interface_flags(&self) -> ZResult<u32>;
#[zbus(property)]
fn hw_address(&self) -> ZResult<String>;
#[zbus(property)]
fn set_statistics_refresh_rate(&self, rate_ms: u32) -> ZResult<()>;
#[zbus(property)]
fn get_tx_bytes(&self) -> ZResult<u64>;
#[zbus(property)]
fn get_rx_bytes(&self) -> ZResult<u64>;
}
#[derive(Debug, Clone)]
pub struct DeviceClient {
service_path: String,
proxy: DeviceProxy<'static>,
bus_connection: Arc<Connection>,
}
impl DeviceClient {
pub async fn new(connection: Arc<Connection>, service_path: String) -> Result<Self, Error> {
let proxy = DeviceProxy::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
.interface()
.await
.map_err(|e| Error::new(ErrorKind::NotFound, e.to_string()))?;
Ok(Self {
service_path,
proxy,
bus_connection: connection,
})
}
pub fn service_path(&self) -> &str {
&self.service_path
}
pub async fn interface(&self) -> Result<String, Error> {
self.proxy
.interface()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn device_type(&self) -> Result<DeviceType, Error> {
let dev_type = self
.proxy
.device_type()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
Ok(DeviceType::from(dev_type))
}
pub async fn hw_address(&self) -> Result<String, Error> {
self.proxy
.hw_address()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn udi(&self) -> Result<String, Error> {
self.proxy
.udi()
.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 ip_interface(&self) -> Result<String, Error> {
self.proxy
.ip_interface()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn driver(&self) -> Result<String, Error> {
self.proxy
.driver()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn disconnect(&self) -> Result<(), Error> {
self.proxy
.disconnect()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn active_connection(&self) -> Result<Option<ActiveConnectionClient>, Error> {
let object_path = self
.proxy
.active_connection()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))?;
if object_path.as_str() == "/" {
Ok(None)
} else {
ActiveConnectionClient::new(self.bus_connection.clone(), object_path.to_string())
.await
.map(Some)
}
}
pub async fn ip4_config(&self) -> Result<OwnedObjectPath, Error> {
self.proxy
.ip4_config()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn dhcp4_config(&self) -> Result<OwnedObjectPath, Error> {
self.proxy
.dhcp4_config()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn ip6_config(&self) -> Result<OwnedObjectPath, Error> {
self.proxy
.ip6_config()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn dhcp6_config(&self) -> Result<OwnedObjectPath, Error> {
self.proxy
.dhcp6_config()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn managed(&self) -> Result<bool, Error> {
self.proxy
.managed()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn set_managed(&self, value: bool) -> Result<(), Error> {
self.proxy
.set_managed(value)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn mtu(&self) -> Result<u32, Error> {
self.proxy
.mtu()
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn reapply(
&self,
connection: HashMap<&str, HashMap<&str, Value<'_>>>,
version_id: u64,
flags: u32,
) -> Result<(), Error> {
self.proxy
.reapply(connection, version_id, flags)
.await
.map_err(|e| Error::new(ErrorKind::Other, e.to_string()))
}
pub async fn get_statistics(&self) -> Result<DeviceStatistics, Error> {
match DeviceStatistics::new(self.bus_connection.clone(), self.service_path.clone()).await {
Ok(stats) => Ok(stats),
Err(e) => Err(Error::new(
ErrorKind::Other,
format!("Failed to get statistics: {}", e),
)),
}
}
pub async fn set_statistics_refresh_rate(&self, rate_ms: u32) -> Result<(), Error> {
let stats = self.get_statistics().await?;
match stats.set_refresh_rate_ms(rate_ms).await {
Ok(_) => Ok(()),
Err(e) => Err(Error::new(
ErrorKind::Other,
format!("Failed to set refresh rate: {}", e),
)),
}
}
pub async fn get_tx_bytes(&self) -> Result<u64, Error> {
let stats = self.get_statistics().await?;
match stats.tx_bytes().await {
Ok(bytes) => Ok(bytes),
Err(e) => Err(Error::new(
ErrorKind::Other,
format!("Failed to get TX bytes: {}", e),
)),
}
}
pub async fn get_rx_bytes(&self) -> Result<u64, Error> {
let stats = self.get_statistics().await?;
match stats.rx_bytes().await {
Ok(bytes) => Ok(bytes),
Err(e) => Err(Error::new(
ErrorKind::Other,
format!("Failed to get RX bytes: {}", e),
)),
}
}
}
#[derive(Debug, Clone)]
pub enum Device {
Adsl(AdslClient),
Bluetooth(BluetoothClient),
Bond(BondClient),
Bridge(BridgeClient),
Dummy(DummyClient),
Ethernet(WiredClient),
Generic(GenericClient),
Infiniband(InfinibandClient),
IPTunnel(IPTunnelClient),
Lowpan(LowpanClient),
Macsec(MacsecClient),
Macvlan(MacvlanClient),
Modem(ModemClient),
OlpcMesh(OlpcMeshClient),
Team(TeamClient),
Tun(TunClient),
Veth(VethClient),
WifiP2p(WifiP2PClient),
WiMax(WiMaxClient),
Wired(WiredClient),
Wireless(WirelessClient),
Wpan(WpanClient),
UnsupportedDevice,
}
impl Device {
pub async fn new(connection: Arc<Connection>, service_path: String) -> Result<Self, Error> {
let device = DeviceClient::new(connection.clone(), service_path.clone()).await?;
let dev_type = device.device_type().await?;
match dev_type {
DeviceType::Wifi => {
let wifi = WirelessClient::new(connection, service_path).await?;
Ok(Device::Wireless(wifi))
}
DeviceType::Ethernet => {
let ethernet = WiredClient::new(connection, service_path).await?;
Ok(Device::Ethernet(ethernet))
}
_ => {
let generic = GenericClient::new(connection, service_path).await?;
Ok(Device::Generic(generic))
}
}
}
}