1use super::*;
13
14const READ_MEMORY_BY_ADDRESS_SID: u8 = 0x23;
15use crate::uds::uds_definitions::SEND_RECEIVE_SID_OFFSET;
16
17#[derive(Debug, PartialEq)]
18pub struct ReadMemoryByAddressResponse {
19 data_record: Vec<u8>,
20}
21
22impl UdsClient {
23 pub async fn read_memory_by_address(
33 &self,
34 address_and_memory_length_format_identifier: u8,
35 memory_address: &[u8],
36 memory_size: &[u8],
37 ) -> EcuResponseResult {
38 let request = formulate_request(
39 address_and_memory_length_format_identifier,
40 memory_address,
41 memory_size,
42 );
43 let response = self.send_and_receive(&request).await?;
44 let parsed_response = parse_response(&response);
45 return parsed_response;
46 }
47 pub async fn read_memory_by_address_simplified(
51 &self,
52 memory_address: u64,
53 memory_size: u64,
54 memory_address_len: Option<u8>,
55 memory_size_len: Option<u8>,
56 ) -> EcuResponseResult {
57 let request_arguments = convert_from_simple_to_normal(
58 memory_address,
59 memory_size,
60 memory_address_len,
61 memory_size_len,
62 )?;
63
64 self.read_memory_by_address(
65 request_arguments.0,
66 &request_arguments.1,
67 &request_arguments.2,
68 )
69 .await
70 }
71}
72
73fn convert_from_simple_to_normal(
74 memory_address: u64,
75 memory_size: u64,
76 memory_address_len: Option<u8>,
77 memory_size_len: Option<u8>,
78) -> Result<(u8, Vec<u8>, Vec<u8>), UdsError> {
79 let mut address_encode_bytes = 0;
80 let mut size_encode_bytes = 0;
81
82 let mut i = memory_address;
83 while i > 0 {
84 i = i >> 8;
85 address_encode_bytes += 1;
86 }
87 let mut i = memory_size;
88 while i > 0 {
89 i = i >> 8;
90 size_encode_bytes += 1;
91 }
92
93 if let Some(mut provided_address_len) = memory_address_len {
94 if provided_address_len > 0x8 {
95 warn!("address_len needs to be lower or equal to 0xf, using 0xf instead of provided value");
96 provided_address_len = 0x8;
97 }
98
99 if provided_address_len < address_encode_bytes {
100 warn!("Provided address_len can not hold provided memory_address");
101 return Err(UdsError::InvalidArgument);
102 }
103 if provided_address_len > address_encode_bytes {
104 address_encode_bytes = provided_address_len;
105 }
106 }
107 if let Some(mut provided_memory_size_len) = memory_size_len {
108 if provided_memory_size_len > 0x8 {
109 warn!(
110 "memory_len needs to be lower or equal to 0xf, using 0xf instead of provided value"
111 );
112 provided_memory_size_len = 0x8;
113 }
114 if provided_memory_size_len < size_encode_bytes {
115 error!("Provided memory_len can not hold provided memory_size");
116 return Err(UdsError::InvalidArgument);
117 }
118 if provided_memory_size_len > size_encode_bytes {
119 size_encode_bytes = provided_memory_size_len;
120 }
121 }
122 let address_and_memory_length_format_identifier =
123 (size_encode_bytes << 4) + address_encode_bytes;
124
125 let memory_address_bytes =
127 memory_address.to_be_bytes().as_slice()[(8 - address_encode_bytes as usize)..].to_vec();
128 let memory_size_bytes =
129 memory_size.to_be_bytes().as_slice()[(8 - size_encode_bytes as usize)..].to_vec();
130 Ok((
131 address_and_memory_length_format_identifier,
132 memory_address_bytes,
133 memory_size_bytes,
134 ))
135}
136
137fn formulate_request(
138 address_and_memory_length_format_identifier: u8,
139 memory_address: &[u8],
140 memory_size: &[u8],
141) -> Vec<u8> {
142 let mut request: Vec<u8> = vec![
143 READ_MEMORY_BY_ADDRESS_SID,
144 address_and_memory_length_format_identifier,
145 ];
146 request.extend_from_slice(memory_address);
147 request.extend_from_slice(memory_size);
148
149 request
150}
151fn parse_response(raw_response: &[u8]) -> EcuResponseResult {
152 let sid = raw_response[0];
153 if sid != READ_MEMORY_BY_ADDRESS_SID + SEND_RECEIVE_SID_OFFSET {
154 return Err(UdsError::SidMismatch {
155 expected: READ_MEMORY_BY_ADDRESS_SID + SEND_RECEIVE_SID_OFFSET,
156 received: sid,
157 raw_message: raw_response.to_owned(),
158 });
159 }
160 let read_memory_data = ReadMemoryByAddressResponse {
161 data_record: Vec::from(&raw_response[1..]),
162 };
163 let parsed_response = UdsResponse::ReadMemoryByAddress(DataFormat::Parsed(read_memory_data));
164 Ok(parsed_response)
165}
166
167#[cfg(test)]
168mod tests {
169 use super::*;
170
171 #[test]
172 fn test_ok_convert_from_simple_to_normal() {
173 let memory_address: u64 = 0x12345678;
174 let memory_size: u64 = 0x4321;
175 let memory_address_len: Option<u8> = None;
176 let memory_size_len: Option<u8> = None;
177 let expected: (u8, Vec<u8>, Vec<u8>) =
178 (0x24, vec![0x12, 0x34, 0x56, 0x78], vec![0x43, 0x21]);
179 let result = convert_from_simple_to_normal(
180 memory_address,
181 memory_size,
182 memory_address_len,
183 memory_size_len,
184 );
185 assert_eq!(result, Ok(expected));
186 }
187
188 #[test]
189 fn test_ok_convert_from_simple_to_normal_specified_memory_address_len() {
190 let memory_address: u64 = 0x5678;
191 let memory_size: u64 = 0x4321;
192 let memory_address_len: Option<u8> = Some(6);
193 let memory_size_len: Option<u8> = None;
194 let expected: (u8, Vec<u8>, Vec<u8>) =
195 (0x26, vec![0x0, 0x0, 0x0, 0x0, 0x56, 0x78], vec![0x43, 0x21]);
196 let result = convert_from_simple_to_normal(
197 memory_address,
198 memory_size,
199 memory_address_len,
200 memory_size_len,
201 );
202 assert_eq!(result, Ok(expected));
203 }
204
205 #[test]
206 fn test_ok_convert_from_simple_to_normal_specified_memory_size_len() {
207 let memory_address: u64 = 0x5678;
208 let memory_size: u64 = 0x4321;
209 let memory_address_len: Option<u8> = None;
210 let memory_size_len: Option<u8> = Some(3);
211 let expected: (u8, Vec<u8>, Vec<u8>) = (0x32, vec![0x56, 0x78], vec![0x0, 0x43, 0x21]);
212 let result = convert_from_simple_to_normal(
213 memory_address,
214 memory_size,
215 memory_address_len,
216 memory_size_len,
217 );
218 assert_eq!(result, Ok(expected));
219 }
220
221 #[test]
222 fn test_ok_convert_from_simple_to_normal_specified_both() {
223 let memory_address: u64 = 0x5678;
224 let memory_size: u64 = 0x4321;
225 let memory_address_len: Option<u8> = Some(4);
226 let memory_size_len: Option<u8> = Some(3);
227 let expected: (u8, Vec<u8>, Vec<u8>) =
228 (0x34, vec![0x0, 0x0, 0x56, 0x78], vec![0x0, 0x43, 0x21]);
229 let result = convert_from_simple_to_normal(
230 memory_address,
231 memory_size,
232 memory_address_len,
233 memory_size_len,
234 );
235 assert_eq!(result, Ok(expected));
236 }
237
238 #[test]
239 fn test_err_convert_from_simple_to_normal_specified_memory_address_len_too_small() {
240 let memory_address: u64 = 0x12345678;
241 let memory_size: u64 = 0x4321;
242 let memory_address_len: Option<u8> = Some(3);
243 let memory_size_len: Option<u8> = None;
244 let expected = UdsError::InvalidArgument;
245 let result = convert_from_simple_to_normal(
246 memory_address,
247 memory_size,
248 memory_address_len,
249 memory_size_len,
250 );
251 assert_eq!(result, Err(expected));
252 }
253
254 #[test]
255 fn test_err_convert_from_simple_to_normal_specified_memory_size_len_too_small() {
256 let memory_address: u64 = 0x12345678;
257 let memory_size: u64 = 0x43211234;
258 let memory_address_len: Option<u8> = None;
259 let memory_size_len: Option<u8> = Some(3);
260 let expected = UdsError::InvalidArgument;
261 let result = convert_from_simple_to_normal(
262 memory_address,
263 memory_size,
264 memory_address_len,
265 memory_size_len,
266 );
267 assert_eq!(result, Err(expected));
268 }
269 #[test]
270 fn test_err_convert_from_simple_to_normal_specified_memory_size_len_too_big() {
271 let memory_address: u64 = 0x12345678;
272 let memory_size: u64 = 0x43211234;
273 let memory_address_len: Option<u8> = None;
274 let memory_size_len: Option<u8> = Some(0xff);
275 let expected = (
276 0x84,
277 vec![0x12, 0x34, 0x56, 0x78],
278 vec![0x0, 0x0, 0x0, 0x0, 0x43, 0x21, 0x12, 0x34],
279 );
280 let result = convert_from_simple_to_normal(
281 memory_address,
282 memory_size,
283 memory_address_len,
284 memory_size_len,
285 );
286 assert_eq!(result, Ok(expected));
287 }
288 #[test]
289 fn test_err_convert_from_simple_to_normal_specified_memory_address_len_too_big() {
290 let memory_address: u64 = 0x12345678;
291 let memory_size: u64 = 0x43211234;
292 let memory_address_len: Option<u8> = Some(0xff);
293 let memory_size_len: Option<u8> = None;
294 let expected = (
295 0x48,
296 vec![0x0, 0x0, 0x0, 0x0, 0x12, 0x34, 0x56, 0x78],
297 vec![0x43, 0x21, 0x12, 0x34],
298 );
299 let result = convert_from_simple_to_normal(
300 memory_address,
301 memory_size,
302 memory_address_len,
303 memory_size_len,
304 );
305 assert_eq!(result, Ok(expected));
306 }
307 #[test]
308 fn test_err_convert_from_simple_to_normal_provided_address_too_big() {
309 let memory_address: u64 = 0x1122_3344_5566_7788;
310 let memory_size: u64 = 0x43211234;
311 let memory_address_len: Option<u8> = None;
312 let memory_size_len: Option<u8> = None;
313 let expected = (
314 0x48,
315 vec![0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
316 vec![0x43, 0x21, 0x12, 0x34],
317 );
318 let result = convert_from_simple_to_normal(
319 memory_address,
320 memory_size,
321 memory_address_len,
322 memory_size_len,
323 );
324
325 assert_eq!(result, Ok(expected));
326 }
327 #[test]
328 fn test_err_convert_from_simple_to_normal_provided_size_too_big() {
329 let memory_address: u64 = 0x1122;
330 let memory_size: u64 = 0x1122_3344_5566_7788;
331 let memory_address_len: Option<u8> = None;
332 let memory_size_len: Option<u8> = None;
333 let expected = (
334 0x82,
335 vec![0x11, 0x22],
336 vec![0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
337 );
338 let result = convert_from_simple_to_normal(
339 memory_address,
340 memory_size,
341 memory_address_len,
342 memory_size_len,
343 );
344 assert_eq!(result, Ok(expected));
345 }
346 #[test]
347 fn test_ok_compose_request() {
348 let address_and_memory_length_format_identifier: u8 = 0x24;
349 let memory_address: [u8; 4] = [0x4, 0x32, 0x12, 0x1];
350 let memory_size: [u8; 2] = [0x1, 0x12];
351 let expected = vec![
352 READ_MEMORY_BY_ADDRESS_SID,
353 0x24,
354 0x4,
355 0x32,
356 0x12,
357 0x1,
358 0x1,
359 0x12,
360 ];
361 let result = formulate_request(
362 address_and_memory_length_format_identifier,
363 &memory_address,
364 &memory_size,
365 );
366 assert_eq!(result, expected);
367 }
368 #[test]
369 fn test_ok_parse_response() {
370 let sid = READ_MEMORY_BY_ADDRESS_SID + SEND_RECEIVE_SID_OFFSET;
371 let data = vec![sid, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
372 let expected =
373 UdsResponse::ReadMemoryByAddress(DataFormat::Parsed(ReadMemoryByAddressResponse {
374 data_record: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
375 }));
376 let result = parse_response(&data);
377 assert_eq!(result, Ok(expected));
378 }
379}