iso13400_2/request/
mod.rs

1use crate::{constants::*, error::Error, utils, Eid, LogicAddress, RoutingActiveType};
2use getset::{CopyGetters, Getters};
3
4/****** --- UDP --- ********/
5#[derive(Debug, Clone, Eq, PartialEq)]
6pub struct VehicleID; // 0x0001
7
8impl VehicleID {
9    #[inline]
10    const fn length() -> usize {
11        0
12    }
13}
14
15impl TryFrom<&[u8]> for VehicleID {
16    type Error = Error;
17    fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
18        let _ = utils::data_len_check(data, Self::length(), true)?;
19
20        Ok(Self)
21    }
22}
23
24impl From<VehicleID> for Vec<u8> {
25    fn from(_: VehicleID) -> Self {
26        let mut result = UDP_REQ_VEHICLE_IDENTIFIER.to_be_bytes().to_vec();
27        let length = VehicleID::length() as u32;
28        result.extend(length.to_be_bytes());
29
30        result
31    }
32}
33
34#[derive(Debug, Clone, Eq, PartialEq, CopyGetters)]
35#[get_copy = "pub"]
36pub struct VehicleIDWithEID {
37    // 0x0002
38    pub(crate) eid: Eid,
39}
40
41impl VehicleIDWithEID {
42    pub fn new(eid: Eid) -> Self {
43        Self { eid }
44    }
45
46    #[inline]
47    const fn length() -> usize {
48        Eid::length()
49    }
50}
51
52impl TryFrom<&[u8]> for VehicleIDWithEID {
53    type Error = Error;
54    fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
55        let _ = utils::data_len_check(data, Self::length(), true)?;
56        let eid = Eid::try_from(data)?;
57
58        Ok(Self { eid })
59    }
60}
61
62impl From<VehicleIDWithEID> for Vec<u8> {
63    fn from(val: VehicleIDWithEID) -> Self {
64        let mut result = UDP_REQ_VEHICLE_ID_WITH_EID.to_be_bytes().to_vec();
65        let length = VehicleIDWithEID::length() as u32;
66        result.extend(length.to_be_bytes());
67        result.append(&mut val.eid.into());
68
69        result
70    }
71}
72
73#[derive(Debug, Clone, Eq, PartialEq, Getters)]
74#[get = "pub"]
75pub struct VehicleIDWithVIN {
76    // 0x0003
77    pub(crate) vin: String,
78}
79
80impl VehicleIDWithVIN {
81    pub fn new(vin: &str) -> Result<Self, Error> {
82        let vin_len = vin.len();
83        if vin_len != Self::length() {
84            return Err(Error::InvalidParam(format!(
85                "length of vin must equal {}",
86                Self::length()
87            )));
88        }
89
90        Ok(Self {
91            vin: vin.to_owned(),
92        })
93    }
94
95    #[inline]
96    const fn length() -> usize {
97        LENGTH_OF_VIN
98    }
99}
100
101impl TryFrom<&[u8]> for VehicleIDWithVIN {
102    type Error = Error;
103    fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
104        let (_, offset) = utils::data_len_check(data, Self::length(), true)?;
105        let vin = match String::from_utf8(data[offset..].to_vec()) {
106            Ok(v) => v,
107            Err(_) => {
108                rsutil::warn!("invalid UTF-8 string: {}", hex::encode(data));
109                "-".repeat(Self::length())
110            }
111        };
112
113        Ok(Self { vin })
114    }
115}
116
117impl From<VehicleIDWithVIN> for Vec<u8> {
118    fn from(val: VehicleIDWithVIN) -> Self {
119        let mut result = UDP_REQ_VEHICLE_ID_WITH_VIN.to_be_bytes().to_vec();
120        let length = VehicleIDWithVIN::length() as u32;
121        result.extend(length.to_be_bytes());
122        result.append(&mut val.vin.as_bytes().to_vec());
123
124        result
125    }
126}
127
128#[derive(Debug, Clone, Eq, PartialEq)]
129pub struct EntityStatus; // 0x4001
130
131impl EntityStatus {
132    #[inline]
133    const fn length() -> usize {
134        0
135    }
136}
137
138impl TryFrom<&[u8]> for EntityStatus {
139    type Error = Error;
140    fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
141        let _ = utils::data_len_check(data, Self::length(), true)?;
142
143        Ok(Self)
144    }
145}
146
147impl From<EntityStatus> for Vec<u8> {
148    fn from(_: EntityStatus) -> Self {
149        let mut result = UDP_REQ_ENTITY_STATUS.to_be_bytes().to_vec();
150        let length = EntityStatus::length() as u32;
151        result.extend(length.to_be_bytes());
152
153        result
154    }
155}
156
157#[derive(Debug, Clone, Eq, PartialEq)]
158pub struct DiagnosticPowerMode; // 0x4003
159
160impl DiagnosticPowerMode {
161    #[inline]
162    const fn length() -> usize {
163        0
164    }
165}
166
167impl TryFrom<&[u8]> for DiagnosticPowerMode {
168    type Error = Error;
169    fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
170        let _ = utils::data_len_check(data, Self::length(), true)?;
171
172        Ok(Self)
173    }
174}
175
176impl From<DiagnosticPowerMode> for Vec<u8> {
177    fn from(_: DiagnosticPowerMode) -> Self {
178        let mut result = UDP_REQ_DIAGNOSTIC_POWER_MODE.to_be_bytes().to_vec();
179        let length = DiagnosticPowerMode::length() as u32;
180        result.extend(length.to_be_bytes());
181
182        result
183    }
184}
185
186/****** --- end of UDP --- ********/
187
188/****** --- TCP --- ********/
189#[derive(Debug, Clone, Eq, PartialEq, CopyGetters)]
190#[get_copy = "pub"]
191pub struct RoutingActive {
192    // 0x0005
193    pub(crate) src_addr: LogicAddress,
194    pub(crate) active: RoutingActiveType,
195    pub(crate) reserved: u32,
196    pub(crate) user_def: Option<u32>,
197}
198
199impl RoutingActive {
200    pub fn new(src_addr: LogicAddress, active: RoutingActiveType, user_def: Option<u32>) -> Self {
201        Self {
202            src_addr,
203            active,
204            reserved: Default::default(),
205            user_def,
206        }
207    }
208
209    /// min length
210    #[inline]
211    const fn length() -> usize {
212        SIZE_OF_ADDRESS + 1 + 4
213    }
214}
215
216impl TryFrom<&[u8]> for RoutingActive {
217    type Error = Error;
218    fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
219        let (data_len, mut offset) = utils::data_len_check(data, Self::length(), false)?;
220        let src_addr =
221            u16::from_be_bytes(data[offset..offset + SIZE_OF_ADDRESS].try_into().unwrap());
222        offset += SIZE_OF_ADDRESS;
223        let src_addr = LogicAddress::from(src_addr);
224        let active = data[offset];
225        offset += 1;
226        let active = RoutingActiveType::from(active);
227        let reserved = u32::from_be_bytes(data[offset..offset + 4].try_into().unwrap());
228        offset += 4;
229        let user_def = match data_len - offset {
230            0 => Ok(None),
231            4 => Ok(Some(u32::from_be_bytes(
232                data[offset..offset + 4].try_into().unwrap(),
233            ))),
234            _ => Err(Error::InvalidLength {
235                actual: data_len,
236                expected: Self::length() + 4,
237            }),
238        }?;
239
240        Ok(Self {
241            src_addr,
242            active,
243            reserved,
244            user_def,
245        })
246    }
247}
248
249impl From<RoutingActive> for Vec<u8> {
250    fn from(val: RoutingActive) -> Self {
251        let mut result = TCP_REQ_ROUTING_ACTIVE.to_be_bytes().to_vec();
252        let mut length = RoutingActive::length() as u32;
253        if val.user_def.is_some() {
254            length += 4;
255        }
256        result.extend(length.to_be_bytes());
257        let src_addr: u16 = val.src_addr.into();
258        result.extend(src_addr.to_be_bytes());
259        result.push(val.active.into());
260        result.extend(val.reserved.to_be_bytes());
261        if let Some(user_def) = val.user_def {
262            result.extend(user_def.to_be_bytes());
263        }
264
265        result
266    }
267}
268
269#[derive(Debug, Clone, Eq, PartialEq)]
270pub struct AliveCheck; // 0x0007
271
272impl AliveCheck {
273    #[inline]
274    const fn length() -> usize {
275        0
276    }
277}
278
279impl TryFrom<&[u8]> for AliveCheck {
280    type Error = Error;
281    fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
282        let _ = utils::data_len_check(data, Self::length(), true)?;
283
284        Ok(Self)
285    }
286}
287
288impl From<AliveCheck> for Vec<u8> {
289    fn from(_: AliveCheck) -> Self {
290        let mut result = TCP_REQ_ALIVE_CHECK.to_be_bytes().to_vec();
291        let length = AliveCheck::length() as u32;
292        result.extend(length.to_be_bytes());
293
294        result
295    }
296}
297/****** --- end of TCP --- ********/