1use super::{write_preamble, Error as PktError, Identifier, MacAddress, SerializablePacket};
20use serde::{Deserialize, Serialize};
21use std::io::{Cursor, Write};
22
23#[derive(Debug, Clone)]
24pub struct Packet {
25 pub random_token: u16,
26 pub gateway_mac: MacAddress,
27 pub data: Data,
28}
29
30impl Packet {
31 pub fn get_result(&self) -> Result<Option<u32>, Error> {
32 self.data.get_result()
33 }
34}
35
36impl SerializablePacket for Packet {
37 fn serialize(&self, buffer: &mut [u8]) -> Result<u64, PktError> {
38 let mut w = Cursor::new(buffer);
39 write_preamble(&mut w, self.random_token)?;
40 w.write_all(&[Identifier::TxAck as u8])?;
41 w.write_all(self.gateway_mac.as_bytes())?;
42 w.write_all(serde_json::to_string(&self.data)?.as_bytes())?;
43 Ok(w.position())
44 }
45}
46
47impl From<Packet> for super::Packet {
48 fn from(packet: Packet) -> super::Packet {
49 super::Packet::Up(super::Up::TxAck(packet))
50 }
51}
52
53#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
88#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
89enum ErrorField {
90 None,
91 TooLate,
92 TooEarly,
93 CollisionPacket,
94 CollisionBeacon,
95 TxFreq,
96 TxPower,
97 GpsUnlocked,
98 SendLBT,
99 SendFail,
100}
101
102impl From<Result<(), Error>> for ErrorField {
103 fn from(other: Result<(), Error>) -> ErrorField {
104 match other {
105 Err(Error::TooLate) => ErrorField::TooLate,
106 Err(Error::TooEarly) => ErrorField::TooEarly,
107 Err(Error::CollisionPacket) => ErrorField::CollisionPacket,
108 Err(Error::CollisionBeacon) => ErrorField::CollisionBeacon,
109 Err(Error::InvalidTransmitFrequency) => ErrorField::TxFreq,
110 Err(Error::InvalidTransmitPower(_)) => ErrorField::TxPower,
111 Err(Error::AdjustedTransmitPower(_, _)) => ErrorField::TxPower,
112 Err(Error::GpsUnlocked) => ErrorField::GpsUnlocked,
113 Err(Error::SendLBT) => ErrorField::SendLBT,
114 Err(Error::SendFail) => ErrorField::SendFail,
115 _ => ErrorField::None,
116 }
117 }
118}
119
120impl ErrorField {
121 fn as_result(&self, tmst: Option<u32>) -> Result<Option<u32>, Error> {
122 match self {
123 ErrorField::TooEarly => Err(Error::TooEarly),
124 ErrorField::CollisionPacket => Err(Error::CollisionPacket),
125 ErrorField::CollisionBeacon => Err(Error::CollisionBeacon),
126 ErrorField::TooLate => Err(Error::TooLate),
127 ErrorField::TxFreq => Err(Error::InvalidTransmitFrequency),
128 ErrorField::TxPower => Err(Error::InvalidTransmitPower(None)),
129 ErrorField::GpsUnlocked => Err(Error::GpsUnlocked),
130 ErrorField::SendLBT => Err(Error::SendLBT),
131 ErrorField::SendFail => Err(Error::SendFail),
132 ErrorField::None => Ok(tmst),
133 }
134 }
135}
136
137use thiserror::Error;
138#[derive(Debug, Error, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
139pub enum Error {
140 #[error("TxAck::Error::TOO_LATE")]
141 TooLate,
142 #[error("TxAck::Error::TOO_EARLY")]
143 TooEarly,
144 #[error("TxAck::Error::COLLISION_PACKET")]
145 CollisionPacket,
146 #[error("TxAck::Error::COLLISION_BEACON")]
147 CollisionBeacon,
148 #[error("TxAck::Error::TX_FREQ")]
149 InvalidTransmitFrequency,
150 #[error("TxAck::Error::TX_POWER({0:?})")]
151 InvalidTransmitPower(Option<i32>),
152 #[error("TxAck::Error::ADJUSTED_TX_POWER({0:?})")]
153 AdjustedTransmitPower(Option<i32>, Option<u32>),
154 #[error("TxAck::Error::GPS_UNLOCKED")]
155 GpsUnlocked,
156 #[error("TxAck::Error::SEND_LBT")]
157 SendLBT,
158 #[error("TxAck::Error::SEND_FAIL")]
159 SendFail,
160}
161
162#[derive(Debug, Serialize, Deserialize, Clone)]
163pub struct Data {
164 txpk_ack: TxPkAck,
165}
166
167#[derive(Debug, Serialize, Deserialize, Clone)]
168pub struct TxPkAck {
169 #[serde(skip_serializing_if = "Option::is_none")]
170 tmst: Option<u32>,
171 #[serde(flatten)]
172 result: Option<TxPkAckResult>,
173}
174
175impl Default for Data {
176 fn default() -> Self {
177 Data {
178 txpk_ack: TxPkAck {
179 tmst: None,
180 result: Some(TxPkAckResult::Error {
181 error: ErrorField::None,
182 }),
183 },
184 }
185 }
186}
187
188impl Data {
189 pub fn new_with_error(error: Error) -> Data {
190 let (tmst, result) = if let Error::AdjustedTransmitPower(value, tmst) = error {
191 (
192 tmst,
193 TxPkAckResult::Warn {
194 warn: ErrorField::from(Err(error)),
195 value,
196 },
197 )
198 } else {
199 (
200 None,
201 TxPkAckResult::Error {
202 error: ErrorField::from(Err(error)),
203 },
204 )
205 };
206 Data {
207 txpk_ack: TxPkAck {
208 tmst,
209 result: Some(result),
210 },
211 }
212 }
213
214 pub fn get_result(&self) -> Result<Option<u32>, Error> {
215 match &self.txpk_ack.result {
216 Some(TxPkAckResult::Error { error }) => (*error).as_result(self.txpk_ack.tmst),
217 Some(TxPkAckResult::Warn { warn, value }) => {
218 if let ErrorField::TxPower = warn {
221 Err(Error::AdjustedTransmitPower(*value, self.txpk_ack.tmst))
222 } else {
223 (*warn).as_result(self.txpk_ack.tmst)
224 }
225 }
226 None => Ok(self.txpk_ack.tmst),
227 }
228 }
229}
230
231#[derive(Debug, Clone, Serialize, Deserialize)]
232#[serde(untagged)]
233enum TxPkAckResult {
234 Error {
235 error: ErrorField,
236 },
237 Warn {
238 warn: ErrorField,
239 #[serde(skip_serializing_if = "Option::is_none")]
240 value: Option<i32>,
241 },
242}
243
244impl Default for TxPkAckResult {
245 fn default() -> Self {
246 TxPkAckResult::Error {
247 error: ErrorField::None,
248 }
249 }
250}
251
252#[test]
253fn tx_nack_too_late() {
254 let json = "{\"txpk_ack\": { \"error\": \"TOO_LATE\"}}";
255 let parsed: Data = serde_json::from_str(json).expect("Error parsing tx_ack");
256 if let Err(Error::TooLate) = parsed.get_result() {
257 } else {
258 assert!(false);
259 }
260}
261
262#[test]
263fn tx_ack_deser() {
264 let json = "{\"txpk_ack\":{\"error\":\"NONE\"}}";
265 let parsed: Data = serde_json::from_str(json).expect("Error parsing tx_ack");
266 if let Err(_) = parsed.get_result() {
267 assert!(false);
268 }
269}
270
271#[test]
272fn tx_ack_deser_minimal() {
273 let json = "{\"txpk_ack\":{}}";
274 let parsed: Data = serde_json::from_str(json).expect("Error parsing tx_ack");
275 if let Err(_) = parsed.get_result() {
276 assert!(false);
277 }
278}
279
280#[test]
281fn tx_ack_deser_empty_error() {
282 let json = "{\"txpk_ack\":{\"error\":\"\"}}";
283 let parsed: Data = serde_json::from_str(json).expect("Error parsing tx_ack");
284 if let Err(_) = parsed.get_result() {
285 assert!(false);
286 }
287}
288
289#[test]
290fn tx_ack_deser_with_tmst() {
291 let json = "{\"txpk_ack\":{\"error\":\"NONE\", \"tmst\": 1234}}";
292 let parsed: Data = serde_json::from_str(json).expect("Error parsing tx_ack");
293 match parsed.get_result() {
294 Ok(Some(tmst)) => assert_eq!(1234, tmst),
295 _ => assert!(false),
296 }
297}
298
299#[test]
300fn tx_nack_tx_power_legacy() {
301 let json = "{ \"txpk_ack\": { \"error\" : \"TX_POWER\"}}";
302 let parsed: Data = serde_json::from_str(json).expect("Error parsing tx_ack");
303 if let Err(Error::InvalidTransmitPower(v)) = parsed.get_result() {
304 assert!(v.is_none());
305 } else {
306 assert!(false);
307 }
308}
309
310#[test]
311fn tx_nack_tx_power_sx1302deser() {
312 let json = "{ \"txpk_ack\": { \"warn\" : \"TX_POWER\", \"value\" : 27 }}";
313 let parsed: Data = serde_json::from_str(json).expect("Error parsing tx_ack");
314 if let Err(Error::AdjustedTransmitPower(power_used, tmst)) = parsed.get_result() {
315 if let (Some(power_used), None) = (power_used, tmst) {
316 assert_eq!(power_used, 27)
317 } else {
318 assert!(false)
319 }
320 } else {
321 assert!(false)
322 }
323}
324
325#[test]
326fn tx_nack_tx_power_sx1302deser_with_tmst() {
327 let json = "{ \"txpk_ack\": { \"warn\" : \"TX_POWER\", \"value\" : 27, \"tmst\": 1234 }}";
328 let parsed: Data = serde_json::from_str(json).expect("Error parsing tx_ack");
329 if let Err(Error::AdjustedTransmitPower(power_used, tmst)) = parsed.get_result() {
330 if let (Some(power_used), Some(tmst)) = (power_used, tmst) {
331 assert_eq!(power_used, 27);
332 assert_eq!(tmst, 1234)
333 } else {
334 assert!(false)
335 }
336 } else {
337 assert!(false)
338 }
339}
340
341#[test]
342fn tx_nack_tx_power_sx1302_ser() {
343 let invalid_transmit_power = Data::new_with_error(Error::AdjustedTransmitPower(Some(27), None));
344 let str = serde_json::to_string(&invalid_transmit_power).expect("serialization error");
345 assert_eq!("{\"txpk_ack\":{\"warn\":\"TX_POWER\",\"value\":27}}", str)
346}
347
348#[test]
349fn null_terminate() {
350 let bytes = hex::decode("02904905aa555a00000000007b227478706b5f61636b223a7b227761726e223a2254585f504f574552222c2276616c7565223a32372c22746d7374223a333937353336363839317d7d00").unwrap();
351 let _frame = crate::packet::Packet::parse(&bytes).unwrap();
352}
353
354#[test]
355fn dont_null_terminate() {
356 let bytes = hex::decode("02904905aa555a00000000007b227478706b5f61636b223a7b227761726e223a2254585f504f574552222c2276616c7565223a32372c22746d7374223a333937353336363839317d7d").unwrap();
357 let _frame = crate::packet::Packet::parse(&bytes).unwrap();
358}