Skip to main content

simple_someip/e2e/
state.rs

1//! State tracking structures for E2E profiles.
2
3/// State for E2E Profile 4 protection/checking.
4#[derive(Debug, Clone)]
5pub struct Profile4State {
6    /// Counter for protection (incremented on each protect call).
7    pub(crate) protect_counter: u16,
8    /// Last received counter for checking.
9    pub(crate) last_counter: Option<u16>,
10}
11
12impl Profile4State {
13    /// Create a new Profile 4 state with initial counter value of 0.
14    #[must_use]
15    pub fn new() -> Self {
16        Self {
17            protect_counter: 0,
18            last_counter: None,
19        }
20    }
21
22    /// Create a new Profile 4 state with a specific initial counter.
23    #[must_use]
24    pub fn with_initial_counter(counter: u16) -> Self {
25        Self {
26            protect_counter: counter,
27            last_counter: None,
28        }
29    }
30
31    /// Returns the current protection counter value.
32    #[must_use]
33    pub const fn protect_counter(&self) -> u16 {
34        self.protect_counter
35    }
36
37    /// Returns the last received counter value, or `None` if no message
38    /// has been checked yet.
39    #[must_use]
40    pub const fn last_counter(&self) -> Option<u16> {
41        self.last_counter
42    }
43
44    /// Reset the state to initial values.
45    pub fn reset(&mut self) {
46        self.protect_counter = 0;
47        self.last_counter = None;
48    }
49}
50
51impl Default for Profile4State {
52    fn default() -> Self {
53        Self::new()
54    }
55}
56
57/// State for E2E Profile 5 protection/checking.
58#[derive(Debug, Clone)]
59pub struct Profile5State {
60    /// Counter for protection (incremented on each protect call).
61    pub(crate) protect_counter: u8,
62    /// Last received counter for checking.
63    pub(crate) last_counter: Option<u8>,
64}
65
66impl Profile5State {
67    /// Create a new Profile 5 state with initial counter value of 0.
68    #[must_use]
69    pub fn new() -> Self {
70        Self {
71            protect_counter: 0,
72            last_counter: None,
73        }
74    }
75
76    /// Create a new Profile 5 state with a specific initial counter.
77    #[must_use]
78    pub fn with_initial_counter(counter: u8) -> Self {
79        Self {
80            protect_counter: counter,
81            last_counter: None,
82        }
83    }
84
85    /// Returns the current protection counter value.
86    #[must_use]
87    pub const fn protect_counter(&self) -> u8 {
88        self.protect_counter
89    }
90
91    /// Returns the last received counter value, or `None` if no message
92    /// has been checked yet.
93    #[must_use]
94    pub const fn last_counter(&self) -> Option<u8> {
95        self.last_counter
96    }
97
98    /// Reset the state to initial values.
99    pub fn reset(&mut self) {
100        self.protect_counter = 0;
101        self.last_counter = None;
102    }
103}
104
105impl Default for Profile5State {
106    fn default() -> Self {
107        Self::new()
108    }
109}
110
111#[cfg(test)]
112mod tests {
113    use super::*;
114
115    #[test]
116    fn profile4_reset_clears_state() {
117        let mut state = Profile4State::with_initial_counter(42);
118        state.last_counter = Some(10);
119        state.reset();
120        assert_eq!(state.protect_counter, 0);
121        assert!(state.last_counter.is_none());
122    }
123
124    #[test]
125    fn profile4_default_matches_new() {
126        let from_new = Profile4State::new();
127        let from_default = Profile4State::default();
128        assert_eq!(from_new.protect_counter, from_default.protect_counter);
129        assert_eq!(from_new.last_counter, from_default.last_counter);
130    }
131
132    #[test]
133    fn profile5_reset_clears_state() {
134        let mut state = Profile5State::with_initial_counter(42);
135        state.last_counter = Some(10);
136        state.reset();
137        assert_eq!(state.protect_counter, 0);
138        assert!(state.last_counter.is_none());
139    }
140
141    #[test]
142    fn profile5_default_matches_new() {
143        let from_new = Profile5State::new();
144        let from_default = Profile5State::default();
145        assert_eq!(from_new.protect_counter, from_default.protect_counter);
146        assert_eq!(from_new.last_counter, from_default.last_counter);
147    }
148
149    #[test]
150    fn profile4_with_initial_counter_sets_counter() {
151        let state = Profile4State::with_initial_counter(42);
152        assert_eq!(state.protect_counter(), 42);
153        assert_eq!(state.last_counter(), None);
154    }
155
156    #[test]
157    fn profile4_accessors() {
158        let mut state = Profile4State::new();
159        assert_eq!(state.protect_counter(), 0);
160        assert_eq!(state.last_counter(), None);
161        state.protect_counter = 5;
162        state.last_counter = Some(3);
163        assert_eq!(state.protect_counter(), 5);
164        assert_eq!(state.last_counter(), Some(3));
165    }
166
167    #[test]
168    fn profile5_with_initial_counter_sets_counter() {
169        let state = Profile5State::with_initial_counter(42);
170        assert_eq!(state.protect_counter(), 42);
171        assert_eq!(state.last_counter(), None);
172    }
173
174    #[test]
175    fn profile5_accessors() {
176        let mut state = Profile5State::new();
177        assert_eq!(state.protect_counter(), 0);
178        assert_eq!(state.last_counter(), None);
179        state.protect_counter = 5;
180        state.last_counter = Some(3);
181        assert_eq!(state.protect_counter(), 5);
182        assert_eq!(state.last_counter(), Some(3));
183    }
184}