Skip to main content

ace_uds/message/services/
response_on_event.rs

1use ace_core::{DiagError, FrameIter, FrameRead, FrameWrite};
2use ace_macros::FrameCodec;
3
4use crate::{UdsError, ValidationError};
5
6#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
7pub struct ResponseOnEventRequest<'a> {
8    pub storage_state: StorageState,
9    pub event_type: EventType<'a>,
10}
11
12#[repr(u8)]
13#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
14#[frame(error = UdsError)]
15pub enum StorageState {
16    #[frame(id = 0x00)]
17    DoNotStoreEvent,
18    #[frame(id = 0x01)]
19    StoreEvent,
20}
21
22#[repr(u8)]
23#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
24#[frame(error = UdsError)]
25pub enum EventType<'a> {
26    #[frame(id = 0x00)]
27    StopResponseOnEvent(StopResponseOnEvent),
28    #[frame(id = 0x01)]
29    OnDtcStatusChange(OnDtcStatusChange<'a>),
30    #[frame(id = 0x03)]
31    OnChangeOfDataIdentifier(OnChangeOfDataIdentifier<'a>),
32    #[frame(id = 0x04)]
33    ReportActivatedEvents(ReportActivatedEvents),
34    #[frame(id = 0x05)]
35    StartResponseOnEvent(StartResponseOnEvent),
36    #[frame(id = 0x06)]
37    ClearResponseOnEvent(ClearResponseOnEvent),
38    #[frame(id = 0x07)]
39    OnComparisonOfValues(OnComparisonOfValues<'a>),
40    #[frame(id = 0x08)]
41    ReportMostRecentDtcOnStatusChange(ReportMostRecentDtcOnStatusChange),
42    #[frame(id = 0x09)]
43    ReportDtcRecordInformationOnDtcStatusChange(ReportDtcRecordInformationOnDtcStatusChange<'a>),
44    #[frame(id_pat = "0x02 | 0x0A..=0x3F")]
45    IsoSaeReserved(u8),
46}
47
48#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
49#[frame(error = UdsError)]
50pub struct StopResponseOnEvent {
51    pub event_window_time: EventWindowTime,
52}
53
54#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
55#[frame(error = UdsError)]
56pub struct OnDtcStatusChange<'a> {
57    pub event_window_time: EventWindowTime,
58    pub dtc_status_mask: u8,
59    pub service_to_respond_to_record: &'a [u8],
60}
61
62#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
63#[frame(error = UdsError)]
64pub struct OnChangeOfDataIdentifier<'a> {
65    pub event_window_time: EventWindowTime,
66    pub data_identifier: u16,
67    pub service_to_respond_to_record: &'a [u8],
68}
69
70#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
71#[frame(error = UdsError)]
72pub struct ReportActivatedEvents {
73    pub event_window_time: EventWindowTime,
74}
75
76#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
77#[frame(error = UdsError)]
78pub struct StartResponseOnEvent {
79    pub event_window_time: EventWindowTime,
80}
81
82#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
83#[frame(error = UdsError)]
84pub struct ClearResponseOnEvent {
85    pub event_window_time: EventWindowTime,
86}
87
88#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
89#[frame(error = UdsError)]
90pub struct OnComparisonOfValues<'a> {
91    pub event_window_time: EventWindowTime,
92    pub event_type_record: [u8; 10],
93    pub service_to_response_to_record: &'a [u8],
94}
95
96#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
97#[frame(error = UdsError)]
98pub struct ReportMostRecentDtcOnStatusChange {
99    pub event_window_time: EventWindowTime,
100    pub dtc_status_mask: u8,
101}
102
103#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
104#[frame(error = UdsError)]
105pub struct ReportDtcRecordInformationOnDtcStatusChange<'a> {
106    pub event_window_time: EventWindowTime,
107    pub dtc_status_mask: u8,
108    pub read_dtc_information_sub_function: u8,
109    pub read_dtc_information_parameters: &'a [u8],
110}
111
112impl<'a> ace_core::codec::FrameRead<'a> for ResponseOnEventRequest<'a> {
113    type Error = UdsError;
114    fn decode(buf: &mut &'a [u8]) -> Result<Self, Self::Error> {
115        let byte = *buf
116            .first()
117            .ok_or(UdsError::from(DiagError::LengthMismatch {
118                expected: 1,
119                actual: 0,
120            }))?;
121        *buf = &buf[1..];
122
123        let storage_state = match (byte & 0x40) >> 6 {
124            0x00 => StorageState::DoNotStoreEvent,
125            _ => StorageState::StoreEvent,
126        };
127
128        let event_type = match byte & 0x3F {
129            0x00 => EventType::StopResponseOnEvent(StopResponseOnEvent::decode(buf)?),
130            0x01 => EventType::OnDtcStatusChange(OnDtcStatusChange::decode(buf)?),
131            0x03 => EventType::OnChangeOfDataIdentifier(OnChangeOfDataIdentifier::decode(buf)?),
132            0x04 => EventType::ReportActivatedEvents(ReportActivatedEvents::decode(buf)?),
133            0x05 => EventType::StartResponseOnEvent(StartResponseOnEvent::decode(buf)?),
134            0x06 => EventType::ClearResponseOnEvent(ClearResponseOnEvent::decode(buf)?),
135            0x07 => EventType::OnComparisonOfValues(OnComparisonOfValues::decode(buf)?),
136            0x08 => EventType::ReportMostRecentDtcOnStatusChange(
137                ReportMostRecentDtcOnStatusChange::decode(buf)?,
138            ),
139            0x09 => EventType::ReportDtcRecordInformationOnDtcStatusChange(
140                ReportDtcRecordInformationOnDtcStatusChange::decode(buf)?,
141            ),
142            v @ (0x02 | 0x0A..=0x3F) => EventType::IsoSaeReserved(v),
143            val => return Err(UdsError::Validation(ValidationError::InvalidEventType(val))),
144        };
145
146        Ok(Self {
147            storage_state,
148            event_type,
149        })
150    }
151}
152
153impl ace_core::codec::FrameWrite for ResponseOnEventRequest<'_> {
154    type Error = UdsError;
155    fn encode<W: ace_core::codec::Writer>(&self, buf: &mut W) -> Result<(), Self::Error> {
156        let storage_bit: u8 = match self.storage_state {
157            StorageState::DoNotStoreEvent => 0x00,
158            StorageState::StoreEvent => 0x40,
159        };
160
161        let event_bits: u8 = match &self.event_type {
162            EventType::StopResponseOnEvent(_) => 0x00,
163            EventType::OnDtcStatusChange(_) => 0x01,
164            EventType::OnChangeOfDataIdentifier(_) => 0x03,
165            EventType::ReportActivatedEvents(_) => 0x04,
166            EventType::StartResponseOnEvent(_) => 0x05,
167            EventType::ClearResponseOnEvent(_) => 0x06,
168            EventType::OnComparisonOfValues(_) => 0x07,
169            EventType::ReportMostRecentDtcOnStatusChange(_) => 0x08,
170            EventType::ReportDtcRecordInformationOnDtcStatusChange(_) => 0x09,
171            EventType::IsoSaeReserved(v) => *v,
172        };
173
174        buf.write_bytes(&[storage_bit | event_bits])
175            .map_err(|e| UdsError::from(e))?;
176
177        match &self.event_type {
178            EventType::StopResponseOnEvent(inner) => inner.encode(buf)?,
179            EventType::OnDtcStatusChange(inner) => inner.encode(buf)?,
180            EventType::OnChangeOfDataIdentifier(inner) => inner.encode(buf)?,
181            EventType::ReportActivatedEvents(inner) => inner.encode(buf)?,
182            EventType::StartResponseOnEvent(inner) => inner.encode(buf)?,
183            EventType::ClearResponseOnEvent(inner) => inner.encode(buf)?,
184            EventType::OnComparisonOfValues(inner) => inner.encode(buf)?,
185            EventType::ReportMostRecentDtcOnStatusChange(inner) => inner.encode(buf)?,
186            EventType::ReportDtcRecordInformationOnDtcStatusChange(inner) => inner.encode(buf)?,
187            EventType::IsoSaeReserved(_) => {}
188        }
189
190        Ok(())
191    }
192}
193
194#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
195pub enum ResponseOnEventResponse<'a> {
196    ReportActivatedEventsResponse(ReportActivatedEventsResponse<'a>),
197    AllButReportActivatedEvents(AllButReportActivatedEvents<'a>),
198}
199
200impl<'a> FrameRead<'a> for ResponseOnEventResponse<'a> {
201    type Error = UdsError;
202
203    fn decode(buf: &mut &'a [u8]) -> Result<Self, Self::Error> {
204        // Peek at the event type byte - do not consume it.
205        // Both inner structs read it themselves as their first field.
206        let event_type = *buf
207            .first()
208            .ok_or(UdsError::from(DiagError::LengthMismatch {
209                expected: 1,
210                actual: 0,
211            }))?;
212
213        if event_type == 0x04 {
214            Ok(Self::ReportActivatedEventsResponse(
215                ReportActivatedEventsResponse::decode(buf)?,
216            ))
217        } else {
218            Ok(Self::AllButReportActivatedEvents(
219                AllButReportActivatedEvents::decode(buf)?,
220            ))
221        }
222    }
223}
224
225impl FrameWrite for ResponseOnEventResponse<'_> {
226    type Error = UdsError;
227
228    fn encode<W: ace_core::codec::Writer>(&self, buf: &mut W) -> Result<(), Self::Error> {
229        match self {
230            Self::ReportActivatedEventsResponse(inner) => inner.encode(buf),
231            Self::AllButReportActivatedEvents(inner) => inner.encode(buf),
232        }
233    }
234}
235
236#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
237#[frame(error = UdsError)]
238pub enum EventTypeValue {
239    #[frame(id = 0x00)]
240    StopResponseOnEvent,
241    #[frame(id = 0x01)]
242    OnDtcStatusChange,
243    #[frame(id = 0x03)]
244    OnChangeOfDataIdentifier,
245    #[frame(id = 0x04)]
246    ReportActivatedEvents,
247    #[frame(id = 0x05)]
248    StartResponseOnEvent,
249    #[frame(id = 0x06)]
250    ClearResponseOnEvent,
251    #[frame(id = 0x07)]
252    OnComparisonOfValues,
253    #[frame(id = 0x08)]
254    ReportMostRecentDtcOnStatusChange,
255    #[frame(id = 0x09)]
256    ReportDtcRecordInformationOnDtcStatusChange,
257    #[frame(id_pat = "0x02 | 0x0A..=0x3F")]
258    IsoSaeReserved(u8),
259}
260
261#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
262#[frame(error = UdsError)]
263pub struct AllButReportActivatedEvents<'a> {
264    pub event_type: EventTypeValue,
265    pub number_of_identified_events: u8,
266    pub event_window_time: EventWindowTime,
267    pub remaining: &'a [u8],
268}
269
270#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
271#[frame(error = UdsError)]
272pub struct ReportActivatedEventsResponse<'a> {
273    pub event_type: EventTypeValue,
274    pub number_of_activated_events: u8,
275    pub events: FrameIter<'a, Event<'a>>,
276}
277
278#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
279#[frame(error = UdsError)]
280pub struct Event<'a> {
281    pub event_window_time: EventWindowTime,
282    pub remaining: &'a [u8],
283}
284
285#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
286#[frame(error = UdsError)]
287pub enum EventWindowTime {
288    #[frame(id_pat = "0x00..=0x01 | 0x09..=0xFF")]
289    IsoSaeReserved(u8),
290    #[frame(id = 0x02)]
291    InfiniteTimeToResponse,
292    #[frame(id = 0x03)]
293    ShortEventWindowTime,
294    #[frame(id = 0x04)]
295    MediumEventWindowTime,
296    #[frame(id = 0x05)]
297    LongEventWindowTime,
298    #[frame(id = 0x06)]
299    PowerWindowTime,
300    #[frame(id = 0x07)]
301    IgnitionWindowTime,
302    #[frame(id = 0x08)]
303    ManufacturerTriggerEventWindowTime,
304}