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#[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}