1use crate::{message::DataIdentifier, UdsError};
2use ace_core::{DiagError, FrameIter};
3use ace_macros::FrameCodec;
4
5#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
6#[frame(error = UdsError)]
7pub struct ReadScalingDataByIdentifierRequest<'a> {
8 pub data_identifiers: FrameIter<'a, DataIdentifier>,
9}
10
11#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
12#[frame(error = UdsError)]
13pub struct ReadScalingDataByIdentifierResponse<'a> {
14 pub data_identifier: DataIdentifier,
15 pub scaling_bytes: FrameIter<'a, ScalingByte<'a>>,
16}
17
18#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
19pub struct ScalingByte<'a> {
20 pub high_nibble: ScalingByteHighNibble,
21 pub low_nibble: ScalingByteLowNibble,
22 pub extension: ScalingByteExtension<'a>,
23}
24
25impl<'a> ace_core::codec::FrameRead<'a> for ScalingByte<'a> {
26 type Error = UdsError;
27 fn decode(buf: &mut &'a [u8]) -> Result<Self, Self::Error> {
28 let byte = *buf
29 .first()
30 .ok_or(UdsError::from(DiagError::LengthMismatch {
31 expected: 1,
32 actual: 0,
33 }))?;
34 *buf = &buf[1..];
35
36 let high_nibble = ScalingByteHighNibble::decode(&mut &[byte >> 4][..])?;
37 let low_nibble = ScalingByteLowNibble::decode(&mut &[byte & 0x0F][..])?;
38 let length = (byte & 0x0F) as usize;
39
40 let extension = match &high_nibble {
41 ScalingByteHighNibble::BitMappedReportedWithoutMask => {
42 let mut ext_buf =
43 ace_core::codec::take_n(buf, length).map_err(|e| UdsError::from(e))?;
44 ScalingByteExtension::BitMappedReportedWithoutMask(
45 BitMappedReportedWithoutMask::decode(&mut ext_buf)?,
46 )
47 }
48 ScalingByteHighNibble::Formula => {
49 let mut ext_buf =
50 ace_core::codec::take_n(buf, length).map_err(|e| UdsError::from(e))?;
51 ScalingByteExtension::Formula(Formula::decode(&mut ext_buf)?)
52 }
53 ScalingByteHighNibble::UnitFormat => {
54 let mut ext_buf =
55 ace_core::codec::take_n(buf, length).map_err(|e| UdsError::from(e))?;
56 ScalingByteExtension::UnitFormat(UnitFormat::decode(&mut ext_buf)?)
57 }
58 ScalingByteHighNibble::StateAndConnectionType => {
59 let mut ext_buf =
60 ace_core::codec::take_n(buf, length).map_err(|e| UdsError::from(e))?;
61 ScalingByteExtension::StateAndConnectionType(StateAndConnectionType::decode(
62 &mut ext_buf,
63 )?)
64 }
65 _ => ScalingByteExtension::None,
66 };
67
68 Ok(Self {
69 high_nibble,
70 low_nibble,
71 extension,
72 })
73 }
74}
75
76impl ace_core::codec::FrameWrite for ScalingByte<'_> {
77 type Error = UdsError;
78 fn encode<W: ace_core::codec::Writer>(&self, buf: &mut W) -> Result<(), Self::Error> {
79 let high: u8 = match &self.high_nibble {
80 ScalingByteHighNibble::UnsignedNumeric => 0x0,
81 ScalingByteHighNibble::SignedNumberic => 0x1,
82 ScalingByteHighNibble::BitMappedReportedWithoutMask => 0x2,
83 ScalingByteHighNibble::BitMappedReportedWithMask => 0x3,
84 ScalingByteHighNibble::BinaryCodedDecimal => 0x4,
85 ScalingByteHighNibble::StateEncodedVariable => 0x5,
86 ScalingByteHighNibble::ASCII => 0x6,
87 ScalingByteHighNibble::SignedFloatingPoint => 0x7,
88 ScalingByteHighNibble::Packet => 0x8,
89 ScalingByteHighNibble::Formula => 0x9,
90 ScalingByteHighNibble::UnitFormat => 0xA,
91 ScalingByteHighNibble::StateAndConnectionType => 0xB,
92 ScalingByteHighNibble::IsoSaeReserved(v) => *v,
93 };
94
95 let low: u8 = match &self.low_nibble {
96 ScalingByteLowNibble::NumberOfBytes(n) => *n,
97 };
98
99 buf.write_bytes(&[(high << 4) | low])
100 .map_err(|e| UdsError::from(e))?;
101
102 match &self.extension {
103 ScalingByteExtension::BitMappedReportedWithoutMask(inner) => inner.encode(buf)?,
104 ScalingByteExtension::Formula(inner) => inner.encode(buf)?,
105 ScalingByteExtension::UnitFormat(inner) => inner.encode(buf)?,
106 ScalingByteExtension::StateAndConnectionType(inner) => inner.encode(buf)?,
107 ScalingByteExtension::None => {}
108 }
109
110 Ok(())
111 }
112}
113
114#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
115#[frame(error = UdsError)]
116#[repr(u8)]
117pub enum ScalingByteHighNibble {
118 #[frame(id = 0x0)]
119 UnsignedNumeric,
120 #[frame(id = 0x1)]
121 SignedNumberic,
122 #[frame(id = 0x2)]
123 BitMappedReportedWithoutMask,
124 #[frame(id = 0x3)]
125 BitMappedReportedWithMask,
126 #[frame(id = 0x4)]
127 BinaryCodedDecimal,
128 #[frame(id = 0x5)]
129 StateEncodedVariable,
130 #[frame(id = 0x6)]
131 ASCII,
132 #[frame(id = 0x7)]
133 SignedFloatingPoint,
134 #[frame(id = 0x8)]
135 Packet,
136 #[frame(id = 0x9)]
137 Formula,
138 #[frame(id = 0xA)]
139 UnitFormat,
140 #[frame(id = 0xB)]
141 StateAndConnectionType,
142 #[frame(id_pat = "0xC..=0xF")]
143 IsoSaeReserved(u8),
144}
145
146#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
147#[frame(error = UdsError)]
148#[repr(u8)]
149pub enum ScalingByteLowNibble {
150 #[frame(id_pat = "0x0..=0xF")]
151 NumberOfBytes(u8),
152}
153
154#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
155pub enum ScalingByteExtension<'a> {
156 BitMappedReportedWithoutMask(BitMappedReportedWithoutMask<'a>),
157 Formula(Formula<'a>),
158 UnitFormat(UnitFormat),
159 StateAndConnectionType(StateAndConnectionType),
160 None,
161}
162
163#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
164pub struct BitMappedReportedWithoutMask<'a> {
165 pub mask_byte: u8,
166 pub remaining: &'a [u8],
167}
168
169impl<'a> ace_core::codec::FrameRead<'a> for BitMappedReportedWithoutMask<'a> {
170 type Error = UdsError;
171 fn decode(buf: &mut &'a [u8]) -> Result<Self, Self::Error> {
172 let mask_byte = *buf
173 .first()
174 .ok_or(UdsError::from(DiagError::LengthMismatch {
175 expected: 1,
176 actual: 0,
177 }))?;
178 *buf = &buf[1..];
179
180 let remaining = *buf;
181 *buf = &buf[buf.len()..];
182
183 Ok(Self {
184 mask_byte,
185 remaining,
186 })
187 }
188}
189
190impl ace_core::codec::FrameWrite for BitMappedReportedWithoutMask<'_> {
191 type Error = UdsError;
192 fn encode<W: ace_core::codec::Writer>(&self, buf: &mut W) -> Result<(), Self::Error> {
193 buf.write_bytes(&[self.mask_byte])
194 .map_err(|e| UdsError::from(e))?;
195 buf.write_bytes(self.remaining)
196 .map_err(|e| UdsError::from(e))
197 }
198}
199
200#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
201#[frame(error = UdsError)]
202pub struct Formula<'a> {
203 pub formula_identifier: FormulaIdentifier,
204 pub c0_high_byte: u8,
205 pub c0_low_byte: u8,
206 pub remaining: &'a [u8],
207}
208
209#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
210#[frame(error = UdsError)]
211pub enum FormulaIdentifier {
212 #[frame(id = 0x00)]
213 LinearFormula,
214 #[frame(id = 0x01)]
215 LinearScaleWithOffset,
216 #[frame(id = 0x02)]
217 ReciprocalWithScaleAndOffset,
218 #[frame(id = 0x03)]
219 ScaledReciprocal,
220 #[frame(id = 0x04)]
221 OffsetThenScale,
222 #[frame(id = 0x05)]
223 RationalFormula,
224 #[frame(id = 0x06)]
225 LinearScale,
226 #[frame(id = 0x07)]
227 Reciprocal,
228 #[frame(id = 0x08)]
229 Offset,
230 #[frame(id = 0x09)]
231 RatioScale,
232 #[frame(id_pat = "0x0A..=0x7F")]
233 IsoSaeReserved(u8),
234 #[frame(id_pat = "0x80..=0xFF")]
235 VehicleManufacturerSpecific(u8),
236}
237
238#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
239#[frame(error = UdsError)]
240#[repr(u8)]
241pub enum UnitFormat {
242 #[frame(id = 0x00)]
243 NoUnit,
244 #[frame(id = 0x01)]
245 Metre,
246 #[frame(id = 0x02)]
247 Foot,
248 #[frame(id = 0x03)]
249 Inch,
250 #[frame(id = 0x04)]
251 Yard,
252 #[frame(id = 0x05)]
253 MileEnglish,
254 #[frame(id = 0x06)]
255 Gram,
256 #[frame(id = 0x07)]
257 TonMetric,
258 #[frame(id = 0x08)]
259 Second,
260 #[frame(id = 0x09)]
261 Minute,
262 #[frame(id = 0x0A)]
263 Hour,
264 #[frame(id = 0x0B)]
265 Day,
266 #[frame(id = 0x0C)]
267 Year,
268 #[frame(id = 0x0D)]
269 Ampere,
270 #[frame(id = 0x0E)]
271 Volt,
272 #[frame(id = 0x0F)]
273 Coulomb,
274 #[frame(id = 0x10)]
275 Ohm,
276 #[frame(id = 0x11)]
277 Farad,
278 #[frame(id = 0x12)]
279 Henry,
280 #[frame(id = 0x13)]
281 Siemens,
282 #[frame(id = 0x14)]
283 Weber,
284 #[frame(id = 0x15)]
285 Tesla,
286 #[frame(id = 0x16)]
287 Kelvin,
288 #[frame(id = 0x17)]
289 Celcius,
290 #[frame(id = 0x18)]
291 Fahrenheit,
292 #[frame(id = 0x19)]
293 Candela,
294 #[frame(id = 0x1A)]
295 Radian,
296 #[frame(id = 0x1B)]
297 Degree,
298 #[frame(id = 0x1C)]
299 Hertz,
300 #[frame(id = 0x1D)]
301 Joule,
302 #[frame(id = 0x1E)]
303 Newton,
304 #[frame(id = 0x1F)]
305 Kilopond,
306 #[frame(id = 0x20)]
307 PoundForce,
308 #[frame(id = 0x21)]
309 Watt,
310 #[frame(id = 0x22)]
311 HorsePowerMetric,
312 #[frame(id = 0x23)]
313 HorsePowerUkUs,
314 #[frame(id = 0x24)]
315 Pascal,
316 #[frame(id = 0x25)]
317 Bar,
318 #[frame(id = 0x26)]
319 Atmosphere,
320 #[frame(id = 0x27)]
321 PoundForcePerSquareInch,
322 #[frame(id = 0x28)]
323 Becquerel,
324 #[frame(id = 0x29)]
325 Lumen,
326 #[frame(id = 0x2A)]
327 Lux,
328 #[frame(id = 0x2B)]
329 Litre,
330 #[frame(id = 0x2C)]
331 GallonBritish,
332 #[frame(id = 0x2D)]
333 GallonUsLiq,
334 #[frame(id = 0x2E)]
335 CubicInch,
336 #[frame(id = 0x2F)]
337 MeterPerSecond,
338 #[frame(id = 0x30)]
339 KilometerPerHour,
340 #[frame(id = 0x31)]
341 MilePerHour,
342 #[frame(id = 0x32)]
343 RevolutionsPerSecond,
344 #[frame(id = 0x33)]
345 RevolutionsPerMinute,
346 #[frame(id = 0x34)]
347 Counts,
348 #[frame(id = 0x35)]
349 Percent,
350 #[frame(id = 0x36)]
351 MilligramPerStroke,
352 #[frame(id = 0x37)]
353 MeterPerSquareSecond,
354 #[frame(id = 0x38)]
355 NewtonMeter,
356 #[frame(id = 0x39)]
357 LitrePerMinute,
358 #[frame(id = 0x3A)]
359 WattPerSquareMeter,
360 #[frame(id = 0x3B)]
361 BarPerSecond,
362 #[frame(id = 0x3C)]
363 RadiansPerSecond,
364 #[frame(id = 0x3D)]
365 RadiansPerSquareSecond,
366 #[frame(id = 0x3E)]
367 KilogramPerSquareMeter,
368 #[frame(id = 0x3F)]
369 Reserved,
370 #[frame(id = 0x40)]
371 Exa,
372 #[frame(id = 0x41)]
373 Peta,
374 #[frame(id = 0x42)]
375 Tera,
376 #[frame(id = 0x43)]
377 Giga,
378 #[frame(id = 0x44)]
379 Mega,
380 #[frame(id = 0x45)]
381 Kilo,
382 #[frame(id = 0x46)]
383 Hecto,
384 #[frame(id = 0x47)]
385 Deca,
386 #[frame(id = 0x48)]
387 Deci,
388 #[frame(id = 0x49)]
389 Centi,
390 #[frame(id = 0x4A)]
391 Milli,
392 #[frame(id = 0x4B)]
393 Micro,
394 #[frame(id = 0x4C)]
395 Nano,
396 #[frame(id = 0x4D)]
397 Pico,
398 #[frame(id = 0x4E)]
399 Femto,
400 #[frame(id = 0x4F)]
401 Atto,
402 #[frame(id = 0x50)]
403 YearMonthDay,
404 #[frame(id = 0x51)]
405 DayMonthYear,
406 #[frame(id = 0x52)]
407 MonthDayYear,
408 #[frame(id = 0x53)]
409 Week,
410 #[frame(id = 0x54)]
411 UtcHourMinuteSecond,
412 #[frame(id = 0x55)]
413 HourMinuteSecond,
414 #[frame(id = 0x56)]
415 SecondMinuteHourDayMonthYear,
416 #[frame(id = 0x57)]
417 SecondMinuteHourDayMonthYearLocalMinuteOffsetLocalHourOffset,
418 #[frame(id = 0x58)]
419 SecondMinuteHourMonthDayYear,
420 #[frame(id = 0x59)]
421 SecondMinuteHourMonthDayYearLocalMinuteOffsetLocalHourOffset,
422 #[frame(id_pat = "0x5A..=0xFF")]
423 IsoSaeReserved(u8),
424}
425
426#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
427pub struct StateAndConnectionType {
428 pub activity: StateAndConnectionTypeActivity,
429 pub signal: StateAndConnectionTypeSignal,
430 pub input_signal: StateAndConnectionTypeInputSignal,
431 pub resistor: StateAndConnectionTypeResistor,
432}
433
434impl<'a> ace_core::codec::FrameRead<'a> for StateAndConnectionType {
435 type Error = UdsError;
436 fn decode(buf: &mut &'a [u8]) -> Result<Self, Self::Error> {
437 let byte = *buf
438 .first()
439 .ok_or(UdsError::from(DiagError::LengthMismatch {
440 expected: 1,
441 actual: 0,
442 }))?;
443 *buf = &buf[1..];
444
445 let activity = match byte & 0x07 {
446 0x00 => StateAndConnectionTypeActivity::NotActive,
447 0x01 => StateAndConnectionTypeActivity::ActiveFunction1,
448 0x02 => StateAndConnectionTypeActivity::ErrorDetected,
449 0x03 => StateAndConnectionTypeActivity::NotAvailable,
450 0x04 => StateAndConnectionTypeActivity::ActiveFunction2,
451 v => StateAndConnectionTypeActivity::Reserved(v),
452 };
453
454 let signal = match (byte >> 3) & 0x03 {
455 0x00 => StateAndConnectionTypeSignal::SignalAtLowLevel,
456 0x01 => StateAndConnectionTypeSignal::SignalAtMiddleLevel,
457 0x02 => StateAndConnectionTypeSignal::SignalAtHighLevel,
458 _ => StateAndConnectionTypeSignal::Reserved,
459 };
460
461 let input_signal = match (byte >> 5) & 0x01 {
462 0x00 => StateAndConnectionTypeInputSignal::InputSignal,
463 _ => StateAndConnectionTypeInputSignal::NotDefined,
464 };
465
466 let resistor = match (byte >> 6) & 0x03 {
467 0x00 => StateAndConnectionTypeResistor::NotAvailableInEcuConnector,
468 0x01 => StateAndConnectionTypeResistor::PullDownResistor,
469 0x02 => StateAndConnectionTypeResistor::PullUpResistor,
470 _ => StateAndConnectionTypeResistor::PullUpAndPullDown,
471 };
472
473 Ok(Self {
474 activity,
475 signal,
476 input_signal,
477 resistor,
478 })
479 }
480}
481
482impl ace_core::codec::FrameWrite for StateAndConnectionType {
483 type Error = UdsError;
484 fn encode<W: ace_core::codec::Writer>(&self, buf: &mut W) -> Result<(), Self::Error> {
485 let activity_bits: u8 = match self.activity {
486 StateAndConnectionTypeActivity::NotActive => 0x00,
487 StateAndConnectionTypeActivity::ActiveFunction1 => 0x01,
488 StateAndConnectionTypeActivity::ErrorDetected => 0x02,
489 StateAndConnectionTypeActivity::NotAvailable => 0x03,
490 StateAndConnectionTypeActivity::ActiveFunction2 => 0x04,
491 StateAndConnectionTypeActivity::Reserved(v) => v,
492 };
493
494 let signal_bits: u8 = match self.signal {
495 StateAndConnectionTypeSignal::SignalAtLowLevel => 0x00,
496 StateAndConnectionTypeSignal::SignalAtMiddleLevel => 0x01,
497 StateAndConnectionTypeSignal::SignalAtHighLevel => 0x02,
498 StateAndConnectionTypeSignal::Reserved => 0x03,
499 };
500
501 let input_signal_bit: u8 = match self.input_signal {
502 StateAndConnectionTypeInputSignal::InputSignal => 0x00,
503 StateAndConnectionTypeInputSignal::NotDefined => 0x01,
504 };
505
506 let resistor_bits: u8 = match self.resistor {
507 StateAndConnectionTypeResistor::NotAvailableInEcuConnector => 0x00,
508 StateAndConnectionTypeResistor::PullDownResistor => 0x01,
509 StateAndConnectionTypeResistor::PullUpResistor => 0x02,
510 StateAndConnectionTypeResistor::PullUpAndPullDown => 0x03,
511 };
512
513 let byte =
514 activity_bits | (signal_bits << 3) | (input_signal_bit << 5) | (resistor_bits << 6);
515
516 buf.write_bytes(&[byte]).map_err(|e| UdsError::from(e))
517 }
518}
519
520#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
521#[frame(error = UdsError)]
522#[repr(u8)]
523pub enum StateAndConnectionTypeActivity {
524 #[frame(id = 0x00)]
525 NotActive,
526 #[frame(id = 0x01)]
527 ActiveFunction1,
528 #[frame(id = 0x02)]
529 ErrorDetected,
530 #[frame(id = 0x03)]
531 NotAvailable,
532 #[frame(id = 0x04)]
533 ActiveFunction2,
534 #[frame(id_pat = "0x05..=0x07")]
535 Reserved(u8),
536}
537
538#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
539#[frame(error = UdsError)]
540#[repr(u8)]
541pub enum StateAndConnectionTypeSignal {
542 #[frame(id = 0x00)]
543 SignalAtLowLevel,
544 #[frame(id = 0x01)]
545 SignalAtMiddleLevel,
546 #[frame(id = 0x02)]
547 SignalAtHighLevel,
548 #[frame(id = 0x03)]
549 Reserved,
550}
551
552#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
553#[frame(error = UdsError)]
554#[repr(u8)]
555pub enum StateAndConnectionTypeInputSignal {
556 #[frame(id = 0x00)]
557 InputSignal,
558 #[frame(id = 0x01)]
559 NotDefined,
560}
561
562#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
563#[frame(error = UdsError)]
564#[repr(u8)]
565pub enum StateAndConnectionTypeResistor {
566 #[frame(id = 0x00)]
567 NotAvailableInEcuConnector,
568 #[frame(id = 0x01)]
569 PullDownResistor,
570 #[frame(id = 0x02)]
571 PullUpResistor,
572 #[frame(id = 0x03)]
573 PullUpAndPullDown,
574}