Add feature flags to lrwn crate.

This avoids pulling and building unnecessary dependencies for simple
use-cases.
This commit is contained in:
Orne Brocaar
2023-04-27 10:37:34 +01:00
parent 08d69502de
commit 0679f10fad
16 changed files with 267 additions and 101 deletions

View File

@ -46,7 +46,7 @@ tracing-subscriber = { version = "0.3", features = [
# ChirpStack API definitions # ChirpStack API definitions
chirpstack_api = { path = "../api/rust", features = ["default", "internal"] } chirpstack_api = { path = "../api/rust", features = ["default", "internal"] }
lrwn = { path = "../lrwn" } lrwn = { path = "../lrwn", features = ["serde", "diesel", "regions", "crypto"] }
backend = { path = "../backend" } backend = { path = "../backend" }
# HTTP # HTTP

View File

@ -8,12 +8,15 @@ authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2018" edition = "2018"
repository = "https://github.com/chirpstack/chirpstack" repository = "https://github.com/chirpstack/chirpstack"
[package.metadata.docs.rs]
all-features = true
[dependencies] [dependencies]
hex = "0.4" hex = "0.4"
cmac = "0.7" cmac = { version = "0.7", optional = true }
aes = "0.8" aes = { version = "0.8", optional = true }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"], optional = true }
diesel = { version = "2.0", features = [ "postgres" ] } diesel = { version = "2.0", features = ["postgres"], optional = true }
# Error handling # Error handling
thiserror = "1.0" thiserror = "1.0"
@ -21,3 +24,10 @@ anyhow = "1.0"
# Misc # Misc
lazy_static = "1.4" lazy_static = "1.4"
[features]
default = []
diesel = ["dep:diesel", "serde"]
serde = ["dep:serde"]
crypto = ["dep:cmac", "dep:aes"]
regions = []

View File

@ -4,4 +4,4 @@
test: test:
cargo fmt --check cargo fmt --check
cargo clippy cargo clippy
cargo test cargo test --all-features

View File

@ -2,16 +2,23 @@ use std::fmt;
use std::str::FromStr; use std::str::FromStr;
use anyhow::Result; use anyhow::Result;
use diesel::backend::{self, Backend}; #[cfg(feature = "diesel")]
use diesel::sql_types::Binary; use diesel::{
use diesel::{deserialize, serialize}; backend::{self, Backend},
use serde::de::{self, Visitor}; deserialize, serialize,
use serde::{Deserialize, Deserializer, Serialize, Serializer}; sql_types::Binary,
};
#[cfg(feature = "serde")]
use serde::{
de::{self, Visitor},
Deserialize, Deserializer, Serialize, Serializer,
};
use crate::Error; use crate::Error;
#[derive(Copy, Clone, PartialEq, Eq, AsExpression, FromSqlRow, Default)] #[derive(Copy, Clone, PartialEq, Eq, Default)]
#[diesel(sql_type = diesel::sql_types::Binary)] #[cfg_attr(feature = "diesel", derive(AsExpression, FromSqlRow))]
#[cfg_attr(feature = "diesel", diesel(sql_type = diesel::sql_types::Binary))]
pub struct AES128Key([u8; 16]); pub struct AES128Key([u8; 16]);
impl AES128Key { impl AES128Key {
@ -64,6 +71,7 @@ impl FromStr for AES128Key {
} }
} }
#[cfg(feature = "serde")]
impl Serialize for AES128Key { impl Serialize for AES128Key {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -73,6 +81,7 @@ impl Serialize for AES128Key {
} }
} }
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for AES128Key { impl<'de> Deserialize<'de> for AES128Key {
fn deserialize<D>(deserialize: D) -> Result<AES128Key, D::Error> fn deserialize<D>(deserialize: D) -> Result<AES128Key, D::Error>
where where
@ -82,8 +91,10 @@ impl<'de> Deserialize<'de> for AES128Key {
} }
} }
#[cfg(feature = "serde")]
struct Aes128KeyVisitor; struct Aes128KeyVisitor;
#[cfg(feature = "serde")]
impl<'de> Visitor<'de> for Aes128KeyVisitor { impl<'de> Visitor<'de> for Aes128KeyVisitor {
type Value = AES128Key; type Value = AES128Key;
@ -99,6 +110,7 @@ impl<'de> Visitor<'de> for Aes128KeyVisitor {
} }
} }
#[cfg(feature = "diesel")]
impl<DB> deserialize::FromSql<Binary, DB> for AES128Key impl<DB> deserialize::FromSql<Binary, DB> for AES128Key
where where
DB: Backend, DB: Backend,
@ -117,6 +129,7 @@ where
} }
} }
#[cfg(feature = "diesel")]
impl serialize::ToSql<Binary, diesel::pg::Pg> for AES128Key impl serialize::ToSql<Binary, diesel::pg::Pg> for AES128Key
where where
[u8]: serialize::ToSql<Binary, diesel::pg::Pg>, [u8]: serialize::ToSql<Binary, diesel::pg::Pg>,

View File

@ -1,7 +1,9 @@
use anyhow::Result; use anyhow::Result;
#[cfg(feature = "serde")]
use serde::Serialize; use serde::Serialize;
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum CFList { pub enum CFList {
Channels(CFListChannels), Channels(CFListChannels),
ChannelMask(CFListChannelMasks), ChannelMask(CFListChannelMasks),
@ -38,7 +40,8 @@ impl CFList {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct CFListChannels([u32; 5]); pub struct CFListChannels([u32; 5]);
impl CFListChannels { impl CFListChannels {
@ -98,7 +101,8 @@ impl CFListChannels {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct CFListChannelMasks(Vec<ChMask>); pub struct CFListChannelMasks(Vec<ChMask>);
impl CFListChannelMasks { impl CFListChannelMasks {
@ -141,7 +145,8 @@ impl CFListChannelMasks {
/// ChMask encodes the channels usable for uplink access. 0 = channel 1, /// ChMask encodes the channels usable for uplink access. 0 = channel 1,
/// 15 = channel 16. /// 15 = channel 16.
#[derive(Serialize, Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct ChMask([bool; 16]); pub struct ChMask([bool; 16]);
impl ChMask { impl ChMask {

View File

@ -2,8 +2,17 @@ use std::fmt;
use std::str::FromStr; use std::str::FromStr;
use anyhow::Result; use anyhow::Result;
use serde::de::{self, Visitor}; #[cfg(feature = "diesel")]
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use diesel::{
backend::{self, Backend},
deserialize, serialize,
sql_types::Binary,
};
#[cfg(feature = "serde")]
use serde::{
de::{self, Visitor},
Deserialize, Deserializer, Serialize, Serializer,
};
use super::netid::NetID; use super::netid::NetID;
use crate::Error; use crate::Error;
@ -58,6 +67,7 @@ impl FromStr for DevAddrPrefix {
} }
} }
#[cfg(feature = "serde")]
impl Serialize for DevAddrPrefix { impl Serialize for DevAddrPrefix {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -67,6 +77,7 @@ impl Serialize for DevAddrPrefix {
} }
} }
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for DevAddrPrefix { impl<'de> Deserialize<'de> for DevAddrPrefix {
fn deserialize<D>(deserialize: D) -> Result<DevAddrPrefix, D::Error> fn deserialize<D>(deserialize: D) -> Result<DevAddrPrefix, D::Error>
where where
@ -76,8 +87,10 @@ impl<'de> Deserialize<'de> for DevAddrPrefix {
} }
} }
#[cfg(feature = "serde")]
struct DevAddrPrefixVisitor; struct DevAddrPrefixVisitor;
#[cfg(feature = "serde")]
impl<'de> Visitor<'de> for DevAddrPrefixVisitor { impl<'de> Visitor<'de> for DevAddrPrefixVisitor {
type Value = DevAddrPrefix; type Value = DevAddrPrefix;
@ -93,8 +106,9 @@ impl<'de> Visitor<'de> for DevAddrPrefixVisitor {
} }
} }
#[derive(PartialEq, Eq, Copy, Clone, AsExpression, FromSqlRow, Default)] #[derive(PartialEq, Eq, Copy, Clone, Default)]
#[diesel(sql_type = diesel::sql_types::Binary)] #[cfg_attr(feature = "diesel", derive(AsExpression, FromSqlRow))]
#[cfg_attr(feature = "diesel", diesel(sql_type = diesel::sql_types::Binary))]
pub struct DevAddr([u8; 4]); pub struct DevAddr([u8; 4]);
impl DevAddr { impl DevAddr {
@ -226,6 +240,7 @@ impl FromStr for DevAddr {
} }
} }
#[cfg(feature = "serde")]
impl Serialize for DevAddr { impl Serialize for DevAddr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -235,10 +250,7 @@ impl Serialize for DevAddr {
} }
} }
use diesel::backend::{self, Backend}; #[cfg(feature = "diesel")]
use diesel::sql_types::Binary;
use diesel::{deserialize, serialize};
impl<DB> deserialize::FromSql<Binary, DB> for DevAddr impl<DB> deserialize::FromSql<Binary, DB> for DevAddr
where where
DB: Backend, DB: Backend,
@ -257,6 +269,7 @@ where
} }
} }
#[cfg(feature = "diesel")]
impl serialize::ToSql<Binary, diesel::pg::Pg> for DevAddr impl serialize::ToSql<Binary, diesel::pg::Pg> for DevAddr
where where
[u8]: serialize::ToSql<Binary, diesel::pg::Pg>, [u8]: serialize::ToSql<Binary, diesel::pg::Pg>,

View File

@ -1,7 +1,9 @@
use anyhow::Result; use anyhow::Result;
#[cfg(feature = "serde")]
use serde::Serialize; use serde::Serialize;
#[derive(Serialize, PartialEq, Eq, Debug, Clone)] #[derive(PartialEq, Eq, Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct DLSettings { pub struct DLSettings {
pub opt_neg: bool, pub opt_neg: bool,
pub rx2_dr: u8, pub rx2_dr: u8,

View File

@ -2,13 +2,23 @@ use std::fmt;
use std::str::FromStr; use std::str::FromStr;
use anyhow::Result; use anyhow::Result;
use serde::de::{self, Visitor}; #[cfg(feature = "diesel")]
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use diesel::{
backend::{self, Backend},
deserialize, serialize,
sql_types::Binary,
};
#[cfg(feature = "serde")]
use serde::{
de::{self, Visitor},
Deserialize, Deserializer, Serialize, Serializer,
};
use crate::Error; use crate::Error;
#[derive(Copy, Clone, PartialEq, Eq, Hash, AsExpression, FromSqlRow, Default)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Default)]
#[diesel(sql_type = diesel::sql_types::Binary)] #[cfg_attr(feature = "diesel", derive(AsExpression, FromSqlRow))]
#[cfg_attr(feature = "diesel", diesel(sql_type = diesel::sql_types::Binary))]
pub struct EUI64([u8; 8]); pub struct EUI64([u8; 8]);
impl EUI64 { impl EUI64 {
@ -69,6 +79,7 @@ impl FromStr for EUI64 {
} }
} }
#[cfg(feature = "serde")]
impl Serialize for EUI64 { impl Serialize for EUI64 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -78,6 +89,7 @@ impl Serialize for EUI64 {
} }
} }
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for EUI64 { impl<'de> Deserialize<'de> for EUI64 {
fn deserialize<D>(deserialize: D) -> Result<EUI64, D::Error> fn deserialize<D>(deserialize: D) -> Result<EUI64, D::Error>
where where
@ -87,8 +99,10 @@ impl<'de> Deserialize<'de> for EUI64 {
} }
} }
#[cfg(feature = "serde")]
struct Eui64Visitor; struct Eui64Visitor;
#[cfg(feature = "serde")]
impl<'de> Visitor<'de> for Eui64Visitor { impl<'de> Visitor<'de> for Eui64Visitor {
type Value = EUI64; type Value = EUI64;
@ -104,10 +118,7 @@ impl<'de> Visitor<'de> for Eui64Visitor {
} }
} }
use diesel::backend::{self, Backend}; #[cfg(feature = "diesel")]
use diesel::sql_types::Binary;
use diesel::{deserialize, serialize};
impl<DB> deserialize::FromSql<Binary, DB> for EUI64 impl<DB> deserialize::FromSql<Binary, DB> for EUI64
where where
DB: Backend, DB: Backend,
@ -126,6 +137,7 @@ where
} }
} }
#[cfg(feature = "diesel")]
impl serialize::ToSql<Binary, diesel::pg::Pg> for EUI64 impl serialize::ToSql<Binary, diesel::pg::Pg> for EUI64
where where
[u8]: serialize::ToSql<Binary, diesel::pg::Pg>, [u8]: serialize::ToSql<Binary, diesel::pg::Pg>,
@ -138,6 +150,7 @@ where
} }
} }
#[cfg(feature = "diesel")]
impl diesel::sql_types::SqlType for EUI64 { impl diesel::sql_types::SqlType for EUI64 {
type IsNull = diesel::sql_types::is_nullable::NotNull; type IsNull = diesel::sql_types::is_nullable::NotNull;
} }

View File

@ -1,10 +1,12 @@
use anyhow::Result; use anyhow::Result;
#[cfg(feature = "serde")]
use serde::Serialize; use serde::Serialize;
use super::devaddr::DevAddr; use super::devaddr::DevAddr;
use super::maccommand::MACCommandSet; use super::maccommand::MACCommandSet;
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct FHDR { pub struct FHDR {
pub devaddr: DevAddr, pub devaddr: DevAddr,
pub f_ctrl: FCtrl, pub f_ctrl: FCtrl,
@ -82,7 +84,8 @@ impl FHDR {
} }
} }
#[derive(Serialize, Default, Debug, PartialEq, Eq, Clone)] #[derive(Default, Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct FCtrl { pub struct FCtrl {
pub adr: bool, pub adr: bool,
pub adr_ack_req: bool, pub adr_ack_req: bool,

View File

@ -1,3 +1,4 @@
#[cfg(feature = "diesel")]
#[macro_use] #[macro_use]
extern crate diesel; extern crate diesel;
#[macro_use] #[macro_use]
@ -25,12 +26,14 @@ mod dl_settings;
mod error; mod error;
mod eui64; mod eui64;
mod fhdr; mod fhdr;
#[cfg(feature = "crypto")]
pub mod keys; pub mod keys;
mod maccommand; mod maccommand;
mod mhdr; mod mhdr;
mod netid; mod netid;
mod payload; mod payload;
mod phy_payload; mod phy_payload;
#[cfg(feature = "regions")]
pub mod region; pub mod region;
lazy_static! { lazy_static! {

View File

@ -3,12 +3,14 @@ use std::ops::{Deref, DerefMut};
use std::time::Duration; use std::time::Duration;
use anyhow::Result; use anyhow::Result;
#[cfg(feature = "serde")]
use serde::Serialize; use serde::Serialize;
use super::cflist::ChMask; use super::cflist::ChMask;
use super::dl_settings::DLSettings; use super::dl_settings::DLSettings;
#[derive(Serialize, Debug, PartialEq, Eq, Clone, Copy, Hash)] #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum CID { pub enum CID {
ResetInd, ResetInd,
ResetConf, ResetConf,
@ -83,7 +85,8 @@ impl CID {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum MACCommand { pub enum MACCommand {
ResetInd(ResetIndPayload), ResetInd(ResetIndPayload),
ResetConf(ResetConfPayload), ResetConf(ResetConfPayload),
@ -170,7 +173,8 @@ impl MACCommand {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum Version { pub enum Version {
LoRaWAN1_1, LoRaWAN1_1,
} }
@ -198,13 +202,15 @@ impl fmt::Display for Version {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum DwellTime { pub enum DwellTime {
NoLimit, NoLimit,
Limit400ms, Limit400ms,
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum DeviceModeClass { pub enum DeviceModeClass {
ClassA, ClassA,
ClassC, ClassC,
@ -242,7 +248,8 @@ impl fmt::Display for DeviceModeClass {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct MACCommandSet(Vec<MACCommand>); pub struct MACCommandSet(Vec<MACCommand>);
impl Deref for MACCommandSet { impl Deref for MACCommandSet {
@ -780,7 +787,8 @@ impl MACCommandSet {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct ResetIndPayload { pub struct ResetIndPayload {
pub dev_lorawan_version: Version, pub dev_lorawan_version: Version,
} }
@ -803,7 +811,8 @@ impl ResetIndPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct ResetConfPayload { pub struct ResetConfPayload {
pub serv_lorawan_version: Version, pub serv_lorawan_version: Version,
} }
@ -826,7 +835,8 @@ impl ResetConfPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct LinkCheckAnsPayload { pub struct LinkCheckAnsPayload {
pub margin: u8, pub margin: u8,
pub gw_cnt: u8, pub gw_cnt: u8,
@ -851,7 +861,8 @@ impl LinkCheckAnsPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct LinkADRReqPayload { pub struct LinkADRReqPayload {
pub dr: u8, pub dr: u8,
pub tx_power: u8, pub tx_power: u8,
@ -894,7 +905,8 @@ impl LinkADRReqPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct Redundancy { pub struct Redundancy {
pub ch_mask_cntl: u8, pub ch_mask_cntl: u8,
pub nb_rep: u8, pub nb_rep: u8,
@ -922,7 +934,8 @@ impl Redundancy {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct LinkADRAnsPayload { pub struct LinkADRAnsPayload {
pub ch_mask_ack: bool, pub ch_mask_ack: bool,
pub dr_ack: bool, pub dr_ack: bool,
@ -961,7 +974,8 @@ impl LinkADRAnsPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct DutyCycleReqPayload { pub struct DutyCycleReqPayload {
pub max_duty_cycle: u8, pub max_duty_cycle: u8,
} }
@ -988,7 +1002,8 @@ impl DutyCycleReqPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct RxParamSetupReqPayload { pub struct RxParamSetupReqPayload {
pub frequency: u32, pub frequency: u32,
pub dl_settings: DLSettings, pub dl_settings: DLSettings,
@ -1029,7 +1044,8 @@ impl RxParamSetupReqPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct RxParamSetupAnsPayload { pub struct RxParamSetupAnsPayload {
pub channel_ack: bool, pub channel_ack: bool,
pub rx2_dr_ack: bool, pub rx2_dr_ack: bool,
@ -1066,7 +1082,8 @@ impl RxParamSetupAnsPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct DevStatusAnsPayload { pub struct DevStatusAnsPayload {
pub battery: u8, pub battery: u8,
pub margin: i8, pub margin: i8,
@ -1110,7 +1127,8 @@ impl DevStatusAnsPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct NewChannelReqPayload { pub struct NewChannelReqPayload {
pub ch_index: u8, pub ch_index: u8,
pub freq: u32, pub freq: u32,
@ -1177,7 +1195,8 @@ impl NewChannelReqPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct NewChannelAnsPayload { pub struct NewChannelAnsPayload {
pub channel_freq_ok: bool, pub channel_freq_ok: bool,
pub dr_range_ok: bool, pub dr_range_ok: bool,
@ -1209,7 +1228,8 @@ impl NewChannelAnsPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct RxTimingSetupReqPayload { pub struct RxTimingSetupReqPayload {
pub delay: u8, pub delay: u8,
} }
@ -1234,7 +1254,8 @@ impl RxTimingSetupReqPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct TxParamSetupReqPayload { pub struct TxParamSetupReqPayload {
pub uplink_dwell_time: DwellTime, pub uplink_dwell_time: DwellTime,
pub downlink_dwell_time: DwellTime, pub downlink_dwell_time: DwellTime,
@ -1285,7 +1306,8 @@ impl TxParamSetupReqPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct DlChannelReqPayload { pub struct DlChannelReqPayload {
pub ch_index: u8, pub ch_index: u8,
pub freq: u32, pub freq: u32,
@ -1327,7 +1349,8 @@ impl DlChannelReqPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct DlChannelAnsPayload { pub struct DlChannelAnsPayload {
pub uplink_freq_exists: bool, pub uplink_freq_exists: bool,
pub channel_freq_ok: bool, pub channel_freq_ok: bool,
@ -1361,7 +1384,8 @@ impl DlChannelAnsPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct RekeyConfPayload { pub struct RekeyConfPayload {
pub serv_lorawan_version: Version, pub serv_lorawan_version: Version,
} }
@ -1384,7 +1408,8 @@ impl RekeyConfPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct RekeyIndPayload { pub struct RekeyIndPayload {
pub dev_lorawan_version: Version, pub dev_lorawan_version: Version,
} }
@ -1407,7 +1432,8 @@ impl RekeyIndPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct ADRParamSetupReqPayload { pub struct ADRParamSetupReqPayload {
pub adr_param: ADRParam, pub adr_param: ADRParam,
} }
@ -1430,7 +1456,8 @@ impl ADRParamSetupReqPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct ADRParam { pub struct ADRParam {
pub limit_exp: u8, pub limit_exp: u8,
pub delay_exp: u8, pub delay_exp: u8,
@ -1462,7 +1489,8 @@ impl ADRParam {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct DeviceTimeAnsPayload { pub struct DeviceTimeAnsPayload {
pub time_since_gps_epoch: Duration, pub time_since_gps_epoch: Duration,
} }
@ -1496,7 +1524,8 @@ impl DeviceTimeAnsPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct ForceRejoinReqPayload { pub struct ForceRejoinReqPayload {
pub period: u8, pub period: u8,
pub max_retries: u8, pub max_retries: u8,
@ -1541,7 +1570,8 @@ impl ForceRejoinReqPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct RejoinParamSetupReqPayload { pub struct RejoinParamSetupReqPayload {
pub max_time_n: u8, pub max_time_n: u8,
pub max_count_n: u8, pub max_count_n: u8,
@ -1573,7 +1603,8 @@ impl RejoinParamSetupReqPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct RejoinParamSetupAnsPayload { pub struct RejoinParamSetupAnsPayload {
pub time_ok: bool, pub time_ok: bool,
} }
@ -1600,7 +1631,8 @@ impl RejoinParamSetupAnsPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct PingSlotInfoReqPayload { pub struct PingSlotInfoReqPayload {
pub periodicity: u8, pub periodicity: u8,
} }
@ -1627,7 +1659,8 @@ impl PingSlotInfoReqPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct PingSlotChannelReqPayload { pub struct PingSlotChannelReqPayload {
pub freq: u32, pub freq: u32,
pub dr: u8, pub dr: u8,
@ -1669,7 +1702,8 @@ impl PingSlotChannelReqPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct PingSlotChannelAnsPayload { pub struct PingSlotChannelAnsPayload {
pub dr_ok: bool, pub dr_ok: bool,
pub channel_freq_ok: bool, pub channel_freq_ok: bool,
@ -1704,7 +1738,8 @@ impl PingSlotChannelAnsPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct BeaconFreqReqPayload { pub struct BeaconFreqReqPayload {
pub freq: u32, pub freq: u32,
} }
@ -1741,7 +1776,8 @@ impl BeaconFreqReqPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct BeaconFreqAnsPayload { pub struct BeaconFreqAnsPayload {
beacon_freq_ok: bool, beacon_freq_ok: bool,
} }
@ -1768,7 +1804,8 @@ impl BeaconFreqAnsPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct DeviceModeIndPayload { pub struct DeviceModeIndPayload {
pub class: DeviceModeClass, pub class: DeviceModeClass,
} }
@ -1791,7 +1828,8 @@ impl DeviceModeIndPayload {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct DeviceModeConfPayload { pub struct DeviceModeConfPayload {
pub class: DeviceModeClass, pub class: DeviceModeClass,
} }

View File

@ -1,9 +1,11 @@
use std::fmt; use std::fmt;
use anyhow::Result; use anyhow::Result;
#[cfg(feature = "serde")]
use serde::Serialize; use serde::Serialize;
#[derive(Serialize, Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum MType { pub enum MType {
JoinRequest, JoinRequest,
JoinAccept, JoinAccept,
@ -21,12 +23,14 @@ impl fmt::Display for MType {
} }
} }
#[derive(Serialize, Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum Major { pub enum Major {
LoRaWANR1, LoRaWANR1,
} }
#[derive(Debug, PartialEq, Eq, Clone, Serialize)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct MHDR { pub struct MHDR {
pub m_type: MType, pub m_type: MType,
pub major: Major, pub major: Major,

View File

@ -2,8 +2,11 @@ use std::fmt;
use std::str::FromStr; use std::str::FromStr;
use anyhow::Result; use anyhow::Result;
use serde::de::{self, Visitor}; #[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{
de::{self, Visitor},
{Deserialize, Deserializer, Serialize, Serializer},
};
use crate::devaddr::DevAddrPrefix; use crate::devaddr::DevAddrPrefix;
use crate::Error; use crate::Error;
@ -132,6 +135,7 @@ impl FromStr for NetID {
} }
} }
#[cfg(feature = "serde")]
impl Serialize for NetID { impl Serialize for NetID {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -141,6 +145,7 @@ impl Serialize for NetID {
} }
} }
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for NetID { impl<'de> Deserialize<'de> for NetID {
fn deserialize<D>(deserialize: D) -> Result<NetID, D::Error> fn deserialize<D>(deserialize: D) -> Result<NetID, D::Error>
where where
@ -150,8 +155,10 @@ impl<'de> Deserialize<'de> for NetID {
} }
} }
#[cfg(feature = "serde")]
struct NetIdVisitor; struct NetIdVisitor;
#[cfg(feature = "serde")]
impl<'de> Visitor<'de> for NetIdVisitor { impl<'de> Visitor<'de> for NetIdVisitor {
type Value = NetID; type Value = NetID;

View File

@ -1,4 +1,5 @@
use anyhow::Result; use anyhow::Result;
#[cfg(feature = "serde")]
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
use super::cflist::CFList; use super::cflist::CFList;
@ -21,6 +22,7 @@ pub enum Payload {
Raw(Vec<u8>), Raw(Vec<u8>),
} }
#[cfg(feature = "serde")]
impl Serialize for Payload { impl Serialize for Payload {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -37,7 +39,8 @@ impl Serialize for Payload {
} }
} }
#[derive(Serialize, PartialEq, Eq, Debug, Clone)] #[derive(PartialEq, Eq, Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum JoinType { pub enum JoinType {
Join, Join,
RejoinType0, RejoinType0,
@ -85,7 +88,8 @@ impl Payload {
} }
} }
#[derive(Serialize, PartialEq, Eq, Debug, Copy, Clone)] #[derive(PartialEq, Eq, Debug, Copy, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct JoinRequestPayload { pub struct JoinRequestPayload {
pub join_eui: EUI64, pub join_eui: EUI64,
pub dev_eui: EUI64, pub dev_eui: EUI64,
@ -120,7 +124,8 @@ impl JoinRequestPayload {
} }
} }
#[derive(Serialize, PartialEq, Eq, Debug, Clone)] #[derive(PartialEq, Eq, Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct JoinAcceptPayload { pub struct JoinAcceptPayload {
pub join_nonce: u32, // the actual max value is (2^24 -1) pub join_nonce: u32, // the actual max value is (2^24 -1)
pub home_netid: NetID, pub home_netid: NetID,
@ -191,6 +196,7 @@ pub enum FRMPayload {
MACCommandSet(MACCommandSet), MACCommandSet(MACCommandSet),
} }
#[cfg(feature = "serde")]
impl Serialize for FRMPayload { impl Serialize for FRMPayload {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -212,7 +218,8 @@ impl FRMPayload {
} }
} }
#[derive(Serialize, PartialEq, Eq, Debug, Clone, Default)] #[derive(PartialEq, Eq, Debug, Clone, Default)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct MACPayload { pub struct MACPayload {
pub fhdr: FHDR, pub fhdr: FHDR,
pub f_port: Option<u8>, pub f_port: Option<u8>,
@ -287,7 +294,8 @@ impl MACPayload {
} }
} }
#[derive(Serialize, PartialEq, Eq, Debug, Clone)] #[derive(PartialEq, Eq, Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct RejoinRequestType02Payload { pub struct RejoinRequestType02Payload {
pub rejoin_type: JoinType, pub rejoin_type: JoinType,
pub netid: NetID, pub netid: NetID,
@ -343,7 +351,8 @@ impl RejoinRequestType02Payload {
} }
} }
#[derive(Serialize, PartialEq, Eq, Debug, Clone)] #[derive(PartialEq, Eq, Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct RejoinRequestType1Payload { pub struct RejoinRequestType1Payload {
pub rejoin_type: JoinType, pub rejoin_type: JoinType,
pub join_eui: EUI64, pub join_eui: EUI64,

View File

@ -1,17 +1,27 @@
use aes::cipher::{generic_array::GenericArray, BlockDecrypt, BlockEncrypt}; #[cfg(feature = "crypto")]
use aes::{Aes128, Block}; use aes::{
cipher::{generic_array::GenericArray, BlockDecrypt, BlockEncrypt},
Aes128, Block,
};
use anyhow::Result; use anyhow::Result;
#[cfg(feature = "crypto")]
use cmac::{Cmac, Mac}; use cmac::{Cmac, Mac};
#[cfg(feature = "serde")]
use serde::Serialize; use serde::Serialize;
use super::aes128::AES128Key;
use super::devaddr::DevAddr;
use super::eui64::EUI64;
use super::maccommand::{MACCommand, MACCommandSet}; use super::maccommand::{MACCommand, MACCommandSet};
use super::mhdr::{MType, MHDR}; use super::mhdr::{MType, MHDR};
use super::payload::{FRMPayload, JoinAcceptPayload, JoinType, Payload}; use super::payload::{FRMPayload, Payload};
#[cfg(feature = "crypto")]
use super::{
aes128::AES128Key,
devaddr::DevAddr,
eui64::EUI64,
payload::{JoinAcceptPayload, JoinType},
};
#[derive(PartialEq, Eq, Clone, Copy, Serialize)] #[derive(PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum MACVersion { pub enum MACVersion {
LoRaWAN1_0, LoRaWAN1_0,
LoRaWAN1_1, LoRaWAN1_1,
@ -310,7 +320,8 @@ pub enum MACVersion {
/// let phy_decoded = PhyPayload::from_slice(&bytes).unwrap(); /// let phy_decoded = PhyPayload::from_slice(&bytes).unwrap();
/// assert_eq!(phy, phy_decoded); /// assert_eq!(phy, phy_decoded);
/// ``` /// ```
#[derive(Debug, PartialEq, Eq, Clone, Serialize)] #[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct PhyPayload { pub struct PhyPayload {
pub mhdr: MHDR, pub mhdr: MHDR,
pub payload: Payload, pub payload: Payload,
@ -374,6 +385,7 @@ impl PhyPayload {
/// Calculate and set the MIC field for uplink data frames. /// Calculate and set the MIC field for uplink data frames.
/// The conf_f_cnt, tx_dr, tx_ch and s_nwk_s_int_key are only required for LoRaWAN 1.1 and can /// The conf_f_cnt, tx_dr, tx_ch and s_nwk_s_int_key are only required for LoRaWAN 1.1 and can
/// be left blank for LoRaWAN 1.0. /// be left blank for LoRaWAN 1.0.
#[cfg(feature = "crypto")]
pub fn set_uplink_data_mic( pub fn set_uplink_data_mic(
&mut self, &mut self,
mac_version: MACVersion, mac_version: MACVersion,
@ -399,6 +411,7 @@ impl PhyPayload {
/// frame-counter value, as only the 16 lsb are transmitted over the air. /// frame-counter value, as only the 16 lsb are transmitted over the air.
/// The conf_f_cnt, tx_dr, tx_ch and s_nwk_s_int_key are only required for LoRaWAN 1.1 and can /// The conf_f_cnt, tx_dr, tx_ch and s_nwk_s_int_key are only required for LoRaWAN 1.1 and can
/// be left blank for LoRaWAN 1.0. /// be left blank for LoRaWAN 1.0.
#[cfg(feature = "crypto")]
pub fn validate_uplink_data_mic( pub fn validate_uplink_data_mic(
&self, &self,
mac_version: MACVersion, mac_version: MACVersion,
@ -425,6 +438,7 @@ impl PhyPayload {
/// Set the MIC for downlink data frames. /// Set the MIC for downlink data frames.
/// The conf_f_cnt is only required for LoRaWAN 1.1 and can be left blank for LoRaWAN 1.0. /// The conf_f_cnt is only required for LoRaWAN 1.1 and can be left blank for LoRaWAN 1.0.
#[cfg(feature = "crypto")]
pub fn set_downlink_data_mic( pub fn set_downlink_data_mic(
&mut self, &mut self,
mac_version: MACVersion, mac_version: MACVersion,
@ -436,6 +450,7 @@ impl PhyPayload {
Ok(()) Ok(())
} }
#[cfg(feature = "crypto")]
pub fn validate_downlink_data_mic( pub fn validate_downlink_data_mic(
&mut self, &mut self,
mac_version: MACVersion, mac_version: MACVersion,
@ -453,6 +468,7 @@ impl PhyPayload {
/// Validate the cmacF part of the uplink data MIC (LoRaWAN 1.1 only). /// Validate the cmacF part of the uplink data MIC (LoRaWAN 1.1 only).
/// In order to validate the MIC, the f_cnt value must be first set to the full 32 bit /// In order to validate the MIC, the f_cnt value must be first set to the full 32 bit
/// frame-counter value, as only the 16 lsb are transmitted over the air. /// frame-counter value, as only the 16 lsb are transmitted over the air.
#[cfg(feature = "crypto")]
pub fn validate_uplink_data_micf(&self, f_nwk_s_int_key: &AES128Key) -> Result<bool> { pub fn validate_uplink_data_micf(&self, f_nwk_s_int_key: &AES128Key) -> Result<bool> {
// We are only interested in mic[2:] (cmacF bytes), therefore there is no // We are only interested in mic[2:] (cmacF bytes), therefore there is no
// need to pass the correct confFCnt, txDR, txCh and sNwkSIntKey parameters. // need to pass the correct confFCnt, txDR, txCh and sNwkSIntKey parameters.
@ -473,12 +489,14 @@ impl PhyPayload {
} }
/// Set the join-request MIC. /// Set the join-request MIC.
#[cfg(feature = "crypto")]
pub fn set_join_request_mic(&mut self, key: &AES128Key) -> Result<()> { pub fn set_join_request_mic(&mut self, key: &AES128Key) -> Result<()> {
self.mic = Some(self.calculate_upink_join_mic(key)?); self.mic = Some(self.calculate_upink_join_mic(key)?);
Ok(()) Ok(())
} }
/// Validate the join-request MIC. /// Validate the join-request MIC.
#[cfg(feature = "crypto")]
pub fn validate_join_request_mic(&self, key: &AES128Key) -> Result<bool> { pub fn validate_join_request_mic(&self, key: &AES128Key) -> Result<bool> {
if let Some(v) = self.mic { if let Some(v) = self.mic {
let mic = self.calculate_upink_join_mic(key)?; let mic = self.calculate_upink_join_mic(key)?;
@ -489,6 +507,7 @@ impl PhyPayload {
} }
/// Set the the downlink join-accept MIC. /// Set the the downlink join-accept MIC.
#[cfg(feature = "crypto")]
pub fn set_join_accept_mic( pub fn set_join_accept_mic(
&mut self, &mut self,
join_req_type: JoinType, join_req_type: JoinType,
@ -502,6 +521,7 @@ impl PhyPayload {
} }
/// Validate the downlink join-accept MIC. /// Validate the downlink join-accept MIC.
#[cfg(feature = "crypto")]
pub fn validate_join_accept_mic( pub fn validate_join_accept_mic(
&self, &self,
join_req_type: JoinType, join_req_type: JoinType,
@ -522,6 +542,7 @@ impl PhyPayload {
/// the encrypted payload. /// the encrypted payload.
/// For encrypting a join-request response, use the nwk_key, for rejoin-request 0, 1 and 3 /// For encrypting a join-request response, use the nwk_key, for rejoin-request 0, 1 and 3
/// response, use the js_enc_key. /// response, use the js_enc_key.
#[cfg(feature = "crypto")]
pub fn encrypt_join_accept_payload(&mut self, key: &AES128Key) -> Result<()> { pub fn encrypt_join_accept_payload(&mut self, key: &AES128Key) -> Result<()> {
use aes::cipher::KeyInit; use aes::cipher::KeyInit;
@ -566,6 +587,7 @@ impl PhyPayload {
/// of the encrypted payload. /// of the encrypted payload.
/// For decrypting a join-request response, use the nwk_key, for rejoin-request 0, 1 and 3 /// For decrypting a join-request response, use the nwk_key, for rejoin-request 0, 1 and 3
/// response, use the js_enc_key. /// response, use the js_enc_key.
#[cfg(feature = "crypto")]
pub fn decrypt_join_accept_payload(&mut self, key: &AES128Key) -> Result<()> { pub fn decrypt_join_accept_payload(&mut self, key: &AES128Key) -> Result<()> {
use aes::cipher::KeyInit; use aes::cipher::KeyInit;
@ -608,6 +630,7 @@ impl PhyPayload {
} }
/// Encrypt the f_opts with the given key. /// Encrypt the f_opts with the given key.
#[cfg(feature = "crypto")]
pub fn encrypt_f_opts(&mut self, nwk_s_enc_key: &AES128Key) -> Result<()> { pub fn encrypt_f_opts(&mut self, nwk_s_enc_key: &AES128Key) -> Result<()> {
if let Payload::MACPayload(pl) = &mut self.payload { if let Payload::MACPayload(pl) = &mut self.payload {
let f_opts_bytes = pl.fhdr.f_opts.to_vec()?; let f_opts_bytes = pl.fhdr.f_opts.to_vec()?;
@ -638,6 +661,7 @@ impl PhyPayload {
/// Decrypt the f_opts with the given key. /// Decrypt the f_opts with the given key.
/// This automatically calls decode_f_opts_to_mac_commands. /// This automatically calls decode_f_opts_to_mac_commands.
#[cfg(feature = "crypto")]
pub fn decrypt_f_opts(&mut self, nwk_s_enc_key: &AES128Key) -> Result<()> { pub fn decrypt_f_opts(&mut self, nwk_s_enc_key: &AES128Key) -> Result<()> {
self.encrypt_f_opts(nwk_s_enc_key)?; self.encrypt_f_opts(nwk_s_enc_key)?;
self.decode_f_opts_to_mac_commands()?; self.decode_f_opts_to_mac_commands()?;
@ -674,6 +698,7 @@ impl PhyPayload {
} }
/// Encrypt the frm_payload with the given key. /// Encrypt the frm_payload with the given key.
#[cfg(feature = "crypto")]
pub fn encrypt_frm_payload(&mut self, key: &AES128Key) -> Result<()> { pub fn encrypt_frm_payload(&mut self, key: &AES128Key) -> Result<()> {
if let Payload::MACPayload(pl) = &mut self.payload { if let Payload::MACPayload(pl) = &mut self.payload {
// nothing to do // nothing to do
@ -693,6 +718,7 @@ impl PhyPayload {
} }
/// Decrypt the frm_payload with the given key. /// Decrypt the frm_payload with the given key.
#[cfg(feature = "crypto")]
pub fn decrypt_frm_payload(&mut self, key: &AES128Key) -> Result<()> { pub fn decrypt_frm_payload(&mut self, key: &AES128Key) -> Result<()> {
if let Payload::MACPayload(pl) = &mut self.payload { if let Payload::MACPayload(pl) = &mut self.payload {
// nothing to do // nothing to do
@ -718,6 +744,7 @@ impl PhyPayload {
Err(anyhow!("payload must be of type MACPayload")) Err(anyhow!("payload must be of type MACPayload"))
} }
#[cfg(feature = "crypto")]
fn calculate_uplink_data_mic( fn calculate_uplink_data_mic(
&self, &self,
mac_version: MACVersion, mac_version: MACVersion,
@ -797,6 +824,7 @@ impl PhyPayload {
Err(anyhow!("payload must be of type MACPayload")) Err(anyhow!("payload must be of type MACPayload"))
} }
#[cfg(feature = "crypto")]
fn calculate_downlink_data_mic( fn calculate_downlink_data_mic(
&self, &self,
mac_version: MACVersion, mac_version: MACVersion,
@ -844,6 +872,7 @@ impl PhyPayload {
Err(anyhow!("payload must be of type MACPayload")) Err(anyhow!("payload must be of type MACPayload"))
} }
#[cfg(feature = "crypto")]
fn calculate_upink_join_mic(&self, key: &AES128Key) -> Result<[u8; 4]> { fn calculate_upink_join_mic(&self, key: &AES128Key) -> Result<[u8; 4]> {
// mic bytes // mic bytes
let mut mic_bytes = Vec::new(); let mut mic_bytes = Vec::new();
@ -864,6 +893,7 @@ impl PhyPayload {
Ok(mic) Ok(mic)
} }
#[cfg(feature = "crypto")]
fn calculate_downlink_join_mic( fn calculate_downlink_join_mic(
&self, &self,
join_req_type: JoinType, join_req_type: JoinType,
@ -916,6 +946,7 @@ impl PhyPayload {
/// Set the a_fcnt_down to false and use the n_fcnt_down as f_cnt. /// Set the a_fcnt_down to false and use the n_fcnt_down as f_cnt.
/// For downlink if f_port > 0: /// For downlink if f_port > 0:
/// Set the a_fcnt_down to true and use the a_f_cnt_down as f_cnt. /// Set the a_fcnt_down to true and use the a_f_cnt_down as f_cnt.
#[cfg(feature = "crypto")]
pub fn encrypt_f_opts( pub fn encrypt_f_opts(
nwk_s_enc_key: &AES128Key, nwk_s_enc_key: &AES128Key,
a_fcnt_down: bool, a_fcnt_down: bool,
@ -963,6 +994,7 @@ pub fn encrypt_f_opts(
/// Encrypt (and decrypt) the frm_payload. /// Encrypt (and decrypt) the frm_payload.
/// Note that the same function is used for encryption and decryption. /// Note that the same function is used for encryption and decryption.
#[cfg(feature = "crypto")]
pub fn encrypt_frm_payload( pub fn encrypt_frm_payload(
key: &AES128Key, key: &AES128Key,
uplink: bool, uplink: bool,

View File

@ -4,9 +4,13 @@ use std::str::FromStr;
use std::time::Duration; use std::time::Duration;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use diesel::backend::{self, Backend}; #[cfg(feature = "diesel")]
use diesel::sql_types::Text; use diesel::{
use diesel::{deserialize, serialize}; backend::{self, Backend},
sql_types::Text,
{deserialize, serialize},
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
@ -25,9 +29,11 @@ pub mod kr920;
pub mod ru864; pub mod ru864;
pub mod us915; pub mod us915;
#[derive(Deserialize, Serialize, Copy, Clone, Debug, Eq, PartialEq, AsExpression, FromSqlRow)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[diesel(sql_type = diesel::sql_types::Text)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "diesel", derive(AsExpression, FromSqlRow))]
#[cfg_attr(feature = "diesel", diesel(sql_type = diesel::sql_types::Text))]
pub enum CommonName { pub enum CommonName {
EU868, EU868,
US915, US915,
@ -51,6 +57,7 @@ impl fmt::Display for CommonName {
} }
} }
#[cfg(feature = "diesel")]
impl<DB> deserialize::FromSql<Text, DB> for CommonName impl<DB> deserialize::FromSql<Text, DB> for CommonName
where where
DB: Backend, DB: Backend,
@ -62,6 +69,7 @@ where
} }
} }
#[cfg(feature = "diesel")]
impl serialize::ToSql<Text, diesel::pg::Pg> for CommonName impl serialize::ToSql<Text, diesel::pg::Pg> for CommonName
where where
str: serialize::ToSql<Text, diesel::pg::Pg>, str: serialize::ToSql<Text, diesel::pg::Pg>,
@ -104,8 +112,9 @@ impl FromStr for CommonName {
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, AsExpression, FromSqlRow)] #[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[diesel(sql_type = diesel::sql_types::Text)] #[cfg_attr(feature = "diesel", derive(AsExpression, FromSqlRow))]
#[cfg_attr(feature = "diesel", diesel(sql_type = diesel::sql_types::Text))]
pub enum Revision { pub enum Revision {
Latest, Latest,
A, A,
@ -159,6 +168,7 @@ impl FromStr for Revision {
} }
} }
#[cfg(feature = "diesel")]
impl<DB> deserialize::FromSql<Text, DB> for Revision impl<DB> deserialize::FromSql<Text, DB> for Revision
where where
DB: Backend, DB: Backend,
@ -170,6 +180,7 @@ where
} }
} }
#[cfg(feature = "diesel")]
impl serialize::ToSql<Text, diesel::pg::Pg> for Revision impl serialize::ToSql<Text, diesel::pg::Pg> for Revision
where where
str: serialize::ToSql<Text, diesel::pg::Pg>, str: serialize::ToSql<Text, diesel::pg::Pg>,
@ -186,8 +197,9 @@ where
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, AsExpression, FromSqlRow)] #[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[diesel(sql_type = diesel::sql_types::Text)] #[cfg_attr(feature = "diesel", derive(AsExpression, FromSqlRow))]
#[cfg_attr(feature = "diesel", diesel(sql_type = diesel::sql_types::Text))]
pub enum MacVersion { pub enum MacVersion {
Latest, Latest,
LORAWAN_1_0_0, LORAWAN_1_0_0,
@ -241,6 +253,7 @@ impl FromStr for MacVersion {
} }
} }
#[cfg(feature = "diesel")]
impl<DB> deserialize::FromSql<Text, DB> for MacVersion impl<DB> deserialize::FromSql<Text, DB> for MacVersion
where where
DB: Backend, DB: Backend,
@ -252,6 +265,7 @@ where
} }
} }
#[cfg(feature = "diesel")]
impl serialize::ToSql<Text, diesel::pg::Pg> for MacVersion impl serialize::ToSql<Text, diesel::pg::Pg> for MacVersion
where where
str: serialize::ToSql<Text, diesel::pg::Pg>, str: serialize::ToSql<Text, diesel::pg::Pg>,