bitflags::bitflags! {
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct RadioCapabilities: u8 {
const NONE = 0b0000_0000;
const ACK_TIMEOUT = 0b0000_0001;
const ENERGY_SCAN = 0b0000_0010;
const TRANSMIT_RETRIES = 0b0000_0100;
const CSMA_BACKOFF = 0b0000_1000;
const SLEEP_TO_TX = 0b0001_0000;
const TRANSMIT_SEC = 0b0010_0000;
const TRANSMIT_TIMING = 0b0100_0000;
const RECEIVE_TIMING = 0b1000_0000;
}
}
impl RadioCapabilities {
pub fn none(&self) -> bool {
self.is_empty()
}
pub fn ack_timeout(&self) -> bool {
self.contains(Self::ACK_TIMEOUT)
}
pub fn energy_scan(&self) -> bool {
self.contains(Self::ENERGY_SCAN)
}
pub fn transmit_retries(&self) -> bool {
self.contains(Self::TRANSMIT_RETRIES)
}
pub fn csma_backoff(&self) -> bool {
self.contains(Self::CSMA_BACKOFF)
}
pub fn sleep_to_tx(&self) -> bool {
self.contains(Self::SLEEP_TO_TX)
}
pub fn transmit_security(&self) -> bool {
self.contains(Self::TRANSMIT_SEC)
}
pub fn transmit_timing(&self) -> bool {
self.contains(Self::TRANSMIT_TIMING)
}
pub fn receive_timing(&self) -> bool {
self.contains(Self::RECEIVE_TIMING)
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::LazyLock;
static ALL_CAPS: LazyLock<RadioCapabilities> = LazyLock::new(|| {
RadioCapabilities::ACK_TIMEOUT
| RadioCapabilities::ENERGY_SCAN
| RadioCapabilities::TRANSMIT_RETRIES
| RadioCapabilities::CSMA_BACKOFF
| RadioCapabilities::SLEEP_TO_TX
| RadioCapabilities::TRANSMIT_SEC
| RadioCapabilities::TRANSMIT_TIMING
| RadioCapabilities::RECEIVE_TIMING
});
#[test]
fn contains_none() {
let caps = RadioCapabilities::NONE;
assert!(caps.none());
assert!(!ALL_CAPS.none());
}
#[test]
fn contains_ack_timeout() {
let caps = RadioCapabilities::ACK_TIMEOUT;
assert!(!caps.none());
assert!(caps.ack_timeout());
assert!(!caps.energy_scan());
assert!(!caps.transmit_retries());
assert!(!caps.csma_backoff());
assert!(!caps.sleep_to_tx());
assert!(!caps.transmit_security());
assert!(!caps.transmit_timing());
assert!(!caps.receive_timing());
assert!(ALL_CAPS.ack_timeout());
}
#[test]
fn contains_energy_scan() {
let caps = RadioCapabilities::ENERGY_SCAN;
assert!(!caps.none());
assert!(!caps.ack_timeout());
assert!(caps.energy_scan());
assert!(!caps.transmit_retries());
assert!(!caps.csma_backoff());
assert!(!caps.sleep_to_tx());
assert!(!caps.transmit_security());
assert!(!caps.transmit_timing());
assert!(!caps.receive_timing());
assert!(ALL_CAPS.energy_scan());
}
#[test]
fn contains_transmit_retries() {
let caps = RadioCapabilities::TRANSMIT_RETRIES;
assert!(!caps.none());
assert!(!caps.ack_timeout());
assert!(!caps.energy_scan());
assert!(caps.transmit_retries());
assert!(!caps.csma_backoff());
assert!(!caps.sleep_to_tx());
assert!(!caps.transmit_security());
assert!(!caps.transmit_timing());
assert!(!caps.receive_timing());
assert!(ALL_CAPS.transmit_retries());
}
#[test]
fn contains_csma_backoff() {
let caps = RadioCapabilities::CSMA_BACKOFF;
assert!(!caps.none());
assert!(!caps.ack_timeout());
assert!(!caps.energy_scan());
assert!(!caps.transmit_retries());
assert!(caps.csma_backoff());
assert!(!caps.sleep_to_tx());
assert!(!caps.transmit_security());
assert!(!caps.transmit_timing());
assert!(!caps.receive_timing());
assert!(ALL_CAPS.csma_backoff());
}
#[test]
fn contains_sleep_to_tx() {
let caps = RadioCapabilities::SLEEP_TO_TX;
assert!(!caps.none());
assert!(!caps.ack_timeout());
assert!(!caps.energy_scan());
assert!(!caps.transmit_retries());
assert!(!caps.csma_backoff());
assert!(caps.sleep_to_tx());
assert!(!caps.transmit_security());
assert!(!caps.transmit_timing());
assert!(!caps.receive_timing());
assert!(ALL_CAPS.sleep_to_tx());
}
#[test]
fn contains_transmit_security() {
let caps = RadioCapabilities::TRANSMIT_SEC;
assert!(!caps.none());
assert!(!caps.ack_timeout());
assert!(!caps.energy_scan());
assert!(!caps.transmit_retries());
assert!(!caps.csma_backoff());
assert!(!caps.sleep_to_tx());
assert!(caps.transmit_security());
assert!(!caps.transmit_timing());
assert!(!caps.receive_timing());
assert!(ALL_CAPS.transmit_security());
}
#[test]
fn contains_transmit_timing() {
let caps = RadioCapabilities::TRANSMIT_TIMING;
assert!(!caps.none());
assert!(!caps.ack_timeout());
assert!(!caps.energy_scan());
assert!(!caps.transmit_retries());
assert!(!caps.csma_backoff());
assert!(!caps.sleep_to_tx());
assert!(!caps.transmit_security());
assert!(caps.transmit_timing());
assert!(!caps.receive_timing());
assert!(ALL_CAPS.transmit_timing());
}
#[test]
fn contains_receive_timing() {
let caps = RadioCapabilities::RECEIVE_TIMING;
assert!(!caps.none());
assert!(!caps.ack_timeout());
assert!(!caps.energy_scan());
assert!(!caps.transmit_retries());
assert!(!caps.csma_backoff());
assert!(!caps.sleep_to_tx());
assert!(!caps.transmit_security());
assert!(!caps.transmit_timing());
assert!(caps.receive_timing());
assert!(ALL_CAPS.receive_timing());
}
}