ace_uds/message/services/
communication_control.rs1use crate::{UdsError, ValidationError};
2use ace_core::DiagError;
3use ace_macros::FrameCodec;
4
5#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
6#[frame(error = UdsError)]
7pub enum CommunicationControlRequest {
8 #[frame(id_pat = "0x00..=0x03", decode_inner)]
9 WithoutEnhancedAddressInformation(WithoutEnhancedAddressInformation),
10 #[frame(id_pat = "0x04..=0x05", decode_inner)]
11 WithEnhancedAddressInformation(WithEnhancedAddressInformation),
12 #[frame(id_pat = "0x06..=0x3F")]
13 IsoSaeReserved(u8),
14 #[frame(id_pat = "0x40..=0x5F")]
15 VehicleManufacturerSpecific(u8),
16 #[frame(id_pat = "0x60..=0x7E")]
17 SystemSupplierSpecific(u8),
18}
19
20#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
21#[frame(error = UdsError)]
22pub struct WithoutEnhancedAddressInformation {
23 pub control_type: ControlType,
24 pub communication_type: u8,
25}
26#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
27#[frame(error = UdsError)]
28pub struct WithEnhancedAddressInformation {
29 pub control_type: ControlType,
30 pub communication_type: CommunicationType,
31 pub node_identification_number: NodeIdentificationNumber,
32}
33
34#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
35#[frame(error = UdsError)]
36#[repr(u16)]
37pub enum NodeIdentificationNumber {
38 #[frame(id = 0x0000)]
39 IsoSaeReserved,
40 #[frame(id_pat = "0x0001..=u16::MAX")]
41 NodeIdentificationNumber(u16),
42}
43
44#[repr(u8)]
45#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
46#[frame(error = UdsError)]
47pub enum ControlType {
48 #[frame(id = 0x00)]
49 EnableRxAndTx,
50 #[frame(id = 0x01)]
51 EnableRxAndDisableTx,
52 #[frame(id = 0x02)]
53 DisableRxAndDisableTx,
54 #[frame(id = 0x03)]
55 DisableRxAndTx,
56 #[frame(id = 0x04)]
57 EnableRxAndDisableTxWithEnhancedAddressInformation,
58 #[frame(id = 0x05)]
59 EnableRxAndTxWithEnhancedAddressInformation,
60 #[frame(id_pat = "0x06..=0x3F")]
61 IsoSaeReserved(u8),
62 #[frame(id_pat = "0x40..=0x5F")]
63 VehicleManufacturerSpecific(u8),
64 #[frame(id_pat = "0x60..=0x7E")]
65 SystemSupplierSpecific(u8),
66}
67
68#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
69pub struct CommunicationType {
70 pub communication_type: CommunicationTypeValue,
71 pub subnet: Subnet,
72 pub reserved: CommunicationTypeReserved,
73}
74
75#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
76pub enum CommunicationTypeValue {
77 IsoSaeReserved,
78 NormalCommunicationMessages,
79 NetworkManagementCommunicationMessages,
80 JointMessages,
81}
82
83#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
84pub enum Subnet {
85 DisableEnableSpecifiedCommuncationType,
86 DisableEnableSubnetNumber,
87 DisableEnableNetwork,
88}
89
90#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
91pub enum CommunicationTypeReserved {
92 IsoSaeReserved,
93}
94
95impl<'a> ace_core::codec::FrameRead<'a> for CommunicationType {
96 type Error = UdsError;
97 fn decode(buf: &mut &'a [u8]) -> Result<Self, Self::Error> {
98 let byte = *buf
99 .first()
100 .ok_or(UdsError::from(DiagError::LengthMismatch {
101 expected: 1,
102 actual: 0,
103 }))?;
104 *buf = &buf[1..];
105
106 let communication_type = match byte & 0x03 {
107 0x00 => CommunicationTypeValue::IsoSaeReserved,
108 0x01 => CommunicationTypeValue::NormalCommunicationMessages,
109 0x02 => CommunicationTypeValue::NetworkManagementCommunicationMessages,
110 0x03 => CommunicationTypeValue::JointMessages,
111 val => {
112 return Err(UdsError::Validation(
113 ValidationError::InvalidCommunicationTypeValue(val),
114 ))
115 }
116 };
117
118 let reserved = match (byte & 0x0C) >> 2 {
119 0x00..=0x03 => CommunicationTypeReserved::IsoSaeReserved,
120 val => {
121 return Err(UdsError::Validation(
122 ValidationError::InvalidCommunicationReserved(val),
123 ))
124 }
125 };
126
127 let subnet = match (byte & 0xF0) >> 4 {
128 0x00 => Subnet::DisableEnableSpecifiedCommuncationType,
129 0x01..=0x0E => Subnet::DisableEnableSubnetNumber,
130 0x0F => Subnet::DisableEnableNetwork,
131 val => return Err(UdsError::Validation(ValidationError::InvalidSubnet(val))),
132 };
133
134 Ok(Self {
135 communication_type,
136 subnet,
137 reserved,
138 })
139 }
140}
141
142impl ace_core::codec::FrameWrite for CommunicationType {
143 type Error = UdsError;
144 fn encode<W: ace_core::Writer>(&self, buf: &mut W) -> Result<(), Self::Error> {
145 let communication_type_bits: u8 = match self.communication_type {
146 CommunicationTypeValue::IsoSaeReserved => 0x00,
147 CommunicationTypeValue::NormalCommunicationMessages => 0x01,
148 CommunicationTypeValue::NetworkManagementCommunicationMessages => 0x02,
149 CommunicationTypeValue::JointMessages => 0x03,
150 };
151
152 let reserved_bits: u8 = match self.reserved {
153 CommunicationTypeReserved::IsoSaeReserved => 0x00,
154 };
155
156 let subnet_bits: u8 = match self.subnet {
157 Subnet::DisableEnableSpecifiedCommuncationType => 0x00,
158 Subnet::DisableEnableSubnetNumber => 0x01,
159 Subnet::DisableEnableNetwork => 0x0F,
160 };
161
162 let byte = communication_type_bits | (reserved_bits << 2) | (subnet_bits << 4);
163 buf.write_bytes(&[byte]).map_err(|e| UdsError::from(e))
164 }
165}
166
167#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
168#[frame(error = UdsError)]
169pub struct CommunicationControlResponse {
170 pub control_type: ControlType,
171}