1use crate::prelude::*;
7
8#[derive(Debug, Clone)]
21#[cfg_attr(feature="pybindings", pyclass)]
22pub struct TofPacket {
23 pub packet_type : TofPacketType,
25 pub payload : Vec<u8>,
27 pub no_write_to_disk : bool,
30 pub no_send_over_nw : bool,
33 pub creation_time : Instant,
36 pub valid : bool, pub tof_paddles : Arc<HashMap<u8, TofPaddle>>,
38}
39
40impl fmt::Display for TofPacket {
41 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42 let p_len = self.payload.len();
43 if p_len < 4 {
44 write!(f, "<TofPacket: type {:?}, payload size {}>", self.packet_type, p_len)
45 } else {
46 write!(f, "<TofPacket: type {:?}, payload [ {} {} {} {} .. {} {} {} {}] of size {} >",
47 self.packet_type,
48 self.payload[0], self.payload[1], self.payload[2], self.payload[3],
49 self.payload[p_len-4], self.payload[p_len-3], self.payload[p_len - 2], self.payload[p_len-1], p_len )
50 }
51 }
52}
53
54impl Default for TofPacket {
55 fn default() -> Self {
56 Self::new()
57 }
58}
59
60impl PartialEq for TofPacket {
63 fn eq(&self, other: &Self) -> bool {
64 (self.packet_type == other.packet_type) &&
65 (self.payload == other.payload) &&
66 (self.no_write_to_disk == other.no_write_to_disk) &&
67 (self.no_send_over_nw == other.no_send_over_nw) &&
68 (self.valid == other.valid)
69 }
70}
71
72impl TofPacket {
73
74 pub fn new() -> Self {
75 let creation_time = Instant::now();
76 Self {
77 packet_type : TofPacketType::Unknown,
78 payload : Vec::<u8>::new(),
79 no_write_to_disk : false,
80 no_send_over_nw : false,
81 creation_time : creation_time,
82 valid : true,
83 tof_paddles : Arc::new(HashMap::<u8, TofPaddle>::new()),
84 }
85 }
86
87 pub fn zmq_payload_brdcast(&self) -> Vec<u8> {
90 let mut payload = String::from("BRCT").into_bytes();
91 let mut stream = self.to_bytestream();
92 payload.append(&mut stream);
93 payload
94 }
95
96 pub fn zmq_payload_rb(&self, rb_id : u8) -> Vec<u8> {
99 let mut payload = format!("RB{:02}", rb_id).into_bytes();
100 let mut stream = self.to_bytestream();
101 payload.append(&mut stream);
102 payload
103 }
104
105 pub fn unpack<T>(&self) -> Result<T, SerializationError>
107 where T: TofPackable + Serialization {
108
109 let mut pos : usize = 0;
113 if T::TOF_PACKET_TYPE_ALT != TofPacketType::Unknown {
114 if T::TOF_PACKET_TYPE_ALT == self.packet_type {
115 let unpacked : T = T::from_bytestream_alt(&self.payload, &mut pos)?;
116 return Ok(unpacked);
117 } else if T::TOF_PACKET_TYPE == self.packet_type {
118 let unpacked : T = T::from_bytestream(&self.payload, &mut pos)?;
119 return Ok(unpacked);
120 } else {
121 error!("This packet of type {} is neither for a {} nor a {} packet!", self.packet_type, T::TOF_PACKET_TYPE, T::TOF_PACKET_TYPE_ALT);
122 return Err(SerializationError::IncorrectPacketType);
123 }
124 } else { if T::TOF_PACKET_TYPE != self.packet_type {
126 error!("This bytestream is not for a {} packet!", self.packet_type);
127 return Err(SerializationError::IncorrectPacketType);
128 } else {
129 let unpacked : T = T::from_bytestream(&self.payload, &mut pos)?;
130 Ok(unpacked)
131 }
132 }
133 }
134
135 pub fn age(&self) -> u64 {
136 self.creation_time.elapsed().as_secs()
137 }
138}
139
140
141impl Serialization for TofPacket {
142 const HEAD : u16 = 0xaaaa;
143 const TAIL : u16 = 0x5555;
144 const SIZE : usize = 0; fn from_bytestream(stream : &Vec<u8>, pos : &mut usize)
147 -> Result<Self, SerializationError> {
148 if stream.len() < 2 {
149 return Err(SerializationError::StreamTooShort);
150 }
151 let head = parse_u16(stream, pos);
152 if Self::HEAD != head {
153 error!("TofPacket does not start with HEAD signature! {}", Self::HEAD);
154 return Err(SerializationError::HeadInvalid);
155 }
156 let packet_type : TofPacketType;
157 let packet_type_enc = parse_u8(stream, pos);
158 match TofPacketType::try_from(packet_type_enc) {
159 Ok(pt) => packet_type = pt,
160 Err(_) => {
161 error!("Can not decode packet with packet type {}", packet_type_enc);
162 return Err(SerializationError::UnknownPayload);}
163 }
164 let payload_size = parse_u32(stream, pos) as usize;
165 *pos += payload_size;
166 let tail = parse_u16(stream, pos);
167 if Self::TAIL != tail {
168 error!("Packet does not end with TAIL signature");
169 return Err(SerializationError::TailInvalid);
170 }
171 *pos -= 2; *pos -= payload_size;
173
174 let mut tp = TofPacket::new();
175 tp.packet_type = packet_type;
176 tp.payload.extend_from_slice(&stream[*pos..*pos+payload_size]);
177 *pos += 2 + payload_size;
179 Ok(tp)
180 }
181
182 fn to_bytestream(&self)
183 -> Vec<u8> {
184 let mut bytestream = Vec::<u8>::with_capacity(6 + self.payload.len());
185 bytestream.extend_from_slice(&TofPacket::HEAD.to_le_bytes());
186 let p_type = self.packet_type as u8;
187 bytestream.push(p_type);
188 let payload_len = self.payload.len() as u32;
193 bytestream.extend_from_slice(&payload_len.to_le_bytes());
196 bytestream.extend_from_slice(self.payload.as_slice());
197 bytestream.extend_from_slice(&TofPacket::TAIL.to_le_bytes());
198 bytestream
199 }
200}
201
202#[cfg(feature="random")]
203impl FromRandom for TofPacket {
204
205 fn from_random() -> Self {
206 let choices = [
209 TofPacketType::TofEvent,
210 TofPacketType::TofEvent,
211 TofPacketType::TofEvent,
212 TofPacketType::RBWaveform,
213 TofPacketType::RBWaveform,
214 TofPacketType::TofEvent,
215 TofPacketType::TofEvent,
216 TofPacketType::TofEvent,
217 TofPacketType::TofEvent,
218 TofPacketType::TofEvent,
219 TofPacketType::TofEvent,
220 TofPacketType::MasterTrigger,
221 TofPacketType::MasterTrigger,
222 TofPacketType::MasterTrigger,
223 TofPacketType::RBMoniData,
224 TofPacketType::PBMoniData,
225 TofPacketType::LTBMoniData,
226 TofPacketType::PAMoniData,
227 TofPacketType::CPUMoniData,
228 TofPacketType::MtbMoniData,
229 ];
230 let mut rng = rand::rng();
231 let idx = rng.random_range(0..choices.len());
232 let packet_type = choices[idx];
233 match packet_type {
234 TofPacketType::TofEvent => {
235 let te = TofEvent::from_random();
236 return te.pack()
237 }
238 TofPacketType::RBWaveform => {
239 let te = RBWaveform::from_random();
240 return te.pack()
241 }
242 TofPacketType::RBMoniData => {
243 let te = RBMoniData::from_random();
244 return te.pack()
245 }
246 TofPacketType::PAMoniData => {
247 let te = PAMoniData::from_random();
248 return te.pack()
249 }
250 TofPacketType::LTBMoniData => {
251 let te = LTBMoniData::from_random();
252 return te.pack()
253 }
254 TofPacketType::PBMoniData => {
255 let te = PBMoniData::from_random();
256 return te.pack()
257 }
258 TofPacketType::CPUMoniData => {
259 let te = CPUMoniData::from_random();
260 return te.pack()
261 }
262 TofPacketType::MtbMoniData => {
263 let te = MtbMoniData::from_random();
264 return te.pack()
265 }
266 _ => {
267 let te = TofEvent::from_random();
268 return te.pack()
269 }
270 }
271 }
272}
273
274impl Frameable for TofPacket {
275 const CRFRAMEOBJECT_TYPE : CRFrameObjectType = CRFrameObjectType::TofPacket;
276}
277
278#[cfg(feature="pybindings")]
279#[pymethods]
280impl TofPacket {
281
282 #[getter]
283 fn get_packet_type(&self) -> TofPacketType {
284 self.packet_type
285 }
286
287 fn get_paddle(&self, paddle_id : u8) -> PyResult<TofPaddle> {
288 match self.tof_paddles.get(&paddle_id) {
289 None => {
290 let msg = "TofPacket does not contain a reference to paddle {paddle_id}!";
291 return Err(PyValueError::new_err(msg));
292 }
293 Some(paddle) => {
294 return Ok(paddle.clone());
295 }
296 }
297 }
298
299 #[staticmethod]
311 #[pyo3(name = "from_bytestream")]
312 fn from_bytestream_py<'_py>(stream : Vec<u8>, start_pos : usize) -> PyResult<Self>{
313 let mut pos = start_pos;
314 match Self::from_bytestream(&stream, &mut pos) {
315 Ok(tp) => {
316 return Ok(tp);
317 }
318 Err(err) => {
319 let err_msg = format!("Unable to TofPacket from bytestream! {err}");
320 return Err(PyIOError::new_err(err_msg));
321 }
322 }
323 }
324
325 #[pyo3(name="to_bytestream")]
326 fn to_bytestream_py(&self) -> Vec<u8> {
327 self.to_bytestream()
328 }
329
330 #[getter]
331 #[pyo3(name="payload")]
332 fn get_payload_py(&self) -> Vec<u8> {
333 self.payload.clone()
334 }
335
336 #[pyo3(name="unpack")]
337 fn unpack_py(&self,py: Python) -> PyResult<Py<PyAny>> {
338 match self.packet_type {
339 TofPacketType::Unknown => {
340 let msg = "TofPacket is of type 'Unknown' and thus can't be unpacked!";
341 return Err(PyValueError::new_err(msg));
342 },
343 TofPacketType::RBEvent => {
344 match self.unpack::<RBEvent>() {
345 Ok(data) => {
346 return Ok(Py::new(py, data)?.into_any());
347 }
348 Err(err) => {
349 return Err(PyValueError::new_err(err.to_string()));
350 }
351 }
352 },
353 TofPacketType::TofEventDeprecated => {
354 match self.unpack::<TofEvent>() {
355 Ok(data) => {
356 return Ok(Py::new(py, data)?.into_any());
357 }
358 Err(err) => {
359 return Err(PyValueError::new_err(err.to_string()));
360 }
361 }
362 },
363 TofPacketType::RBWaveform => {
364 match self.unpack::<RBWaveform>() {
365 Ok(data) => {
366 return Ok(Py::new(py, data)?.into_any());
367 }
368 Err(err) => {
369 return Err(PyValueError::new_err(err.to_string()));
370 }
371 }
372 },
373 TofPacketType::TofEvent => {
374 match self.unpack::<TofEvent>() {
375 Ok(data) => {
376 return Ok(Py::new(py, data)?.into_any());
377 }
378 Err(err) => {
379 return Err(PyValueError::new_err(err.to_string()));
380 }
381 }
382 },
383 TofPacketType::DataSinkHB => {
384 match self.unpack::<DataSinkHB>() {
385 Ok(data) => {
386 return Ok(Py::new(py, data)?.into_any());
387 }
388 Err(err) => {
389 return Err(PyValueError::new_err(err.to_string()));
390 }
391 }
392 },
393 _ => {
430 match self.unpack::<TofEvent>() {
431 Ok(data) => {
432 return Ok(Py::new(py, data)?.into_any());
433 }
434 Err(err) => {
435 return Err(PyValueError::new_err(err.to_string()));
436 }
437 }
438 },
439 }
440 }
441}
442
443#[cfg(feature="pybindings")]
444pythonize!(TofPacket);
445