Skip to main content

ace_uds/message/services/
read_scaling_data_by_identifier.rs

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}