1use std::{
2 io::{ErrorKind, Write},
3 net::{TcpListener, TcpStream, ToSocketAddrs},
4 time::Duration,
5};
6
7use crate::XvcServer;
8use xvc_protocol::error::ReadError;
9use xvc_protocol::{Message, Version, XvcInfo};
10
11#[derive(Debug, Clone)]
12pub struct Config {
13 pub max_vector_size: u32,
14 pub read_write_timeout: Duration,
15}
16
17impl Default for Config {
18 fn default() -> Self {
19 Self {
20 max_vector_size: 10 * 1024 * 1024,
21 read_write_timeout: Duration::from_secs(30),
22 }
23 }
24}
25
26#[derive(Debug)]
27pub struct Server<T: XvcServer> {
28 server: T,
29 config: Config,
30}
31
32impl<T: XvcServer> Server<T> {
33 pub fn new(server: T, config: Config) -> Server<T> {
34 Server { server, config }
35 }
36
37 pub fn listen(&self, addr: impl ToSocketAddrs) -> Result<(), Box<dyn std::error::Error>> {
38 let listener = TcpListener::bind(addr)?;
39 log::info!("Server listening for connections");
40
41 for stream in listener.incoming() {
42 match stream {
43 Ok(tcp) => {
44 let peer_addr = tcp.peer_addr().ok();
45 if let Some(addr) = peer_addr {
46 log::info!("New client connection from {}", addr);
47 }
48 if let Err(e) = self.handle_client(tcp) {
49 log::error!("Client error: {}", e);
50 }
51 }
52 Err(e) => log::error!("Connection error: {}", e),
53 }
54 }
55 Ok(())
56 }
57
58 fn handle_client(&self, mut tcp: TcpStream) -> Result<(), ReadError> {
59 tcp.set_read_timeout(Some(self.config.read_write_timeout))?;
60 tcp.set_write_timeout(Some(self.config.read_write_timeout))?;
61
62 loop {
63 match Message::from_reader(&mut tcp, self.config.max_vector_size as usize) {
64 Ok(message) => self.process_message(message, &mut tcp)?,
65 Err(ReadError::IoError(err)) if err.kind() == ErrorKind::TimedOut => {
66 log::error!("Client read timeout, closing connection");
67 break;
68 }
69 Err(ReadError::IoError(err))
70 if err.kind() == ErrorKind::ConnectionAborted
71 || err.kind() == ErrorKind::ConnectionReset =>
72 {
73 break;
74 } Err(other) => return Err(other),
76 }
77 }
78 Ok(())
79 }
80
81 fn process_message(&self, message: Message, tcp: &mut TcpStream) -> Result<(), ReadError> {
83 match message {
84 Message::GetInfo => {
85 log::info!("Received GetInfo message");
86 let info = XvcInfo::new(Version::V1_0, self.config.max_vector_size);
87 info.write_to(tcp)?;
88 log::debug!("Sent XVC info response");
89 }
90 Message::SetTck { period_ns } => {
91 log::debug!("Received SetTck message: period_ns={}", period_ns);
92 let ret_period = self.server.set_tck(period_ns);
93 log::debug!("Set TCK returned: period_ns={}", ret_period);
94 tcp.write_all(&ret_period.to_le_bytes())?;
95 }
96 Message::Shift { num_bits, tms, tdi } => {
97 log::debug!(
98 "Received Shift message: num_bits={}, tms_len={}, tdi_len={}",
99 num_bits,
100 tms.len(),
101 tdi.len()
102 );
103 log::trace!("Shift TMS data: {:02x?}", &tms[..]);
104 log::trace!("Shift TDI data: {:02x?}", &tdi[..]);
105 let tdo = self.server.shift(num_bits, tms, tdi);
106 log::trace!("Shift result TDO data: {:02x?}", &tdo[..]);
107 tcp.write_all(&tdo)?;
108 }
109 }
110 Ok(())
111 }
112}