use core::time::Duration;
use log::trace;
use crate::status::Status;
use crate::transceiver::constants::{T_RX_ACK_INIT, T_RX_ACK_MAX, T_RX_ACK_MIN};
use crate::utils::WrappingU3;
#[derive(Debug)]
pub struct State {
status: Status,
frame_number: WrappingU3,
last_received_frame_num: Option<WrappingU3>,
reject: bool,
t_rx_ack: Duration,
}
impl State {
pub const fn new() -> Self {
Self {
status: Status::Disconnected,
frame_number: WrappingU3::ZERO,
last_received_frame_num: None,
reject: false,
t_rx_ack: T_RX_ACK_INIT,
}
}
pub const fn status(&self) -> Status {
self.status
}
pub const fn set_status(&mut self, status: Status) {
self.status = status;
}
pub const fn set_last_received_frame_num(&mut self, frame_num: WrappingU3) {
self.last_received_frame_num.replace(frame_num);
}
pub const fn reject(&self) -> bool {
self.reject
}
pub const fn set_reject(&mut self, reject: bool) {
self.reject = reject;
}
pub const fn t_rx_ack(&self) -> Duration {
self.t_rx_ack
}
pub fn update_t_rx_ack(&mut self, last_ack_duration: Option<Duration>) {
self.t_rx_ack = last_ack_duration
.map_or_else(
|| self.t_rx_ack * 2,
|duration| self.t_rx_ack * 7 / 8 + duration / 2,
)
.clamp(T_RX_ACK_MIN, T_RX_ACK_MAX);
trace!("Updated T_RX_ACK to {:?}", self.t_rx_ack);
}
pub fn next_frame_number(&mut self) -> WrappingU3 {
let frame_number = self.frame_number;
self.frame_number += 1;
frame_number
}
pub fn ack_number(&self) -> WrappingU3 {
self.last_received_frame_num
.map_or_else(WrappingU3::default, |ack_number| ack_number + 1)
}
pub const fn reset(&mut self, status: Status) {
self.status = status;
self.frame_number = WrappingU3::ZERO;
self.last_received_frame_num = None;
self.reject = false;
self.t_rx_ack = T_RX_ACK_INIT;
}
}