1#![deny(unsafe_code)]
6
7mod error;
14mod frame;
15mod handshake;
16mod parser;
17mod resend_sp;
18mod window;
19
20pub use error::{FrameError, HandshakeError, RetransmissionLimitExceeded, UnexpectedSeqError};
21pub use frame::{
22 CONTROL_CHANNEL_ID, Frame, FrameType, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE, ProtocolId,
23 encode_frame,
24};
25pub use handshake::{HandshakeResponse, HandshakeStatus, HostHandshake, TargetHandshake};
26pub use parser::FrameParser;
27pub use resend_sp::{
28 AckOutcome, DEFAULT_MAX_RETRANSMISSION_ATTEMPTS, DEFAULT_RETRANSMISSION_TIMEOUT,
29 DEFAULT_WINDOW_SIZE, FrameStatus, ResendReceiver, ResendSender,
30};
31pub use window::AckTracker;
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36
37 fn assert_frame_eq(
38 frame: &Frame,
39 session_id: u32,
40 channel_id: u16,
41 seq: u8,
42 frame_type: FrameType,
43 payload: &[u8],
44 ) {
45 assert_eq!(frame.session_id, session_id);
46 assert_eq!(frame.channel_id, channel_id);
47 assert_eq!(frame.seq, seq);
48 assert_eq!(frame.frame_type, frame_type);
49 assert_eq!(frame.payload, payload);
50 }
51
52 #[fuchsia::test]
53 fn test_complete_flow_negotiation_and_traffic() {
54 let host = HostHandshake::new(vec![ProtocolId::ResendSP]);
55 let target = TargetHandshake::new(vec![ProtocolId::ResendSP]);
56
57 let (req_type, req_payload) = host.start().unwrap();
58 let req_frame = encode_frame(100, 0, 0, req_type, &req_payload).unwrap();
59
60 let mut target_parser = FrameParser::new();
61 target_parser.feed(&req_frame);
62 let parsed_req = target_parser.next_frame().unwrap();
63 assert_frame_eq(&parsed_req, 100, 0, 0, FrameType::NegotiateReq, &req_payload);
64
65 let (selected, resp_payload) = target.handle_request(&parsed_req.payload).unwrap();
66 assert_eq!(selected, Some(ProtocolId::ResendSP));
67
68 let resp_frame = encode_frame(100, 0, 1, FrameType::NegotiateResp, &resp_payload).unwrap();
69 let mut host_parser = FrameParser::new();
70 host_parser.feed(&resp_frame);
71 let parsed_resp = host_parser.next_frame().unwrap();
72 assert_frame_eq(&parsed_resp, 100, 0, 1, FrameType::NegotiateResp, &resp_payload);
73
74 let negotiated = host.handle_response(&parsed_resp.payload).unwrap();
75 assert_eq!(negotiated, ProtocolId::ResendSP);
76
77 let data_frame = encode_frame(100, 1, 0, FrameType::Data, b"payload_data").unwrap();
79 target_parser.feed(&data_frame);
80 let parsed_data = target_parser.next_frame().unwrap();
81 assert_frame_eq(&parsed_data, 100, 1, 0, FrameType::Data, b"payload_data");
82 }
83
84 #[fuchsia::test]
85 fn test_host_reboot_recovery_flow() {
86 let host = HostHandshake::new(vec![ProtocolId::ResendSP]);
87 let target = TargetHandshake::new(vec![ProtocolId::ResendSP]);
88 let mut target_parser = FrameParser::new();
89 let mut host_parser = FrameParser::new();
90
91 let (req_type, req_payload) = host.start().unwrap();
92 let req_frame = encode_frame(111, 0, 0, req_type, &req_payload).unwrap();
93 target_parser.feed(&req_frame);
94 let parsed_req = target_parser.next_frame().unwrap();
95 let (selected, resp_payload) = target.handle_request(&parsed_req.payload).unwrap();
96 assert_eq!(selected, Some(ProtocolId::ResendSP));
97
98 let resp_frame = encode_frame(111, 0, 1, FrameType::NegotiateResp, &resp_payload).unwrap();
99 host_parser.feed(&resp_frame);
100 let parsed_resp = host_parser.next_frame().unwrap();
101 let negotiated = host.handle_response(&parsed_resp.payload).unwrap();
102 assert_eq!(negotiated, ProtocolId::ResendSP);
103
104 let data_frame = encode_frame(111, 1, 2, FrameType::Data, b"hello").unwrap();
105 target_parser.feed(&data_frame);
106 let parsed_data = target_parser.next_frame().unwrap();
107 assert_eq!(parsed_data.payload, b"hello");
108
109 let host_rebooted = HostHandshake::new(vec![ProtocolId::ResendSP]);
111 let (req_type_2, req_payload_2) = host_rebooted.start().unwrap();
112 let req_frame_2 = encode_frame(222, 0, 0, req_type_2, &req_payload_2).unwrap();
113
114 target_parser.feed(&req_frame_2);
115 let parsed_req_2 = target_parser.next_frame().expect("Target parses reboot handshake");
116 assert_eq!(parsed_req_2.session_id, 222);
117 assert_eq!(parsed_req_2.channel_id, 0);
118 assert_eq!(parsed_req_2.frame_type, FrameType::NegotiateReq);
119 let (selected_2, _) = target.handle_request(&parsed_req_2.payload).unwrap();
120 assert_eq!(selected_2, Some(ProtocolId::ResendSP));
121 }
122
123 #[test]
124 fn test_constants() {
125 assert_eq!(MAX_FRAME_SIZE, 13 + 1024 + 4);
126 assert_eq!(DEFAULT_WINDOW_SIZE, 64);
127 assert_eq!(DEFAULT_MAX_RETRANSMISSION_ATTEMPTS, 60);
128 }
129}