use core::net::{Ipv4Addr, Ipv6Addr};
use alloc::string::String;
use alloc::vec::Vec;
use crate::dm::clusters::gen_diag::{InterfaceTypeEnum, NetifDiag, NetifInfo};
use crate::error::{Error, ErrorCode};
use crate::utils::sync::DynBase;
use super::NetChangeNotif;
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct GenericNetifs;
impl GenericNetifs {
pub fn get(&self) -> Result<Vec<GenericNetif>, Error> {
let mut netifs: Vec<GenericNetif> = Vec::new();
for ia in if_addrs::get_if_addrs().map_err(|_| ErrorCode::NoNetworkInterface)? {
let netif_index = ia.index.unwrap_or(0);
let entry = if let Some(entry) = netifs.iter_mut().find(|n| n.name == ia.name) {
entry
} else {
netifs.push(GenericNetif {
name: ia.name.clone(),
hw_addr: [0; 8],
ipv4addrs: Vec::new(),
ipv6addrs: Vec::new(),
operational: true,
netif_index,
});
netifs.last_mut().unwrap()
};
if entry.netif_index == 0 {
entry.netif_index = netif_index;
}
match ia.addr {
if_addrs::IfAddr::V4(v4) => entry.ipv4addrs.push(v4.ip),
if_addrs::IfAddr::V6(v6) => entry.ipv6addrs.push(v6.ip),
}
}
Ok(netifs)
}
}
impl DynBase for GenericNetifs {}
impl NetifDiag for GenericNetifs {
fn netifs(&self, f: &mut dyn FnMut(&NetifInfo) -> Result<(), Error>) -> Result<(), Error> {
for netif in self.get()? {
f(&netif.to_netif_info())?;
}
Ok(())
}
}
impl NetChangeNotif for GenericNetifs {
async fn wait_changed(&self) {
super::poll_netifs_changed().await;
}
}
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct GenericNetif {
pub name: String,
pub hw_addr: [u8; 8],
pub ipv4addrs: Vec<Ipv4Addr>,
pub ipv6addrs: Vec<Ipv6Addr>,
pub operational: bool,
pub netif_index: u32,
}
impl GenericNetif {
pub fn to_netif_info(&self) -> NetifInfo<'_> {
NetifInfo {
name: &self.name,
operational: self.operational,
offprem_svc_reachable_ipv4: None,
offprem_svc_reachable_ipv6: None,
hw_addr: &self.hw_addr,
ipv4_addrs: &self.ipv4addrs,
ipv6_addrs: &self.ipv6addrs,
netif_type: InterfaceTypeEnum::Unspecified,
netif_index: self.netif_index,
}
}
}