riot_coap_handler_demos/
netif.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//! 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")],
        &[],
    )
}