diff --git a/spdmlib/src/message/mod.rs b/spdmlib/src/message/mod.rs index 38bbef8..fad4a72 100644 --- a/spdmlib/src/message/mod.rs +++ b/spdmlib/src/message/mod.rs @@ -614,10 +614,9 @@ mod tests { payload: SpdmMessagePayload::SpdmVersionResponse(SpdmVersionResponsePayload { version_number_entry_count: 0x02, versions: gen_array_clone( - SpdmVersionStruct { - update: 100, - version: SpdmVersion::SpdmVersion11, - }, + SpdmVersionStruct::init( + SpdmVersion::SpdmVersion11, + 10), MAX_SPDM_VERSION_COUNT, ), }), @@ -632,12 +631,11 @@ mod tests { SpdmRequestResponseCode::SpdmResponseVersion ); if let SpdmMessagePayload::SpdmVersionResponse(payload) = &spdm_message.payload { - assert_eq!(payload.version_number_entry_count, 0x02); - for i in 0..2 { - assert_eq!(payload.versions[i].update, 100); - assert_eq!(payload.versions[i].version, SpdmVersion::SpdmVersion11); - } - } + assert_eq!(payload.version_number_entry_count, 0x01); + assert_eq!(payload.versions[0].get_alpha(), 10); + assert_eq!(payload.versions[0].get_update_number(), 0); + assert_eq!(payload.versions[0].get_version(), SpdmVersion::SpdmVersion11); + }; } #[test] fn test_case1_spdm_message() { diff --git a/spdmlib/src/message/version.rs b/spdmlib/src/message/version.rs index 2c2c4ef..92629b4 100644 --- a/spdmlib/src/message/version.rs +++ b/spdmlib/src/message/version.rs @@ -35,8 +35,35 @@ impl SpdmCodec for SpdmGetVersionRequestPayload { #[derive(Debug, Clone, Default)] pub struct SpdmVersionStruct { - pub update: u8, - pub version: SpdmVersion, + version: SpdmVersion, + update: u8, +} + +impl SpdmVersionStruct { + pub fn init(version: SpdmVersion, alpha: u8) -> SpdmVersionStruct { + let update_version_number = match version { + SpdmVersion::SpdmVersion10 => 0u8, + SpdmVersion::SpdmVersion11 => 0u8, + SpdmVersion::SpdmVersion12 => 0u8, + SpdmVersion::SpdmVersion13 => 2u8, + }; + SpdmVersionStruct { + update: (update_version_number as u8) << 4 | (alpha & 0x0F), + version, + } + } + + pub fn get_alpha(&self) -> u8 { + self.update & 0x0F + } + + pub fn get_update_number(&self) -> u8 { + self.update >> 4 + } + + pub fn get_version(&self) -> SpdmVersion { + self.version + } } impl Codec for SpdmVersionStruct { @@ -100,19 +127,22 @@ impl SpdmCodec for SpdmVersionResponsePayload { } let mut versions = gen_array_clone( - SpdmVersionStruct { - update: 0, - version: SpdmVersion::SpdmVersion10, - }, + SpdmVersionStruct::init(SpdmVersion::SpdmVersion10, 0), MAX_SPDM_VERSION_COUNT, ); let mut version_count = 0; let rest = r.take(version_number_entry_count as usize * 2)?; - for i in 0..version_number_entry_count { + 'version_read_loop: for i in 0..version_number_entry_count { if let Some(ver) = SpdmVersionStruct::read_bytes(&rest[i as usize * 2..]) { if version_count < MAX_SPDM_VERSION_COUNT { + for j in 0..i { + if versions[j as usize].version == ver.version { + // duplicated version, just ignore it + continue 'version_read_loop; + } + } versions[version_count] = ver; version_count += 1; } else { @@ -152,25 +182,30 @@ mod tests { fn test_case1_spdmversion_struct() { let u8_slice = &mut [0u8; 2]; let mut writer = Writer::init(u8_slice); - let value = SpdmVersionStruct { - update: 0xffu8, - version: SpdmVersion::SpdmVersion10, - }; + let value = SpdmVersionStruct::init(SpdmVersion::SpdmVersion10, 0xfu8); + assert!(value.encode(&mut writer).is_ok()); + let mut reader = Reader::init(u8_slice); + assert_eq!(2, reader.left()); + let spdmversionstruct = SpdmVersionStruct::read(&mut reader).unwrap(); + assert_eq!(spdmversionstruct.get_update_number(), 0x0); + assert_eq!(spdmversionstruct.get_alpha(), 0xf); + assert_eq!(spdmversionstruct.get_version(), SpdmVersion::SpdmVersion10); + + let mut writer = Writer::init(u8_slice); + let value = SpdmVersionStruct::init(SpdmVersion::SpdmVersion13, 0u8); assert!(value.encode(&mut writer).is_ok()); let mut reader = Reader::init(u8_slice); assert_eq!(2, reader.left()); let spdmversionstruct = SpdmVersionStruct::read(&mut reader).unwrap(); - assert_eq!(spdmversionstruct.update, 0xff); - assert_eq!(spdmversionstruct.version, SpdmVersion::SpdmVersion10); + assert_eq!(spdmversionstruct.get_update_number(), 0x2); + assert_eq!(spdmversionstruct.get_alpha(), 0x0); + assert_eq!(spdmversionstruct.get_version(), SpdmVersion::SpdmVersion13); } #[test] fn test_case2_spdmversion_struct() { let u8_slice = &mut [0u8; 1]; let mut writer = Writer::init(u8_slice); - let value = SpdmVersionStruct { - update: 100u8, - version: SpdmVersion::SpdmVersion10, - }; + let value = SpdmVersionStruct::init(SpdmVersion::SpdmVersion10, 0xfu8); assert!(value.encode(&mut writer).is_err()); let mut reader = Reader::init(u8_slice); let spdmversionstruct = SpdmVersionStruct::read(&mut reader); @@ -183,10 +218,7 @@ mod tests { let value = SpdmVersionResponsePayload { version_number_entry_count: 2u8, versions: gen_array_clone( - SpdmVersionStruct { - update: 100u8, - version: SpdmVersion::SpdmVersion10, - }, + SpdmVersionStruct::init(SpdmVersion::SpdmVersion10, 0xfu8), MAX_SPDM_VERSION_COUNT, ), }; @@ -199,14 +231,12 @@ mod tests { let version_response = SpdmVersionResponsePayload::spdm_read(&mut context, &mut reader).unwrap(); - assert_eq!(version_response.version_number_entry_count, 2u8); - for i in 0..2 { - assert_eq!(version_response.versions[i].update, 100u8); - assert_eq!( - version_response.versions[i].version, - SpdmVersion::SpdmVersion10 - ); - } + assert_eq!(version_response.version_number_entry_count, 1u8); + assert_eq!(version_response.versions[0].get_alpha(), 0xfu8); + assert_eq!( + version_response.versions[0].get_version(), + SpdmVersion::SpdmVersion10 + ); assert_eq!(0, reader.left()); } #[test] diff --git a/spdmlib/src/requester/get_version_req.rs b/spdmlib/src/requester/get_version_req.rs index d219e21..20b4e5e 100644 --- a/spdmlib/src/requester/get_version_req.rs +++ b/spdmlib/src/requester/get_version_req.rs @@ -60,7 +60,7 @@ impl RequesterContext { mut versions, } = version; - versions.sort_unstable_by(|a, b| b.version.cmp(&a.version)); + versions.sort_unstable_by(|a, b| b.get_version().cmp(&a.get_version())); let mut negotiate_version: Option = None; @@ -71,9 +71,9 @@ impl RequesterContext { .common .config_info .spdm_version - .contains(&Some(spdm_version_struct.version)) + .contains(&Some(spdm_version_struct.get_version())) { - negotiate_version = Some(spdm_version_struct.version); + negotiate_version = Some(spdm_version_struct.get_version()); break; } } diff --git a/spdmlib/src/responder/version_rsp.rs b/spdmlib/src/responder/version_rsp.rs index e9414ff..d451117 100644 --- a/spdmlib/src/responder/version_rsp.rs +++ b/spdmlib/src/responder/version_rsp.rs @@ -77,10 +77,7 @@ impl ResponderContext { let mut version_number_entry_count = 0; let mut versions = gen_array_clone(SpdmVersionStruct::default(), MAX_SPDM_VERSION_COUNT); for v in self.common.config_info.spdm_version.iter().flatten() { - versions[version_number_entry_count] = SpdmVersionStruct { - update: 0, - version: *v, - }; + versions[version_number_entry_count] = SpdmVersionStruct::init(*v, 0); version_number_entry_count += 1; } let response = SpdmMessage { diff --git a/test/spdmlib-test/src/common/util.rs b/test/spdmlib-test/src/common/util.rs index 02148b3..ac86afa 100644 --- a/test/spdmlib-test/src/common/util.rs +++ b/test/spdmlib-test/src/common/util.rs @@ -177,7 +177,7 @@ pub fn req_create_info() -> (SpdmConfigInfo, SpdmProvisionInfo) { Some(SpdmVersion::SpdmVersion10), Some(SpdmVersion::SpdmVersion11), Some(SpdmVersion::SpdmVersion12), - None, + Some(SpdmVersion::SpdmVersion13), ], req_capabilities: req_capabilities, req_ct_exponent: 0, diff --git a/test/spdmlib-test/src/responder_tests/version_rsp.rs b/test/spdmlib-test/src/responder_tests/version_rsp.rs index d6fb6fa..c193184 100644 --- a/test/spdmlib-test/src/responder_tests/version_rsp.rs +++ b/test/spdmlib-test/src/responder_tests/version_rsp.rs @@ -74,12 +74,15 @@ fn test_case0_handle_spdm_version() { ); if let SpdmMessagePayload::SpdmVersionResponse(payload) = &spdm_message.payload { assert_eq!(payload.version_number_entry_count, 0x04); - assert_eq!(payload.versions[0].update, 0); - assert_eq!(payload.versions[0].version, SpdmVersion::SpdmVersion10); - assert_eq!(payload.versions[1].update, 0); - assert_eq!(payload.versions[1].version, SpdmVersion::SpdmVersion11); - assert_eq!(payload.versions[2].update, 0); - assert_eq!(payload.versions[2].version, SpdmVersion::SpdmVersion12); + assert_eq!(payload.versions[0].get_alpha(), 0); + assert_eq!(payload.versions[0].get_version(), SpdmVersion::SpdmVersion10); + assert_eq!(payload.versions[1].get_alpha(), 0); + assert_eq!(payload.versions[1].get_version(), SpdmVersion::SpdmVersion11); + assert_eq!(payload.versions[2].get_alpha(), 0); + assert_eq!(payload.versions[2].get_version(), SpdmVersion::SpdmVersion12); + assert_eq!(payload.versions[3].get_alpha(), 0); + assert_eq!(payload.versions[3].get_update_number(), 2); + assert_eq!(payload.versions[3].get_version(), SpdmVersion::SpdmVersion13); } }; executor::block_on(future);