From 016049981d8ffea8b158ae9be317e761e3fcba33 Mon Sep 17 00:00:00 2001 From: Omelia Iliffe Date: Tue, 5 Dec 2023 12:02:47 +1300 Subject: [PATCH 1/3] Fix status response reading logic when using sync_read at high baudrates multiple response packets are read at the same time, and the tailing packets discarded. By checking if a packet is in the buffer before trying to read new bytes this is prevented. --- src/bus.rs | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/bus.rs b/src/bus.rs index 6d2bc29..cff2a7b 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -161,6 +161,20 @@ where pub fn read_status_response(&mut self) -> Result, ReadError> { let deadline = Instant::now() + self.read_timeout; let stuffed_message_len = loop { + if self.read_len > HEADER_PREFIX.len() { + self.remove_garbage(); + + if self.read_len > STATUS_HEADER_SIZE && self.read_buffer.as_mut()[..self.read_len].starts_with(&HEADER_PREFIX) { + let read_buffer = &self.read_buffer.as_mut()[..self.read_len]; + let body_len = read_buffer[5] as usize + read_buffer[6] as usize * 256; + let body_len = body_len - 2; // Length includes instruction and error fields, which is already included in STATUS_HEADER_SIZE too. + + if self.read_len >= STATUS_HEADER_SIZE + body_len { + break STATUS_HEADER_SIZE + body_len; + } + } + } + if Instant::now() > deadline { trace!("timeout reading status response, data in buffer: {:02X?}", &self.read_buffer.as_ref()[..self.read_len]); return Err(std::io::ErrorKind::TimedOut.into()); @@ -173,23 +187,6 @@ where } self.read_len += new_data; - self.remove_garbage(); - - let read_buffer = &self.read_buffer.as_mut()[..self.read_len]; - if !read_buffer.starts_with(&HEADER_PREFIX) { - continue; - } - - if self.read_len < STATUS_HEADER_SIZE { - continue; - } - - let body_len = read_buffer[5] as usize + read_buffer[6] as usize * 256; - let body_len = body_len - 2; // Length includes instruction and error fields, which is already included in STATUS_HEADER_SIZE too. - - if self.read_len >= STATUS_HEADER_SIZE + body_len { - break STATUS_HEADER_SIZE + body_len; - } }; let buffer = self.read_buffer.as_mut(); From 314a270b803f750633d3ffe5f18a98d871a63db1 Mon Sep 17 00:00:00 2001 From: Omelia Iliffe Date: Thu, 7 Dec 2023 09:58:25 +1300 Subject: [PATCH 2/3] removed extra if in read_status_response --- src/bus.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/bus.rs b/src/bus.rs index cff2a7b..1098748 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -161,17 +161,15 @@ where pub fn read_status_response(&mut self) -> Result, ReadError> { let deadline = Instant::now() + self.read_timeout; let stuffed_message_len = loop { - if self.read_len > HEADER_PREFIX.len() { - self.remove_garbage(); + self.remove_garbage(); - if self.read_len > STATUS_HEADER_SIZE && self.read_buffer.as_mut()[..self.read_len].starts_with(&HEADER_PREFIX) { - let read_buffer = &self.read_buffer.as_mut()[..self.read_len]; - let body_len = read_buffer[5] as usize + read_buffer[6] as usize * 256; - let body_len = body_len - 2; // Length includes instruction and error fields, which is already included in STATUS_HEADER_SIZE too. + if self.read_len > STATUS_HEADER_SIZE { + let read_buffer = &self.read_buffer.as_mut()[..self.read_len]; + let body_len = read_buffer[5] as usize + read_buffer[6] as usize * 256; + let body_len = body_len - 2; // Length includes instruction and error fields, which is already included in STATUS_HEADER_SIZE too. - if self.read_len >= STATUS_HEADER_SIZE + body_len { - break STATUS_HEADER_SIZE + body_len; - } + if self.read_len >= STATUS_HEADER_SIZE + body_len { + break STATUS_HEADER_SIZE + body_len; } } From 1d8e7adf83410c2e3acbfe8ada3423499b36be59 Mon Sep 17 00:00:00 2001 From: omelia-wetaworkshop <137133300+omelia-wetaworkshop@users.noreply.github.com> Date: Thu, 7 Dec 2023 12:17:10 +1300 Subject: [PATCH 3/3] added documenting comment Co-authored-by: Maarten de Vries --- src/bus.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bus.rs b/src/bus.rs index 1098748..ab50f38 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -163,6 +163,8 @@ where let stuffed_message_len = loop { self.remove_garbage(); + // The call to remove_garbage() removes all leading bytes that don't match a status header. + // So if there's enough bytes left, it's a status header. if self.read_len > STATUS_HEADER_SIZE { let read_buffer = &self.read_buffer.as_mut()[..self.read_len]; let body_len = read_buffer[5] as usize + read_buffer[6] as usize * 256;