Skip to main content

gondola_core/packets/
tracker_header.rs

1//! Re-implementation of the tracker header which is attached 
2//! to each telemetry packet.
3//! Re-implemented from bfsw
4// The following file is part of gaps-online-software and published 
5// under the GPLv3 license
6
7use crate::prelude::*;
8
9/// A header 
10#[derive(Debug, Copy, Clone, PartialEq)]
11#[cfg_attr(feature="pybindings", pyclass)]
12pub struct TrackerHeader {
13  pub sync        : u16,
14  pub crc         : u16,
15  pub sys_id      : u8,
16  pub packet_id   : u8,
17  pub length      : u16,
18  pub daq_count   : u16,
19  pub sys_time    : u64,
20  pub version     : u8,
21} 
22
23impl TrackerHeader {
24  
25  pub fn new() -> Self {
26    Self {
27      sync        : 0,
28      crc         : 0,
29      sys_id      : 0,
30      packet_id   : 0,
31      length      : 0,
32      daq_count   : 0,
33      sys_time    : 0,
34      version     : 0,
35    }
36  }
37} 
38
39impl Serialization for TrackerHeader { 
40  const SIZE : usize = 17;
41
42  fn from_bytestream(stream: &Vec<u8>,
43                     pos: &mut usize)
44    -> Result<Self, SerializationError> {
45    if stream.len() < Self::SIZE {
46      error!("Unable to decode TrackerHeader!"); 
47      return Err(SerializationError::StreamTooShort);
48    }
49    let mut h     = TrackerHeader::new();
50    h.sync        = parse_u16(stream, pos);
51    h.crc         = parse_u16(stream, pos); 
52    h.sys_id      = parse_u8 (stream, pos);
53    h.packet_id   = parse_u8 (stream, pos);
54    h.length      = parse_u16(stream, pos);
55    h.daq_count   = parse_u16(stream, pos);
56    let lower     = parse_u32(stream, pos);
57    let upper     = parse_u16(stream, pos);
58    h.sys_time    = make_systime(lower, upper);
59    h.version     = parse_u8 (stream, pos);
60    Ok(h)
61  }
62  
63  fn to_bytestream(&self) -> Vec<u8> {
64    let mut stream = Vec::<u8>::new();
65    stream.extend_from_slice(&self.sync.to_le_bytes());
66    stream.extend_from_slice(&self.crc.to_le_bytes());
67    stream.push(self.sys_id);
68    stream.push(self.packet_id);
69    stream.extend_from_slice(&self.length.to_le_bytes());
70    stream.extend_from_slice(&self.daq_count.to_le_bytes());
71    let lower = (self.sys_time & u32::MAX as u64) as u32;
72    let upper = (self.sys_time >> 32) as u16;
73    stream.extend_from_slice(&lower.to_le_bytes());
74    stream.extend_from_slice(&upper.to_le_bytes());
75    stream.push(self.version);
76    stream
77  }
78}
79
80impl fmt::Display for TrackerHeader {
81  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82    let mut repr = String::from("<TrackerHeader");
83    repr    += &(format!("\n  Sync     : {}", self.sync));
84    repr    += &(format!("\n  Crc      : {}", self.crc));
85    repr    += &(format!("\n  PacketID : {}", self.packet_id));
86    repr    += &(format!("\n  Sys ID   : {}", self.sys_id));
87    repr    += &(format!("\n  Length   : {}", self.length));
88    repr    += &(format!("\n  DAQ Cnt  : {}", self.daq_count));
89    repr    += &(format!("\n  Sys Time : {}", self.sys_time));
90    repr    += &(format!("\n  Version  : {}>", self.version));
91    write!(f, "{}", repr)
92  }
93}
94
95#[cfg(feature="random")]
96impl FromRandom for TrackerHeader {
97
98  fn from_random() -> Self {
99    let mut rng = rand::rng();
100    let mut h   = Self::new();
101    h.sync      = rng.random::<u16>();
102    h.crc       = rng.random::<u16>();
103    h.sys_id    = rng.random_range(0..10) + 128;
104    h.packet_id = rng.random::<u8>();
105    h.length    = rng.random::<u16>();
106    h.daq_count = rng.random::<u16>();
107    h.sys_time  = rng.random::<u64>() & (u64::pow(2,48) - 1); 
108    h.version   = 5; // only do version 5 for now, 
109                     // that is for GAPSI
110    h
111  }
112}
113
114//------------------------------------------------------
115
116#[cfg(feature="pybindings")]
117#[pymethods]
118impl TrackerHeader { 
119
120  #[getter]
121  fn get_sync(&self)        -> u16 {
122    self.sync
123  }
124  
125  #[getter]
126  fn get_crc(&self)         -> u16 {
127    self.crc
128  }
129  
130  #[getter]
131  fn get_sys_id(&self)      -> u8 {
132    self.sys_id
133  }
134  
135  #[getter]
136  fn get_packet_id(&self)   -> u8 {
137    self.packet_id
138  }
139  
140  #[getter]
141  fn get_length(&self)      -> u16 {
142    self.length
143  }
144  
145  #[getter]
146  fn get_daq_count(&self)   -> u16 {
147    self.daq_count
148  }
149  
150  #[getter]
151  fn get_sys_time(&self)    -> u64 {
152    self.sys_time
153  }
154  
155  #[getter]
156  fn get_version(&self)     -> u8 {
157    self.version
158  }
159}
160
161#[cfg(feature="pybindings")]
162pythonize!(TrackerHeader);
163
164#[test]
165#[cfg(feature="random")]
166fn serialize_deserialize_trackerheader() {
167  for _ in 0..10 {
168    let h = TrackerHeader::from_random();
169    let stream = h.to_bytestream();
170    let test   = TrackerHeader::from_bytestream(&stream, &mut 0).unwrap();
171    assert_eq!(h, test);
172  }
173}
174
175