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#[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 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, 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 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 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}