ergot_base/interface_manager/profiles/direct_edge/
mod.rs1use log::{debug, trace};
14use serde::Serialize;
15
16#[cfg(feature = "embedded-io-async-v0_6")]
17pub mod eio_0_6;
18
19#[cfg(feature = "embassy-usb-v0_4")]
20pub mod eusb_0_4;
21
22#[cfg(feature = "embassy-usb-v0_5")]
23pub mod eusb_0_5;
24
25#[cfg(feature = "std")]
26pub mod std_tcp;
27
28use crate::{
29 Header, ProtocolError,
30 interface_manager::{
31 Interface, InterfaceSendError, InterfaceSink, InterfaceState, Profile, SetStateError,
32 },
33 wire_frames::CommonHeader,
34};
35
36pub const CENTRAL_NODE_ID: u8 = 1;
37pub const EDGE_NODE_ID: u8 = 2;
38
39pub enum SetNetIdError {
40 CantSetZero,
41 NoActiveSink,
42}
43
44pub struct DirectEdge<I: Interface> {
46 sink: I::Sink,
47 seq_no: u16,
48 state: InterfaceState,
49 own_node_id: u8,
50 other_node_id: u8,
51}
52
53impl<I: Interface> DirectEdge<I> {
54 pub const fn new_target(sink: I::Sink) -> Self {
55 Self {
56 sink,
57 seq_no: 0,
58 state: InterfaceState::Down,
59 own_node_id: EDGE_NODE_ID,
60 other_node_id: CENTRAL_NODE_ID,
61 }
62 }
63
64 pub const fn new_controller(sink: I::Sink, state: InterfaceState) -> Self {
65 Self {
66 sink,
67 seq_no: 0,
68 state,
69 own_node_id: CENTRAL_NODE_ID,
70 other_node_id: EDGE_NODE_ID,
71 }
72 }
73}
74
75impl<I: Interface> DirectEdge<I> {
76 fn common_send<'b>(
77 &'b mut self,
78 ihdr: &Header,
79 ) -> Result<(&'b mut I::Sink, CommonHeader), InterfaceSendError> {
80 let net_id = match &self.state {
81 InterfaceState::Down | InterfaceState::Inactive => {
82 return Err(InterfaceSendError::NoRouteToDest);
83 }
84 InterfaceState::ActiveLocal { .. } => {
85 return Err(InterfaceSendError::NoRouteToDest);
87 }
88 InterfaceState::Active { net_id, node_id: _ } => *net_id,
89 };
90
91 trace!("common_send header: {:?}", ihdr);
92
93 if net_id == 0 {
94 debug!("Attempted to send via interface before we have been assigned a net ID");
95 return Err(InterfaceSendError::NoRouteToDest);
97 }
98 if ihdr.dst.network_id == net_id && ihdr.dst.node_id == self.own_node_id {
104 return Err(InterfaceSendError::DestinationLocal);
105 }
106
107 let mut hdr = ihdr.clone();
110 hdr.decrement_ttl()?;
111
112 if hdr.src.net_node_any() {
115 hdr.src.network_id = net_id;
119 hdr.src.node_id = self.own_node_id;
120 }
121
122 if hdr.dst.port_id == 255 {
125 hdr.dst.network_id = net_id;
126 hdr.dst.node_id = self.other_node_id;
127 }
128
129 let seq_no = self.seq_no;
130 self.seq_no = self.seq_no.wrapping_add(1);
131
132 let header = CommonHeader {
133 src: hdr.src,
134 dst: hdr.dst,
135 seq_no,
136 kind: hdr.kind,
137 ttl: hdr.ttl,
138 };
139 if [0, 255].contains(&hdr.dst.port_id) && ihdr.any_all.is_none() {
140 return Err(InterfaceSendError::AnyPortMissingKey);
141 }
142
143 Ok((&mut self.sink, header))
144 }
145}
146
147impl<I: Interface> Profile for DirectEdge<I> {
148 type InterfaceIdent = ();
149
150 fn send<T: Serialize>(&mut self, hdr: &Header, data: &T) -> Result<(), InterfaceSendError> {
151 let (intfc, header) = self.common_send(hdr)?;
152
153 let res = intfc.send_ty(&header, hdr.any_all.as_ref(), data);
154
155 match res {
156 Ok(()) => Ok(()),
157 Err(()) => Err(InterfaceSendError::InterfaceFull),
158 }
159 }
160
161 fn send_err(&mut self, hdr: &Header, err: ProtocolError) -> Result<(), InterfaceSendError> {
162 let (intfc, header) = self.common_send(hdr)?;
163
164 let res = intfc.send_err(&header, err);
165
166 match res {
167 Ok(()) => Ok(()),
168 Err(()) => Err(InterfaceSendError::InterfaceFull),
169 }
170 }
171
172 fn send_raw(
173 &mut self,
174 hdr: &Header,
175 hdr_raw: &[u8],
176 data: &[u8],
177 ) -> Result<(), InterfaceSendError> {
178 let (intfc, header) = self.common_send(hdr)?;
179
180 let res = intfc.send_raw(&header, hdr_raw, data);
181
182 match res {
183 Ok(()) => Ok(()),
184 Err(()) => Err(InterfaceSendError::InterfaceFull),
185 }
186 }
187
188 fn interface_state(&mut self, _ident: ()) -> Option<InterfaceState> {
189 Some(self.state)
190 }
191
192 fn set_interface_state(
193 &mut self,
194 _ident: (),
195 state: InterfaceState,
196 ) -> Result<(), SetStateError> {
197 match state {
198 InterfaceState::Down => {
199 self.state = InterfaceState::Down;
200 }
201 InterfaceState::Inactive => {
202 self.state = InterfaceState::Inactive;
203 }
204 InterfaceState::ActiveLocal { node_id } => {
205 if node_id != self.own_node_id {
206 return Err(SetStateError::InvalidNodeId);
207 }
208 self.state = InterfaceState::ActiveLocal { node_id };
209 }
210 InterfaceState::Active { net_id, node_id } => {
211 if node_id != self.own_node_id {
212 return Err(SetStateError::InvalidNodeId);
213 }
214 self.state = InterfaceState::Active { net_id, node_id };
215 }
216 }
217 Ok(())
218 }
219}