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