use std::io::{BufReader, Read, Write};
use std::net::TcpStream;
use std::sync::mpsc;
use std::thread;
use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};
use socketcan::{CanFrame, CanSocket, EmbeddedFrame, ExtendedId, Socket};
pub fn new_client_handler(
mut connection: TcpStream,
can_interface: String,
can_reader: mpsc::Receiver<CanFrame>,
) -> (thread::JoinHandle<()>, thread::JoinHandle<()>) {
let connection_clone = connection.try_clone().unwrap();
let tx_handle = thread::spawn(move || {
let ip = connection.peer_addr().unwrap();
loop {
let frame = can_reader.recv().unwrap();
if send_frame(&mut connection, frame).is_err() {
println!("Connection to client {:?} dropped.", ip);
break;
}
}
});
let rx_handle = thread::spawn(move || {
let ip = connection_clone.peer_addr().unwrap();
let mut connection = BufReader::new(connection_clone);
let can_socket = CanSocket::open(&can_interface).unwrap();
loop {
let Some(id) = connection
.read_u32::<NetworkEndian>()
.ok()
.and_then(ExtendedId::new)
else {
println!("Connection to client {:?} dropped.", ip);
break;
};
let mut data = [0 as u8; 8];
if connection.read_exact(&mut data).is_err() {
println!("Connection to client {:?} dropped.", ip);
break;
}
let frame = CanFrame::new(id, &data).unwrap();
can_socket.write_frame_insist(&frame).unwrap();
}
});
(tx_handle, rx_handle)
}
fn send_frame(connection: &mut TcpStream, frame: CanFrame) -> Result<(), std::io::Error> {
let id = match frame.id() {
socketcan::Id::Standard(id) => id.as_raw() as u32,
socketcan::Id::Extended(id) => id.as_raw(),
};
connection.write_u32::<NetworkEndian>(id)?;
connection.write_all(frame.data())?;
connection.flush().unwrap();
Ok(())
}