1use serialport::SerialPort;
2use std::time::{Duration, Instant};
3use crate::values::*;
4
5pub struct PortHandler {
6 port: Option<Box<dyn SerialPort>>,
7 port_name: String,
8 baudrate: u32,
9 packet_start_time: Instant,
10 packet_timeout: Duration,
11 tx_time_per_byte: f64,
12 pub is_using: bool,
13}
14
15impl PortHandler {
16 pub fn new(port_name: &str) -> Self {
17 Self {
18 port: None,
19 port_name: port_name.to_string(),
20 baudrate: DEFAULT_BAUDRATE,
21 packet_start_time: Instant::now(),
22 packet_timeout: Duration::from_millis(0),
23 tx_time_per_byte: 0.0,
24 is_using: false,
25 }
26 }
27
28 pub fn open_port(&mut self) -> Result<(), String> {
29 self.setup_port()
30 }
31
32 pub fn close_port(&mut self) {
33 self.port = None;
34 }
35
36 pub fn clear_port(&mut self) -> Result<(), String> {
37 if let Some(ref mut port) = self.port {
38 port.flush().map_err(|e| e.to_string())?;
39 }
40 Ok(())
41 }
42
43 pub fn get_bytes_available(&mut self) -> Result<u32, String> {
44 if let Some(ref mut port) = self.port {
45 port.bytes_to_read().map_err(|e| e.to_string())
46 } else {
47 Ok(0)
48 }
49 }
50
51 pub fn read_port(&mut self, length: usize) -> Result<Vec<u8>, String> {
52 if let Some(ref mut port) = self.port {
53 let mut buffer = vec![0u8; length];
54 let bytes_read = port.read(&mut buffer).map_err(|e| e.to_string())?;
55 buffer.truncate(bytes_read);
56 Ok(buffer)
57 } else {
58 Ok(Vec::new())
59 }
60 }
61
62 pub fn write_port(&mut self, packet: &[u8]) -> Result<usize, String> {
63 if let Some(ref mut port) = self.port {
64 port.write(packet).map_err(|e| e.to_string())
65 } else {
66 Err("Port not open".to_string())
67 }
68 }
69
70 pub fn set_packet_timeout(&mut self, packet_length: usize) {
71 self.packet_start_time = Instant::now();
72 let timeout_ms = (self.tx_time_per_byte * packet_length as f64)
73 + (self.tx_time_per_byte * 3.0)
74 + LATENCY_TIMER;
75 self.packet_timeout = Duration::from_millis(timeout_ms as u64);
76 }
77
78 pub fn set_packet_timeout_millis(&mut self, msec: u64) {
79 self.packet_start_time = Instant::now();
80 self.packet_timeout = Duration::from_millis(msec);
81 }
82
83 pub fn is_packet_timeout(&mut self) -> bool {
84 if self.get_time_since_start() > self.packet_timeout {
85 self.packet_timeout = Duration::from_millis(0);
86 true
87 } else {
88 false
89 }
90 }
91
92 fn get_time_since_start(&self) -> Duration {
93 Instant::now().duration_since(self.packet_start_time)
94 }
95
96 fn setup_port(&mut self) -> Result<(), String> {
97 let port = serialport::new(&self.port_name, self.baudrate)
98 .timeout(Duration::from_millis(0))
99 .open()
100 .map_err(|e| format!("Could not open port {}: {}", self.port_name, e))?;
101
102 self.port = Some(port);
103
104 if let Some(ref mut p) = self.port {
106 let _ = p.clear(serialport::ClearBuffer::Input);
107 }
108
109 self.tx_time_per_byte = (1000.0 / self.baudrate as f64) * 10.0;
110
111 Ok(())
112 }
113}