ergot_base/interface_manager/profiles/direct_router/
mod.rs1use log::{debug, trace, warn};
9
10use crate::{
11 Header, ProtocolError,
12 interface_manager::{
13 DeregisterError, Interface, InterfaceSendError, InterfaceState, Profile, SetStateError,
14 profiles::direct_edge::{CENTRAL_NODE_ID, DirectEdge},
15 },
16};
17
18pub mod std_tcp;
19
20#[cfg(feature = "nusb-v0_1")]
21pub mod nusb_0_1;
22
23#[cfg(feature = "tokio-serial-v5")]
24pub mod tokio_serial_5;
25
26struct Node<I: Interface> {
27 edge: DirectEdge<I>,
28 net_id: u16,
29 ident: u64,
30}
31
32pub struct DirectRouter<I: Interface> {
33 interface_ctr: u64,
34 nodes: Vec<Node<I>>,
35}
36
37impl<I: Interface> Profile for DirectRouter<I> {
38 type InterfaceIdent = u64;
39
40 fn send<T: serde::Serialize>(
41 &mut self,
42 hdr: &crate::Header,
43 data: &T,
44 ) -> Result<(), InterfaceSendError> {
45 let intfc = self.find(hdr)?;
46 intfc.send(hdr, data)
47 }
48
49 fn send_err(
50 &mut self,
51 hdr: &crate::Header,
52 err: ProtocolError,
53 ) -> Result<(), InterfaceSendError> {
54 let intfc = self.find(hdr)?;
55 intfc.send_err(hdr, err)
56 }
57
58 fn send_raw(
59 &mut self,
60 hdr: &crate::Header,
61 hdr_raw: &[u8],
62 data: &[u8],
63 ) -> Result<(), InterfaceSendError> {
64 let intfc = self.find(hdr)?;
65 intfc.send_raw(hdr, hdr_raw, data)
66 }
67
68 fn interface_state(&mut self, ident: Self::InterfaceIdent) -> Option<InterfaceState> {
69 let node = self.nodes.iter_mut().find(|n| n.ident == ident)?;
70 node.edge.interface_state(())
71 }
72
73 fn set_interface_state(
74 &mut self,
75 ident: Self::InterfaceIdent,
76 state: InterfaceState,
77 ) -> Result<(), SetStateError> {
78 let Some(node) = self.nodes.iter_mut().find(|n| n.ident == ident) else {
79 return Err(SetStateError::InterfaceNotFound);
80 };
81 node.edge.set_interface_state((), state)
82 }
83}
84
85impl<I: Interface> DirectRouter<I> {
86 pub fn new() -> Self {
87 Self {
88 interface_ctr: 0,
89 nodes: vec![],
90 }
91 }
92
93 pub fn get_nets(&mut self) -> Vec<u16> {
94 self.nodes
95 .iter_mut()
96 .filter_map(|n| match n.edge.interface_state(())? {
97 InterfaceState::Down => None,
98 InterfaceState::Inactive => None,
99 InterfaceState::ActiveLocal { .. } => None,
100 InterfaceState::Active { net_id, node_id: _ } => Some(net_id),
101 })
102 .collect()
103 }
104
105 fn find<'b>(&'b mut self, ihdr: &Header) -> Result<&'b mut DirectEdge<I>, InterfaceSendError> {
106 if ihdr.dst.port_id == 0 && ihdr.any_all.is_none() {
108 return Err(InterfaceSendError::AnyPortMissingKey);
109 }
110
111 let Ok(idx) = self
112 .nodes
113 .binary_search_by_key(&ihdr.dst.network_id, |n| n.net_id)
114 else {
115 return Err(InterfaceSendError::NoRouteToDest);
116 };
117
118 Ok(&mut self.nodes[idx].edge)
119 }
120
121 pub fn register_interface(&mut self, sink: I::Sink) -> Option<u64> {
122 if self.nodes.is_empty() {
123 let net_id = 1;
124 let intfc_id = self.interface_ctr;
125 self.interface_ctr += 1;
126
127 self.nodes.push(Node {
128 edge: DirectEdge::new_controller(
129 sink,
130 InterfaceState::Active {
131 net_id,
132 node_id: CENTRAL_NODE_ID,
133 },
134 ),
135 net_id,
136 ident: intfc_id,
137 });
138 debug!("Alloc'd net_id 1");
139 return Some(intfc_id);
140 } else if self.nodes.len() >= 65534 {
141 warn!("Out of netids!");
142 return None;
143 }
144
145 let mut net_id = 1;
146 for intfc in self.nodes.iter() {
149 if intfc.net_id > net_id {
150 trace!("Found gap: {net_id}");
151 break;
152 }
153 debug_assert!(intfc.net_id == net_id);
154 net_id += 1;
155 }
156 debug_assert!(net_id > 0 && net_id != u16::MAX);
160
161 let intfc_id = self.interface_ctr;
162 self.interface_ctr += 1;
163
164 self.nodes.push(Node {
166 edge: DirectEdge::new_controller(
167 sink,
168 InterfaceState::Active {
169 net_id,
170 node_id: CENTRAL_NODE_ID,
171 },
172 ),
173 net_id,
174 ident: intfc_id,
175 });
176 self.nodes.sort_unstable_by_key(|i| i.net_id);
177 Some(intfc_id)
178 }
179
180 pub fn deregister_interface(&mut self, ident: u64) -> Result<(), DeregisterError> {
181 let Some(pos) = self.nodes.iter().position(|n| n.ident == ident) else {
182 return Err(DeregisterError::NoSuchInterface);
183 };
184 _ = self.nodes.remove(pos);
185 Ok(())
186 }
187}
188
189impl<I: Interface> Default for DirectRouter<I> {
190 fn default() -> Self {
191 Self::new()
192 }
193}