From 2d37685bd23e5ae3d6672a2c3da076c408217deb Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Fri, 19 Jun 2026 14:20:25 +0200 Subject: [PATCH] udp interface --- src/bin/demo_handler_udp.rs | 46 ++++++++++++++++++++++++++++ src/interfaces/mod.rs | 3 +- src/interfaces/udp_interface.rs | 54 +++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 src/bin/demo_handler_udp.rs create mode 100644 src/interfaces/udp_interface.rs diff --git a/src/bin/demo_handler_udp.rs b/src/bin/demo_handler_udp.rs new file mode 100644 index 0000000..d717cbb --- /dev/null +++ b/src/bin/demo_handler_udp.rs @@ -0,0 +1,46 @@ +use std::net::UdpSocket; + +use devicehandling_traits::device_handlers::demo_handler::{ + DemoHandler, FirstTelecommandData, SecondTelecommandData, Telecommands as DemoTelecommands, +}; + +use devicehandling_traits::interfaces::udp_interface::UdpWrapper; +use devicehandling_traits::runtime::{DeviceHandlerRuntime, Mode}; +use devicehandling_traits::{init_logging, runtime}; +use mio_serial::SerialStream; + +type RuntimeTelecommands = runtime::Telecommands; + +fn main() { + init_logging(log::LevelFilter::Trace); + log::info!("Running Demo Handler with usb\n"); + + let demo_handler = DemoHandler::new(); + + // Local port to listen on, should be RANA_NET_IP_UDP_SIM_FSW_UARTLITE_RW_0 + let socket = UdpSocket::bind("localhost:8311").unwrap(); + // Port the sim listens on, ask them, they do not implement RANA, yet + socket.connect("localhost:8100").unwrap(); + let mut udp_interface = UdpWrapper { + socket, + buffer: Vec::new(), + }; + + let mut runtime = DeviceHandlerRuntime::new(demo_handler); + + let mode_on_tc = RuntimeTelecommands::Mode(Mode::On); + + runtime.run_once(&mode_on_tc, &mut udp_interface); + + let demo_tc_1 = DemoTelecommands::FirstTelecommand(FirstTelecommandData { a_number: 13 }); + + runtime.run_once(&RuntimeTelecommands::Device(demo_tc_1), &mut udp_interface); + + let demo_tc_2 = DemoTelecommands::SecondTelecommand(SecondTelecommandData { a_float: 1.2 }); + + runtime.run_once(&RuntimeTelecommands::Device(demo_tc_2), &mut udp_interface); + + let mode_off_tc = RuntimeTelecommands::Mode(Mode::Off); + + runtime.run_once(&mode_off_tc, &mut udp_interface); +} diff --git a/src/interfaces/mod.rs b/src/interfaces/mod.rs index 44417ed..839c666 100644 --- a/src/interfaces/mod.rs +++ b/src/interfaces/mod.rs @@ -1,2 +1,3 @@ pub mod echo_interface; -pub mod serial_interface; \ No newline at end of file +pub mod serial_interface; +pub mod udp_interface; \ No newline at end of file diff --git a/src/interfaces/udp_interface.rs b/src/interfaces/udp_interface.rs new file mode 100644 index 0000000..3e3b1ab --- /dev/null +++ b/src/interfaces/udp_interface.rs @@ -0,0 +1,54 @@ +use std::net::UdpSocket; + +use crate::io::{Error, Read, Write}; + + +pub struct UdpWrapper { + pub socket: UdpSocket, + pub buffer: Vec, +} + + +impl Write for UdpWrapper { + fn put(&mut self, data: &[u8]) -> crate::io::Result<()> { + self.buffer.extend(data); + Ok(()) + } + + fn putc(&mut self, data: u8) -> crate::io::Result<()> { + self.buffer.push(data); + Ok(()) + } + + fn flush(&mut self) -> crate::io::Result<()> { + let res = self.socket.send(&self.buffer); + self.buffer.clear(); + match res { + Ok(_) => return Ok(()), + Err(_) => return Err(Error::Unknown), // TODO + } + } +} + +impl Read for UdpWrapper { + fn read<'a>(&mut self, buffer: &'a mut [u8]) -> crate::io::Result<&'a [u8]> { + let res = self.socket.recv(buffer); + log::trace!("udp read {:?}", res); + if let Ok(written) = res { + if written > buffer.len() { + // TODO + return Err(Error::Unknown); + } + return Ok(&buffer[..written]); + } + if let Err(e) = res { + if e.raw_os_error().unwrap_or(0) == 4 { + // TODO + return Ok(&[]); + } else { + log::error!("udp read err {:?}", e); + } + } + Err(Error::Unknown) + } +} \ No newline at end of file