Files
ccsds_spp/src/header/apid.rs

124 lines
3.1 KiB
Rust
Raw Normal View History

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<u16> for ApId
{
fn from(value: u16) -> Self
{
ApId
{
value
}
}
}
impl From<ApId> for u16
{
fn from(apid: ApId) -> u16
{
apid.value
}
}
impl FromBytes for ApId
{
type Error = PacketError;
fn from_bytes(bytes: &[u8]) -> Result<Parsed<Self>, 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<usize, Self::Error>
{
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<Self, Self::Error>
{
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(())
}
}