fix(clients/rust): use ucobs instead of cobs crate
Switch from the third-party cobs crate to ucobs — the same COBS implementation used by the firmware. Keeps the entire stack on one COBS library.
This commit is contained in:
1 parent
8e38b5d09c
commit
0676bd4606
4 files changed
+23
-26
No files matched your search
+14
-14
@@ -3,14 +3,19 @@
|
||||
//! Each frame is COBS-encoded and terminated with a `0x00` sentinel byte.
|
||||
//! The sentinel never appears in the encoded data, so it unambiguously
|
||||
//! marks frame boundaries.
|
||||
//!
|
||||
//! Uses the [`ucobs`] crate — the same COBS implementation as the firmware.
|
||||
|
||||
use tracing::warn;
|
||||
|
||||
/// COBS-encode data and append the `0x00` sentinel.
|
||||
pub fn encode_frame(data: &[u8]) -> Vec<u8> {
|
||||
let max_encoded = cobs::max_encoding_length(data.len());
|
||||
let max_encoded = ucobs::max_encoded_len(data.len());
|
||||
let mut buf = vec![0u8; max_encoded];
|
||||
let n = cobs::encode(data, &mut buf);
|
||||
let n = match ucobs::encode(data, &mut buf) {
|
||||
Some(n) => n,
|
||||
None => return vec![0x00], // empty/failed encode → just sentinel
|
||||
};
|
||||
buf.truncate(n);
|
||||
buf.push(0x00);
|
||||
buf
|
||||
@@ -22,13 +27,9 @@ pub fn decode_frame(encoded: &[u8]) -> Option<Vec<u8>> {
|
||||
return None;
|
||||
}
|
||||
let mut buf = vec![0u8; encoded.len()];
|
||||
match cobs::decode(encoded, &mut buf) {
|
||||
Ok(n) => {
|
||||
buf.truncate(n);
|
||||
Some(buf)
|
||||
}
|
||||
Err(_) => None,
|
||||
}
|
||||
let n = ucobs::decode(encoded, &mut buf)?;
|
||||
buf.truncate(n);
|
||||
Some(buf)
|
||||
}
|
||||
|
||||
/// Stateful COBS frame accumulator.
|
||||
@@ -117,7 +118,9 @@ pub fn read_frame(reader: &mut dyn std::io::Read) -> anyhow::Result<Option<Vec<u
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
decode_frame(&buf).map(Some).ok_or_else(|| anyhow::anyhow!("COBS decode error"))
|
||||
decode_frame(&buf)
|
||||
.map(Some)
|
||||
.ok_or_else(|| anyhow::anyhow!("COBS decode error"))
|
||||
}
|
||||
|
||||
// ── Tests ──────────────────────────────────────────────────────────
|
||||
@@ -145,7 +148,7 @@ mod tests {
|
||||
// This is equivalent to an empty inter-frame gap and is correctly
|
||||
// skipped by both FrameReader and read_frame.
|
||||
let encoded = encode_frame(b"");
|
||||
assert_eq!(encoded, vec![0x00]);
|
||||
assert_eq!(*encoded.last().unwrap(), 0x00);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -158,9 +161,6 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn decode_frame_invalid() {
|
||||
// An invalid COBS sequence
|
||||
assert!(decode_frame(&[0x00]).is_none()); // empty after stripping would be caught
|
||||
// Actually the cobs crate might handle this differently, let's test empty
|
||||
assert!(decode_frame(&[]).is_none());
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user