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}