iso14229_1/request/
dynamically_define_did.rs

1//! request of Service 2C
2
3
4use 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),           // (mem_addr, mem_size),
16        others: Vec<(u128, u128)>,      // at least one
17    },
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                // addr_len,
116                // size_len,
117                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}