gondola_core/packets/
telemetry_packet_header.rs1use crate::prelude::*;
8
9#[derive(Debug, Copy, Clone, PartialEq)]
12#[cfg_attr(feature = "pybindings", pyclass, pyo3(name="TelemetryPacketHeader"))]
13pub struct TelemetryPacketHeader {
14 pub sync : u16,
16 pub packet_type : TelemetryPacketType,
19 pub timestamp : u32,
22 pub counter : u16,
25 pub length : u16,
27 pub checksum : u16
32}
33
34impl TelemetryPacketHeader {
35
36 pub fn new() -> Self {
37 Self {
38 sync : 0,
39 packet_type : TelemetryPacketType::Unknown,
40 timestamp : 0,
41 counter : 0,
42 length : 0,
43 checksum : 0,
44 }
45 }
46
47 pub fn forge(packet_type : TelemetryPacketType) -> Self {
49 let mut header = Self::new();
50 header.sync = 0x90EB;
51 header.packet_type = packet_type;
52 header
53 }
54
55 pub fn convert_telemetry_header_ts(timestamp : u32) -> f64 {
59 (timestamp as f64) * 0.064 + 1631030675.0
60 }
61
62 pub fn get_gcutime(&self) -> f64 {
64 Self::convert_telemetry_header_ts(self.timestamp)
66 }
67}
68
69#[cfg(feature="pybindings")]
72#[pymethods]
73impl TelemetryPacketHeader {
74
75 #[staticmethod]
79 #[pyo3(name="convert_telemetry_header_ts")]
80 fn convert_telemetry_header_ts_py(timestamp : u32) -> f64 {
81 Self::convert_telemetry_header_ts(timestamp)
82 }
83
84 #[getter]
85 fn gcutime(&self) -> f64 {
86 self.get_gcutime()
87 }
88
89 #[getter]
90 fn get_packet_type(&self) -> TelemetryPacketType {
91 self.packet_type
92 }
93
94 #[getter]
95 fn get_timestamp(&self) -> u32 {
96 self.timestamp
97 }
98
99 #[getter]
100 fn get_counter(&self) -> u16 {
101 self.counter
102 }
103
104 #[getter]
105 fn get_length(&self) -> u16 {
106 self.length
107 }
108
109 #[getter]
110 fn get_checksum(&self) -> u16 {
111 self.checksum
112 }
113}
114
115impl Serialization for TelemetryPacketHeader {
118
119 const HEAD : u16 = 0x90eb;
120 const TAIL : u16 = 0x0000; const SIZE : usize = 13;
122
123 fn from_bytestream(stream : &Vec<u8>,
124 pos : &mut usize)
125 -> Result<Self, SerializationError> {
126 if stream.len() < *pos + Self::SIZE {
127 return Err(SerializationError::StreamTooShort);
128 }
129 if parse_u16(stream, pos) != 0x90eb {
130 error!("The given position {} does not point to a valid header signature of {}", pos, 0x90eb);
131 return Err(SerializationError::HeadInvalid {});
132 }
133 let mut thead = TelemetryPacketHeader::new();
134 thead.sync = 0x90eb;
135 thead.packet_type = TelemetryPacketType::from(parse_u8 (stream, pos));
136 thead.timestamp = parse_u32(stream, pos);
137 thead.counter = parse_u16(stream, pos);
138 thead.length = parse_u16(stream, pos);
139 thead.checksum = parse_u16(stream, pos);
140 Ok(thead)
141 }
142
143 fn to_bytestream(&self) -> Vec<u8> {
144 let mut stream = Vec::<u8>::new();
145 stream.extend_from_slice(&self.sync.to_le_bytes());
148 stream.extend_from_slice(&(self.packet_type as u8).to_le_bytes());
149 stream.extend_from_slice(&self.timestamp.to_le_bytes());
150 stream.extend_from_slice(&self.counter.to_le_bytes());
151 stream.extend_from_slice(&self.length.to_le_bytes());
152 stream.extend_from_slice(&self.checksum.to_le_bytes());
153 stream
154 }
155}
156
157impl fmt::Display for TelemetryPacketHeader {
158 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
159 let mut repr = String::from("<TelemetryPacketHeader:");
160 repr += &(format!("\n Header : {}",self.sync));
161 repr += &(format!("\n Packet Type : {}",self.packet_type));
162 repr += &(format!("\n Timestamp : {}",self.timestamp));
163 repr += &(format!("\n Counter : {}",self.counter));
164 repr += &(format!("\n Length : {}",self.length));
165 repr += &(format!("\n Checksum : {}>",self.checksum));
166 write!(f, "{}", repr)
167 }
168}
169
170#[cfg(feature="random")]
171impl FromRandom for TelemetryPacketHeader {
172
173 fn from_random() -> Self {
174 let mut h = Self::new();
175 let mut rng = rand::rng();
176 h.sync = 0x90eb;
177 h.packet_type = TelemetryPacketType::from_random();
178 h.timestamp = rng.random::<u32>();
179 h.counter = rng.random::<u16>();
180 h.length = rng.random::<u16>();
181 h.checksum = rng.random::<u16>();
182 h
183 }
184}
185
186#[cfg(feature="pybindings")]
187pythonize!(TelemetryPacketHeader);
188
189#[test]
190#[cfg(feature="random")]
191fn serialize_deserialize_telemetrypacketheader() {
192 for _ in 0..10 {
193 let h = TelemetryPacketHeader::from_random();
194 let stream = h.to_bytestream();
195 let test = TelemetryPacketHeader::from_bytestream(&stream, &mut 0);
196 assert_eq!(h,test.unwrap());
197 }
198}
199
200