use std::time::Duration;
#[derive(Debug, Copy, Clone, Default)]
pub struct PacketSequenceNumber(u32);
impl PacketSequenceNumber {
pub const fn new(psn: u32) -> Option<Self> {
if psn < (1 << 24) {
Some(Self(psn))
} else {
None
}
}
pub const fn code(&self) -> u32 {
self.0
}
}
#[derive(Debug, Copy, Clone, Default)]
pub enum MaximumTransferUnit {
MTU256 = 1,
MTU512 = 2,
MTU1024 = 3,
MTU2048 = 4,
#[default]
MTU4096 = 5,
}
impl MaximumTransferUnit {
pub const fn code(&self) -> u8 {
*self as u8
}
}
#[derive(Debug, Copy, Clone)]
pub struct MinRnrTimer(u8);
impl MinRnrTimer {
const DURATION_ZERO: Duration = Duration::from_micros(655360);
const DURATION_TABLE: [Duration; 31] = [
Duration::from_micros(10), Duration::from_micros(20), Duration::from_micros(30), Duration::from_micros(40), Duration::from_micros(60), Duration::from_micros(80), Duration::from_micros(120), Duration::from_micros(160), Duration::from_micros(240), Duration::from_micros(320), Duration::from_micros(480), Duration::from_micros(640), Duration::from_micros(960), Duration::from_micros(1280), Duration::from_micros(1920), Duration::from_micros(2560), Duration::from_micros(3840), Duration::from_micros(5120), Duration::from_micros(7680), Duration::from_micros(10240), Duration::from_micros(15360), Duration::from_micros(20480), Duration::from_micros(30720), Duration::from_micros(40960), Duration::from_micros(61440), Duration::from_micros(81920), Duration::from_micros(122880), Duration::from_micros(163840), Duration::from_micros(245760), Duration::from_micros(327680), Duration::from_micros(491520), ];
pub const fn limited(code: u8) -> Option<Self> {
if code > 0 && code < 32 {
Some(MinRnrTimer(code))
} else {
None
}
}
#[allow(clippy::cast_possible_truncation)]
pub fn min_duration_greater_than(timeout: Duration) -> Self {
MinRnrTimer(match Self::DURATION_TABLE.binary_search(&timeout) {
Ok(idx) => (idx + 1) as u8, Err(idx) if idx < Self::DURATION_TABLE.len() => (idx + 1) as u8, _ => 0, })
}
pub fn duration(&self) -> Duration {
if self.0 > 0 {
*Self::DURATION_TABLE
.get(self.0 as usize - 1)
.expect("rnr_timeout cannot be greater than 31")
} else {
Self::DURATION_ZERO
}
}
pub const fn code(&self) -> u8 {
self.0
}
}
impl Default for MinRnrTimer {
fn default() -> MinRnrTimer {
MinRnrTimer(16)
}
}
#[derive(Debug, Copy, Clone)]
pub enum MaxRnrRetries {
Limited(u8),
Unlimited,
}
impl MaxRnrRetries {
pub const fn limited(retries: u8) -> Option<Self> {
if retries < 7 {
Some(MaxRnrRetries::Limited(retries))
} else {
None
}
}
pub const fn unlimited() -> Self {
MaxRnrRetries::Unlimited
}
pub const fn retries(&self) -> Option<u8> {
match self {
MaxRnrRetries::Limited(retries) => Some(*retries),
MaxRnrRetries::Unlimited => None,
}
}
pub const fn code(&self) -> u8 {
match self {
MaxRnrRetries::Limited(retries) => *retries,
MaxRnrRetries::Unlimited => 7,
}
}
}
impl Default for MaxRnrRetries {
fn default() -> MaxRnrRetries {
MaxRnrRetries::Limited(6)
}
}
#[derive(Debug, Copy, Clone)]
pub enum AckTimeout {
Limited(u8),
Unlimited,
}
impl AckTimeout {
pub const fn limited(code: u8) -> Option<Self> {
if code > 0 && code < 32 {
Some(AckTimeout::Limited(code))
} else {
None
}
}
pub const fn unlimited() -> Self {
AckTimeout::Unlimited
}
#[allow(clippy::cast_possible_truncation)]
pub const fn min_duration_greater_than(timeout: Duration) -> Option<Self> {
let code = (timeout.as_nanos() / 4096).next_power_of_two().ilog2();
if code > 0 && code < 32 {
Some(AckTimeout::Limited(code as u8))
} else {
None
}
}
pub fn duration(&self) -> Option<Duration> {
match self {
AckTimeout::Limited(code) => Some(Duration::from_nanos(4096u64 << code)),
AckTimeout::Unlimited => None,
}
}
pub const fn code(&self) -> u8 {
match self {
AckTimeout::Limited(code) => *code,
AckTimeout::Unlimited => 0,
}
}
}
impl Default for AckTimeout {
fn default() -> AckTimeout {
AckTimeout::Limited(4)
}
}
#[derive(Debug, Copy, Clone)]
pub struct MaxAckRetries(u8);
impl MaxAckRetries {
pub const fn limited(retries: u8) -> Option<Self> {
if retries <= 7 {
Some(MaxAckRetries(retries))
} else {
None
}
}
pub const fn retries(&self) -> u8 {
self.0
}
pub const fn code(&self) -> u8 {
self.retries()
}
}
impl Default for MaxAckRetries {
fn default() -> MaxAckRetries {
MaxAckRetries(6)
}
}