use deku::prelude::*;
mod addressee;
mod network;
pub use addressee::Addressee;
pub use network::{Control, Frame, HoppingControl};
use crate::types::VarInt;
#[derive(DekuRead, DekuWrite, Default, Debug, Copy, Clone, PartialEq)]
#[cfg_attr(not(feature = "_wizzilab"), deku(bits = 4))]
#[cfg_attr(feature = "_wizzilab", deku(bits = 3))]
#[deku(type = "u8")]
pub enum NlsMethod {
#[default]
#[deku(id = "0x00")]
None,
#[deku(id = "0x01")]
AesCtr,
#[deku(id = "0x02")]
AesCbcMac128,
#[deku(id = "0x03")]
AesCbcMac64,
#[deku(id = "0x04")]
AesCbcMac32,
#[deku(id = "0x05")]
AesCcm128,
#[deku(id = "0x06")]
AesCcm64,
#[deku(id = "0x07")]
AesCcm32,
}
#[derive(DekuRead, DekuWrite, Default, Debug, Clone, PartialEq)]
#[deku(ctx = "nls_method: NlsMethod", id = "nls_method")]
pub enum NlsState {
#[default]
#[deku(id = "NlsMethod::None")]
None,
#[deku(id = "NlsMethod::AesCtr")]
AesCtr([u8; 5]),
#[deku(id = "NlsMethod::AesCbcMac128")]
AesCbcMac128([u8; 5]),
#[deku(id = "NlsMethod::AesCbcMac64")]
AesCbcMac64([u8; 5]),
#[deku(id = "NlsMethod::AesCbcMac32")]
AesCbcMac32([u8; 5]),
#[deku(id = "NlsMethod::AesCcm128")]
AesCcm128([u8; 5]),
#[deku(id = "NlsMethod::AesCcm64")]
AesCcm64([u8; 5]),
#[deku(id = "NlsMethod::AesCcm32")]
AesCcm32([u8; 5]),
}
#[derive(DekuRead, DekuWrite, Default, Debug, Copy, Clone, PartialEq)]
#[deku(bits = 2, type = "u8")]
pub enum AddressType {
#[deku(id = "0x00")]
NbId,
#[default]
#[deku(id = "0x01")]
NoId,
#[deku(id = "0x02")]
Uid,
#[deku(id = "0x03")]
Vid,
}
#[derive(DekuRead, DekuWrite, Debug, Clone, PartialEq)]
#[deku(ctx = "address_type: AddressType", id = "address_type")]
pub enum Address {
#[deku(id = "AddressType::NbId")]
NbId(VarInt),
#[deku(id = "AddressType::NoId")]
NoId,
#[deku(id = "AddressType::Uid")]
Uid(#[deku(endian = "big")] u64),
#[deku(id = "AddressType::Vid")]
Vid(#[deku(endian = "big")] u16),
}
impl Default for Address {
fn default() -> Self {
Self::NoId
}
}
#[cfg(test)]
mod tests {
use super::*;
use hex_literal::hex;
#[cfg(feature = "_wizzilab")]
use crate::transport::GroupCondition;
use crate::{link::AccessClass, test_tools::test_item};
#[test]
fn test_vid_aesccm32() {
test_item(
Addressee::new(
#[cfg(feature = "_wizzilab")]
false,
#[cfg(feature = "_wizzilab")]
GroupCondition::Any,
Address::Vid(0xABCD),
NlsState::AesCcm32(hex!("00 11 22 33 44")),
AccessClass::new(0x0F, 0x0F),
),
&hex!("37 FF ABCD 0011223344"),
)
}
#[test]
fn test_noid_none() {
test_item(
Addressee::new(
#[cfg(feature = "_wizzilab")]
false,
#[cfg(feature = "_wizzilab")]
GroupCondition::Any,
Address::NoId,
NlsState::None,
AccessClass::default(),
),
&[0b0010000, 0],
);
}
#[test]
fn test_nbid_none() {
test_item(
Addressee::new(
#[cfg(feature = "_wizzilab")]
false,
#[cfg(feature = "_wizzilab")]
GroupCondition::Any,
Address::NbId(VarInt::new(0, false).unwrap()),
NlsState::None,
AccessClass::default(),
),
&[0, 0, 0],
);
}
#[test]
fn test_uid_none() {
test_item(
Addressee::new(
#[cfg(feature = "_wizzilab")]
false,
#[cfg(feature = "_wizzilab")]
GroupCondition::Any,
Address::Uid(0),
NlsState::None,
AccessClass::default(),
),
&[0b00100000, 0, 0, 0, 0, 0, 0, 0, 0, 0],
);
}
#[test]
fn test_nbid_aesctr() {
test_item(
Addressee::new(
#[cfg(feature = "_wizzilab")]
false,
#[cfg(feature = "_wizzilab")]
GroupCondition::Any,
Address::NbId(VarInt::new(1, false).unwrap()),
NlsState::AesCtr([0, 1, 2, 3, 4]),
AccessClass::default(),
),
&[0b00000001, 0, 1, 0, 1, 2, 3, 4],
);
}
#[test]
fn test_vid_none() {
test_item(
Addressee::new(
#[cfg(feature = "_wizzilab")]
false,
#[cfg(feature = "_wizzilab")]
GroupCondition::Any,
Address::Vid(0x1234),
NlsState::None,
AccessClass::new(0, 5),
),
&[0b00110000, 5, 0b00010010, 0b00110100],
);
}
#[test]
fn test_uid_none2() {
test_item(
Addressee::new(
#[cfg(feature = "_wizzilab")]
false,
#[cfg(feature = "_wizzilab")]
GroupCondition::Any,
Address::Uid(0x1234567890123456),
NlsState::None,
AccessClass::new(0x06, 0x09),
),
&[
0b00100000, 105, 0b00010010, 0b00110100, 0b01010110, 0b01111000, 0b10010000,
0b00010010, 0b00110100, 0b01010110,
],
);
}
#[test]
fn test_noid_aescbcmac128() {
test_item(
Addressee::new(
#[cfg(feature = "_wizzilab")]
false,
#[cfg(feature = "_wizzilab")]
GroupCondition::Any,
Address::NoId,
NlsState::AesCbcMac128([10, 20, 30, 40, 50]),
AccessClass::new(0x0B, 0x0E),
),
&[0b00010010, 0xBE, 10, 20, 30, 40, 50],
);
}
#[test]
fn test_nbid_none2() {
test_item(
Addressee::new(
#[cfg(feature = "_wizzilab")]
false,
#[cfg(feature = "_wizzilab")]
GroupCondition::Any,
Address::NbId(VarInt::new(100, false).unwrap()),
NlsState::None,
AccessClass::new(0, 0),
),
&[0, 0, 0x39],
);
}
}