seeed_erpc/
tcpip_rpcs.rs

1#[allow(dead_code)]
2use super::{codec, ids, Err};
3use no_std_net::Ipv4Addr;
4use nom::{bytes::streaming::take, number::streaming};
5
6/// Initializes the layer 3 subsystem.
7pub struct AdapterInit {}
8
9impl super::RPC for AdapterInit {
10    type ReturnValue = ();
11    type Error = ();
12
13    fn header(&self, seq: u32) -> codec::Header {
14        codec::Header {
15            sequence: seq,
16            msg_type: ids::MsgType::Invocation,
17            service: ids::Service::TCPIP,
18            request: ids::TCPIPRequest::AdapterInit.into(),
19        }
20    }
21
22    fn parse(&mut self, data: &[u8]) -> Result<Self::ReturnValue, Err<Self::Error>> {
23        let (_, hdr) = codec::Header::parse(data)?;
24        if hdr.msg_type != ids::MsgType::Reply
25            || hdr.service != ids::Service::TCPIP
26            || hdr.request != ids::TCPIPRequest::AdapterInit.into()
27        {
28            return Err(Err::NotOurs);
29        }
30
31        Ok(())
32    }
33}
34
35/// Stops any DHCP client management.
36pub struct DHCPClientStop {
37    pub interface: super::L3Interface,
38}
39
40impl super::RPC for DHCPClientStop {
41    type ReturnValue = i32;
42    type Error = ();
43
44    fn args(&self, buff: &mut heapless::Vec<u8, 64>) {
45        let interface_id = self.interface as u32;
46        buff.extend_from_slice(&interface_id.to_le_bytes()).ok();
47    }
48
49    fn header(&self, seq: u32) -> codec::Header {
50        codec::Header {
51            sequence: seq,
52            msg_type: ids::MsgType::Invocation,
53            service: ids::Service::TCPIP,
54            request: ids::TCPIPRequest::DHCPClientStop.into(),
55        }
56    }
57
58    fn parse(&mut self, data: &[u8]) -> Result<Self::ReturnValue, Err<Self::Error>> {
59        let (data, hdr) = codec::Header::parse(data)?;
60        if hdr.msg_type != ids::MsgType::Reply
61            || hdr.service != ids::Service::TCPIP
62            || hdr.request != ids::TCPIPRequest::DHCPClientStop.into()
63        {
64            return Err(Err::NotOurs);
65        }
66
67        let (_, ret_val) = streaming::le_i32(data)?;
68        Ok(ret_val)
69    }
70}
71
72/// Starts the DHCP client.
73pub struct DHCPClientStart {
74    pub interface: super::L3Interface,
75}
76
77impl super::RPC for DHCPClientStart {
78    type ReturnValue = i32;
79    type Error = ();
80
81    fn args(&self, buff: &mut heapless::Vec<u8, 64>) {
82        let interface_id = self.interface as u32;
83        buff.extend_from_slice(&interface_id.to_le_bytes()).ok();
84    }
85
86    fn header(&self, seq: u32) -> codec::Header {
87        codec::Header {
88            sequence: seq,
89            msg_type: ids::MsgType::Invocation,
90            service: ids::Service::TCPIP,
91            request: ids::TCPIPRequest::DHCPClientStart.into(),
92        }
93    }
94
95    fn parse(&mut self, data: &[u8]) -> Result<Self::ReturnValue, Err<Self::Error>> {
96        let (data, hdr) = codec::Header::parse(data)?;
97        if hdr.msg_type != ids::MsgType::Reply
98            || hdr.service != ids::Service::TCPIP
99            || hdr.request != ids::TCPIPRequest::DHCPClientStart.into()
100        {
101            return Err(Err::NotOurs);
102        }
103
104        let (_, ret_val) = streaming::le_i32(data)?;
105        Ok(ret_val)
106    }
107}
108
109/// Returns the IP configuration the station is using.
110pub struct GetIPInfo {
111    pub interface: super::L3Interface,
112}
113
114impl super::RPC for GetIPInfo {
115    type ReturnValue = super::IPInfo;
116    type Error = i32;
117
118    fn header(&self, seq: u32) -> codec::Header {
119        codec::Header {
120            sequence: seq,
121            msg_type: ids::MsgType::Invocation,
122            service: ids::Service::TCPIP,
123            request: ids::TCPIPRequest::GetIPInfo.into(),
124        }
125    }
126
127    fn args(&self, buff: &mut heapless::Vec<u8, 64>) {
128        let interface_id = self.interface as u32;
129        buff.extend_from_slice(&interface_id.to_le_bytes()).ok();
130    }
131
132    fn parse(&mut self, data: &[u8]) -> Result<Self::ReturnValue, Err<Self::Error>> {
133        let (data, hdr) = codec::Header::parse(data)?;
134        if hdr.msg_type != ids::MsgType::Reply
135            || hdr.service != ids::Service::TCPIP
136            || hdr.request != ids::TCPIPRequest::GetIPInfo.into()
137        {
138            return Err(Err::NotOurs);
139        }
140
141        let (data, payload_length) = streaming::le_u32(data)?;
142        if payload_length != 12 {
143            return Err(Err::RPCErr(1));
144        }
145
146        let (data, ip) = take(4u8)(data)?;
147        let (data, mask) = take(4u8)(data)?;
148        let (data, gateway) = take(4u8)(data)?;
149
150        let (_, result) = streaming::le_u32(data)?;
151        if result != 0 {
152            Err(Err::RPCErr(result as i32))
153        } else {
154            Ok(super::IPInfo {
155                ip: Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3]),
156                netmask: Ipv4Addr::new(mask[0], mask[1], mask[2], mask[3]),
157                gateway: Ipv4Addr::new(gateway[0], gateway[1], gateway[2], gateway[3]),
158            })
159        }
160    }
161}