semtech_udp/packet/
pull_resp.rs1use super::{
14 tx_ack, types, write_preamble, Error as PktError, Identifier, MacAddress, SerializablePacket,
15 Tmst,
16};
17
18use serde::{Deserialize, Serialize};
19use std::io::{Cursor, Write};
20use types::{deserialize_codr, serialize_codr, DataRate, Modulation};
21
22#[derive(Debug, Clone)]
23pub struct Packet {
24 pub random_token: u16,
25 pub data: Data,
26}
27
28impl Packet {
29 pub fn into_ack_for_gateway(self, gateway_mac: MacAddress) -> tx_ack::Packet {
30 tx_ack::Packet {
31 gateway_mac,
32 random_token: self.random_token,
33 data: tx_ack::Data::default(),
34 }
35 }
36
37 pub fn into_nack_with_error_for_gateway(
38 self,
39 error: super::tx_ack::Error,
40 gateway_mac: MacAddress,
41 ) -> tx_ack::Packet {
42 tx_ack::Packet {
43 gateway_mac,
44 random_token: self.random_token,
45 data: super::tx_ack::Data::new_with_error(error),
46 }
47 }
48
49 pub fn into_nack_with_error(self, e: super::tx_ack::Error) -> tx_ack::Packet {
51 self.into_nack_with_error_for_gateway(e, MacAddress::from([0; 8]))
52 }
53
54 pub fn into_ack(self) -> tx_ack::Packet {
56 self.into_ack_for_gateway(MacAddress::from([0; 8]))
57 }
58}
59
60#[derive(Debug, Serialize, Deserialize, Clone)]
61pub struct Data {
62 pub txpk: TxPk,
63}
64
65impl Data {
66 pub fn from_txpk(txpk: TxPk) -> Data {
67 Data { txpk }
68 }
69}
70
71#[derive(Debug, Serialize, Deserialize, Clone)]
93pub struct TxPk {
94 #[serde(flatten)]
95 pub time: Time,
96 pub freq: f64, pub rfch: u64, pub powe: u64, pub modu: Modulation, pub datr: DataRate, #[serde(
102 serialize_with = "serialize_codr",
103 deserialize_with = "deserialize_codr"
104 )]
105 pub codr: Option<lora_modulation::CodingRate>, #[serde(skip_serializing_if = "Option::is_none")]
107 pub fdev: Option<u64>, pub ipol: bool, pub prea: Option<u64>, #[serde(flatten)]
111 pub data: PhyData,
112 #[serde(skip_serializing_if = "Option::is_none")]
113 pub ncrc: Option<bool>, }
115
116#[derive(Debug, Serialize, Deserialize, Clone)]
117pub struct Time {
118 imme: bool, #[serde(skip_serializing_if = "Option::is_none")]
120 tmst: Option<Tmst>, #[serde(skip_serializing_if = "Option::is_none")]
122 tmms: Option<Tmst>, }
124
125impl Time {
126 pub fn is_immediate(&self) -> bool {
127 self.imme
128 }
129
130 pub fn tmst(&self) -> Option<u32> {
131 if let Some(Tmst::Tmst(val)) = self.tmst {
132 Some(val)
133 } else {
134 None
135 }
136 }
137
138 pub fn tmms(&self) -> Option<u32> {
139 if let Some(Tmst::Tmst(val)) = self.tmms {
140 Some(val)
141 } else {
142 None
143 }
144 }
145
146 pub fn immediate() -> Time {
147 Time {
148 imme: true,
149 tmst: None,
150 tmms: None,
151 }
152 }
153
154 pub fn by_tmst(tmst: u32) -> Time {
155 Time {
156 imme: false,
157 tmst: Some(Tmst::Tmst(tmst)),
158 tmms: None,
159 }
160 }
161
162 pub fn by_tmms(tmms: u32) -> Time {
163 Time {
164 imme: false,
165 tmst: None,
166 tmms: Some(Tmst::Tmst(tmms)),
167 }
168 }
169}
170
171#[derive(Debug, Serialize, Deserialize, Clone)]
172pub struct PhyData {
173 #[serde(with = "crate::packet::types::base64")]
174 data: Vec<u8>,
175 size: usize,
176}
177
178impl AsRef<[u8]> for PhyData {
179 fn as_ref(&self) -> &[u8] {
180 self.data.as_ref()
181 }
182}
183
184impl PhyData {
185 pub fn new(data: Vec<u8>) -> Self {
186 Self {
187 size: data.len(),
188 data,
189 }
190 }
191 pub fn set(&mut self, data: Vec<u8>) {
192 self.size = data.len();
193 self.data = data;
194 }
195
196 pub fn data(&self) -> &[u8] {
197 self.data.as_ref()
198 }
199 pub fn len(&self) -> usize {
200 self.size
201 }
202
203 pub fn is_empty(&self) -> bool {
204 self.size == 0
205 }
206}
207
208impl TxPk {
209 pub fn is_immediate(&self) -> bool {
210 self.time.imme
211 }
212
213 pub fn get_tmst(&self) -> Option<u32> {
214 if let Some(Tmst::Tmst(tmst)) = self.time.tmst {
215 Some(tmst)
216 } else {
217 None
218 }
219 }
220}
221
222use std::fmt;
223impl fmt::Display for TxPk {
224 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
225 write!(
226 f,
227 "{}, {:.2} MHz, {:?}, len: {}",
228 if let Some(Tmst::Tmst(time)) = self.time.tmst {
229 format!("@{time} us")
230 } else {
231 "immediately".into()
232 },
233 self.freq,
234 self.datr,
235 self.data.size
236 )
237 }
238}
239
240impl SerializablePacket for Packet {
241 fn serialize(&self, buffer: &mut [u8]) -> std::result::Result<u64, PktError> {
242 let mut w = Cursor::new(buffer);
243 write_preamble(&mut w, self.random_token)?;
244 w.write_all(&[Identifier::PullResp as u8])?;
245 w.write_all(serde_json::to_string(&self.data)?.as_bytes())?;
246 Ok(w.position())
247 }
248}
249
250impl From<Packet> for super::Packet {
251 fn from(packet: Packet) -> super::Packet {
252 super::Packet::Down(super::Down::PullResp(Box::new(packet)))
253 }
254}
255
256impl From<Box<Packet>> for super::Packet {
257 fn from(packet: Box<Packet>) -> super::Packet {
258 super::Packet::Down(super::Down::PullResp(packet))
259 }
260}