1use chrono::{DateTime, Utc};
2
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6use crate::parser::{tcp_frame, udp_datagram};
7
8#[derive(Debug, PartialEq, Copy, Clone)]
16#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
17pub enum Codec {
18 C8,
19 C8Ext,
20 C16,
21 C12,
22 C13,
23 C14,
24}
25
26impl From<u8> for Codec {
27 fn from(value: u8) -> Self {
28 match value {
29 0x08 => Self::C8,
30 0x8E => Self::C8Ext,
31 0x10 => Self::C16,
32 0x0C => Self::C12,
33 0x0D => Self::C13,
34 0x0E => Self::C14,
35 _ => panic!("Unknown value: {}", value),
36 }
37 }
38}
39
40impl From<Codec> for u8 {
41 fn from(value: Codec) -> u8 {
42 match value {
43 Codec::C8 => 0x08,
44 Codec::C8Ext => 0x8E,
45 Codec::C16 => 0x10,
46 Codec::C12 => 0x0C,
47 Codec::C13 => 0x0D,
48 Codec::C14 => 0x0E,
49 }
50 }
51}
52
53#[derive(Debug, PartialEq, Copy, Clone)]
57#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
58pub enum Priority {
59 Low,
60 High,
61 Panic,
62}
63
64impl From<u8> for Priority {
65 fn from(value: u8) -> Self {
66 match value {
67 0x00 => Self::Low,
68 0x01 => Self::High,
69 0x02 => Self::Panic,
70 _ => panic!("Unknown value: {}", value),
71 }
72 }
73}
74
75#[derive(Debug, PartialEq, Copy, Clone)]
79#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
80pub enum EventGenerationCause {
81 None,
82 OnExit,
83 OnEntrance,
84 OnBoth,
85 Reserved,
86 Hysteresis,
87 OnChange,
88 Eventual,
89 Periodical,
90}
91
92impl From<u8> for EventGenerationCause {
93 fn from(value: u8) -> Self {
94 match value {
95 0 => Self::OnExit,
96 1 => Self::OnEntrance,
97 2 => Self::OnBoth,
98 3 => Self::Reserved,
99 4 => Self::Hysteresis,
100 5 => Self::OnChange,
101 6 => Self::Eventual,
102 7 => Self::Periodical,
103 _ => panic!("Unknown value: {}", value),
104 }
105 }
106}
107
108#[derive(Debug, PartialEq, Clone)]
112#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
113pub struct AVLDatagram {
114 pub packet_id: u16,
116 pub avl_packet_id: u8,
118 pub imei: String,
119 pub codec: Codec,
120 pub records: Vec<AVLRecord>,
122}
123
124impl<'a> TryFrom<&'a [u8]> for AVLDatagram {
125 type Error = nom::Err<nom::error::Error<&'a [u8]>>;
126
127 fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
128 match udp_datagram(value) {
129 Ok((_, datagram)) => Ok(datagram),
130 Err(e) => Err(e),
131 }
132 }
133}
134
135#[derive(Debug, PartialEq, Clone)]
137#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
138pub struct AVLFrame {
139 pub codec: Codec,
140 pub records: Vec<AVLRecord>,
142 pub crc16: u32,
144}
145
146impl<'a> TryFrom<&'a [u8]> for AVLFrame {
147 type Error = nom::Err<nom::error::Error<&'a [u8]>>;
148
149 fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
150 match tcp_frame(value) {
151 Ok((_, TeltonikaFrame::AVL(frame))) => Ok(frame),
152 Err(e) => Err(e),
153 _ => Err(nom::Err::Failure(nom::error::Error::new(
154 value,
155 nom::error::ErrorKind::Fail,
156 ))),
157 }
158 }
159}
160
161#[derive(Debug, PartialEq, Clone)]
163#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
164pub struct AVLRecord {
165 pub timestamp: DateTime<Utc>,
167 pub priority: Priority,
169 pub longitude: f64,
170 pub latitude: f64,
171 pub altitude: u16,
172 pub angle: u16,
174 pub satellites: u8,
176 pub speed: u16,
178 pub trigger_event_id: u16,
180 pub generation_type: Option<EventGenerationCause>,
182 pub io_events: Vec<AVLEventIO>,
184}
185
186#[derive(Debug, PartialEq, Clone)]
188#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
189pub struct AVLEventIO {
190 pub id: u16,
192 pub value: AVLEventIOValue,
196}
197
198#[derive(Debug, PartialEq, Clone)]
199#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
200pub enum AVLEventIOValue {
201 U8(u8),
202 U16(u16),
203 U32(u32),
204 U64(u64),
205 #[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
206 Variable(Vec<u8>),
207}
208
209#[derive(Debug, PartialEq, Clone)]
211#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
212pub struct GPRSFrame {
213 pub codec: Codec,
214 pub command_responses: Vec<String>,
216 pub crc16: u32,
218}
219
220#[derive(Debug, PartialEq, Clone)]
224#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
225pub enum TeltonikaFrame {
226 AVL(AVLFrame),
227 GPRS(GPRSFrame),
228}
229
230impl TeltonikaFrame {
231 pub fn unwrap_avl(self) -> AVLFrame {
232 if let Self::AVL(frame) = self {
233 return frame;
234 }
235 panic!("Frame is GPRS!")
236 }
237
238 pub fn unwrap_gprs(self) -> GPRSFrame {
239 if let Self::GPRS(frame) = self {
240 return frame;
241 }
242 panic!("Frame is AVL!")
243 }
244}