1#![allow(dead_code)]
2
3use super::*;
20use crate::uds::uds_definitions::SEND_RECEIVE_SID_OFFSET;
21
22const READ_DATA_BY_IDENTIFIER_SID: u8 = 0x22;
23
24#[derive(Debug, PartialEq)]
26pub struct ReadDataByIdentifierResponse {
27 data_records: Vec<DataRecord>,
28}
29
30#[derive(Debug, PartialEq)]
32pub struct DataRecord {
33 data_identifier: u16,
34 data: Vec<u8>,
35}
36
37impl UdsClient {
38 pub async fn read_data_by_identifier(&self, data_identifiers: &[u16]) -> EcuResponseResult {
39 if data_identifiers.len() == 1 {
40 return self
41 .read_single_data_by_identifier(data_identifiers[0])
42 .await;
43 }
44 let request = compose_read_data_by_identifier_request(data_identifiers);
45 let raw_response = self.send_and_receive(&request).await?;
46 let response = parse_read_data_by_identifier_response(&raw_response);
47 response
48 }
49 async fn read_data_by_identifier_tuple(
53 &self,
54 data_identifiers_and_lengths: &[(u16, u32)],
55 ) -> EcuResponseResult {
56 let mut data_identifiers = vec![];
57 for (i, _) in data_identifiers_and_lengths {
58 data_identifiers.push(*i);
59 }
60 let request: Vec<u8> = compose_read_data_by_identifier_request(&data_identifiers);
61 let response = self.send_and_receive(&request).await?;
62 let parsed_response =
63 parse_read_data_by_identifier_tuple_response(data_identifiers_and_lengths, &response);
64 return parsed_response;
65 }
66
67 async fn read_single_data_by_identifier(&self, data_identifier: u16) -> EcuResponseResult {
68 self.read_data_by_identifier_tuple(&[(data_identifier, u32::MAX)])
69 .await
70 }
71}
72
73fn compose_read_data_by_identifier_request(data_identifiers: &[u16]) -> Vec<u8> {
74 let mut request: Vec<u8> = vec![READ_DATA_BY_IDENTIFIER_SID];
75 for &i in data_identifiers {
76 let msb = (i >> 8) as u8;
77 request.push(msb);
78 let lsb = i as u8;
79 request.push(lsb);
80 }
81 return request;
82}
83
84fn parse_read_data_by_identifier_response(raw_response: &[u8]) -> EcuResponseResult {
85 let mut response_iter = raw_response.iter();
86 let sid = *response_iter.next().ok_or(UdsError::ResponseEmpty)?;
87 if sid != READ_DATA_BY_IDENTIFIER_SID + SEND_RECEIVE_SID_OFFSET {
88 return Err(UdsError::SidMismatch {
89 expected: READ_DATA_BY_IDENTIFIER_SID + SEND_RECEIVE_SID_OFFSET,
90 received: sid,
91 raw_message: raw_response.to_vec(),
92 });
93 }
94 let ret = UdsResponse::ReadDataByIdentifier(DataFormat::Raw(raw_response[1..].to_vec()));
95 Ok(ret)
96}
97
98fn parse_read_data_by_identifier_tuple_response(
101 data_identifiers_and_lengths: &[(u16, u32)],
102 raw_response: &[u8],
103) -> EcuResponseResult {
104 let mut response_iterator = raw_response.iter();
105 let sid = *response_iterator.next().ok_or(UdsError::InvalidLength {
106 raw_message: raw_response.to_vec(),
107 })?;
108
109 if sid != READ_DATA_BY_IDENTIFIER_SID + SEND_RECEIVE_SID_OFFSET {
110 return Err(UdsError::SidMismatch {
111 expected: READ_DATA_BY_IDENTIFIER_SID + SEND_RECEIVE_SID_OFFSET,
112 received: sid,
113 raw_message: raw_response.to_vec(),
114 });
115 }
116
117 let mut data_records = Vec::new();
118
119 for &(did, len) in data_identifiers_and_lengths {
120 let msb = *response_iterator.next().ok_or(UdsError::InvalidLength {
121 raw_message: raw_response.to_vec(),
122 })?;
123 let lsb = *response_iterator.next().ok_or(UdsError::InvalidLength {
124 raw_message: raw_response.to_vec(),
125 })?;
126 let response_did = ((msb as u16) << 8) + (lsb as u16);
127
128 if did != response_did {
129 return Err(UdsError::DidMismatch {
130 expected: did,
131 received: response_did,
132 raw_message: raw_response.to_vec(),
133 });
134 }
135 let mut data_record: Vec<u8> = Vec::new();
136 if len != u32::MAX {
137 for _ in 0..len {
138 data_record.push(*response_iterator.next().ok_or(UdsError::InvalidLength {
139 raw_message: raw_response.to_vec(),
140 })?);
141 }
142 } else {
143 loop {
144 let next_element = response_iterator.next();
145 match next_element {
146 Some(&x) => data_record.push(x),
147 None => break,
148 }
149 }
150 }
151
152 let data_record = DataRecord {
153 data_identifier: response_did,
154 data: data_record,
155 };
156 data_records.push(data_record);
157 }
158 let read_data_by_identifier_response = ReadDataByIdentifierResponse { data_records };
162
163 let ret =
164 UdsResponse::ReadDataByIdentifier(DataFormat::Parsed(read_data_by_identifier_response));
165 return Ok(ret);
166}
167#[cfg(test)]
168mod tests {
169 use super::*;
170
171 #[test]
172 fn test_ok_message() {
173 let data_identifiers_and_lengths = vec![(10, 1), (20, 10)];
174 let dummy_message = vec![
175 READ_DATA_BY_IDENTIFIER_SID + SEND_RECEIVE_SID_OFFSET,
176 0,
177 10,
178 0,
179 0,
180 20,
181 0,
182 0,
183 0,
184 0,
185 0,
186 1,
187 2,
188 3,
189 4,
190 5,
191 ];
192
193 let reference =
194 UdsResponse::ReadDataByIdentifier(DataFormat::Parsed(ReadDataByIdentifierResponse {
195 data_records: vec![
196 DataRecord {
197 data_identifier: 10,
198 data: vec![0],
199 },
200 DataRecord {
201 data_identifier: 20,
202 data: vec![0, 0, 0, 0, 0, 1, 2, 3, 4, 5],
203 },
204 ],
205 }));
206
207 let result = parse_read_data_by_identifier_tuple_response(
208 &data_identifiers_and_lengths,
209 &dummy_message,
210 );
211 assert_eq!(result, Ok(reference));
212 }
213 #[test]
214 fn test_did_mismatch() {
215 let data_identifiers_and_lengths = vec![(10, 1), (20, 10)];
216 let dummy_message = vec![
217 READ_DATA_BY_IDENTIFIER_SID + SEND_RECEIVE_SID_OFFSET,
218 0,
219 10,
220 0,
221 0,
222 21,
223 0,
224 0,
225 0,
226 0,
227 0,
228 1,
229 2,
230 3,
231 4,
232 5,
233 ];
234
235 let result = parse_read_data_by_identifier_tuple_response(
236 &data_identifiers_and_lengths,
237 &dummy_message,
238 );
239 assert_eq!(
240 result,
241 Err(UdsError::DidMismatch {
242 expected: 20,
243 received: 21,
244 raw_message: dummy_message
245 })
246 );
247 }
248 #[test]
249 fn test_sid_mismatch() {
250 let data_identifiers_and_lengths = vec![(10, 1), (20, 10)];
251 let dummy_message = vec![
252 READ_DATA_BY_IDENTIFIER_SID + SEND_RECEIVE_SID_OFFSET + 10,
253 0,
254 10,
255 0,
256 0,
257 20,
258 0,
259 0,
260 0,
261 0,
262 0,
263 1,
264 2,
265 3,
266 4,
267 5,
268 ];
269
270 let result = parse_read_data_by_identifier_tuple_response(
271 &data_identifiers_and_lengths,
272 &dummy_message,
273 );
274 assert_eq!(
275 result,
276 Err(UdsError::SidMismatch {
277 expected: READ_DATA_BY_IDENTIFIER_SID + SEND_RECEIVE_SID_OFFSET,
278 received: READ_DATA_BY_IDENTIFIER_SID + SEND_RECEIVE_SID_OFFSET + 10,
279 raw_message: dummy_message,
280 })
281 );
282 }
283 #[test]
284 fn test_invalid_length_short() {
285 let data_identifiers_and_lengths = vec![(10, 1), (20, 10), (21, 0)];
286 let dummy_message = vec![
287 READ_DATA_BY_IDENTIFIER_SID + SEND_RECEIVE_SID_OFFSET,
288 0,
289 10,
290 0,
291 0,
292 20,
293 0,
294 0,
295 0,
296 0,
297 0,
298 1,
299 2,
300 3,
301 4,
302 0,
303 21,
304 ];
305
306 let result = parse_read_data_by_identifier_tuple_response(
307 &data_identifiers_and_lengths,
308 &dummy_message,
309 );
310 assert_eq!(
311 result,
312 Err(UdsError::InvalidLength {
313 raw_message: dummy_message
314 })
315 );
316 }
317 #[test]
318 fn test_parse_with_zero_len() {
319 let data_identifiers_and_lengths = vec![(10, u32::MAX)];
320 let dummy_message = vec![
321 READ_DATA_BY_IDENTIFIER_SID + SEND_RECEIVE_SID_OFFSET,
322 0,
323 10,
324 32,
325 32,
326 21,
327 65,
328 9,
329 8,
330 7,
331 4,
332 ];
333
334 let reference =
335 UdsResponse::ReadDataByIdentifier(DataFormat::Parsed(ReadDataByIdentifierResponse {
336 data_records: vec![DataRecord {
337 data_identifier: 10,
338 data: vec![32, 32, 21, 65, 9, 8, 7, 4],
339 }],
340 }));
341
342 let result = parse_read_data_by_identifier_tuple_response(
343 &data_identifiers_and_lengths,
344 &dummy_message,
345 );
346 assert_eq!(result, Ok(reference));
347 }
348 #[test]
349 fn test_formulate_request() {
350 let data_identifiers = vec![0x10, 0x20, 0x30, 0x4320, 0x4200];
351 let result = compose_read_data_by_identifier_request(&data_identifiers);
352 let reference = vec![
353 READ_DATA_BY_IDENTIFIER_SID,
354 0x0,
355 0x10,
356 0x0,
357 0x20,
358 0x0,
359 0x30,
360 0x43,
361 0x20,
362 0x42,
363 0x00,
364 ];
365 assert_eq!(result, reference);
366 }
367}