ace_uds/message/services/
write_memory_by_address.rs1use crate::UdsError;
2use ace_macros::FrameCodec;
3
4#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
5#[frame(error = UdsError)]
6pub struct WriteMemoryByAddressRequest<'a> {
7 pub address_and_length_format_identifier: u8,
8 #[frame(
9 length = "(address_and_length_format_identifier & 0x0F) as usize",
10 bytes
11 )]
12 pub memory_address: &'a [u8],
13 #[frame(length = "(address_and_length_format_identifier >> 4) as usize", bytes)]
14 pub memory_size: &'a [u8],
15 #[frame(read_all, bytes)]
16 pub data_record: &'a [u8],
17}
18
19#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
20#[frame(error = UdsError)]
21pub struct WriteMemoryByAddressResponse<'a> {
22 pub address_and_length_format_identifier: u8,
23 #[frame(
24 length = "(address_and_length_format_identifier & 0x0F) as usize",
25 bytes
26 )]
27 pub memory_address: &'a [u8],
28 #[frame(length = "(address_and_length_format_identifier >> 4) as usize", bytes)]
29 pub memory_size: &'a [u8],
30}
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35 use ace_core::codec::{decode_from_slice, FrameWrite};
36
37 #[cfg(feature = "alloc")]
38 use alloc::borrow::ToOwned;
39 #[cfg(feature = "alloc")]
40 use alloc::vec;
41
42 const REQUEST_FRAME: &[u8] = &[0x12, 0xAA, 0xBB, 0x04, 0xDE, 0xAD, 0xBE, 0xEF];
47
48 const RESPONSE_FRAME: &[u8] = &[0x12, 0xAA, 0xBB, 0x04];
52
53 #[test]
54 fn request_decode() {
55 let req: WriteMemoryByAddressRequest = decode_from_slice(REQUEST_FRAME).unwrap();
56 assert_eq!(req.address_and_length_format_identifier, 0x12);
57 assert_eq!(req.memory_address, &[0xAA, 0xBB]);
58 assert_eq!(req.memory_size, &[0x04]);
59 assert_eq!(req.data_record, &[0xDE, 0xAD, 0xBE, 0xEF]);
60 }
61
62 #[test]
63 fn request_encode_roundtrip() {
64 let req: WriteMemoryByAddressRequest = decode_from_slice(REQUEST_FRAME).unwrap();
65 let mut buf = [0u8; 64];
66 req.encode(&mut buf.as_mut()).unwrap();
67 assert_eq!(&buf[..REQUEST_FRAME.len()], REQUEST_FRAME);
68 }
69
70 #[test]
71 fn response_decode() {
72 let resp: WriteMemoryByAddressResponse = decode_from_slice(RESPONSE_FRAME).unwrap();
73 assert_eq!(resp.address_and_length_format_identifier, 0x12);
74 assert_eq!(resp.memory_address, &[0xAA, 0xBB]);
75 assert_eq!(resp.memory_size, &[0x04]);
76 }
77
78 #[test]
79 fn response_encode_roundtrip() {
80 let resp: WriteMemoryByAddressResponse = decode_from_slice(RESPONSE_FRAME).unwrap();
81 let mut buf = [0u8; 64];
82 resp.encode(&mut buf.as_mut()).unwrap();
83 assert_eq!(&buf[..RESPONSE_FRAME.len()], RESPONSE_FRAME);
84 }
85
86 #[test]
87 fn request_truncated_address() {
88 let bad: &[u8] = &[0x13, 0xAA, 0xBB];
90 let result = decode_from_slice::<WriteMemoryByAddressRequest>(bad);
91 assert!(result.is_err());
92 }
93
94 #[test]
95 fn request_truncated_size() {
96 let bad: &[u8] = &[0x22, 0xAA, 0xBB, 0x04];
98 let result = decode_from_slice::<WriteMemoryByAddressRequest>(bad);
99 assert!(result.is_err());
100 }
101
102 #[test]
103 fn response_truncated() {
104 let bad: &[u8] = &[0x12, 0xAA];
106 let result = decode_from_slice::<WriteMemoryByAddressResponse>(bad);
107 assert!(result.is_err());
108 }
109
110 #[cfg(feature = "alloc")]
111 #[test]
112 fn request_to_owned() {
113 let req: WriteMemoryByAddressRequest = decode_from_slice(REQUEST_FRAME).unwrap();
114 let owned = req.to_owned();
115 assert_eq!(owned.address_and_length_format_identifier, 0x12);
116 assert_eq!(owned.memory_address, vec![0xAA, 0xBB]);
117 assert_eq!(owned.memory_size, vec![0x04]);
118 assert_eq!(owned.data_record, vec![0xDE, 0xAD, 0xBE, 0xEF]);
119 }
120
121 #[cfg(feature = "alloc")]
122 #[test]
123 fn response_to_owned() {
124 let resp: WriteMemoryByAddressResponse = decode_from_slice(RESPONSE_FRAME).unwrap();
125 let owned = resp.to_owned();
126 assert_eq!(owned.address_and_length_format_identifier, 0x12);
127 assert_eq!(owned.memory_address, vec![0xAA, 0xBB]);
128 assert_eq!(owned.memory_size, vec![0x04]);
129 }
130
131 #[cfg(feature = "alloc")]
132 #[test]
133 fn owned_request_encode_roundtrip() {
134 let owned: WriteMemoryByAddressRequestOwned = decode_from_slice(REQUEST_FRAME).unwrap();
135 let mut buf = [0u8; 64];
136 owned.encode(&mut buf.as_mut()).unwrap();
137 assert_eq!(&buf[..REQUEST_FRAME.len()], REQUEST_FRAME);
138 }
139
140 #[cfg(feature = "alloc")]
141 #[test]
142 fn owned_response_encode_roundtrip() {
143 let owned: WriteMemoryByAddressResponseOwned = decode_from_slice(RESPONSE_FRAME).unwrap();
144 let mut buf = [0u8; 64];
145 owned.encode(&mut buf.as_mut()).unwrap();
146 assert_eq!(&buf[..RESPONSE_FRAME.len()], RESPONSE_FRAME);
147 }
148}