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