1use super::types::SequenceNumber;
17use std::collections::VecDeque;
18use std::time::{Duration, Instant};
19
20pub const DEFAULT_WINDOW_SIZE: u8 = 8;
22
23pub const DEFAULT_RTO: Duration = Duration::from_secs(2);
25
26pub const MAX_RTO: Duration = Duration::from_secs(30);
28
29pub const DEFAULT_MAX_RETRIES: u32 = 5;
31
32#[derive(Debug, Clone)]
34pub struct ArqConfig {
35 pub window_size: u8,
37 pub initial_rto: Duration,
39 pub max_rto: Duration,
41 pub max_retries: u32,
43}
44
45impl Default for ArqConfig {
46 fn default() -> Self {
47 Self {
48 window_size: DEFAULT_WINDOW_SIZE,
49 initial_rto: DEFAULT_RTO,
50 max_rto: MAX_RTO,
51 max_retries: DEFAULT_MAX_RETRIES,
52 }
53 }
54}
55
56impl ArqConfig {
57 pub fn for_ble() -> Self {
59 Self {
60 window_size: 4, initial_rto: Duration::from_millis(1500),
62 max_rto: Duration::from_secs(15),
63 max_retries: 5,
64 }
65 }
66
67 pub fn for_lora() -> Self {
69 Self {
70 window_size: 2, initial_rto: Duration::from_secs(10),
72 max_rto: Duration::from_secs(60),
73 max_retries: 3,
74 }
75 }
76}
77
78#[derive(Debug, Clone)]
80pub struct SendEntry {
81 pub seq: SequenceNumber,
83 pub data: Vec<u8>,
85 #[allow(dead_code)]
87 first_sent: Instant,
88 last_sent: Instant,
90 pub transmissions: u32,
92}
93
94impl SendEntry {
95 pub fn new(seq: SequenceNumber, data: Vec<u8>) -> Self {
97 let now = Instant::now();
98 Self {
99 seq,
100 data,
101 first_sent: now,
102 last_sent: now,
103 transmissions: 1,
104 }
105 }
106
107 pub fn time_since_sent(&self) -> Duration {
109 self.last_sent.elapsed()
110 }
111
112 #[allow(dead_code)]
114 pub fn total_time(&self) -> Duration {
115 self.first_sent.elapsed()
116 }
117
118 pub fn mark_retransmitted(&mut self) {
120 self.last_sent = Instant::now();
121 self.transmissions += 1;
122 }
123}
124
125#[derive(Debug)]
127pub struct SendWindow {
128 config: ArqConfig,
130 next_seq: SequenceNumber,
132 base_seq: SequenceNumber,
134 unacked: VecDeque<SendEntry>,
136 current_rto: Duration,
138 srtt: Option<Duration>,
140}
141
142impl SendWindow {
143 pub fn new(config: ArqConfig) -> Self {
145 Self {
146 current_rto: config.initial_rto,
147 config,
148 next_seq: SequenceNumber::new(0),
149 base_seq: SequenceNumber::new(0),
150 unacked: VecDeque::new(),
151 srtt: None,
152 }
153 }
154
155 pub fn with_defaults() -> Self {
157 Self::new(ArqConfig::default())
158 }
159
160 pub fn next_seq(&self) -> SequenceNumber {
162 self.next_seq
163 }
164
165 pub fn can_send(&self) -> bool {
167 self.unacked.len() < self.config.window_size as usize
168 }
169
170 pub fn is_full(&self) -> bool {
172 !self.can_send()
173 }
174
175 pub fn in_flight(&self) -> usize {
177 self.unacked.len()
178 }
179
180 pub fn len(&self) -> usize {
182 self.in_flight()
183 }
184
185 pub fn is_empty(&self) -> bool {
187 self.unacked.is_empty()
188 }
189
190 pub fn send(&mut self, data: Vec<u8>) -> Option<SequenceNumber> {
194 if !self.can_send() {
195 return None;
196 }
197
198 let seq = self.next_seq;
199 self.next_seq = self.next_seq.next();
200 self.unacked.push_back(SendEntry::new(seq, data));
201
202 Some(seq)
203 }
204
205 pub fn add(
210 &mut self,
211 seq: SequenceNumber,
212 data: Vec<u8>,
213 ) -> Result<(), super::types::ConstrainedError> {
214 if self.is_full() {
215 return Err(super::types::ConstrainedError::SendBufferFull);
216 }
217
218 self.unacked.push_back(SendEntry::new(seq, data));
219 Ok(())
220 }
221
222 pub fn acknowledge(&mut self, ack: SequenceNumber) -> usize {
227 let mut count = 0;
228
229 while let Some(entry) = self.unacked.front() {
231 let dist = self.base_seq.distance_to(entry.seq);
232 let ack_dist = self.base_seq.distance_to(ack);
233
234 if dist <= ack_dist {
235 if let Some(entry) = self.unacked.pop_front() {
237 if entry.transmissions == 1 {
239 self.update_rtt(entry.time_since_sent());
241 }
242 count += 1;
243 }
244 } else {
245 break;
246 }
247 }
248
249 if count > 0 {
251 self.base_seq = ack.next();
252 }
253
254 count
255 }
256
257 fn update_rtt(&mut self, sample: Duration) {
261 const ALPHA: f64 = 0.125; if let Some(srtt) = self.srtt {
264 let srtt_secs = srtt.as_secs_f64();
265 let sample_secs = sample.as_secs_f64();
266
267 let new_srtt = (1.0 - ALPHA) * srtt_secs + ALPHA * sample_secs;
269
270 let new_rto = (2.0 * new_srtt).clamp(
272 self.config.initial_rto.as_secs_f64(),
273 self.config.max_rto.as_secs_f64(),
274 );
275
276 self.srtt = Some(Duration::from_secs_f64(new_srtt));
277 self.current_rto = Duration::from_secs_f64(new_rto);
278 } else {
279 self.srtt = Some(sample);
281 self.current_rto = sample * 2;
282 }
283 }
284
285 pub fn rto(&self) -> Duration {
287 self.current_rto
288 }
289
290 pub fn get_retransmissions(&mut self) -> Option<Vec<(SequenceNumber, Vec<u8>)>> {
295 let rto = self.current_rto;
296 let max_retries = self.config.max_retries;
297 let mut retransmits = Vec::new();
298
299 for entry in &mut self.unacked {
300 if entry.time_since_sent() > rto {
301 if entry.transmissions > max_retries {
302 return None;
304 }
305 retransmits.push((entry.seq, entry.data.clone()));
306 entry.mark_retransmitted();
307 }
308 }
309
310 if !retransmits.is_empty() {
312 self.current_rto = (self.current_rto * 2).min(self.config.max_rto);
313 }
314
315 Some(retransmits)
316 }
317
318 pub fn reset(&mut self) {
320 self.next_seq = SequenceNumber::new(0);
321 self.base_seq = SequenceNumber::new(0);
322 self.unacked.clear();
323 self.current_rto = self.config.initial_rto;
324 self.srtt = None;
325 }
326}
327
328#[derive(Debug)]
330pub struct ReceiveWindow {
331 window_size: u8,
333 next_expected: SequenceNumber,
335 cumulative_ack: SequenceNumber,
337 out_of_order: VecDeque<(SequenceNumber, Vec<u8>)>,
339}
340
341impl ReceiveWindow {
342 pub fn new(window_size: u8) -> Self {
344 Self {
345 window_size,
346 next_expected: SequenceNumber::new(0),
347 cumulative_ack: SequenceNumber::new(0),
348 out_of_order: VecDeque::new(),
349 }
350 }
351
352 pub fn with_defaults() -> Self {
354 Self::new(DEFAULT_WINDOW_SIZE)
355 }
356
357 pub fn cumulative_ack(&self) -> SequenceNumber {
359 self.cumulative_ack
360 }
361
362 pub fn is_in_window(&self, seq: SequenceNumber) -> bool {
364 self.next_expected.is_in_window(seq, self.window_size)
365 }
366
367 pub fn receive(
372 &mut self,
373 seq: SequenceNumber,
374 data: Vec<u8>,
375 ) -> Option<Vec<(SequenceNumber, Vec<u8>)>> {
376 if !self.is_in_window(seq) {
378 return None;
380 }
381
382 if seq == self.next_expected {
383 let mut deliverable = vec![(seq, data)];
385 self.next_expected = self.next_expected.next();
386 self.cumulative_ack = seq;
387
388 while let Some(entry_idx) = self
390 .out_of_order
391 .iter()
392 .position(|(s, _)| *s == self.next_expected)
393 {
394 if let Some((s, d)) = self.out_of_order.remove(entry_idx) {
395 deliverable.push((s, d));
396 self.next_expected = self.next_expected.next();
397 self.cumulative_ack = s;
398 }
399 }
400
401 Some(deliverable)
402 } else {
403 if !self.out_of_order.iter().any(|(s, _)| *s == seq) {
405 let pos = self
407 .out_of_order
408 .iter()
409 .position(|(s, _)| {
410 self.next_expected.distance_to(*s) > self.next_expected.distance_to(seq)
411 })
412 .unwrap_or(self.out_of_order.len());
413 self.out_of_order.insert(pos, (seq, data));
414 }
415 None
416 }
417 }
418
419 pub fn reset(&mut self) {
421 self.next_expected = SequenceNumber::new(0);
422 self.cumulative_ack = SequenceNumber::new(0);
423 self.out_of_order.clear();
424 }
425
426 pub fn reset_with_seq(&mut self, start_seq: SequenceNumber) {
428 self.next_expected = start_seq;
429 self.cumulative_ack = start_seq;
430 self.out_of_order.clear();
431 }
432
433 pub fn buffered_count(&self) -> usize {
435 self.out_of_order.len()
436 }
437}
438
439#[cfg(test)]
440mod tests {
441 use super::*;
442
443 #[test]
444 fn test_arq_config_defaults() {
445 let config = ArqConfig::default();
446 assert_eq!(config.window_size, DEFAULT_WINDOW_SIZE);
447 assert_eq!(config.initial_rto, DEFAULT_RTO);
448 }
449
450 #[test]
451 fn test_arq_config_ble() {
452 let config = ArqConfig::for_ble();
453 assert!(config.window_size < DEFAULT_WINDOW_SIZE);
454 assert!(config.initial_rto < DEFAULT_RTO);
455 }
456
457 #[test]
458 fn test_send_entry() {
459 let entry = SendEntry::new(SequenceNumber::new(5), b"test".to_vec());
460 assert_eq!(entry.seq, SequenceNumber::new(5));
461 assert_eq!(entry.transmissions, 1);
462 assert!(entry.time_since_sent() < Duration::from_secs(1));
463 }
464
465 #[test]
466 fn test_send_window_basic() {
467 let mut window = SendWindow::with_defaults();
468 assert!(window.can_send());
469 assert_eq!(window.in_flight(), 0);
470
471 let seq = window.send(b"hello".to_vec()).unwrap();
473 assert_eq!(seq, SequenceNumber::new(0));
474 assert_eq!(window.in_flight(), 1);
475
476 let acked = window.acknowledge(SequenceNumber::new(0));
478 assert_eq!(acked, 1);
479 assert_eq!(window.in_flight(), 0);
480 }
481
482 #[test]
483 fn test_send_window_full() {
484 let config = ArqConfig {
485 window_size: 2,
486 ..Default::default()
487 };
488 let mut window = SendWindow::new(config);
489
490 assert!(window.send(b"1".to_vec()).is_some());
492 assert!(window.send(b"2".to_vec()).is_some());
493 assert!(!window.can_send());
494 assert!(window.send(b"3".to_vec()).is_none());
495 }
496
497 #[test]
498 fn test_send_window_cumulative_ack() {
499 let mut window = SendWindow::with_defaults();
500
501 window.send(b"1".to_vec());
503 window.send(b"2".to_vec());
504 window.send(b"3".to_vec());
505 assert_eq!(window.in_flight(), 3);
506
507 let acked = window.acknowledge(SequenceNumber::new(1));
509 assert_eq!(acked, 2);
510 assert_eq!(window.in_flight(), 1);
511 }
512
513 #[test]
514 fn test_receive_window_in_order() {
515 let mut window = ReceiveWindow::with_defaults();
516
517 let result = window.receive(SequenceNumber::new(0), b"first".to_vec());
519 assert!(result.is_some());
520 let packets = result.unwrap();
521 assert_eq!(packets.len(), 1);
522 assert_eq!(packets[0].1, b"first");
523
524 assert_eq!(window.cumulative_ack(), SequenceNumber::new(0));
525 }
526
527 #[test]
528 fn test_receive_window_out_of_order() {
529 let mut window = ReceiveWindow::with_defaults();
530
531 let result = window.receive(SequenceNumber::new(1), b"second".to_vec());
533 assert!(result.is_none());
534 assert_eq!(window.buffered_count(), 1);
535
536 let result = window.receive(SequenceNumber::new(0), b"first".to_vec());
538 assert!(result.is_some());
539 let packets = result.unwrap();
540 assert_eq!(packets.len(), 2);
541 assert_eq!(packets[0].1, b"first");
542 assert_eq!(packets[1].1, b"second");
543
544 assert_eq!(window.cumulative_ack(), SequenceNumber::new(1));
545 assert_eq!(window.buffered_count(), 0);
546 }
547
548 #[test]
549 fn test_receive_window_duplicate() {
550 let mut window = ReceiveWindow::with_defaults();
551
552 window.receive(SequenceNumber::new(0), b"first".to_vec());
554
555 let result = window.receive(SequenceNumber::new(0), b"first".to_vec());
557 assert!(result.is_none());
558 }
559
560 #[test]
561 fn test_receive_window_out_of_window() {
562 let config = ArqConfig {
563 window_size: 4,
564 ..Default::default()
565 };
566 let mut window = ReceiveWindow::new(config.window_size);
567
568 let result = window.receive(SequenceNumber::new(10), b"data".to_vec());
570 assert!(result.is_none());
571 assert_eq!(window.buffered_count(), 0);
572 }
573
574 #[test]
575 fn test_send_window_reset() {
576 let mut window = SendWindow::with_defaults();
577 window.send(b"data".to_vec());
578 assert_eq!(window.in_flight(), 1);
579
580 window.reset();
581 assert_eq!(window.in_flight(), 0);
582 assert_eq!(window.next_seq(), SequenceNumber::new(0));
583 }
584
585 #[test]
586 fn test_receive_window_reset() {
587 let mut window = ReceiveWindow::with_defaults();
588 window.receive(SequenceNumber::new(1), b"data".to_vec());
589 assert_eq!(window.buffered_count(), 1);
590
591 window.reset();
592 assert_eq!(window.buffered_count(), 0);
593 }
594}