1use doip_definitions::message::DoipMessage;
2use tokio_util::bytes::{Buf, BytesMut};
3
4use crate::{error::DecodeError, DoipCodec};
5
6pub const MAX: usize = 8 * 1024 * 1024;
7
8impl tokio_util::codec::Decoder for DoipCodec {
9 type Item = DoipMessage;
10 type Error = DecodeError;
11
12 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
13 if src.is_empty() {
14 return Ok(None);
15 };
16 if src.len() > MAX {
17 return Err(DecodeError::IoError(std::io::Error::new(
18 std::io::ErrorKind::InvalidData,
19 format!("Frame of length {} is too large.", src.len()),
20 )));
21 }
22
23 let data = src[..src.len()].to_vec();
24
25 match DoipMessage::parse_from_bytes(data) {
26 Ok(msg) => {
27 src.advance(msg.header.payload_length as usize + 8);
28 Ok(Some(msg))
29 }
30 Err(err) => Err(DecodeError::ParseError(err)),
31 }
32 }
33}
34
35#[cfg(test)]
36mod tests {
37 use crate::DoipCodec;
38 use doip_definitions::{
39 header::{DoipHeader, DoipVersion, PayloadType},
40 message::DoipMessage,
41 };
42 use tokio_util::{bytes::BytesMut, codec::Decoder};
43
44 #[test]
45 fn test_decode_single_message() {
46 let mut decoder = DoipCodec {};
47 let mut bytes = BytesMut::new();
48
49 let src = [0x02, 0xfd, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00];
50 bytes.extend_from_slice(&src);
51
52 let msg = decoder.decode(&mut bytes);
53 assert!(msg.is_ok(), "Expected to receive a result.");
54
55 assert!(
56 msg.as_ref().unwrap().is_some(),
57 "Expected to receive a defined message."
58 );
59
60 let res = msg.unwrap().unwrap();
61 let payload_type = (&*res.payload).payload_type();
62 let payload_len = (&*res.payload).to_bytes().len();
63
64 assert_eq!(
65 res.header,
66 DoipHeader {
67 protocol_version: DoipVersion::Iso13400_2012,
68 inverse_protocol_version: 0xfd,
69 payload_type: PayloadType::VehicleIdentificationRequest,
70 payload_length: 0
71 },
72 "Unexpected message: {:?}",
73 res
74 );
75
76 assert_eq!(
77 payload_type,
78 PayloadType::VehicleIdentificationRequest,
79 "Unexpected payload: {:?}",
80 payload_type
81 );
82
83 assert_eq!(payload_len, 0, "Unexpected payload: {:?}", payload_len);
84 }
85
86 #[test]
87 fn test_decode_single_message_short() {
88 let mut decoder = DoipCodec {};
89 let mut bytes = BytesMut::new();
90
91 let src = [0x02, 0xfd, 0x00, 0x01, 0x00, 0x00, 0x00];
92 bytes.extend_from_slice(&src);
93
94 let msg = decoder.decode(&mut bytes);
95
96 assert!(
97 msg.is_err(),
98 "Expected to receive an Err(ParseError::IndexFailure)."
99 );
100 }
101
102 #[test]
103 fn test_decode_many_message() {
104 let mut decoder = DoipCodec {};
105 let mut bytes = BytesMut::new();
106 let number_of_messages: usize = 30;
107
108 let src = [0x02, 0xfd, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00].repeat(number_of_messages);
109 bytes.extend_from_slice(&src);
110
111 let mut messages: Vec<DoipMessage> = vec![];
112
113 while bytes.len() >= 8 {
114 let msg = decoder.decode(&mut bytes).unwrap();
115
116 let _ = match msg {
117 Some(msg) => messages.push(msg),
118 None => continue,
119 };
120 }
121
122 assert_eq!(
123 messages.len(),
124 number_of_messages,
125 "Unexpected messages: {:?}",
126 messages
127 );
128 }
129}