uds_client/uds_client/
pci.rs

1/// The definition for the Protocol Control Information (PCI) byte type used in ISO 15765-2 (CAN TP).
2#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3pub enum PciType {
4    /// Single Frame (SF): Used for messages that fit in a single frame (<= 7 bytes).
5    /// PCI byte range: 0x00-0x0F.
6    SingleFrame,
7    /// First Frame (FF): Indicates the start of a multi-frame message (> 7 bytes).
8    /// PCI byte range: 0x10-0x1F.
9    FirstFrame,
10    /// Consecutive Frame (CF): Contains the continuation of a multi-frame message.
11    /// PCI byte range: 0x20-0x2F.
12    ConsecutiveFrame,
13    /// Flow Control (FC): Used for flow control to regulate the transmission of consecutive frames.
14    /// PCI byte range: 0x30-0x3F.
15    FlowControl,
16}
17
18/// Represents a PCI byte, which consists of a PCI type and an associated value.
19#[derive(Debug, Clone, Copy)]
20pub struct PciByte {
21    /// The type of PCI frame.
22    pub pci_type: PciType,
23    /// The actual PCI byte value.
24    pub value: u8,
25}
26
27/// Implements conversion from `PciByte` to `u8`, encoding the PCI type and value into a single byte.
28impl From<PciByte> for u8 {
29    fn from(pci_byte: PciByte) -> Self {
30        match pci_byte.pci_type {
31            PciType::SingleFrame => pci_byte.value & 0x0F, // Mask with 0x0F for SF.
32            PciType::FirstFrame => 0x10 | (pci_byte.value & 0x0F), // Set the first nibble to 0x1.
33            PciType::ConsecutiveFrame => 0x20 | (pci_byte.value & 0x0F), // Set the first nibble to 0x2.
34            PciType::FlowControl => 0x30 | (pci_byte.value & 0x0F), // Set the first nibble to 0x3.
35        }
36    }
37}
38
39/// Implementation for PCI byte handling based on ISO 15765-2 (CAN TP).
40impl PciByte {
41    /// Creates a new `PciByte` instance with the specified PCI type and value.
42    pub fn new(pci_type: PciType, value: u8) -> Self {
43        Self { pci_type, value }
44    }
45
46    /// Returns the PCI type of this byte.
47    pub fn get_type(&self) -> PciType {
48        self.pci_type
49    }
50
51    /// Returns the raw value of this PCI byte.
52    pub fn get_value(&self) -> u8 {
53        self.value
54    }
55
56    /// Encodes the PCI byte into a single `u8` value according to the CAN TP specification.
57    pub fn as_byte(&self) -> u8 {
58        match self.pci_type {
59            PciType::SingleFrame => self.value & 0x0F, // Mask to get the lower 4 bits.
60            PciType::FirstFrame => 0x10 | (self.value & 0x0F), // OR with 0x10 for FF.
61            PciType::ConsecutiveFrame => 0x20 | (self.value & 0x0F), // OR with 0x20 for CF.
62            PciType::FlowControl => 0x30 | (self.value & 0x0F), // OR with 0x30 for FC.
63        }
64    }
65}