1use crate::{DynamicallyDID, DefinitionType, DynamicallyMemAddr, Error, RequestData, Configuration, utils};
5
6#[derive(Debug, Clone, Eq, PartialEq)]
7pub enum DynamicallyDefineDID {
8 DefineByIdentifier {
9 did: DynamicallyDID,
10 source: DynamicallyMemAddr,
11 others: Vec<DynamicallyMemAddr>
12 },
13 DefineByMemoryAddress {
14 did: DynamicallyDID,
15 memory: (u128, u128), others: Vec<(u128, u128)>, },
18 ClearDynamicallyDefinedDataIdentifier(Option<DynamicallyDID>),
19}
20
21impl RequestData for DynamicallyDefineDID {
22 type SubFunc = DefinitionType;
23 fn try_parse(data: &[u8], sub_func: Option<Self::SubFunc>, cfg: &Configuration) -> Result<Self, Error> {
24 match sub_func {
25 Some(v) => {
26 let data_len = data.len();
27 let mut offset = 0;
28 match v {
29 DefinitionType::DefineByIdentifier => {
30 utils::data_length_check(data_len, offset + 6, false)?;
31
32 let did = DynamicallyDID::try_from(
33 u16::from_be_bytes([data[offset], data[offset + 1]])
34 )?;
35 offset += 2;
36 let source = DynamicallyMemAddr::try_from(&data[offset..])?;
37 offset += 4;
38
39 let mut others = Vec::new();
40 while data_len > offset {
41 utils::data_length_check(data_len, offset + 2, false)?;
42
43 others.push( DynamicallyMemAddr::try_from(&data[offset..])?);
44 offset += 2;
45 }
46
47 Ok(Self::DefineByIdentifier { did, source, others })
48 },
49 DefinitionType::DefineByMemoryAddress => {
50 utils::data_length_check(data_len, offset + 6, false)?;
51
52 let did = DynamicallyDID::try_from(
53 u16::from_be_bytes([data[offset], data[offset + 1]])
54 )?;
55 offset += 2;
56
57 let alfi = data[offset];
58 offset += 1;
59 let mem_addr_len = (alfi & 0x0F) as usize;
60 let mem_size_len = ((alfi & 0xF0) >> 4) as usize;
61 utils::data_length_check(data_len, offset + mem_addr_len + mem_size_len, false)?;
62
63 let mem_addr = utils::slice_to_u128(&data[offset..offset + mem_addr_len], cfg.bo_addr);
64 offset += mem_addr_len;
65 let mem_size = utils::slice_to_u128(&data[offset..offset + mem_size_len], cfg.bo_mem_size);
66 offset += mem_size_len;
67
68 let mut others = Vec::new();
69 while data_len > offset {
70 utils::data_length_check(data_len, offset + mem_addr_len + mem_size_len, false)?;
71
72 let mem_addr = utils::slice_to_u128(&data[offset..offset + mem_addr_len], cfg.bo_addr);
73 offset += mem_addr_len;
74 let mem_size = utils::slice_to_u128(&data[offset..offset + mem_size_len], cfg.bo_mem_size);
75 offset += mem_size_len;
76 others.push((mem_addr, mem_size));
77 }
78
79 Ok(Self::DefineByMemoryAddress {
80 did, memory: (mem_addr, mem_size), others
81 })
82 },
83 DefinitionType::ClearDynamicallyDefinedDataIdentifier => {
84 let dyn_did = match data_len - offset {
85 0 => Ok(None),
86 2 => Ok(Some(DynamicallyDID::try_from(
87 u16::from_be_bytes([data[offset], data[offset + 1]])
88 )?)),
89 v => Err(Error::InvalidDataLength { expect: 2, actual: v }),
90 }?;
91
92 Ok(Self::ClearDynamicallyDefinedDataIdentifier(dyn_did))
93 },
94 }
95 },
96 None => panic!("Sub-function required"),
97 }
98 }
99 #[inline]
100 fn to_vec(self, cfg: &Configuration) -> Vec<u8> {
101 let mut result: Vec<u8> = Vec::new();
102 match self {
103 Self::DefineByIdentifier {
104 did,
105 source,
106 others,
107 } => {
108 result.append(&mut did.into());
109 result.append(&mut source.into());
110 others.into_iter()
111 .for_each(|v| result.append(&mut v.into()));
112 },
113 Self::DefineByMemoryAddress {
114 did,
115 memory,
118 others,
119 } => {
120 result.append(&mut did.into());
121
122 let mut max_addr = memory.0;
123 let mut max_size = memory.1;
124 others.iter()
125 .for_each(|v| {
126 let curr_addr = (*v).0;
127 let curr_size = (*v).1;
128 if curr_addr > max_addr {
129 max_addr = curr_addr;
130 }
131
132 if curr_size > max_size {
133 max_size = curr_size;
134 }
135 });
136
137 let mem_addr_len = utils::length_of_u_type(max_addr);
138 let mem_size_len = utils::length_of_u_type(max_size);
139 result.push(((mem_size_len << 4) | mem_addr_len) as u8);
140
141 let mut mem_addr = utils::u128_to_vec(memory.0, mem_addr_len, cfg.bo_addr);
142 let mut mem_size = utils::u128_to_vec(memory.1, mem_size_len, cfg.bo_mem_size);
143 result.append(&mut mem_addr);
144 result.append(&mut mem_size);
145
146 others.into_iter()
147 .for_each(|v| {
148 let mut mem_addr = utils::u128_to_vec(v.0, mem_addr_len, cfg.bo_addr);
149 let mut mem_size = utils::u128_to_vec(v.1, mem_size_len, cfg.bo_mem_size);
150 result.append(&mut mem_addr);
151 result.append(&mut mem_size);
152 });
153 },
154 Self::ClearDynamicallyDefinedDataIdentifier(did) => {
155 if let Some(v) = did {
156 result.append(&mut v.into());
157 }
158 },
159 }
160
161 result
162 }
163}
164
165#[cfg(test)]
166mod tests {
167 use crate::{Configuration, DynamicallyDID, DynamicallyMemAddr, RequestData};
168 use super::DynamicallyDefineDID;
169
170 #[test]
171 fn new() -> anyhow::Result<()> {
172 let cfg = Configuration::default();
173 let source = hex::decode("2C01F30112340102567801019ABC0104")?;
174 let request = DynamicallyDefineDID::DefineByIdentifier {
175 did: DynamicallyDID::try_from(0xF301)?,
176 source: DynamicallyMemAddr {
177 did: 0x1234,
178 position: 1,
179 mem_size: 2,
180 },
181 others: vec![
182 DynamicallyMemAddr {
183 did: 0x5678,
184 position: 1,
185 mem_size: 1,
186 },
187 DynamicallyMemAddr {
188 did: 0x9ABC,
189 position: 1,
190 mem_size: 4,
191 }
192 ]
193 };
194 let result: Vec<_> = request.to_vec(&cfg);
195 assert_eq!(result, source[2..].to_vec());
196
197 let source = hex::decode("2C02F302240009196900012109196900012109196b0102131019950001")?;
198 let request = DynamicallyDefineDID::DefineByMemoryAddress {
199 did: DynamicallyDID::try_from(0xF302)?,
200 memory: (0x00091969, 1),
201 others: vec![
202 (0x21091969, 1),
203 (0x2109196B, 0x0102),
204 (0x13101995, 1),
205 ],
206 };
207 let result: Vec<_> = request.to_vec(&cfg);
208 assert_eq!(result, source[2..].to_vec());
209
210 Ok(())
211 }
212}