Skip to main content

bp7/
primary.rs

1use crate::error::Error;
2use crate::error::ErrorList;
3
4use super::bundle::*;
5use super::crc::*;
6use super::dtntime::*;
7use super::eid::*;
8use super::flags::*;
9use core::fmt;
10use core::{convert::TryFrom, time::Duration};
11use serde::de::{SeqAccess, Visitor};
12use serde::ser::{SerializeSeq, Serializer};
13use serde::{de, Deserialize, Deserializer, Serialize};
14use thiserror::Error;
15
16/******************************
17 *
18 * Primary Block
19 *
20 ******************************/
21
22#[derive(Error, Debug)]
23pub enum PrimaryBuilderError {
24    #[error("no destination endpoint was provided")]
25    NoDestination,
26}
27
28#[derive(Default, Clone, Debug, PartialEq)]
29pub struct PrimaryBlockBuilder {
30    bundle_control_flags: BundleControlFlagsType,
31    crc: CrcValue,
32    destination: EndpointID,
33    source: EndpointID,
34    report_to: EndpointID,
35    creation_timestamp: CreationTimestamp,
36    lifetime: Duration,
37    fragmentation_offset: FragOffsetType,
38    total_data_length: TotalDataLengthType,
39}
40impl PrimaryBlockBuilder {
41    pub fn new() -> Self {
42        // let mut builder = PrimaryBlockBuilder::default();
43        // should this be set by default?
44        // builder.creation_timestamp = CreationTimestamp::now();
45        PrimaryBlockBuilder::default()
46    }
47    pub fn bundle_control_flags(mut self, flags: BundleControlFlagsType) -> Self {
48        self.bundle_control_flags = flags;
49        self
50    }
51    pub fn crc(mut self, crc: CrcValue) -> Self {
52        self.crc = crc;
53        self
54    }
55    pub fn destination(mut self, dest: EndpointID) -> Self {
56        self.destination = dest;
57        self
58    }
59    pub fn source(mut self, source: EndpointID) -> Self {
60        self.source = source;
61        self
62    }
63    pub fn report_to(mut self, report_to: EndpointID) -> Self {
64        self.report_to = report_to;
65        self
66    }
67    pub fn creation_timestamp(mut self, creation_timestamp: CreationTimestamp) -> Self {
68        self.creation_timestamp = creation_timestamp;
69        self
70    }
71    pub fn lifetime(mut self, lifetime: Duration) -> Self {
72        self.lifetime = lifetime;
73        self
74    }
75    pub fn fragmentation_offset(mut self, offset: FragOffsetType) -> Self {
76        self.fragmentation_offset = offset;
77        self
78    }
79    pub fn total_data_length(mut self, length: TotalDataLengthType) -> Self {
80        self.total_data_length = length;
81        self
82    }
83    pub fn build(self) -> Result<PrimaryBlock, PrimaryBuilderError> {
84        if self.destination == EndpointID::none() {
85            Err(PrimaryBuilderError::NoDestination)
86        } else {
87            Ok(PrimaryBlock {
88                version: DTN_VERSION,
89                bundle_control_flags: self.bundle_control_flags,
90                crc: self.crc,
91                destination: self.destination,
92                source: self.source,
93                report_to: self.report_to,
94                creation_timestamp: self.creation_timestamp,
95                lifetime: self.lifetime,
96                fragmentation_offset: self.fragmentation_offset,
97                total_data_length: self.total_data_length,
98            })
99        }
100    }
101}
102
103//#[derive(Debug, Serialize_tuple, Deserialize_tuple, Clone)]
104#[derive(Debug, Clone, PartialEq)]
105pub struct PrimaryBlock {
106    version: DtnVersionType,
107    pub bundle_control_flags: BundleControlFlagsType,
108    pub crc: CrcValue,
109    pub destination: EndpointID,
110    pub source: EndpointID,
111    pub report_to: EndpointID,
112    pub creation_timestamp: CreationTimestamp,
113    /// in milliseconds
114    pub lifetime: Duration,
115    pub fragmentation_offset: FragOffsetType,
116    pub total_data_length: TotalDataLengthType,
117}
118
119impl Serialize for PrimaryBlock {
120    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
121    where
122        S: Serializer,
123    {
124        let num_elems = if !self.crc.has_crc() && !self.has_fragmentation() {
125            8
126        } else if self.crc.has_crc() && !self.has_fragmentation() {
127            9
128        } else if !self.crc.has_crc() && self.has_fragmentation() {
129            10
130        } else {
131            11
132        };
133
134        let mut seq = serializer.serialize_seq(Some(num_elems))?;
135        seq.serialize_element(&self.version)?;
136        seq.serialize_element(&self.bundle_control_flags)?;
137        seq.serialize_element(&self.crc.to_code())?;
138        seq.serialize_element(&self.destination)?;
139        seq.serialize_element(&self.source)?;
140        seq.serialize_element(&self.report_to)?;
141        seq.serialize_element(&self.creation_timestamp)?;
142        seq.serialize_element(&(self.lifetime.as_millis() as u64))?;
143        if self.has_fragmentation() {
144            seq.serialize_element(&self.fragmentation_offset)?;
145            seq.serialize_element(&self.total_data_length)?;
146        }
147
148        if self.crc.has_crc() {
149            seq.serialize_element(&serde_bytes::Bytes::new(self.crc.bytes().unwrap()))?;
150        }
151
152        seq.end()
153    }
154}
155
156impl<'de> Deserialize<'de> for PrimaryBlock {
157    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
158    where
159        D: Deserializer<'de>,
160    {
161        struct PrimaryBlockVisitor;
162
163        impl<'de> Visitor<'de> for PrimaryBlockVisitor {
164            type Value = PrimaryBlock;
165
166            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
167                formatter.write_str("PrimaryBlock")
168            }
169
170            fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
171            where
172                V: SeqAccess<'de>,
173            {
174                let version: DtnVersionType = seq
175                    .next_element()?
176                    .ok_or_else(|| de::Error::invalid_length(0, &self))?;
177                let bundle_control_flags: BundleControlFlagsType = seq
178                    .next_element()?
179                    .ok_or_else(|| de::Error::invalid_length(1, &self))?;
180                let crc_type: CrcRawType = seq
181                    .next_element()?
182                    .ok_or_else(|| de::Error::invalid_length(2, &self))?;
183                let destination: EndpointID = seq
184                    .next_element()?
185                    .ok_or_else(|| de::Error::invalid_length(3, &self))?;
186                let source: EndpointID = seq
187                    .next_element()?
188                    .ok_or_else(|| de::Error::invalid_length(4, &self))?;
189                let report_to: EndpointID = seq
190                    .next_element()?
191                    .ok_or_else(|| de::Error::invalid_length(5, &self))?;
192                let creation_timestamp: CreationTimestamp = seq
193                    .next_element()?
194                    .ok_or_else(|| de::Error::invalid_length(6, &self))?;
195                let lifetime_u64: u64 = seq
196                    .next_element()?
197                    .ok_or_else(|| de::Error::invalid_length(7, &self))?;
198                let lifetime = Duration::from_millis(lifetime_u64);
199
200                let rest = seq.size_hint().unwrap_or(0);
201                let mut fragmentation_offset: FragOffsetType = 0;
202                let mut total_data_length: TotalDataLengthType = 0;
203
204                if rest > 1 {
205                    fragmentation_offset = seq
206                        .next_element()?
207                        .ok_or_else(|| de::Error::invalid_length(8, &self))?;
208                    total_data_length = seq
209                        .next_element()?
210                        .ok_or_else(|| de::Error::invalid_length(9, &self))?;
211                }
212                let crc = if crc_type == CRC_NO {
213                    CrcValue::CrcNo
214                } else if crc_type == CRC_16 {
215                    let crcbuf: ByteBuffer = seq
216                        .next_element::<serde_bytes::ByteBuf>()?
217                        .ok_or_else(|| de::Error::invalid_length(7 + rest, &self))?
218                        .into_vec();
219                    let mut outbuf: [u8; 2] = [0; 2];
220                    if crcbuf.len() != outbuf.len() {
221                        return Err(de::Error::invalid_length(7 + rest, &self));
222                    }
223                    outbuf.copy_from_slice(&crcbuf);
224                    CrcValue::Crc16(outbuf)
225                } else if crc_type == CRC_32 {
226                    let crcbuf: ByteBuffer = seq
227                        .next_element::<serde_bytes::ByteBuf>()?
228                        .ok_or_else(|| de::Error::invalid_length(7 + rest, &self))?
229                        .into_vec();
230                    let mut outbuf: [u8; 4] = [0; 4];
231                    if crcbuf.len() != outbuf.len() {
232                        return Err(de::Error::invalid_length(7 + rest, &self));
233                    }
234                    outbuf.copy_from_slice(&crcbuf);
235                    CrcValue::Crc32(outbuf)
236                } else {
237                    CrcValue::Unknown(crc_type)
238                };
239                Ok(PrimaryBlock {
240                    version,
241                    bundle_control_flags,
242                    crc,
243                    destination,
244                    source,
245                    report_to,
246                    creation_timestamp,
247                    lifetime,
248                    fragmentation_offset,
249                    total_data_length,
250                })
251            }
252        }
253
254        deserializer.deserialize_any(PrimaryBlockVisitor)
255    }
256}
257impl Default for PrimaryBlock {
258    fn default() -> Self {
259        PrimaryBlock::new()
260    }
261}
262
263impl PrimaryBlock {
264    pub fn new() -> PrimaryBlock {
265        PrimaryBlock {
266            version: DTN_VERSION,
267            bundle_control_flags: 0,
268            crc: CrcValue::CrcNo,
269            destination: EndpointID::new(),
270            source: EndpointID::new(),
271            report_to: EndpointID::new(),
272            creation_timestamp: CreationTimestamp::new(),
273            lifetime: Duration::new(0, 0),
274            fragmentation_offset: 0,
275            total_data_length: 0,
276        }
277    }
278
279    pub fn has_fragmentation(&self) -> bool {
280        self.bundle_control_flags
281            .contains(BundleControlFlags::BUNDLE_IS_FRAGMENT)
282    }
283    pub fn is_lifetime_exceeded(&self) -> bool {
284        if self.creation_timestamp.dtntime() == 0 {
285            return false;
286        }
287
288        let now = crate::dtn_time_now();
289        self.creation_timestamp.dtntime() + (self.lifetime.as_millis() as u64) <= now
290    }
291    pub fn validate(&self) -> Result<(), ErrorList> {
292        let mut errors: ErrorList = Vec::new();
293
294        if self.version != DTN_VERSION {
295            errors.push(Error::PrimaryBlockError(format!(
296                "Wrong version, {} instead of {}",
297                self.version, DTN_VERSION
298            )));
299        }
300
301        // bundle control flags
302        if let Err(mut err) = self.bundle_control_flags.validate() {
303            errors.append(&mut err);
304        }
305
306        if let Err(chk_err) = self.destination.validate() {
307            errors.push(chk_err.into());
308        }
309
310        if let Err(chk_err) = self.source.validate() {
311            errors.push(chk_err.into());
312        }
313        if let Err(chk_err) = self.report_to.validate() {
314            errors.push(chk_err.into());
315        }
316
317        if self.has_crc() && !self.clone().check_crc() {
318            errors.push(Error::PrimaryBlockError("CRC check failed".to_string()));
319        }
320
321        if !errors.is_empty() {
322            return Err(errors);
323        }
324        Ok(())
325    }
326}
327
328impl CrcBlock for PrimaryBlock {
329    fn crc_value(&self) -> &CrcValue {
330        &self.crc
331    }
332    fn set_crc(&mut self, crc: CrcValue) {
333        self.crc = crc;
334    }
335}
336impl Block for PrimaryBlock {
337    fn to_cbor(&self) -> ByteBuffer {
338        serde_cbor::to_vec(&self).expect("Error exporting primary block to cbor")
339    }
340}
341pub fn new_primary_block(
342    dst: &str,
343    src: &str,
344    creation_timestamp: CreationTimestamp,
345    lifetime: Duration,
346) -> PrimaryBlock {
347    let dst_eid = EndpointID::try_from(dst).unwrap();
348    let src_eid = EndpointID::try_from(src).unwrap();
349
350    PrimaryBlock {
351        version: DTN_VERSION,
352        bundle_control_flags: 0,
353        crc: CrcValue::CrcNo,
354        destination: dst_eid,
355        source: src_eid.clone(),
356        report_to: src_eid,
357        creation_timestamp,
358        lifetime,
359        fragmentation_offset: 0,
360        total_data_length: 0,
361    }
362}