From 89bcd4c0a2e3ceb8d21f37d1eded7ff660055a7c Mon Sep 17 00:00:00 2001 From: Raul Victor Trombin Date: Thu, 10 Oct 2024 19:38:02 -0300 Subject: [PATCH 1/2] src: examples: Add omniscan example --- examples/omniscan450.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 examples/omniscan450.rs diff --git a/examples/omniscan450.rs b/examples/omniscan450.rs new file mode 100644 index 0000000000..ebccf05056 --- /dev/null +++ b/examples/omniscan450.rs @@ -0,0 +1,25 @@ +mod common; +use common::{configure_tracing, create_port, Port}; + +use bluerobotics_ping::{device::PingDevice, error::PingError, omniscan450::Device as OmniScan450}; + +#[tokio::main] +async fn main() -> Result<(), PingError> { + configure_tracing(); + + println!("Parsing user provided values and creating port..."); + let port = create_port().await; + + println!("Creating your Omniscan device"); + let omniscan450 = match port { + Port::Serial(port) => OmniScan450::new(port), + Port::Udp(port) => OmniScan450::new(port), + Port::Tcp(port) => OmniScan450::new(port), + }; + + let device_information = omniscan450.device_information().await?; + + println!("Device information: {device_information:?}"); + + Ok(()) +} From ef4efc8e7db6c0ef341a4ce99d8d6d72122e9477 Mon Sep 17 00:00:00 2001 From: Raul Victor Trombin Date: Wed, 16 Apr 2025 17:00:34 -0300 Subject: [PATCH 2/2] examples: common: Add tcp stream option --- examples/common/mod.rs | 51 +++++++++++++++++++++++++++++++++-------- examples/ping_1d.rs | 1 + examples/ping_360.rs | 1 + examples/ping_common.rs | 1 + 4 files changed, 45 insertions(+), 9 deletions(-) diff --git a/examples/common/mod.rs b/examples/common/mod.rs index d06082e860..f5618711ed 100644 --- a/examples/common/mod.rs +++ b/examples/common/mod.rs @@ -3,7 +3,9 @@ use std::{ net::{IpAddr, SocketAddr}, path::PathBuf, str::FromStr, + time::Duration, }; +use tokio::{net::TcpStream, time::timeout}; use tokio_serial::{SerialPort, SerialPortBuilderExt}; use tracing_subscriber; use udp_stream::UdpStream; @@ -11,19 +13,24 @@ use udp_stream::UdpStream; #[derive(Parser, Debug)] #[command(version, about, long_about = None)] pub struct Args { - #[arg(long, group = "source", conflicts_with_all = ["udp_address"])] + #[arg(long, group = "source", conflicts_with_all = ["udp_address", "tcp_address"])] pub serial_port: Option, #[arg(long, default_value_t = 115200)] pub serial_baud_rate: u32, - #[arg(long, group = "source", conflicts_with_all = ["serial_port"])] + #[arg(long, group = "source", conflicts_with_all = ["serial_port", "tcp_address"])] pub udp_address: Option, #[arg(long, default_value_t = 8080)] pub udp_port: u32, + #[arg(long, group = "source", conflicts_with_all = ["serial_port", "udp_address"])] + pub tcp_address: Option, + #[arg(long, default_value_t = 8080)] + pub tcp_port: u32, } pub enum Port { Serial(tokio_serial::SerialStream), Udp(udp_stream::UdpStream), + Tcp(TcpStream), } pub fn configure_tracing() { @@ -37,8 +44,8 @@ pub fn configure_tracing() { pub async fn create_port() -> Port { let args = Args::parse(); - match (args.serial_port, args.udp_address) { - (Some(serial_port), None) => { + match (args.serial_port, args.udp_address, args.tcp_address) { + (Some(serial_port), None, None) => { println!("Using serial port: {:?}", serial_port); let port = tokio_serial::new(serial_port.to_string_lossy(), args.serial_baud_rate) .open_native_async() @@ -50,7 +57,7 @@ pub async fn create_port() -> Port { port.clear(tokio_serial::ClearBuffer::All).unwrap(); Port::Serial(port) } - (None, Some(udp_address)) => { + (None, Some(udp_address), None) => { println!("Using UDP address: {}", udp_address); let socket_addr = SocketAddr::from_str(&format!("{}:{}", udp_address, args.udp_port)) .map_err(|e| { @@ -67,12 +74,38 @@ pub async fn create_port() -> Port { .unwrap(); Port::Udp(port) } - (None, None) => { - eprintln!("Error: either serial_port_name or udp_address must be provided"); + (None, None, Some(tcp_address)) => { + println!("Using TCP address: {}", tcp_address); + let socket_addr = SocketAddr::from_str(&format!("{}:{}", tcp_address, args.tcp_port)) + .map_err(|e| { + eprintln!("Error parsing TCP address: {}", e); + e + }) + .unwrap(); + + match timeout(Duration::from_secs(10), TcpStream::connect(socket_addr)).await { + Ok(connection_result) => match connection_result { + Ok(port) => { + println!("Successfully connected to TCP server"); + Port::Tcp(port) + } + Err(e) => { + eprintln!("Error connecting to TCP socket: {}", e); + std::process::exit(1); + } + }, + Err(_) => { + eprintln!("TCP connection timed out after 10 seconds"); + std::process::exit(1); + } + } + } + (None, None, None) => { + eprintln!("Error: either serial_port, udp_address, or tcp_address must be provided"); std::process::exit(1); } - (Some(_), Some(_)) => { - eprintln!("Error: serial_port_name and udp_address are mutually exclusive"); + _ => { + eprintln!("Error: serial_port, udp_address, and tcp_address are mutually exclusive"); std::process::exit(1); } } diff --git a/examples/ping_1d.rs b/examples/ping_1d.rs index a6677039ab..d6ca598860 100644 --- a/examples/ping_1d.rs +++ b/examples/ping_1d.rs @@ -21,6 +21,7 @@ async fn main() -> Result<(), PingError> { let ping1d = match port { Port::Serial(port) => Ping1D::new(port), Port::Udp(port) => Ping1D::new(port), + Port::Tcp(port) => Ping1D::new(port), }; // Creating a subscription channel which will receive 30 Profile measurements, we'll check this after the next methods! diff --git a/examples/ping_360.rs b/examples/ping_360.rs index f66a1864b8..bc54657366 100644 --- a/examples/ping_360.rs +++ b/examples/ping_360.rs @@ -17,6 +17,7 @@ async fn main() -> Result<(), PingError> { let ping360 = match port { Port::Serial(port) => Ping360::new(port), Port::Udp(port) => Ping360::new(port), + Port::Tcp(port) => Ping360::new(port), }; println!("Reading transducer data:"); diff --git a/examples/ping_common.rs b/examples/ping_common.rs index 4f4acf5e2f..fbe0897fd8 100644 --- a/examples/ping_common.rs +++ b/examples/ping_common.rs @@ -16,6 +16,7 @@ async fn main() -> Result<(), PingError> { let ping = match port { Port::Serial(port) => Device::new(port), Port::Udp(port) => Device::new(port), + Port::Tcp(port) => Device::new(port), }; // Creating a subscription channel which will receive 2 Protocol Messages, we'll print the device id!