diff --git a/candid_server/src/client_handler.rs b/candid_server/src/client_handler.rs index 5812531..bf4b08f 100644 --- a/candid_server/src/client_handler.rs +++ b/candid_server/src/client_handler.rs @@ -22,12 +22,9 @@ pub fn new_client_handler( let frame = can_reader.recv().unwrap(); // Relay to the client - match connection.write_fmt(format_args!("{:X}\n", frame)) { - Ok(_) => {} - Err(_) => { - println!("Connection to client {:?} dropped.", ip); - break; - } + if let Err(_) = write_frame(&mut connection, frame) { + println!("Connection to client {:?} dropped.", ip); + break; } } }); @@ -64,3 +61,8 @@ pub fn new_client_handler( (tx_handle, rx_handle) } + +fn write_frame(connection: &mut TcpStream, frame: CANFrame) -> Result<(), std::io::Error> { + connection.write_fmt(format_args!("{:X}\n", frame))?; + Ok(()) +} -- 2.51.2 From 367bb202dbc62b7fef0681a7324186b494055af5 Mon Sep 17 00:00:00 2001 From: Alex van de Sandt Date: Fri, 12 Apr 2019 15:47:06 -0400 Subject: [PATCH 2/5] Transmit frames as raw bytes rather than formatted strings --- candid_server/src/client_handler.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/candid_server/src/client_handler.rs b/candid_server/src/client_handler.rs index bf4b08f..7a1cef7 100644 --- a/candid_server/src/client_handler.rs +++ b/candid_server/src/client_handler.rs @@ -3,7 +3,7 @@ use std::net::TcpStream; use std::sync::mpsc; use std::thread; -use byteorder::{NetworkEndian, ReadBytesExt}; +use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt}; use socketcan::{CANFrame, CANSocket}; @@ -63,6 +63,7 @@ pub fn new_client_handler( } fn write_frame(connection: &mut TcpStream, frame: CANFrame) -> Result<(), std::io::Error> { - connection.write_fmt(format_args!("{:X}\n", frame))?; + connection.write_u32::(frame.id())?; + connection.write(&frame.data())?; Ok(()) } -- 2.51.2 From 640f8f31cf543c40715555df39ea36dc0068740c Mon Sep 17 00:00:00 2001 From: Alex van de Sandt Date: Fri, 12 Apr 2019 16:33:36 -0400 Subject: [PATCH 3/5] Use Frames to communicate with server --- candid_client/Cargo.toml | 3 +++ candid_client/examples/echo.rs | 8 ++++---- candid_client/examples/send.rs | 11 ++++++----- candid_client/src/candid_connection.rs | 22 +++++++++++++++------- candid_client/src/frame.rs | 13 +++++++++++++ candid_client/src/lib.rs | 4 ++++ 6 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 candid_client/src/frame.rs diff --git a/candid_client/Cargo.toml b/candid_client/Cargo.toml index 4cb31ae..5fa480d 100644 --- a/candid_client/Cargo.toml +++ b/candid_client/Cargo.toml @@ -10,6 +10,9 @@ documentation = "https://docs.rs/crate/candid_client/" repository = "https://gitlab.com/avandesa/candid-rs" keywords = ["CAN", "SocketCAN"] +[dependencies] +byteorder = "^1.3" + [dev-dependencies] clap = "^2.32" rand = "^0.6" diff --git a/candid_client/examples/echo.rs b/candid_client/examples/echo.rs index 33909b1..67700e6 100644 --- a/candid_client/examples/echo.rs +++ b/candid_client/examples/echo.rs @@ -18,10 +18,10 @@ fn main() { let addr = matches.value_of("addr").unwrap(); - let client = CandidConnection::new(addr).expect("Couldn't connect to server"); + let mut client = CandidConnection::new(addr).expect("Couldn't connect to server"); - for line in client.lines() { - let line = line.unwrap(); - println!("Received: \"{}\"", line); + loop { + let frame = client.read_frame().unwrap(); + println!("{:?}", frame); } } diff --git a/candid_client/examples/send.rs b/candid_client/examples/send.rs index 7bc93bf..ac43cca 100644 --- a/candid_client/examples/send.rs +++ b/candid_client/examples/send.rs @@ -24,12 +24,13 @@ fn main() { for i in 1..10 { let data = random::().to_ne_bytes(); - println!("Sending {}, {:?}", i as u32, data); - client.write_frame(i, data).unwrap(); + let frame = Frame::new(i, data); + println!("Sending {:?}", frame); + client.write_frame(Frame::new(i, data)).unwrap(); } - for line in client.lines() { - let line = line.unwrap(); - println!("Received: \"{}\"", line); + loop { + let frame = client.read_frame().unwrap(); + println!("{:?}", frame); } } diff --git a/candid_client/src/candid_connection.rs b/candid_client/src/candid_connection.rs index 22b8d01..453fd4b 100644 --- a/candid_client/src/candid_connection.rs +++ b/candid_client/src/candid_connection.rs @@ -1,7 +1,11 @@ +use crate::Frame; + use std::io::prelude::*; use std::io::{BufReader, BufWriter, Lines}; use std::net::{TcpStream, ToSocketAddrs}; +use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt}; + pub struct CandidConnection { read_stream: BufReader, write_stream: BufWriter, @@ -22,15 +26,19 @@ impl CandidConnection { } /// Reads a single CAN frame sent by the server. - pub fn read_frame(&mut self) -> Result { - let mut buffer = String::new(); - self.read_stream.read_line(&mut buffer)?; - Ok(buffer) + pub fn read_frame(&mut self) -> Result { + let id = self.read_stream.read_u32::()?; + + let mut data = [0 as u8; 8]; + self.read_stream.read_exact(&mut data)?; + + Ok(Frame::new(id, data)) } - pub fn write_frame(&mut self, id: u32, data: [u8; 8]) -> Result<(), std::io::Error> { - self.write_stream.write(&id.to_be_bytes())?; - self.write_stream.write(&data)?; + pub fn write_frame(&mut self, frame: Frame) -> Result<(), std::io::Error> { + self.write_stream.write_u32::(frame.id)?; + self.write_stream.write(&frame.data)?; + self.write_stream.flush().unwrap(); Ok(()) } diff --git a/candid_client/src/frame.rs b/candid_client/src/frame.rs new file mode 100644 index 0000000..ca5c6bf --- /dev/null +++ b/candid_client/src/frame.rs @@ -0,0 +1,13 @@ +#[derive(Debug)] +pub struct Frame { + pub id: u32, + pub data: [u8; 8], +} + +impl Frame { + // TODO: Implement more frame functionality from `socketcan-rs` + pub fn new(id: u32, data: [u8; 8]) -> Frame { + // TODO: Error checking, etc + Frame { id, data } + } +} diff --git a/candid_client/src/lib.rs b/candid_client/src/lib.rs index a0887aa..ffb5643 100644 --- a/candid_client/src/lib.rs +++ b/candid_client/src/lib.rs @@ -1,3 +1,7 @@ +//! Hello world! + pub mod candid_connection; +pub mod frame; pub use candid_connection::CandidConnection; +pub use frame::Frame; -- 2.51.2 From fb7afd9b8b3e2c5039a4ddf3a4fc820b6f913b39 Mon Sep 17 00:00:00 2001 From: Alex van de Sandt Date: Fri, 12 Apr 2019 16:34:15 -0400 Subject: [PATCH 4/5] Flush buffer when sending --- candid_server/src/client_handler.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/candid_server/src/client_handler.rs b/candid_server/src/client_handler.rs index 7a1cef7..b364a9b 100644 --- a/candid_server/src/client_handler.rs +++ b/candid_server/src/client_handler.rs @@ -65,5 +65,6 @@ pub fn new_client_handler( fn write_frame(connection: &mut TcpStream, frame: CANFrame) -> Result<(), std::io::Error> { connection.write_u32::(frame.id())?; connection.write(&frame.data())?; + connection.flush().unwrap(); Ok(()) } -- 2.51.2 From 80bedf021e6ff464b7c0dd2ed2a3593c142940f2 Mon Sep 17 00:00:00 2001 From: Alex van de Sandt Date: Fri, 12 Apr 2019 16:38:32 -0400 Subject: [PATCH 5/5] Update client README --- candid_client/README | 4 ++-- candid_client/src/lib.rs | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/candid_client/README b/candid_client/README index 5495f63..bc67208 100644 --- a/candid_client/README +++ b/candid_client/README @@ -12,9 +12,9 @@ Documentation: https://docs.rs/crates/candid_client/ ### Prerequisites -CANdid Client itself has no special dependencies, but for it to be useful, you must be able to run CANdid server on your computer or another system accesible over the network. See [CANdid server](https://crates.io/crates/candid_server/) for more information. +CANdid Client itself only depends on [`byteorder`](https://crates.io/crates/byteorder). However, for it to be useful, you must be able to run CANdid server on your computer or another system accessible over the network. See [CANdid server](https://crates.io/crates/candid_server/) for mor information. -The example `echo` uses [`clap`](https://crates.io/crates/clap/) to handle command line arguments. +The example `echo` uses [`clap`](https://crates.io/crates/clap/) to handle command line arguments. The example `send` uses [`rand`](https://crates.io/crates/rand) to generate random data. ### Examples diff --git a/candid_client/src/lib.rs b/candid_client/src/lib.rs index ffb5643..46c4312 100644 --- a/candid_client/src/lib.rs +++ b/candid_client/src/lib.rs @@ -1,5 +1,3 @@ -//! Hello world! - pub mod candid_connection; pub mod frame;