Read from serial device with timeouts
This commit is contained in:
		@@ -18,7 +18,7 @@ use crate::utils::{
 | 
				
			|||||||
    to_ascii_debug,
 | 
					    to_ascii_debug,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn find_begin_of_improv_packet(buffer: &Vec<u8>) -> Result<usize> {
 | 
					pub fn find_begin_of_improv_packet(buffer: &[u8]) -> Result<usize> {
 | 
				
			||||||
    let mut improv_header_char: usize = 0;
 | 
					    let mut improv_header_char: usize = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (i, b) in buffer.iter().enumerate() {
 | 
					    for (i, b) in buffer.iter().enumerate() {
 | 
				
			||||||
@@ -40,6 +40,31 @@ pub fn find_begin_of_improv_packet(buffer: &Vec<u8>) -> Result<usize> {
 | 
				
			|||||||
    bail!("Improv header not found");
 | 
					    bail!("Improv header not found");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct PacketBounds {
 | 
				
			||||||
 | 
					    begin: usize,
 | 
				
			||||||
 | 
					    end: usize,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn find_packet(buffer: &[u8]) -> Result<PacketBounds> {
 | 
				
			||||||
 | 
					        let improv_packet_offset = find_begin_of_improv_packet(buffer)
 | 
				
			||||||
 | 
					            .context("Failed to find improv header in received bytes from serial device")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let improv_packet_len_position = improv_packet_offset + 8;
 | 
				
			||||||
 | 
					        if buffer.len() <= improv_packet_len_position {
 | 
				
			||||||
 | 
					            bail!("Byte that contains length of improv packet not available in buffer");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let improv_packet_end = improv_packet_offset + 10 + <u8 as Into<usize>>::into(buffer[improv_packet_len_position]);
 | 
				
			||||||
 | 
					        if buffer.len() <= improv_packet_end {
 | 
				
			||||||
 | 
					            bail!("Buffer stops before improv packet ends");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(PacketBounds {
 | 
				
			||||||
 | 
					            begin: improv_packet_offset,
 | 
				
			||||||
 | 
					            end: improv_packet_end,
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct SerialInterface {
 | 
					pub struct SerialInterface {
 | 
				
			||||||
    interface: Box<dyn tokio_serial::SerialPort>,
 | 
					    interface: Box<dyn tokio_serial::SerialPort>,
 | 
				
			||||||
    buffer: Vec<u8>,
 | 
					    buffer: Vec<u8>,
 | 
				
			||||||
@@ -77,7 +102,7 @@ impl SerialInterface {
 | 
				
			|||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn recv_bytes(&mut self) -> Result<Vec<u8>> {
 | 
					    pub fn fill_buffer(&mut self) -> Result<()> {
 | 
				
			||||||
        let available_bytes = self.interface.bytes_to_read()
 | 
					        let available_bytes = self.interface.bytes_to_read()
 | 
				
			||||||
            .context("Failed to figure out how many bytes are available to read")?
 | 
					            .context("Failed to figure out how many bytes are available to read")?
 | 
				
			||||||
            .try_into()?;
 | 
					            .try_into()?;
 | 
				
			||||||
@@ -85,10 +110,13 @@ impl SerialInterface {
 | 
				
			|||||||
        debug!("Available bytes to read: {}", available_bytes);
 | 
					        debug!("Available bytes to read: {}", available_bytes);
 | 
				
			||||||
        let mut buffer: Vec<u8> = vec![0; available_bytes];
 | 
					        let mut buffer: Vec<u8> = vec![0; available_bytes];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if buffer.len() > 0 {
 | 
					        if buffer.len() <= 0 {
 | 
				
			||||||
 | 
					            debug!("No bytes available to read");
 | 
				
			||||||
 | 
					            return Ok(());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.interface.read(&mut buffer)
 | 
					        self.interface.read(&mut buffer)
 | 
				
			||||||
            .context("Failed to read bytes from serial device")?;
 | 
					            .context("Failed to read bytes from serial device")?;
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if log_enabled!(Level::Debug) {
 | 
					        if log_enabled!(Level::Debug) {
 | 
				
			||||||
            debug!("Received bytes: \n{}\n{}", hex::encode(&buffer), to_ascii_debug(&buffer));
 | 
					            debug!("Received bytes: \n{}\n{}", hex::encode(&buffer), to_ascii_debug(&buffer));
 | 
				
			||||||
@@ -96,23 +124,36 @@ impl SerialInterface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        self.buffer.append(&mut buffer);
 | 
					        self.buffer.append(&mut buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn recv_bytes(&mut self) -> Result<Vec<u8>> {
 | 
				
			||||||
 | 
					        let retry_counter = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let packet_bounds: PacketBounds;
 | 
				
			||||||
 | 
					        let mut buffer: Vec<u8>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        loop {
 | 
				
			||||||
 | 
					            if retry_counter > 300 {
 | 
				
			||||||
 | 
					                bail!("Failed to fetch more data, timed out");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            self.fill_buffer()
 | 
				
			||||||
 | 
					                .context("Failed to fill read buffer")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            buffer = self.buffer.clone();
 | 
					            buffer = self.buffer.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if log_enabled!(Level::Debug) {
 | 
					            if let Ok(pb) = find_packet(&buffer) {
 | 
				
			||||||
            debug!("Buffer: \n{}\n{}", hex::encode(&buffer), to_ascii_debug(&buffer));
 | 
					                packet_bounds = pb;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let improv_packet_offset = find_begin_of_improv_packet(&buffer).context("Failed to find improv header in received bytes from serial device")?;
 | 
					            std::thread::sleep(std::time::Duration::from_millis(10));
 | 
				
			||||||
 | 
					 | 
				
			||||||
        let improv_packet_end = improv_packet_offset + 10 + <u8 as Into<usize>>::into(buffer[improv_packet_offset+8]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if buffer.len() <= improv_packet_end {
 | 
					 | 
				
			||||||
            bail!("Incomplete packet, packet longer than available in buffer");
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let packet_bytes = buffer[improv_packet_offset..improv_packet_end].to_vec();
 | 
					        let packet_bytes = buffer[packet_bounds.begin..packet_bounds.end].to_vec();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.buffer = buffer[improv_packet_end..].to_vec();
 | 
					        self.buffer = buffer[packet_bounds.end..].to_vec();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if log_enabled!(Level::Debug) {
 | 
					        if log_enabled!(Level::Debug) {
 | 
				
			||||||
            debug!("Received packet: \n{}\n{}", hex::encode(&packet_bytes), to_ascii_debug(&packet_bytes));
 | 
					            debug!("Received packet: \n{}\n{}", hex::encode(&packet_bytes), to_ascii_debug(&packet_bytes));
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user