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:
5 files changed
+30
-36
No files matched your search
Generated
+7
-10
@@ -26,15 +26,6 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "cobs"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.10.1"
|
||||
@@ -56,9 +47,9 @@ name = "donglora-client"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cobs",
|
||||
"serialport",
|
||||
"tracing",
|
||||
"ucobs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -240,6 +231,12 @@ dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ucobs"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "311fbab511bafd13c109aff41f67d4c4426bf919a6670647e69f0d2af95ac01d"
|
||||
|
||||
[[package]]
|
||||
name = "unescaper"
|
||||
version = "0.1.8"
|
||||
|
||||
@@ -11,7 +11,7 @@ categories = ["hardware-support"]
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
cobs = "0.3"
|
||||
ucobs = "0.3"
|
||||
serialport = "4"
|
||||
tracing = "0.1"
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ loop {
|
||||
|
||||
## Dependencies
|
||||
|
||||
- `cobs` — COBS framing
|
||||
- `ucobs` — COBS framing (same implementation as the firmware)
|
||||
- `serialport` — USB serial communication
|
||||
- `anyhow` — error handling
|
||||
- `tracing` — logging
|
||||
+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