1pub mod envelope;
2pub mod types;
3
4use alloc::collections::VecDeque;
5use alloc::vec::Vec;
6
7#[cfg(test)]
8use crate::constants::CHANNEL_SEQ_MAX;
9use crate::constants::{
10 CHANNEL_ENVELOPE_OVERHEAD, CHANNEL_FAST_RATE_THRESHOLD, CHANNEL_MAX_TRIES, CHANNEL_RTT_FAST,
11 CHANNEL_RTT_MEDIUM, CHANNEL_RTT_SLOW, CHANNEL_SEQ_MODULUS, CHANNEL_WINDOW,
12 CHANNEL_WINDOW_FLEXIBILITY, CHANNEL_WINDOW_MAX_FAST, CHANNEL_WINDOW_MAX_MEDIUM,
13 CHANNEL_WINDOW_MAX_SLOW, CHANNEL_WINDOW_MIN, CHANNEL_WINDOW_MIN_LIMIT_FAST,
14 CHANNEL_WINDOW_MIN_LIMIT_MEDIUM,
15};
16
17pub use types::{ChannelAction, ChannelError, MessageType, Sequence};
18
19use envelope::{pack_envelope, unpack_envelope};
20
21struct Envelope {
23 sequence: Sequence,
24 raw: Vec<u8>,
25 tries: u8,
26 sent_at: f64,
27 delivered: bool,
28}
29
30pub struct Channel {
35 tx_ring: VecDeque<Envelope>,
36 rx_ring: VecDeque<Envelope>,
37 next_sequence: u16,
38 next_rx_sequence: u16,
39 window: u16,
40 window_max: u16,
41 window_min: u16,
42 window_flexibility: u16,
43 fast_rate_rounds: u16,
44 medium_rate_rounds: u16,
45 max_tries: u8,
46 rtt: f64,
47}
48
49impl Channel {
50 pub fn new(initial_rtt: f64) -> Self {
52 let (window, window_max, window_min, window_flexibility) = if initial_rtt > CHANNEL_RTT_SLOW
53 {
54 (1, 1, 1, 1)
55 } else {
56 (
57 CHANNEL_WINDOW,
58 CHANNEL_WINDOW_MAX_SLOW,
59 CHANNEL_WINDOW_MIN,
60 CHANNEL_WINDOW_FLEXIBILITY,
61 )
62 };
63
64 Channel {
65 tx_ring: VecDeque::new(),
66 rx_ring: VecDeque::new(),
67 next_sequence: 0,
68 next_rx_sequence: 0,
69 window,
70 window_max,
71 window_min,
72 window_flexibility,
73 fast_rate_rounds: 0,
74 medium_rate_rounds: 0,
75 max_tries: CHANNEL_MAX_TRIES,
76 rtt: initial_rtt,
77 }
78 }
79
80 pub fn set_rtt(&mut self, rtt: f64) {
82 self.rtt = rtt;
83 }
84
85 pub fn mdu(&self, link_mdu: usize) -> usize {
87 let mdu = link_mdu.saturating_sub(CHANNEL_ENVELOPE_OVERHEAD);
88 mdu.min(0xFFFF)
89 }
90
91 pub fn is_ready_to_send(&self) -> bool {
93 let outstanding = self.tx_ring.iter().filter(|e| !e.delivered).count() as u16;
94 outstanding < self.window
95 }
96
97 pub fn send(
99 &mut self,
100 msgtype: u16,
101 payload: &[u8],
102 now: f64,
103 link_mdu: usize,
104 ) -> Result<Vec<ChannelAction>, ChannelError> {
105 if !self.is_ready_to_send() {
106 return Err(ChannelError::NotReady);
107 }
108
109 let sequence = self.next_sequence;
110 let raw = pack_envelope(msgtype, sequence, payload);
111 if raw.len() > link_mdu {
112 return Err(ChannelError::MessageTooBig);
113 }
114
115 self.next_sequence = ((self.next_sequence as u32 + 1) % CHANNEL_SEQ_MODULUS) as u16;
116 self.tx_ring.push_back(Envelope {
117 sequence,
118 raw: raw.clone(),
119 tries: 1,
120 sent_at: now,
121 delivered: false,
122 });
123
124 Ok(alloc::vec![ChannelAction::SendOnLink { raw, sequence }])
125 }
126
127 pub fn receive(&mut self, raw: &[u8], _now: f64) -> Vec<ChannelAction> {
132 let (_msgtype, sequence, _payload) = match unpack_envelope(raw) {
133 Ok(r) => r,
134 Err(_) => return Vec::new(),
135 };
136
137 if self.is_outside_rx_window(sequence) {
141 return Vec::new();
142 }
143
144 if self.rx_ring.iter().any(|e| e.sequence == sequence) {
146 return Vec::new();
147 }
148
149 let envelope = Envelope {
151 sequence,
152 raw: raw.to_vec(),
153 tries: 0,
154 sent_at: 0.0,
155 delivered: false,
156 };
157 self.emplace_rx(envelope);
158
159 self.collect_contiguous()
161 }
162
163 pub fn flush_tx(&mut self) {
166 self.tx_ring.clear();
167 }
168
169 pub fn cancel_send(&mut self, sequence: Sequence) -> bool {
171 let Some(pos) = self.tx_ring.iter().position(|e| e.sequence == sequence) else {
172 return false;
173 };
174 self.tx_ring.remove(pos);
175 let expected_next = ((sequence as u32 + 1) % CHANNEL_SEQ_MODULUS) as u16;
176 if self.next_sequence == expected_next {
177 self.next_sequence = sequence;
178 }
179 true
180 }
181
182 pub fn packet_delivered(&mut self, sequence: Sequence) -> Vec<ChannelAction> {
184 if let Some(pos) = self.tx_ring.iter().position(|e| e.sequence == sequence) {
185 self.tx_ring.remove(pos);
186
187 if self.window < self.window_max {
188 self.window += 1;
189 }
190
191 self.adapt_window_on_delivery();
193 }
194 Vec::new()
195 }
196
197 pub fn packet_timeout(&mut self, sequence: Sequence, now: f64) -> Vec<ChannelAction> {
199 let pos = match self.tx_ring.iter().position(|e| e.sequence == sequence) {
200 Some(p) => p,
201 None => return Vec::new(),
202 };
203
204 let envelope = &self.tx_ring[pos];
205 if envelope.tries >= self.max_tries {
206 self.tx_ring.clear();
207 self.rx_ring.clear();
208 return alloc::vec![ChannelAction::TeardownLink];
209 }
210
211 let envelope = &mut self.tx_ring[pos];
213 envelope.tries += 1;
214 envelope.sent_at = now;
215 let raw = envelope.raw.clone();
216
217 if self.window > self.window_min {
219 self.window -= 1;
220 if self.window_max > self.window_min + self.window_flexibility {
221 self.window_max -= 1;
222 }
223 }
224
225 alloc::vec![ChannelAction::SendOnLink { raw, sequence }]
226 }
227
228 pub fn get_packet_timeout(&self, tries: u8) -> f64 {
232 let base = 1.5_f64.powi((tries as i32) - 1);
233 let rtt_factor = (self.rtt * 2.5).max(0.025);
234 let ring_factor = (self.tx_ring.len() as f64) + 1.5;
235 base * rtt_factor * ring_factor
236 }
237
238 pub fn get_tries(&self, sequence: Sequence) -> Option<u8> {
240 self.tx_ring
241 .iter()
242 .find(|e| e.sequence == sequence)
243 .map(|e| e.tries)
244 }
245
246 pub fn tick(&mut self, now: f64) -> Vec<ChannelAction> {
248 let timed_out: Vec<Sequence> = self
249 .tx_ring
250 .iter()
251 .filter(|e| !e.delivered && now - e.sent_at >= self.get_packet_timeout(e.tries))
252 .map(|e| e.sequence)
253 .collect();
254
255 let mut actions = Vec::new();
256 for sequence in timed_out {
257 actions.extend(self.packet_timeout(sequence, now));
258 }
259 actions
260 }
261
262 pub fn shutdown(&mut self) {
264 self.tx_ring.clear();
265 self.rx_ring.clear();
266 }
267
268 pub fn window(&self) -> u16 {
270 self.window
271 }
272
273 pub fn window_max(&self) -> u16 {
275 self.window_max
276 }
277
278 pub fn outstanding(&self) -> usize {
280 self.tx_ring.iter().filter(|e| !e.delivered).count()
281 }
282
283 fn is_outside_rx_window(&self, sequence: Sequence) -> bool {
286 sequence.wrapping_sub(self.next_rx_sequence) > CHANNEL_WINDOW_MAX_FAST
287 }
288
289 fn emplace_rx(&mut self, envelope: Envelope) {
290 let env_dist = envelope.sequence.wrapping_sub(self.next_rx_sequence);
293 for (i, existing) in self.rx_ring.iter().enumerate() {
294 if envelope.sequence == existing.sequence {
295 return; }
297 let exist_dist = existing.sequence.wrapping_sub(self.next_rx_sequence);
298 if env_dist < exist_dist {
299 self.rx_ring.insert(i, envelope);
300 return;
301 }
302 }
303 self.rx_ring.push_back(envelope);
304 }
305
306 fn collect_contiguous(&mut self) -> Vec<ChannelAction> {
307 let mut actions = Vec::new();
308
309 loop {
310 let front_match = self
311 .rx_ring
312 .front()
313 .map(|e| e.sequence == self.next_rx_sequence)
314 .unwrap_or(false);
315
316 if !front_match {
317 break;
318 }
319
320 let envelope = self.rx_ring.pop_front().unwrap();
321
322 if let Ok((msgtype, _seq, payload)) = unpack_envelope(&envelope.raw) {
324 actions.push(ChannelAction::MessageReceived {
325 msgtype,
326 payload: payload.to_vec(),
327 sequence: envelope.sequence,
328 });
329 }
330
331 self.next_rx_sequence =
332 ((self.next_rx_sequence as u32 + 1) % CHANNEL_SEQ_MODULUS) as u16;
333
334 if self.next_rx_sequence == 0 {
336 }
338 }
339
340 actions
341 }
342
343 fn adapt_window_on_delivery(&mut self) {
344 if self.rtt == 0.0 {
345 return;
346 }
347
348 if self.rtt > CHANNEL_RTT_FAST {
349 self.fast_rate_rounds = 0;
350
351 if self.rtt > CHANNEL_RTT_MEDIUM {
352 self.medium_rate_rounds = 0;
353 } else {
354 self.medium_rate_rounds += 1;
355 if self.window_max < CHANNEL_WINDOW_MAX_MEDIUM
356 && self.medium_rate_rounds == CHANNEL_FAST_RATE_THRESHOLD
357 {
358 self.window_max = CHANNEL_WINDOW_MAX_MEDIUM;
359 self.window_min = CHANNEL_WINDOW_MIN_LIMIT_MEDIUM;
360 }
361 }
362 } else {
363 self.fast_rate_rounds += 1;
364 if self.window_max < CHANNEL_WINDOW_MAX_FAST
365 && self.fast_rate_rounds == CHANNEL_FAST_RATE_THRESHOLD
366 {
367 self.window_max = CHANNEL_WINDOW_MAX_FAST;
368 self.window_min = CHANNEL_WINDOW_MIN_LIMIT_FAST;
369 }
370 }
371 }
372}
373
374#[cfg(test)]
375mod tests {
376 use super::*;
377
378 #[test]
379 fn test_new_default() {
380 let ch = Channel::new(0.5);
381 assert_eq!(ch.window, CHANNEL_WINDOW);
382 assert_eq!(ch.window_max, CHANNEL_WINDOW_MAX_SLOW);
383 assert!(ch.is_ready_to_send());
384 }
385
386 #[test]
387 fn test_new_very_slow() {
388 let ch = Channel::new(2.0);
389 assert_eq!(ch.window, 1);
390 assert_eq!(ch.window_max, 1);
391 }
392
393 #[test]
394 fn test_send_receive() {
395 let mut ch = Channel::new(0.1);
396 let actions = ch.send(0x01, b"hello", 1.0, 500).unwrap();
397 assert_eq!(actions.len(), 1);
398 match &actions[0] {
399 ChannelAction::SendOnLink { raw, sequence } => {
400 assert_eq!(*sequence, 0);
401 let mut ch2 = Channel::new(0.1);
403 let recv_actions = ch2.receive(raw, 1.1);
404 assert_eq!(recv_actions.len(), 1);
405 match &recv_actions[0] {
406 ChannelAction::MessageReceived {
407 msgtype,
408 payload,
409 sequence,
410 } => {
411 assert_eq!(*msgtype, 0x01);
412 assert_eq!(payload, b"hello");
413 assert_eq!(*sequence, 0);
414 }
415 _ => panic!("Expected MessageReceived"),
416 }
417 }
418 _ => panic!("Expected SendOnLink"),
419 }
420 }
421
422 #[test]
423 fn test_send_not_ready() {
424 let mut ch = Channel::new(0.1);
425 ch.send(0x01, b"a", 1.0, 500).unwrap();
427 ch.send(0x01, b"b", 1.0, 500).unwrap();
428 assert!(!ch.is_ready_to_send());
430 assert_eq!(ch.send(0x01, b"c", 1.0, 500), Err(ChannelError::NotReady));
431 }
432
433 #[test]
434 fn test_message_too_big_does_not_consume_sequence() {
435 let mut ch = Channel::new(0.1);
436 assert_eq!(
437 ch.send(0x01, b"hello", 1.0, 2),
438 Err(ChannelError::MessageTooBig)
439 );
440
441 let actions = ch.send(0x01, b"ok", 2.0, 500).unwrap();
442 match &actions[0] {
443 ChannelAction::SendOnLink { sequence, .. } => assert_eq!(*sequence, 0),
444 _ => panic!("Expected SendOnLink"),
445 }
446 }
447
448 #[test]
449 fn test_cancel_send_rewinds_sequence_and_frees_window() {
450 let mut ch = Channel::new(CHANNEL_RTT_SLOW + 1.0);
451 let actions = ch.send(0x01, b"first", 1.0, 500).unwrap();
452 let sequence = match &actions[0] {
453 ChannelAction::SendOnLink { sequence, .. } => *sequence,
454 _ => panic!("Expected SendOnLink"),
455 };
456 assert!(!ch.is_ready_to_send());
457
458 assert!(ch.cancel_send(sequence));
459 assert!(ch.is_ready_to_send());
460 let actions = ch.send(0x01, b"retry", 2.0, 500).unwrap();
461 match &actions[0] {
462 ChannelAction::SendOnLink { sequence, .. } => assert_eq!(*sequence, 0),
463 _ => panic!("Expected SendOnLink"),
464 }
465 }
466
467 #[test]
468 fn test_packet_delivered_grows_window() {
469 let mut ch = Channel::new(0.1);
470 ch.send(0x01, b"a", 1.0, 500).unwrap();
471 ch.send(0x01, b"b", 1.0, 500).unwrap();
472
473 assert_eq!(ch.window, 2);
474 ch.packet_delivered(0);
475 assert_eq!(ch.window, 3);
476 }
477
478 #[test]
479 fn test_packet_timeout_shrinks_window() {
480 let mut ch = Channel::new(0.1);
481 ch.send(0x01, b"a", 1.0, 500).unwrap();
482 ch.send(0x01, b"b", 1.0, 500).unwrap();
483
484 ch.packet_delivered(0);
486 assert_eq!(ch.window, 3);
487
488 let actions = ch.packet_timeout(1, 2.0);
490 assert_eq!(actions.len(), 1); assert_eq!(ch.window, 2);
492 }
493
494 #[test]
495 fn test_tick_retransmits_timed_out_packets() {
496 let mut ch = Channel::new(0.1);
497 ch.send(0x01, b"a", 0.0, 500).unwrap();
498
499 let timeout = ch.get_packet_timeout(1);
500 let actions = ch.tick(timeout + 0.01);
501 assert_eq!(actions.len(), 1);
502 match &actions[0] {
503 ChannelAction::SendOnLink { sequence, .. } => assert_eq!(*sequence, 0),
504 _ => panic!("Expected SendOnLink"),
505 }
506 assert_eq!(ch.get_tries(0), Some(2));
507 }
508
509 #[test]
510 fn test_max_retries_teardown() {
511 let mut ch = Channel::new(0.1);
512 ch.send(0x01, b"a", 1.0, 500).unwrap();
513
514 for i in 0..4 {
516 let actions = ch.packet_timeout(0, 2.0 + i as f64);
517 assert_eq!(actions.len(), 1);
518 match &actions[0] {
519 ChannelAction::SendOnLink { .. } => {}
520 _ => panic!("Expected SendOnLink"),
521 }
522 }
523
524 let actions = ch.packet_timeout(0, 10.0);
526 assert_eq!(actions.len(), 1);
527 match &actions[0] {
528 ChannelAction::TeardownLink => {}
529 _ => panic!("Expected TeardownLink"),
530 }
531 }
532
533 #[test]
534 fn test_sequence_wrapping() {
535 let mut ch = Channel::new(0.1);
536 ch.next_sequence = CHANNEL_SEQ_MAX;
537
538 ch.send(0x01, b"wrap", 1.0, 500).unwrap();
539 assert_eq!(ch.next_sequence, 0);
540
541 ch.send(0x01, b"after", 1.0, 500).unwrap();
542 assert_eq!(ch.next_sequence, 1);
543 }
544
545 #[test]
546 fn test_out_of_order_buffering() {
547 let mut ch = Channel::new(0.1);
548
549 let raw0 = pack_envelope(0x01, 0, b"first");
551 let raw1 = pack_envelope(0x01, 1, b"second");
552
553 let actions = ch.receive(&raw1, 1.0);
555 assert!(actions.is_empty()); let actions = ch.receive(&raw0, 1.1);
559 assert_eq!(actions.len(), 2); match &actions[0] {
561 ChannelAction::MessageReceived { sequence, .. } => assert_eq!(*sequence, 0),
562 _ => panic!("Expected MessageReceived"),
563 }
564 match &actions[1] {
565 ChannelAction::MessageReceived { sequence, .. } => assert_eq!(*sequence, 1),
566 _ => panic!("Expected MessageReceived"),
567 }
568 }
569
570 #[test]
571 fn receive_window_accepts_exact_forward_edge_and_rejects_beyond_it() {
572 let mut ch = Channel::new(0.1);
573 let edge = CHANNEL_WINDOW_MAX_FAST;
574 let beyond = edge + 1;
575
576 assert!(ch
577 .receive(&pack_envelope(0x01, edge, b"edge"), 1.0)
578 .is_empty());
579 assert_eq!(ch.rx_ring.len(), 1);
580 assert!(ch
581 .receive(&pack_envelope(0x01, beyond, b"beyond"), 1.1)
582 .is_empty());
583 assert_eq!(ch.rx_ring.len(), 1);
584 assert!(ch
585 .receive(&pack_envelope(0x01, 40_000, b"far"), 1.2)
586 .is_empty());
587 assert_eq!(ch.rx_ring.len(), 1);
588 }
589
590 #[test]
591 fn receive_window_enforces_modular_edge_across_sequence_wrap() {
592 let mut ch = Channel::new(0.1);
593 ch.next_rx_sequence = 0xFFFE;
594 let edge = ch.next_rx_sequence.wrapping_add(CHANNEL_WINDOW_MAX_FAST);
595 let beyond = edge.wrapping_add(1);
596 let behind = ch.next_rx_sequence.wrapping_sub(1);
597
598 assert!(ch
599 .receive(&pack_envelope(0x01, edge, b"edge"), 1.0)
600 .is_empty());
601 assert_eq!(ch.rx_ring.len(), 1);
602 assert!(ch
603 .receive(&pack_envelope(0x01, beyond, b"beyond"), 1.1)
604 .is_empty());
605 assert!(ch
606 .receive(&pack_envelope(0x01, behind, b"behind"), 1.2)
607 .is_empty());
608 assert_eq!(ch.rx_ring.len(), 1);
609 }
610
611 #[test]
612 fn test_duplicate_rejection() {
613 let mut ch = Channel::new(0.1);
614 let raw = pack_envelope(0x01, 0, b"hello");
615
616 let actions = ch.receive(&raw, 1.0);
617 assert_eq!(actions.len(), 1);
618
619 let actions = ch.receive(&raw, 1.1);
621 assert!(actions.is_empty());
622 }
623
624 #[test]
625 fn test_get_packet_timeout() {
626 let ch = Channel::new(0.1);
627 let t1 = ch.get_packet_timeout(1);
628 let t2 = ch.get_packet_timeout(2);
629 assert!(t2 > t1); }
631
632 #[test]
633 fn test_mdu() {
634 let ch = Channel::new(0.1);
635 assert_eq!(ch.mdu(431), 431 - CHANNEL_ENVELOPE_OVERHEAD);
636 }
637
638 #[test]
639 fn test_window_upgrade_fast() {
640 let mut ch = Channel::new(0.05); ch.window_max = CHANNEL_WINDOW_MAX_SLOW;
642
643 for i in 0..CHANNEL_FAST_RATE_THRESHOLD {
645 ch.send(0x01, b"x", i as f64, 500).unwrap();
646 ch.packet_delivered(i);
647 }
648
649 assert_eq!(ch.window_max, CHANNEL_WINDOW_MAX_FAST);
650 assert_eq!(ch.window_min, CHANNEL_WINDOW_MIN_LIMIT_FAST);
651 }
652
653 #[test]
654 fn test_window_upgrade_medium() {
655 let mut ch = Channel::new(0.5); ch.window_max = CHANNEL_WINDOW_MAX_SLOW;
657
658 for i in 0..CHANNEL_FAST_RATE_THRESHOLD {
659 ch.send(0x01, b"x", i as f64, 500).unwrap();
660 ch.packet_delivered(i);
661 }
662
663 assert_eq!(ch.window_max, CHANNEL_WINDOW_MAX_MEDIUM);
664 assert_eq!(ch.window_min, CHANNEL_WINDOW_MIN_LIMIT_MEDIUM);
665 }
666
667 #[test]
668 fn test_shutdown() {
669 let mut ch = Channel::new(0.1);
670 ch.send(0x01, b"a", 1.0, 500).unwrap();
671 ch.shutdown();
672 assert_eq!(ch.outstanding(), 0);
673 }
674
675 #[test]
676 fn test_message_too_big() {
677 let mut ch = Channel::new(0.1);
678 let big = vec![0u8; 500];
679 assert_eq!(
681 ch.send(0x01, &big, 1.0, 10),
682 Err(ChannelError::MessageTooBig)
683 );
684 }
685
686 #[test]
687 fn test_receive_sequence_wrap_at_boundary() {
688 let mut ch = Channel::new(0.1);
689 ch.next_rx_sequence = CHANNEL_SEQ_MAX;
690
691 let raw_max = pack_envelope(0x01, CHANNEL_SEQ_MAX, b"last");
692 let raw_zero = pack_envelope(0x01, 0, b"first_after_wrap");
693
694 let actions = ch.receive(&raw_max, 1.0);
695 assert_eq!(actions.len(), 1);
696 assert_eq!(ch.next_rx_sequence, 0);
697
698 let actions = ch.receive(&raw_zero, 1.1);
699 assert_eq!(actions.len(), 1);
700 match &actions[0] {
701 ChannelAction::MessageReceived { sequence, .. } => assert_eq!(*sequence, 0),
702 _ => panic!("Expected MessageReceived"),
703 }
704 }
705
706 #[test]
707 fn test_receive_wrap_boundary_out_of_order() {
708 let mut ch = Channel::new(0.1);
710 ch.next_rx_sequence = 0xFFFE;
711
712 let raw_fffe = pack_envelope(0x01, 0xFFFE, b"a");
713 let raw_ffff = pack_envelope(0x01, 0xFFFF, b"b");
714 let raw_0000 = pack_envelope(0x01, 0x0000, b"c");
715
716 let actions = ch.receive(&raw_0000, 1.0);
718 assert!(actions.is_empty()); let actions = ch.receive(&raw_ffff, 1.1);
721 assert!(actions.is_empty()); let actions = ch.receive(&raw_fffe, 1.2);
724 assert_eq!(actions.len(), 3); match &actions[0] {
726 ChannelAction::MessageReceived {
727 sequence, payload, ..
728 } => {
729 assert_eq!(*sequence, 0xFFFE);
730 assert_eq!(payload, b"a");
731 }
732 _ => panic!("Expected MessageReceived"),
733 }
734 match &actions[1] {
735 ChannelAction::MessageReceived {
736 sequence, payload, ..
737 } => {
738 assert_eq!(*sequence, 0xFFFF);
739 assert_eq!(payload, b"b");
740 }
741 _ => panic!("Expected MessageReceived"),
742 }
743 match &actions[2] {
744 ChannelAction::MessageReceived {
745 sequence, payload, ..
746 } => {
747 assert_eq!(*sequence, 0x0000);
748 assert_eq!(payload, b"c");
749 }
750 _ => panic!("Expected MessageReceived"),
751 }
752 }
753
754 #[test]
755 fn test_many_messages_in_order() {
756 let mut sender = Channel::new(0.05);
757 let mut receiver = Channel::new(0.05);
758
759 for i in 0..20u16 {
760 if i >= 2 {
762 sender.packet_delivered(i - 2);
763 }
764
765 let actions = sender.send(0x01, &[i as u8], i as f64, 500).unwrap();
766 let raw = match &actions[0] {
767 ChannelAction::SendOnLink { raw, .. } => raw.clone(),
768 _ => panic!("Expected SendOnLink"),
769 };
770
771 let recv_actions = receiver.receive(&raw, i as f64 + 0.1);
772 assert_eq!(recv_actions.len(), 1);
773 match &recv_actions[0] {
774 ChannelAction::MessageReceived {
775 payload, sequence, ..
776 } => {
777 assert_eq!(*sequence, i);
778 assert_eq!(payload, &[i as u8]);
779 }
780 _ => panic!("Expected MessageReceived"),
781 }
782 }
783 }
784}