#![allow(dead_code)]
use core::mem;
use heapless::FnvIndexMap;
use heapless::Vec;
use crate::internal::types::IeeeAddress;
use crate::internal::types::ShortAddress;
use crate::security::frame::SecurityLevel;
#[derive(Debug)]
#[repr(u8)]
pub enum DeviceType {
Coordinator = 0x00,
Router = 0x01,
EndDevice = 0x02,
}
const NWKC_COORDINATOR_CAPABLE: bool = true;
const NWKC_DEFAULT_SECURITY_LEVEL: u8 = 0x00; const NWKC_MIN_HEADER_OVERHEAD: u8 = 0x08;
const NWKC_PROTOCOL_VERSION: u8 = 0x02;
const NWKC_WAIT_BEFORE_VALIDATION: u32 = 0x9c40;
const NWKC_ROUTE_DISCOVERY_TIME: u32 = 0x4c4b4;
const NWKC_MAX_BROADCAST_JITTER: u32 = 0x7d0;
const NWKC_INITIAL_RREQ_RETRIES: u8 = 0x03;
const NWKC_RREQ_RETRIES: u8 = 0x02;
const NWKC_RREQ_RETRY_INTERVAL: u32 = 0x1f02;
const NWKC_MIN_RREQ_JITTER: u32 = 0x3f;
const NWKC_MAX_RREQ_JITTER: u32 = 0xfa0;
const NWKC_MAC_FRAME_OVERHEAD: u8 = 0x0b;
const MAX_NEIGBOUR_TABLE: usize = 16;
const MAX_ROUTE_TABLE: usize = 8;
const MAX_BROADCAST_TRANSACTION_TABLE: usize = 4;
const MAX_GROUP_ID_TABLE: usize = 4;
const MAX_ROUTE_RECORD_TABLE: usize = 8;
const MAX_NWK_ADDRESS_MAP: usize = 16;
const MAX_MAC_INTERFACE_TABLE: usize = 1;
#[derive(Debug, Default)]
pub(crate) struct Nib {
sequence_number: u8,
passive_ack_timeout: u32,
max_broadcast_retries: u8,
max_children: u8,
max_depth: u8,
max_routers: u8,
neighbor_table: Vec<NwkNeighbor, MAX_NEIGBOUR_TABLE>,
network_broadcast_delivery_time: u32,
report_constant_cost: u8,
route_table: Vec<NwkRoute, MAX_ROUTE_TABLE>,
sym_link: bool,
capability_information: CapabilityInformation,
addr_alloc: u8,
use_tree_routing: bool,
manager_addr: u16,
max_source_route: u8,
update_id: u8,
transaction_persistence_time: u16,
network_address: ShortAddress,
stack_profile: u8,
broadcast_transaction_table: Vec<TransactionRecord, MAX_BROADCAST_TRANSACTION_TABLE>,
group_idtable: Vec<u16, MAX_GROUP_ID_TABLE>,
extended_panid: IeeeAddress,
use_multicast: bool,
route_record_table: Vec<RouteRecord, MAX_ROUTE_RECORD_TABLE>,
is_concentrator: bool,
concentrator_radius: u8,
concentrator_discovery_time: u8,
security_level: SecurityLevel,
security_material_set: u8,
active_key_seq_number: u8,
all_fresh: u8,
link_status_period: u8,
router_age_limit: u8,
unique_addr: bool,
address_map: FnvIndexMap<IeeeAddress, ShortAddress, MAX_NWK_ADDRESS_MAP>,
time_stamp: bool,
panid: ShortAddress,
tx_total: u16,
leave_request_allowed: bool,
parent_information: u8,
end_device_timeout_default: u8,
leave_request_without_rejoin_allowed: bool,
ieee_address: IeeeAddress,
mac_interface_table: Vec<MacInterface, MAX_MAC_INTERFACE_TABLE>,
}
impl Nib {
pub(crate) fn init() -> Self {
Self {
max_broadcast_retries: 0x03,
use_tree_routing: true,
max_source_route: 0x0c,
transaction_persistence_time: 0x01f4,
network_address: ShortAddress(0xffff),
use_multicast: true,
link_status_period: 0x0f,
router_age_limit: 0x03,
unique_addr: true,
end_device_timeout_default: 0x08,
leave_request_without_rejoin_allowed: true,
..Default::default()
}
}
}
#[derive(Debug, Default)]
pub(crate) struct CapabilityInformation(u8);
#[derive(Debug)]
pub(crate) struct NwkNeighbor {
extended_address: IeeeAddress,
network_address: ShortAddress,
device_type: DeviceType,
rx_on_when_idle: bool,
end_device_configuration: u16,
timeout_counter: u32,
device_timeout: u32,
relationship: u8,
transmit_failure: u8,
lqi: u8,
outgoing_cost: Option<u8>,
age: Option<u8>,
incoming_beacon_timestamp: Option<u8>,
beacon_transmission_time: Option<u8>,
keepalive_received: bool,
mac_interface_index: u8,
mac_unicast_bytes_transmitted: Option<u32>,
mac_unicast_bytes_received: Option<u32>,
}
#[derive(Debug)]
#[repr(u8)]
pub(crate) enum RouteStatus {
Active,
DiscoveryUnderway,
DiscoveryFailed,
Inavtive,
ValidationUnderway,
Reserved,
}
#[derive(Debug)]
pub(crate) struct NwkRoute {
pub destination_address: ShortAddress,
pub next_hop_address: ShortAddress,
status: u8,
}
impl NwkRoute {
pub(crate) fn status(&self) -> RouteStatus {
let status = self.status & 0b111;
if status > 0x4 {
RouteStatus::Reserved
} else {
unsafe { mem::transmute::<u8, RouteStatus>(status) }
}
}
pub(crate) fn no_route_cache(&self) -> bool {
(self.status >> 3) & 0b1 != 0
}
pub(crate) fn many_to_one(&self) -> bool {
(self.status >> 4) & 0b1 != 0
}
pub(crate) fn route_record_required(&self) -> bool {
(self.status >> 5) & 0b1 != 0
}
pub(crate) fn group_id(&self) -> bool {
(self.status >> 6) & 0b1 != 0
}
}
#[derive(Debug)]
pub(crate) struct TransactionRecord {
pub source_address: ShortAddress,
pub sequence_number: u8,
pub expiration_time: u8,
}
#[derive(Debug)]
pub(crate) struct RouteRecord {
pub network_address: ShortAddress,
pub relay_count: u16,
pub path: Vec<ShortAddress, 16>,
}
#[derive(Debug)]
pub(crate) struct MacInterface {}