uds_client/uds_client/
frame.rs

1#[derive(Debug)]
2pub enum FrameError {
3    InvalidFrameType,
4    InvalidSize,
5    InvalidCanLength,
6    Others,
7}
8
9#[derive(Debug, Clone, PartialEq)]
10pub enum UdsFrame {
11    Single(UdsSingleFrame),
12    First(UdsFirstFrame),
13    Consecutive(UdsConsecutiveFrame),
14    FlowControl(UdsFlowControlFrame),
15}
16
17impl UdsFrame {
18    pub fn to_vec(&self) -> Result<Vec<u8>, FrameError> {
19        match self {
20            UdsFrame::Single(uds_single_frame) => uds_single_frame.to_vec(),
21            UdsFrame::First(uds_first_frame) => uds_first_frame.to_vec(),
22            UdsFrame::Consecutive(uds_consecutive_frame) => uds_consecutive_frame.to_vec(),
23            UdsFrame::FlowControl(uds_flow_control_frame) => uds_flow_control_frame.to_vec(),
24        }
25    }
26
27    pub fn from_vec(data: Vec<u8>) -> Result<Self, FrameError> {
28        if data.is_empty() {
29            return Err(FrameError::InvalidCanLength);
30        }
31
32        let frame_type = data[0] >> 4; // First 4 bits determine the frame type
33
34        match frame_type {
35            0x0 => {
36                // Single Frame
37                if data.len() < 2 {
38                    return Err(FrameError::InvalidSize);
39                }
40                let size = data[0] & 0x0F;
41                let sid = data[1];
42                let did = if data.len() > 2 {
43                    Some(((data[2] as u16) << 8) | data[3] as u16)
44                } else {
45                    None
46                };
47                let payload = data[2..].to_vec();
48                Ok(UdsFrame::Single(UdsSingleFrame {
49                    size,
50                    sid,
51                    did,
52                    payload,
53                }))
54            }
55            0x1 => {
56                // First Frame
57                if data.len() < 3 {
58                    return Err(FrameError::InvalidSize);
59                }
60                let size = (((data[0] & 0x0F) as u16) << 8) | data[1] as u16;
61                let sid = data[2];
62                let did = if data.len() > 3 {
63                    Some(((data[3] as u16) << 8) | data[4] as u16)
64                } else {
65                    None
66                };
67                let payload = data[3..].to_vec();
68                Ok(UdsFrame::First(UdsFirstFrame {
69                    size,
70                    sid,
71                    did,
72                    payload,
73                }))
74            }
75            0x2 => {
76                // Consecutive Frame
77                if data.len() < 2 {
78                    return Err(FrameError::InvalidSize);
79                }
80                let seq_num = data[0] & 0x0F;
81                let payload = data[1..].to_vec();
82                Ok(UdsFrame::Consecutive(UdsConsecutiveFrame {
83                    seq_num,
84                    payload,
85                }))
86            }
87            0x3 => {
88                // Flow Control Frame
89                if data.len() < 3 {
90                    return Err(FrameError::InvalidSize);
91                }
92                let flag = data[0] & 0x0F;
93                let block_size = data[1];
94                let separation_time = data[2];
95                let padding = data[3..].to_vec();
96                Ok(UdsFrame::FlowControl(UdsFlowControlFrame {
97                    flag,
98                    block_size,
99                    separation_time,
100                    padding,
101                }))
102            }
103            _ => Err(FrameError::InvalidFrameType),
104        }
105    }
106}
107
108#[derive(Debug, Clone, PartialEq)]
109pub struct UdsSingleFrame {
110    pub size: u8,         // Size of payload (4 bits, max 7)
111    pub sid: u8,          // Service Identifier (SID)
112    pub did: Option<u16>, // Diagnostic Identifier (optional, some services use it)
113    pub payload: Vec<u8>,
114}
115
116#[derive(Debug, Clone, PartialEq)]
117pub struct UdsFirstFrame {
118    pub size: u16,        // Size of total payload (12 bits)
119    pub sid: u8,          // Service Identifier (SID)
120    pub did: Option<u16>, // Diagnostic Identifier
121    pub payload: Vec<u8>,
122}
123
124#[derive(Debug, Clone, PartialEq)]
125pub struct UdsConsecutiveFrame {
126    pub seq_num: u8, // Sequence number (0-15, 4 bits)
127    pub payload: Vec<u8>,
128}
129
130#[derive(Debug, Clone, PartialEq)]
131pub struct UdsFlowControlFrame {
132    pub flag: u8,            // Flag status (0=Continue, 1=Wait, 2=Overflow)
133    pub block_size: u8,      // Number of Consecutive Frames to send before next FC
134    pub separation_time: u8, // Delay between frames in milliseconds
135    pub padding: Vec<u8>,
136}
137
138impl UdsSingleFrame {
139    pub fn new(sid: u8, did: Option<u16>, payload: Vec<u8>) -> Result<Self, FrameError> {
140        if payload.len() > 7 {
141            return Err(FrameError::InvalidCanLength);
142        }
143
144        Ok(Self {
145            size: payload.len() as u8,
146            sid,
147            did,
148            payload,
149        })
150    }
151
152    pub fn to_vec(&self) -> Result<Vec<u8>, FrameError> {
153        if self.payload.len() > 7 {
154            return Err(FrameError::InvalidSize);
155        }
156
157        let mut frame = Vec::new();
158        frame.push(self.size & 0x0F); // PCI byte (first nibble is 0 for Single Frame)
159        frame.push(self.sid);
160        if let Some(did) = self.did {
161            frame.extend_from_slice(&did.to_be_bytes());
162        }
163        frame.extend_from_slice(&self.payload);
164
165        Ok(frame)
166    }
167}
168
169impl UdsFirstFrame {
170    pub fn new(sid: u8, size: u16, did: Option<u16>, payload: Vec<u8>) -> Result<Self, FrameError> {
171        if payload.len() > 6 {
172            return Err(FrameError::InvalidCanLength);
173        }
174
175        Ok(Self {
176            size,
177            sid,
178            did,
179            payload,
180        })
181    }
182
183    pub fn to_vec(&self) -> Result<Vec<u8>, FrameError> {
184        if self.payload.len() > 6 {
185            return Err(FrameError::InvalidSize);
186        }
187
188        let mut frame = Vec::new();
189        frame.push(0x10 | ((self.size >> 8) as u8 & 0x0F)); // PCI first byte
190        frame.push((self.size & 0xFF) as u8); // PCI second byte
191        frame.push(self.sid);
192        if let Some(did) = self.did {
193            frame.extend_from_slice(&did.to_be_bytes());
194        }
195        frame.extend_from_slice(&self.payload);
196
197        Ok(frame)
198    }
199}
200
201impl UdsConsecutiveFrame {
202    pub fn new(seq_num: u8, payload: Vec<u8>) -> Result<Self, FrameError> {
203        if payload.len() > 7 {
204            return Err(FrameError::InvalidCanLength);
205        }
206
207        Ok(Self { seq_num, payload })
208    }
209
210    pub fn to_vec(&self) -> Result<Vec<u8>, FrameError> {
211        if self.payload.len() > 7 {
212            return Err(FrameError::InvalidSize);
213        }
214
215        let mut frame = Vec::new();
216        frame.push(0x20 | (self.seq_num & 0x0F)); // PCI byte
217        frame.extend_from_slice(&self.payload);
218
219        Ok(frame)
220    }
221}
222
223impl UdsFlowControlFrame {
224    pub fn new(
225        flag: u8,
226        block_size: u8,
227        separation_time: u8,
228        padding: Vec<u8>,
229    ) -> Result<Self, FrameError> {
230        if padding.len() > 5 {
231            return Err(FrameError::InvalidCanLength);
232        }
233        Ok(Self {
234            flag,
235            block_size,
236            separation_time,
237            padding,
238        })
239    }
240
241    pub fn to_vec(&self) -> Result<Vec<u8>, FrameError> {
242        let frame = vec![
243            0x30 | (self.flag & 0x0F), // PCI byte
244            self.block_size,
245            self.separation_time,
246        ];
247
248        Ok(frame)
249    }
250}