//! Handlers for network interface exploration in RIOT
// FIXME port from gnrc_netif to netif
use coap_handler_implementations::wkc;
struct AllNetifs;
impl coap_handler_implementations::TypeRenderable for AllNetifs {
type Get = Self;
type Put = ();
type Post = ();
fn get(&mut self) -> Result<Self::Get, u8> {
Ok(AllNetifs)
}
}
impl<C> minicbor::Encode<C> for AllNetifs {
fn encode<W: minicbor::encode::Write>(
&self,
e: &mut minicbor::Encoder<W>,
ctx: &mut C,
) -> Result<(), minicbor::encode::Error<W::Error>> {
let e = e.begin_array()?;
for netif in riot_wrappers::gnrc::Netif::all() {
SerializedNetif(netif).encode(e, ctx)?;
}
e.end()?;
Ok(())
}
}
struct SerializedNetif(riot_wrappers::gnrc::Netif);
impl<C> minicbor::Encode<C> for SerializedNetif {
fn encode<W: minicbor::encode::Write>(
&self,
e: &mut minicbor::Encoder<W>,
ctx: &mut C,
) -> Result<(), minicbor::encode::Error<W::Error>> {
let pidnum: i16 = self.0.pid().into();
let ipaddrs = self.0.ipv6_addrs();
let e = e.array(2 + ipaddrs.is_ok() as u64)?;
e.i16(pidnum)?; // FIXME could be u16 (KernelPID should support both)
crate::minicbor_helpers::encode_as_mac(&self.0.l2addr(), e, ctx)?;
if let Ok(ipaddrs) = ipaddrs {
let e = e.array(ipaddrs.len() as _)?;
for a in &ipaddrs {
let a = a.into();
e.encode(crate::minicbor_helpers::IpWithZone {
ip: &a,
zone: u16::try_from(pidnum).and_then(|u| u.try_into()).ok(), // or Some(....expect("PIDs are valid zone identifiers"))
})?;
}
};
Ok(())
}
}
/// Build a handler that will report a summary of the current GNRC network interfaces in CBOR form
///
/// The precise format is subject to change, but currently it produces an array of netifs, each
/// with its process ID, its link-local address, and (if IPv6-enabled) a list of assigned IPv6
/// addresses.
///
/// All MAC and IP addresses are expressed using the appropriate CBOR tags.
pub fn netif() -> impl coap_handler::Handler + coap_handler::Reporting {
wkc::ConstantSingleRecordReport::new_with_path(
coap_handler_implementations::TypeHandler::new_minicbor_0_24(AllNetifs),
&[coap_handler::Attribute::Title("Network interfaces")],
&[],
)
}