use crate::check_buffer_len; use crate::bits::*; use crate::error::PacketError; /// # Application Process Identifier /// /// The APID shall provide the naming mechanism for the managed data path. /// /// The APID may uniquely identify the individual sending or receiving application /// process within a particular space vehicle. /// /// For Idle Packets the APID shall be ‘11111111111’. /// /// ## NOTES /// - The APID is unique only within its naming domain. /// - There are no restrictions on the selection of APIDs except for the APID /// for Idle Packets stated above. In particular, APIDs are not required to /// be numbered consecutively. /// - The Recommended Standard used a reserved APID to carry specific PDUs by, /// for example, CFDP and LTP. This capability of acting as ‘shim’ protocol /// is preserved; that is, SPP can still carry PDUs of other protocols, but /// the coupling of APIDs to protocols is now mission specific. Missions may /// use the optional Packet Secondary Header to create an extended naming /// domain, but such uses are not specifically defined in this protocol. /// This is reflected by the fact that the only reserved value is now the /// one for Idle Packets. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct ApId { value: u16 } impl ApId { /// The 16 bit version of the mask for the ApId bits in the header. pub const MASK_U16: u16 = 0b0000011111111111; /// The 8 bit array version of the mask for the ApId bits in the header. /// The pub const MASK_ARR: [u8; 2] = [0b00000111, 0b11111111]; } impl From for ApId { fn from(value: u16) -> Self { ApId { value } } } impl From for u16 { fn from(apid: ApId) -> u16 { apid.value } } impl FromBytes for ApId { type Error = PacketError; fn from_bytes(bytes: &[u8]) -> Result, Self::Error> { check_buffer_len!(2usize, bytes); let id: u16 = (((bytes[0] & ApId::MASK_ARR[0]) as u16) << 8) | (((bytes[1] & ApId::MASK_ARR[1]) as u16)); Ok(Parsed::new(2usize, id.into())) } } impl IntoBytes for ApId { type Error = PacketError; fn into_bytes(self, buffer: &mut [u8]) -> Result { check_buffer_len!(2usize, buffer); let id: u16 = self.value; buffer[0] = ((id >> 8) as u8) & ApId::MASK_ARR[0]; buffer[1] = (id as u8) & ApId::MASK_ARR[1]; Ok(2usize) } } impl FromBits for ApId { type Error = PacketError; fn from_bits(bytes: &[u8], mask: &[u8]) -> Result { check_buffer_len!(2usize, bytes, mask); let id: u16 = (((bytes[0] & mask[0]) as u16) << 8) | ((bytes[1] & mask[1]) as u16); Ok(id.into()) } } impl IntoBits for ApId { type Error = PacketError; fn into_bits(self, bytes: &mut [u8], mask: &[u8]) -> Result<(), Self::Error> { check_buffer_len!(2usize, bytes, mask); update_masked_bits_arr(&mut [bytes[0], bytes[1]], &[mask[0], mask[1]], &self.value.to_be_bytes()); Ok(()) } }