Skip to main content

ace_uds/message/services/
communication_control.rs

1use 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}