gondola_core/packets/
telemetry_packet.rs

1//! Wrapper for all telemetry data - original implementation in 
2//! bfsw
3// The following file is part of gaps-online-software and published 
4// under the GPLv3 license
5
6use crate::prelude::*;
7
8/// A wrapper for packets from the telemetry stream
9///
10/// This is very compact and mostly used as an 
11/// intermediary
12#[derive(Debug, Clone, PartialEq)]
13#[cfg_attr(feature = "pybindings", pyclass, pyo3(name="TelemetryPacket"))]
14pub struct TelemetryPacket {
15  pub header  : TelemetryPacketHeader,
16  pub payload : Vec<u8>
17}
18
19#[cfg(feature="pybindings")]
20#[pymethods]
21impl TelemetryPacket {
22
23  /// Get a zero copy view of the payload 
24  /// Might be mostly useful for debugging purposes
25  #[getter]
26  fn payload<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
27    Ok(PyBytes::new(py, &self.payload))
28  }
29
30  #[getter]
31  fn header(&self) -> TelemetryPacketHeader {
32    // clone is fine here, since the packet header 
33    // is pretty small
34    self.header.clone()
35  }
36
37  #[getter]
38  fn packet_type(&self) -> TelemetryPacketType {
39    TelemetryPacketType::from(self.header.packet_type)
40  }
41
42  /// Check if this is either any of the different merged event 
43  /// types 
44  #[pyo3(name="is_event_packet")]
45  fn is_event_packet_py(&self) -> bool {
46    self.is_event_packet()
47  }
48}
49
50impl TelemetryPacket {
51
52  pub fn new() -> Self {
53    Self {
54      header  : TelemetryPacketHeader::new(),
55      payload : Vec::<u8>::new()
56    }
57  }
58 
59  pub fn is_event_packet(&self) -> bool {
60    if self.header.packet_type == TelemetryPacketType::NoTofDataEvent
61      || self.header.packet_type == TelemetryPacketType::NoGapsTriggerEvent 
62      || self.header.packet_type == TelemetryPacketType::InterestingEvent 
63      || self.header.packet_type == TelemetryPacketType::BoringEvent {
64      true 
65    } else {
66      false
67    }
68  }
69
70  /// Unpack the TelemetryPacket and return its content
71  pub fn unpack<T>(&self) -> Result<T, SerializationError>
72    where T: TelemetryPackable + Serialization {
73    if !T::TEL_PACKET_TYPES_EVENT.contains(&self.header.packet_type) &&
74      T::TEL_PACKET_TYPE != self.header.packet_type {
75      error!("This bytestream is not for a {} packet!", self.header.packet_type);
76      return Err(SerializationError::IncorrectPacketType);
77    }
78    let unpacked : T = T::from_bytestream(&self.payload, &mut 0)?;
79    Ok(unpacked)
80  }
81} 
82
83impl Serialization for TelemetryPacket {
84
85  /// No "classical" head byte marker
86  const HEAD : u16 = 0;
87  /// No "classical" tail byte marker
88  const TAIL : u16 = 0;
89  /// variable size
90  const SIZE : usize = 0;
91
92  fn from_bytestream(stream : &Vec<u8>, pos : &mut usize) -> Result<Self, SerializationError> {
93    let mut tpacket: TelemetryPacket = TelemetryPacket::new();
94    let header: TelemetryPacketHeader  = TelemetryPacketHeader::from_bytestream(stream, pos)?;
95    tpacket.header = header;
96    tpacket.payload = stream[*pos..*pos + header.length as usize - TelemetryPacketHeader::SIZE].to_vec();
97    Ok(tpacket)
98  }
99
100  fn to_bytestream(&self) -> Vec<u8> {
101    let mut stream: Vec<u8> = Vec::<u8>::new();
102    let mut s_head = self.header.to_bytestream();
103    stream.append(&mut s_head);
104    stream.extend_from_slice(self.payload.as_slice());
105    stream
106  }
107}
108
109impl Default for TelemetryPacket { 
110  fn default() -> Self {
111    Self::new()
112  }
113}
114
115impl fmt::Display for TelemetryPacket {
116  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117    let mut repr: String = String::from("<TelemetryPacket:");
118    repr += &(format!("\n  Header      : {}",self.header));
119    repr += &(format!("\n  Payload len : {}>",self.payload.len()));
120    write!(f, "{}", repr)
121  }
122}
123
124impl Frameable for TelemetryPacket {
125  const CRFRAMEOBJECT_TYPE : CRFrameObjectType = CRFrameObjectType::TelemetryPacket;
126}
127
128
129#[cfg(feature="pybindings")]
130pythonize!(TelemetryPacket);
131
132