use super::{
tx_ack, write_preamble, Error as PktError, Identifier, MacAddress, SerializablePacket,
StringOrNum,
};
use serde::{Deserialize, Serialize};
use std::io::{Cursor, Write};
#[derive(Debug, Clone)]
pub struct Packet {
pub random_token: u16,
pub data: Data,
}
impl Packet {
pub fn into_ack_for_gateway(self, gateway_mac: MacAddress) -> tx_ack::Packet {
tx_ack::Packet {
gateway_mac,
random_token: self.random_token,
data: None,
}
}
pub fn into_nack_with_error_for_gateway(
self,
error: super::tx_ack::Error,
gateway_mac: MacAddress,
) -> tx_ack::Packet {
tx_ack::Packet {
gateway_mac,
random_token: self.random_token,
data: Some(super::tx_ack::TxPkNack::new(error)),
}
}
pub fn into_nack_with_error(self, e: super::tx_ack::Error) -> tx_ack::Packet {
self.into_nack_with_error_for_gateway(e, MacAddress { bytes: [0; 8] })
}
pub fn into_ack(self) -> tx_ack::Packet {
self.into_ack_for_gateway(MacAddress { bytes: [0; 8] })
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Data {
pub txpk: TxPk,
}
impl Data {
pub fn from_txpk(txpk: TxPk) -> Data {
Data { txpk }
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TxPk {
pub imme: bool, pub tmst: StringOrNum, #[serde(skip_serializing_if = "Option::is_none")]
pub tmms: Option<StringOrNum>, pub freq: f64, pub rfch: u64, pub powe: u64, pub modu: String, pub datr: String, pub codr: String, #[serde(skip_serializing_if = "Option::is_none")]
pub fdev: Option<u64>, pub ipol: bool, pub prea: Option<u64>, pub size: u64, pub data: String, #[serde(skip_serializing_if = "Option::is_none")]
pub ncrc: Option<bool>, }
impl SerializablePacket for Packet {
fn serialize(&self, buffer: &mut [u8]) -> std::result::Result<u64, PktError> {
let mut w = Cursor::new(buffer);
write_preamble(&mut w, self.random_token)?;
w.write_all(&[Identifier::PullResp as u8])?;
w.write_all(&serde_json::to_string(&self.data)?.as_bytes())?;
Ok(w.position())
}
}
impl From<Packet> for super::Packet {
fn from(packet: Packet) -> super::Packet {
super::Packet::Down(super::Down::PullResp(Box::new(packet)))
}
}
impl From<Box<Packet>> for super::Packet {
fn from(packet: Box<Packet>) -> super::Packet {
super::Packet::Down(super::Down::PullResp(packet))
}
}