Skip to content

Commit b225fbe

Browse files
committed
wip: squashme: encode/decode
Signed-off-by: leongross <[email protected]>
1 parent 21101c1 commit b225fbe

17 files changed

+1373
-208
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ edition = "2024"
77
[dependencies]
88
zerocopy = {version = "0.8.17", features = ["derive"]}
99
bitfield = "0.14.0"
10+
bytemuck = "1.24.0"

src/codec.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use zerocopy::{FromBytes, Immutable, IntoBytes};
66
pub enum PldmCodecError {
77
BufferTooShort,
88
Unsupported,
9+
InvalidData,
910
}
1011

1112
/// A trait for encoding and decoding PLDM (Platform Level Data Model) messages.
@@ -67,6 +68,9 @@ pub trait PldmCodecWithLifetime<'a>: core::fmt::Debug + Sized {
6768
}
6869

6970
// Default implementation of PldmCodec for types that can leverage zerocopy.
71+
// TODO: can we generalize this to use sub-struct encodes when possible?
72+
// There are structs like PldmFirmwareString that contain variable-length data
73+
// that would need special handling.
7074
impl<T> PldmCodec for T
7175
where
7276
T: core::fmt::Debug + Sized + FromBytes + IntoBytes + Immutable,

src/message/firmware_update/get_fw_params.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,31 +331,34 @@ mod test {
331331
}
332332

333333
#[test]
334-
fn test_get_firmware_parameters_request() {
334+
fn test_get_firmware_parameters_request_codec() {
335335
let request = GetFirmwareParametersRequest::new(0, PldmMsgType::Request);
336336
let mut buffer = [0u8; PLDM_MSG_HEADER_LEN];
337337
request.encode(&mut buffer).unwrap();
338+
338339
let decoded_request = GetFirmwareParametersRequest::decode(&buffer).unwrap();
339340
assert_eq!(request, decoded_request);
340341
}
341342

342343
#[test]
343-
fn test_get_firmware_parameters() {
344+
fn test_get_firmware_parameters_codec() {
344345
let firmware_parameters = construct_firmware_params();
345346
let mut buffer = [0u8; 1024];
346347
let size = firmware_parameters.encode(&mut buffer).unwrap();
347348
assert_eq!(size, firmware_parameters.codec_size_in_bytes());
349+
348350
let decoded_firmware_parameters = FirmwareParameters::decode(&buffer[..size]).unwrap();
349351
assert_eq!(firmware_parameters, decoded_firmware_parameters);
350352
}
351353

352354
#[test]
353-
fn test_get_firmware_parameters_response() {
355+
fn test_get_firmware_parameters_response_codec() {
354356
let firmware_parameters = construct_firmware_params();
355357
let response = GetFirmwareParametersResponse::new(0, 0, &firmware_parameters);
356358
let mut buffer = [0u8; 1024];
357359
let size = response.encode(&mut buffer).unwrap();
358360
assert_eq!(size, response.codec_size_in_bytes());
361+
359362
let decoded_response = GetFirmwareParametersResponse::decode(&buffer[..size]).unwrap();
360363
assert_eq!(response, decoded_response);
361364
}

src/message/firmware_update/get_package_data.rs

Lines changed: 113 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,72 @@ impl<'a> GetDeviceMetaDataResponse<'a> {
283283
}
284284
}
285285

286+
impl<'a> PldmCodecWithLifetime<'a> for GetDeviceMetaDataResponse<'a> {
287+
fn encode(&self, buffer: &mut [u8]) -> Result<usize, PldmCodecError> {
288+
let size = core::mem::size_of::<Self>() - core::mem::size_of::<&'a [u8]>();
289+
if buffer.len() < size + self.portion_of_device_metadata.len() {
290+
return Err(PldmCodecError::BufferTooShort);
291+
}
292+
293+
let mut offset = 0;
294+
self.hdr
295+
.write_to_prefix(&mut buffer[offset..])
296+
.map_err(|_| PldmCodecError::BufferTooShort)?;
297+
offset += PLDM_MSG_HEADER_LEN;
298+
299+
buffer[offset] = self.completion_code;
300+
offset += 1;
301+
302+
buffer[offset..offset + size_of::<u32>()]
303+
.copy_from_slice(&self.next_data_transfer_handle.to_le_bytes());
304+
offset += size_of::<u32>();
305+
306+
buffer[offset] = self.transfer_flag;
307+
offset += size_of::<u8>();
308+
309+
buffer[offset..offset + self.portion_of_device_metadata.len()]
310+
.copy_from_slice(self.portion_of_device_metadata);
311+
312+
Ok(size)
313+
}
314+
315+
fn decode(buffer: &'a [u8]) -> Result<Self, PldmCodecError> {
316+
let size = core::mem::size_of::<Self>() - core::mem::size_of::<&'a [u8]>();
317+
if buffer.len() < size {
318+
return Err(PldmCodecError::BufferTooShort);
319+
}
320+
321+
let mut offset = 0;
322+
let hdr = PldmMsgHeader::read_from_prefix(&buffer[offset..])
323+
.map_err(|_| PldmCodecError::BufferTooShort)?
324+
.0;
325+
offset += PLDM_MSG_HEADER_LEN;
326+
327+
let completion_code = buffer[offset];
328+
offset += size_of::<u8>();
329+
330+
let next_data_transfer_handle = u32::from_le_bytes(
331+
buffer[offset..offset + 4]
332+
.try_into()
333+
.map_err(|_| PldmCodecError::BufferTooShort)?,
334+
);
335+
offset += size_of::<u32>();
336+
337+
let transfer_flag = buffer[offset];
338+
offset += size_of::<u8>();
339+
340+
let portion_of_device_metadata = &buffer[offset..];
341+
342+
Ok(Self {
343+
hdr,
344+
completion_code,
345+
next_data_transfer_handle,
346+
transfer_flag,
347+
portion_of_device_metadata,
348+
})
349+
}
350+
}
351+
286352
/// The FD sends this command to transfer the data that was originally obtained by the UA through the
287353
/// [GetDeviceMetaData] command. This command shall only be used if the FD indicated in the
288354
/// [RequestUpdate] response that it had device metadata that needed to be obtained by the UA. The FD can
@@ -438,7 +504,7 @@ mod tests {
438504
use crate::codec::PldmCodec;
439505

440506
#[test]
441-
fn test_get_package_data_request() {
507+
fn test_get_package_data_request_codec() {
442508
let instance_id: InstanceId = 0x01;
443509
let data_transfer_handle: u32 = 0x12345678;
444510
let transfer_operation_flag = TransferOperationFlag::GetFirstPart;
@@ -454,7 +520,7 @@ mod tests {
454520
}
455521

456522
#[test]
457-
fn test_get_package_data_response() {
523+
fn test_get_package_data_response_codec() {
458524
const PORTION_LEN: usize = 10;
459525

460526
let instance_id: InstanceId = 0x01;
@@ -475,15 +541,13 @@ mod tests {
475541
- core::mem::size_of::<usize>()
476542
+ PORTION_LEN];
477543

478-
dbg!(&buffer_fitted.len());
479-
480544
resp.encode(&mut buffer_fitted).unwrap();
481545
let decoded = GetPackageDataResponse::decode(&buffer_fitted).unwrap();
482546
assert_eq!(resp, decoded);
483547
}
484548

485549
#[test]
486-
fn test_get_device_metadata_request() {
550+
fn test_get_metadata_request_codec() {
487551
let instance_id: InstanceId = 0x01;
488552
let data_transfer_handle = 0x12345678;
489553
let req = GetMetaDataRequest::new(
@@ -500,7 +564,7 @@ mod tests {
500564
}
501565

502566
#[test]
503-
fn test_get_device_metadata_response() {
567+
fn test_get_meta_data_response_codec() {
504568
let instance_id: InstanceId = 0x01;
505569
let data_transfer_handle = 0x12345678;
506570
let payload = [11u8; 20];
@@ -513,10 +577,52 @@ mod tests {
513577
&payload,
514578
);
515579

516-
let mut buffer = [0u8; 9 + 20];
580+
let mut buffer =
581+
[0u8; core::mem::size_of::<GetMetaDataResponse>() - core::mem::size_of::<&[u8]>() + 20];
517582
resp.encode(&mut buffer).unwrap();
518583

519584
let decoded = GetMetaDataResponse::decode(&mut buffer).unwrap();
520585
assert_eq!(resp, decoded);
521586
}
587+
588+
#[test]
589+
fn test_get_device_meta_data_request_codec() {
590+
let instance_id: InstanceId = 0x01;
591+
let data_transfer_handle = 0x12345678;
592+
let req = GetDeviceMetaDataRequest::new(
593+
instance_id,
594+
data_transfer_handle,
595+
TransferOperationFlag::GetFirstPart,
596+
);
597+
598+
let mut buffer = [0u8; core::mem::size_of::<GetDeviceMetaDataRequest>()];
599+
req.encode(&mut buffer).unwrap();
600+
601+
let decoded = GetDeviceMetaDataRequest::decode(&buffer).unwrap();
602+
assert_eq!(req, decoded);
603+
}
604+
605+
#[test]
606+
fn test_get_device_meta_data_response_codec() {
607+
let instance_id: InstanceId = 0x01;
608+
let data_transfer_handle = 0x12345678;
609+
const TEST_PAYLOAD_LEN: usize = 20;
610+
let payload = [11u8; TEST_PAYLOAD_LEN];
611+
612+
let resp = GetDeviceMetaDataResponse::new(
613+
instance_id,
614+
GetDeviceMetaDataCodes::BaseCodes(PldmBaseCompletionCode::Success),
615+
data_transfer_handle,
616+
TransferOperationFlag::GetFirstPart,
617+
&payload,
618+
);
619+
620+
let mut buffer = [0u8; core::mem::size_of::<GetDeviceMetaDataResponse>()
621+
- core::mem::size_of::<&[u8]>()
622+
+ TEST_PAYLOAD_LEN];
623+
resp.encode(&mut buffer).unwrap();
624+
625+
let decoded = GetDeviceMetaDataResponse::decode(&mut buffer).unwrap();
626+
assert_eq!(resp, decoded);
627+
}
522628
}

src/message/firmware_update/get_status.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ mod test {
189189
use crate::codec::PldmCodec;
190190

191191
#[test]
192-
fn test_get_status_request() {
192+
fn test_get_status_request_codec() {
193193
let instance_id = 1;
194194
let msg_type = PldmMsgType::Request;
195195
let request = GetStatusRequest::new(instance_id, msg_type);
@@ -202,7 +202,7 @@ mod test {
202202
}
203203

204204
#[test]
205-
fn test_get_status_response() {
205+
fn test_get_status_response_codec() {
206206
let response = GetStatusResponse::new(
207207
1,
208208
0,

src/message/firmware_update/pass_component.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ mod tests {
154154
use super::*;
155155

156156
#[test]
157-
fn test_pass_component_table_request() {
157+
fn test_pass_component_table_request_codec() {
158158
let request = PassComponentTableRequest::new(
159159
1,
160160
PldmMsgType::Request,
@@ -173,7 +173,7 @@ mod tests {
173173
}
174174

175175
#[test]
176-
fn test_pass_component_table_response() {
176+
fn test_pass_component_table_response_codec() {
177177
let response = PassComponentTableResponse::new(
178178
0,
179179
0,

src/message/firmware_update/query_devid.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ mod test {
214214
use crate::protocol::firmware_update::{Descriptor, DescriptorType};
215215

216216
#[test]
217-
fn test_query_device_identifiers_resp() {
217+
fn test_query_device_identifiers_resp_codec() {
218218
let instance_id = 0;
219219
let completion_code = 0;
220220

0 commit comments

Comments
 (0)