spp_rust/
packet.rs

1use bitvec::prelude::*;
2
3use crate::{OCTET, PRIMARY_HEADER_SIZE, MAX_DATA_SIZE, MAX_SP_SIZE};
4use crate::pri_header::{Identification, SequenceControl, PrimaryHeader, SecHeaderFlag};
5use crate::data::{DataField, SecondaryHeader, UserData};
6use crate::errors::SPPError;
7
8#[derive(Default)]
9pub struct Builder<'a> {
10    id: Option<Identification>,
11    seq: Option<SequenceControl>,
12    sec_head: Option<&'a SecondaryHeader<'a>>,
13    user_data: Option<&'a UserData<'a>>,
14    idle: bool,
15    _aux: BitArr!(for MAX_DATA_SIZE + 48, in u8),
16}
17
18impl<'a> Builder<'a> {
19    fn new() -> Self {
20        Self { _aux: bitarr!(u8, LocalBits; 0; MAX_SP_SIZE), ..Default::default() }
21    }
22
23    pub fn idle(&mut self, set: bool) {
24        self.idle = set
25    }
26
27    pub fn identification(&mut self, id: Option<Identification>) {
28        self.id = id
29    }
30    
31    pub fn sequence_control(&mut self, sequence_control: Option<SequenceControl>) {
32        self.seq = sequence_control
33    }
34
35    pub fn secondary_header(&mut self, sec_head: Option<&'a SecondaryHeader>) {
36        self.sec_head = sec_head
37    }
38
39    pub fn user_data(&mut self, user_data: Option<&'a UserData>) {
40        self.user_data = user_data
41    }
42
43    pub fn build(mut self) -> Result<SpacePacket<'a>, SPPError> {
44        let (id, seq) = match (&self.id, &self.seq) {
45            (None, None) => return Err(SPPError::MandatoryFieldNotPresent),
46            (None, _) => return Err(SPPError::MandatoryFieldNotPresent),
47            (_, None) => return Err(SPPError::MandatoryFieldNotPresent),
48            (id, seq) => (id.clone().unwrap(), seq.clone().unwrap()),
49        };
50
51        if self.idle {
52            let new_id = Identification::new_idle(id.packet_type.clone());
53            self.identification(Some(new_id));
54        }
55        
56        let mut pri_head = PrimaryHeader::new(&id, &seq);
57        let mut data = DataField::new();
58
59        if let SecHeaderFlag::Present = id.sec_header_flag {
60            if self.sec_head.is_none() {
61                return Err(SPPError::SecondaryHeaderNotPresent);
62            } else if self.sec_head.as_ref().unwrap().len() < 1 {
63                return Err(SPPError::SecondaryHeaderNotPresent);
64            }
65        }
66
67        data.sec_header(self.sec_head);
68        data.user_data(self.user_data);
69
70        let final_lenght: usize = data.len() / OCTET;
71
72        if final_lenght > MAX_DATA_SIZE {
73            return Err(SPPError::MaxDataSizeExedded); // Total data size exceeds max data size
74        }
75
76        pri_head.data_lenght(final_lenght);
77        
78        let sp: SpacePacket<'_> = SpacePacket::new(pri_head, data, self._aux);
79
80        if sp.data_field.len() < OCTET {
81            return Err(SPPError::MinDataLen); // Data field must be at least 1 octet long
82        }
83
84        Ok(sp)
85    }
86}
87
88
89#[derive(Debug)]
90pub struct SpacePacket<'a> {
91    primary_header: PrimaryHeader,
92    data_field: DataField<'a>,
93    _aux: BitArr!(for MAX_DATA_SIZE + 48, in u8),
94}
95
96
97impl<'a> SpacePacket<'a> {
98    fn new(ph: PrimaryHeader, df: DataField<'a>, _aux: BitArr!(for MAX_SP_SIZE, in u8)) -> Self {
99        Self { primary_header: ph, data_field: df, _aux}
100    }
101    
102    pub fn builder() -> Builder<'static> {
103        Builder::new()
104    }
105
106    pub fn to_bits(&mut self) -> &BitSlice<u8> {        
107        self.primary_header.to_bits(&mut self._aux);
108        
109        let mut l = 48;
110        
111        self.data_field.to_bits(&mut (&mut l, &mut self._aux));
112
113        &self._aux[..l]
114    }
115
116    pub fn len(&self) -> usize {
117        self.data_field.len() + PRIMARY_HEADER_SIZE
118    }
119}
120
121pub struct OctetStringSpacePacket<'a> {
122    pub primary_header: PrimaryHeader,
123    pub data_field: &'a BitSlice<u8>,
124}
125
126impl<'a> OctetStringSpacePacket<'a> {
127    pub fn new_from_slice(s: &'a BitSlice<u8>) -> Self {
128        let primary_header = PrimaryHeader::new_from_slice(&s[..48]);
129
130        let dl = (primary_header.data_length.data[0].to_le() 
131                        + primary_header.data_length.data[1].to_le()) 
132                        * OCTET as u8;
133                        
134        let data_field = &s[48..48 + dl as usize];
135
136        Self { primary_header, data_field }
137    }
138}