diff --git a/Cargo.lock b/Cargo.lock index 66e2477..8d4946a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -371,9 +371,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "crc" -version = "3.0.1" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" dependencies = [ "crc-catalog", ] diff --git a/Cargo.toml b/Cargo.toml index 3981216..9e9826f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/CodeConstruct/mctp-rs" anyhow = "1.0.80" argh = "0.1.12" chrono = { version = "0.4", default-features = false } -crc = "3.0" +crc = "3.3" defmt = "0.3" deku = { git = "https://github.com/CodeConstruct/deku.git", tag = "cc/deku-v0.19.1/no-alloc-3", default-features = false } embedded-io-adapters = { version = "0.6", features = ["std", "futures-03"] } diff --git a/pldm-file/src/client.rs b/pldm-file/src/client.rs index 1f6bb88..2975440 100644 --- a/pldm-file/src/client.rs +++ b/pldm-file/src/client.rs @@ -167,6 +167,8 @@ where req_offset, req_length, }; + let crc32 = crc::Crc::::new(&crc::CRC_32_ISO_HDLC); + let mut digest = crc32.digest(); loop { let mut tx_buf = [0; 18]; let l = req.to_slice(&mut tx_buf).map_err(|_| PldmError::NoSpace)?; @@ -196,12 +198,11 @@ where let (resp_data, resp_cs) = rest.split_at(resp_data_len); - let crc32 = crc::Crc::::new(&crc::CRC_32_ISO_HDLC); - let calc_cs = crc32.checksum(resp_data); + digest.update(resp_data); // unwrap: we have asserted the lengths above let cs = u32::from_le_bytes(resp_cs.try_into().unwrap()); - if calc_cs != cs { + if digest.clone().finalize() != cs { return Err(proto_error!("data checksum mismatch")); } diff --git a/pldm-file/src/host.rs b/pldm-file/src/host.rs index 830de17..9888716 100644 --- a/pldm-file/src/host.rs +++ b/pldm-file/src/host.rs @@ -23,6 +23,9 @@ pub trait Host { fn read(&self, buf: &mut [u8], offset: usize) -> std::io::Result; } +const CRC32: crc::Crc> = + crc::Crc::>::new(&crc::CRC_32_ISO_HDLC); + // Created at the first stage (XFER_FIRST_PART) of a MultpartReceive, // where we have the offset and size. struct FileTransferContext { @@ -31,6 +34,23 @@ struct FileTransferContext { len: usize, // Current transfer 0..len offset: usize, + digest: crc::Digest<'static, u32, crc::Table<16>>, +} + +impl FileTransferContext { + fn new(start: usize, len: usize) -> Self { + Self { + start, + len, + offset: 0, + digest: CRC32.digest(), + } + } + + fn reset(&mut self) { + self.offset = 0; + self.digest = CRC32.digest(); + } } // Created on DfOpen @@ -346,11 +366,14 @@ impl Responder { // Set new transfer context if cmd.xfer_op == pldm::control::xfer_op::FIRST_PART { if let Some(ctx) = file_ctx.xfer_ctx.as_mut() { - ctx.offset = 0; - } else { - let new_ctx = Self::init_read(&cmd)?; // a repeated FIRST_PART is valid, and restarts the transfer - file_ctx.xfer_ctx.replace(new_ctx); + ctx.reset(); + } else { + let ctx = FileTransferContext::new( + cmd.req_offset as usize, + cmd.req_length as usize, + ); + file_ctx.xfer_ctx.replace(ctx); }; } @@ -402,8 +425,9 @@ impl Responder { let data = &mut resp_data[l..]; host.read(data, xfer_ctx.start + offset) .map_err(|_| CCode::ERROR)?; - let crc32 = crc::Crc::::new(&crc::CRC_32_ISO_HDLC); - let cs = crc32.checksum(data); + + xfer_ctx.digest.update(data); + let cs = xfer_ctx.digest.clone().finalize(); resp_data.extend_from_slice(&cs.to_le_bytes()); xfer_ctx.offset = offset; @@ -411,19 +435,6 @@ impl Responder { Ok(resp) } - - fn init_read( - req: &pldm::control::MultipartReceiveReq, - ) -> Result { - trace!("init_read {req:?}"); - let start = req.req_offset as usize; - let len = req.req_length as usize; - Ok(FileTransferContext { - start, - len, - offset: 0, - }) - } } impl Default for Responder { diff --git a/pldm-platform/src/proto.rs b/pldm-platform/src/proto.rs index e93c71d..b12677b 100644 --- a/pldm-platform/src/proto.rs +++ b/pldm-platform/src/proto.rs @@ -675,8 +675,7 @@ impl GetPDRResp { next_data_transfer_handle: 0, transfer_flag: xfer_flag::START_AND_END, record_data: Default::default(), - // TODO crc - crc: Some(0), + crc: None, }; let cap = s.record_data.capacity(); s.record_data.resize_default(cap).unwrap();