diff --git a/src/lib.rs b/src/lib.rs index 77f93fb..ab5ff9f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -978,6 +978,41 @@ impl CcsdsPacket for CcsdsPacketCreatorWithReservedData<'_> { } } +/// Identifier for CCSDS packets. +/// +/// This struct simply combines the [PacketId] and [PacketSequenceControl] fields from the +/// CCSDS packet. +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CcsdsPacketId { + pub packet_id: PacketId, + pub psc: PacketSequenceControl, +} + +impl Hash for CcsdsPacketId { + fn hash(&self, state: &mut H) { + self.packet_id.hash(state); + self.psc.raw().hash(state); + } +} + +impl CcsdsPacketId { + #[inline] + pub const fn new(packet_id: PacketId, psc: PacketSequenceControl) -> Self { + Self { packet_id, psc } + } + + /// Extract the CCSDS packet ID from the given [CcsdsPacket]. + #[inline] + pub fn new_from_ccsds_packet(packet: &P) -> Self { + Self { + packet_id: packet.packet_id(), + psc: packet.psc(), + } + } +} + /// CCSDS packet creator with optional support for a CRC16 CCITT checksum appended to the /// end of the packet. #[derive(Debug)] @@ -2106,4 +2141,14 @@ pub(crate) mod tests { ); assert_eq!(sph.data_len(), 0); } + + #[test] + fn ccsds_packet_id() { + let packet_id = PacketId::new_for_tc(false, u11::new(0x5)); + let psc = PacketSequenceControl::new(SequenceFlags::Unsegmented, u14::new(0)); + let sph = SpacePacketHeader::new(packet_id, psc, 0); + let id = CcsdsPacketId::new_from_ccsds_packet(&sph); + assert_eq!(id.packet_id, packet_id); + assert_eq!(id.psc, psc); + } } diff --git a/src/seq_count.rs b/src/seq_count.rs index 20d6c38..4d392cc 100644 --- a/src/seq_count.rs +++ b/src/seq_count.rs @@ -402,24 +402,28 @@ mod tests { } #[test] + #[cfg(feature = "portable-atomic")] fn test_portable_atomic_counter_u8() { let mut sync_u8_counter = portable_atomic::AtomicU8::new(0); common_counter_test(&mut sync_u8_counter); } #[test] + #[cfg(feature = "portable-atomic")] fn test_portable_atomic_counter_u16() { let mut sync_u16_counter = portable_atomic::AtomicU16::new(0); common_counter_test(&mut sync_u16_counter); } #[test] + #[cfg(feature = "portable-atomic")] fn test_portable_atomic_counter_u32() { let mut sync_u32_counter = portable_atomic::AtomicU32::new(0); common_counter_test(&mut sync_u32_counter); } #[test] + #[cfg(feature = "portable-atomic")] fn test_portable_atomic_counter_u64() { let mut sync_u64_counter = portable_atomic::AtomicU64::new(0); common_counter_test(&mut sync_u64_counter); @@ -439,6 +443,7 @@ mod tests { } #[test] + #[cfg(feature = "portable-atomic")] fn test_portable_atomic_u8_counter_overflow() { let sync_u8_counter = portable_atomic::AtomicU8::new(0); common_overflow_test_u8(&sync_u8_counter);