1use super::engine::{ConstrainedEngine, EngineConfig, EngineEvent};
14use super::state::ConnectionState;
15use super::types::{ConnectionId, ConstrainedAddr, ConstrainedError};
16use crate::transport::TransportAddr;
17use std::net::SocketAddr;
18
19#[derive(Debug, Clone)]
21pub struct EngineOutput {
22 pub destination: TransportAddr,
24 pub data: Vec<u8>,
26}
27
28impl EngineOutput {
29 pub fn new(destination: TransportAddr, data: Vec<u8>) -> Self {
31 Self { destination, data }
32 }
33}
34
35#[derive(Debug)]
40pub struct ConstrainedEngineAdapter {
41 engine: ConstrainedEngine,
43 addr_map: std::collections::HashMap<TransportAddr, SocketAddr>,
46 reverse_map: std::collections::HashMap<SocketAddr, TransportAddr>,
48 next_synthetic: u32,
50}
51
52impl ConstrainedEngineAdapter {
53 pub fn new(config: EngineConfig) -> Self {
55 Self {
56 engine: ConstrainedEngine::new(config),
57 addr_map: std::collections::HashMap::new(),
58 reverse_map: std::collections::HashMap::new(),
59 next_synthetic: 1,
60 }
61 }
62
63 pub fn for_ble() -> Self {
65 Self::new(EngineConfig::for_ble())
66 }
67
68 pub fn for_lora() -> Self {
70 Self::new(EngineConfig::for_lora())
71 }
72
73 fn get_or_create_socket_addr(&mut self, addr: &TransportAddr) -> SocketAddr {
78 if let TransportAddr::Udp(socket_addr) = addr {
79 return *socket_addr;
81 }
82
83 if let Some(socket_addr) = self.addr_map.get(addr) {
85 return *socket_addr;
86 }
87
88 let ip = std::net::Ipv4Addr::new(
90 127,
91 ((self.next_synthetic >> 16) & 0xFF) as u8,
92 ((self.next_synthetic >> 8) & 0xFF) as u8,
93 (self.next_synthetic & 0xFF) as u8,
94 );
95 let socket_addr = SocketAddr::new(
96 std::net::IpAddr::V4(ip),
97 (self.next_synthetic % 65535) as u16,
98 );
99 self.next_synthetic += 1;
100
101 self.addr_map.insert(addr.clone(), socket_addr);
102 self.reverse_map.insert(socket_addr, addr.clone());
103
104 socket_addr
105 }
106
107 fn socket_to_transport(&self, socket_addr: &SocketAddr) -> TransportAddr {
109 self.reverse_map
110 .get(socket_addr)
111 .cloned()
112 .unwrap_or(TransportAddr::Udp(*socket_addr))
113 }
114
115 pub fn connect(
117 &mut self,
118 remote: &TransportAddr,
119 ) -> Result<(ConnectionId, Vec<EngineOutput>), ConstrainedError> {
120 let socket_addr = self.get_or_create_socket_addr(remote);
121 let (conn_id, packet) = self.engine.connect(socket_addr)?;
122 let output = EngineOutput::new(remote.clone(), packet);
123 Ok((conn_id, vec![output]))
124 }
125
126 pub fn process_incoming(
128 &mut self,
129 source: &TransportAddr,
130 data: &[u8],
131 ) -> Result<Vec<EngineOutput>, ConstrainedError> {
132 let socket_addr = self.get_or_create_socket_addr(source);
133 let responses = self.engine.process_incoming(socket_addr, data)?;
134
135 Ok(responses
136 .into_iter()
137 .map(|(addr, packet)| {
138 let dest = self.socket_to_transport(&addr);
139 EngineOutput::new(dest, packet)
140 })
141 .collect())
142 }
143
144 pub fn send(
146 &mut self,
147 connection_id: ConnectionId,
148 data: &[u8],
149 ) -> Result<Vec<EngineOutput>, ConstrainedError> {
150 let responses = self.engine.send(connection_id, data)?;
151
152 Ok(responses
153 .into_iter()
154 .map(|(addr, packet)| {
155 let dest = self.socket_to_transport(&addr);
156 EngineOutput::new(dest, packet)
157 })
158 .collect())
159 }
160
161 pub fn recv(&mut self, connection_id: ConnectionId) -> Option<Vec<u8>> {
163 self.engine.recv(connection_id)
164 }
165
166 pub fn close(
168 &mut self,
169 connection_id: ConnectionId,
170 ) -> Result<Vec<EngineOutput>, ConstrainedError> {
171 let responses = self.engine.close(connection_id)?;
172
173 Ok(responses
174 .into_iter()
175 .map(|(addr, packet)| {
176 let dest = self.socket_to_transport(&addr);
177 EngineOutput::new(dest, packet)
178 })
179 .collect())
180 }
181
182 pub fn poll(&mut self) -> Vec<EngineOutput> {
184 let responses = self.engine.poll();
185
186 responses
187 .into_iter()
188 .map(|(addr, packet)| {
189 let dest = self.socket_to_transport(&addr);
190 EngineOutput::new(dest, packet)
191 })
192 .collect()
193 }
194
195 pub fn next_event(&mut self) -> Option<AdapterEvent> {
197 self.engine.next_event().map(|event| match event {
198 EngineEvent::ConnectionAccepted {
199 connection_id,
200 remote_addr,
201 } => {
202 let addr = self.socket_to_transport(&remote_addr);
203 AdapterEvent::ConnectionAccepted {
204 connection_id,
205 remote_addr: ConstrainedAddr::new(addr),
206 }
207 }
208 EngineEvent::ConnectionEstablished { connection_id } => {
209 AdapterEvent::ConnectionEstablished { connection_id }
210 }
211 EngineEvent::DataReceived {
212 connection_id,
213 data,
214 } => AdapterEvent::DataReceived {
215 connection_id,
216 data,
217 },
218 EngineEvent::ConnectionClosed { connection_id } => {
219 AdapterEvent::ConnectionClosed { connection_id }
220 }
221 EngineEvent::ConnectionError {
222 connection_id,
223 error,
224 } => AdapterEvent::ConnectionError {
225 connection_id,
226 error,
227 },
228 EngineEvent::Transmit {
229 remote_addr,
230 packet,
231 } => {
232 let addr = self.socket_to_transport(&remote_addr);
233 AdapterEvent::Transmit {
234 destination: addr,
235 packet,
236 }
237 }
238 })
239 }
240
241 pub fn connection_count(&self) -> usize {
243 self.engine.connection_count()
244 }
245
246 pub fn engine(&self) -> &ConstrainedEngine {
248 &self.engine
249 }
250
251 pub fn engine_mut(&mut self) -> &mut ConstrainedEngine {
253 &mut self.engine
254 }
255
256 pub fn connection_state(&self, connection_id: ConnectionId) -> Option<ConnectionState> {
258 self.engine.connection_state(connection_id)
259 }
260
261 pub fn active_connections(&self) -> Vec<ConnectionId> {
263 self.engine.active_connections()
264 }
265}
266
267#[derive(Debug, Clone)]
269pub enum AdapterEvent {
270 ConnectionAccepted {
272 connection_id: ConnectionId,
274 remote_addr: ConstrainedAddr,
276 },
277 ConnectionEstablished {
279 connection_id: ConnectionId,
281 },
282 DataReceived {
284 connection_id: ConnectionId,
286 data: Vec<u8>,
288 },
289 ConnectionClosed {
291 connection_id: ConnectionId,
293 },
294 ConnectionError {
296 connection_id: ConnectionId,
298 error: String,
300 },
301 Transmit {
303 destination: TransportAddr,
305 packet: Vec<u8>,
307 },
308}
309
310#[cfg(test)]
311mod tests {
312 use super::*;
313
314 #[test]
315 fn test_adapter_creation() {
316 let adapter = ConstrainedEngineAdapter::for_ble();
317 assert_eq!(adapter.connection_count(), 0);
318 }
319
320 #[test]
321 fn test_adapter_connect_udp() {
322 let mut adapter = ConstrainedEngineAdapter::for_ble();
323 let addr = TransportAddr::Udp("192.168.1.100:8080".parse().unwrap());
324
325 let result = adapter.connect(&addr);
326 assert!(result.is_ok());
327
328 let (_conn_id, outputs) = result.unwrap();
329 assert_eq!(outputs.len(), 1);
330 assert_eq!(outputs[0].destination, addr);
331 assert!(!outputs[0].data.is_empty());
332 assert_eq!(adapter.connection_count(), 1);
333 }
334
335 #[test]
336 fn test_adapter_connect_ble() {
337 let mut adapter = ConstrainedEngineAdapter::for_ble();
338 let addr = TransportAddr::Ble {
339 device_id: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF],
340 service_uuid: None,
341 };
342
343 let result = adapter.connect(&addr);
344 assert!(result.is_ok());
345
346 let (_conn_id, outputs) = result.unwrap();
347 assert_eq!(outputs.len(), 1);
348 assert_eq!(outputs[0].destination, addr);
350 assert!(!outputs[0].data.is_empty());
351 }
352
353 #[test]
354 fn test_adapter_synthetic_address_reuse() {
355 let mut adapter = ConstrainedEngineAdapter::for_ble();
356 let addr = TransportAddr::Ble {
357 device_id: [0x11, 0x22, 0x33, 0x44, 0x55, 0x66],
358 service_uuid: None,
359 };
360
361 let socket1 = adapter.get_or_create_socket_addr(&addr);
363 let socket2 = adapter.get_or_create_socket_addr(&addr);
364 assert_eq!(socket1, socket2);
365 }
366
367 #[test]
368 fn test_adapter_different_addresses() {
369 let mut adapter = ConstrainedEngineAdapter::for_ble();
370
371 let addr1 = TransportAddr::Ble {
372 device_id: [0x11, 0x22, 0x33, 0x44, 0x55, 0x66],
373 service_uuid: None,
374 };
375 let addr2 = TransportAddr::Ble {
376 device_id: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF],
377 service_uuid: None,
378 };
379
380 let socket1 = adapter.get_or_create_socket_addr(&addr1);
381 let socket2 = adapter.get_or_create_socket_addr(&addr2);
382
383 assert_ne!(socket1, socket2);
385 }
386
387 #[test]
388 fn test_adapter_poll() {
389 let mut adapter = ConstrainedEngineAdapter::for_ble();
390
391 let outputs = adapter.poll();
393 assert!(outputs.is_empty());
394 }
395}