Source code for uds.messages.uds_packet

"""
Module with common implementation of UDS packets for all bus types.

:ref:`UDS Packets <knowledge-base-uds-packet>` are defined on middle layers of UDS OSI Model.
"""

__all__ = ["AbstractUdsPacketType", "AbstractUdsPacket", "AbstractUdsPacketRecord",
           "PacketTyping", "PacketsTuple", "PacketsSequence",
           "PacketsDefinitionTuple", "PacketsDefinitionSequence",
           "PacketsRecordsTuple", "PacketsRecordsSequence",
           "PacketTypesTuple"]

from abc import ABC, abstractmethod
from typing import Union, Tuple, List, Any

from uds.utilities import NibbleEnum, ValidatedEnum, ExtendableEnum, \
    RawBytes, RawBytesTuple, validate_raw_bytes,\
    ReassignmentError, TimeStamp
from .transmission_attributes import AddressingMemberTyping, AddressingType, \
    TransmissionDirection, DirectionMemberTyping


[docs]class AbstractUdsPacketType(NibbleEnum, ValidatedEnum, ExtendableEnum): """ Abstract definition of UDS packet type. Packet type information is carried by :ref:`Network Protocol Control Information (N_PCI) <knowledge-base-n-pci>`. Enums with packet types (N_PCI) values for certain buses (e.g. CAN, LIN, FlexRay) must inherit after this class. Note: There are some differences in values for each bus (e.g. LIN does not use Flow Control). """
[docs] @classmethod @abstractmethod def is_initial_packet_type(cls, value: Any) -> bool: # type: ignore """ Check whether given argument is a member or a value of packet type that initiates a diagnostic message. :param value: Value to check. :return: True if given argument is a packet type that initiates a diagnostic message, else False. """ cls.validate_member(value)
[docs]class AbstractUdsPacket(ABC): """Abstract definition of UDS Packet (Network Protocol Data Unit - N_PDU).""" def __init__(self, raw_data: RawBytes, addressing: AddressingMemberTyping) -> None: """ Create a storage for a single UDS packet. :param raw_data: Raw bytes of UDS packet data. :param addressing: Addressing type for which this packet is relevant. """ self.raw_data = raw_data # type: ignore self.addressing = addressing # type: ignore @property def addressing(self) -> AddressingType: """Addressing type for which this packet is relevant.""" return self.__addressing @addressing.setter def addressing(self, value: AddressingMemberTyping): """ Set value of addressing type attribute. :param value: Value of addressing type to set. """ AddressingType.validate_member(value) self.__addressing = AddressingType(value) @property def raw_data(self) -> RawBytesTuple: """Raw bytes of data that this packet carries.""" return self.__raw_data @raw_data.setter def raw_data(self, value: RawBytes): """ Set value of raw bytes of data. :param value: Raw bytes of data to be carried by this packet. """ validate_raw_bytes(value) self.__raw_data = tuple(value) @property # noqa: F841 @abstractmethod def packet_type(self) -> AbstractUdsPacketType: """UDS packet type value - N_PCI value of this N_PDU."""
[docs]class AbstractUdsPacketRecord(ABC): """Abstract definition of a storage for historic information about transmitted or received UDS Packet.""" @abstractmethod def __init__(self, frame: object, direction: DirectionMemberTyping) -> None: """ Create a record of a historic information about a packet that was either received or transmitted. :param frame: Frame that carried this UDS packet. :param direction: Information whether this packet was transmitted or received. """ self.frame = frame self.direction = direction # type: ignore @abstractmethod def __validate_frame(self, value: Any) -> None: """ Validate whether the argument contains value with a frame object. :param value: Value to validate. :raise TypeError: The frame argument has other type than expected. :raise ValueError: Some attribute of the frame argument is missing or its value is unexpected. """ @property def frame(self) -> object: """Frame that carried this packet.""" return self.__frame @frame.setter def frame(self, value: DirectionMemberTyping): """ Set value of frame attribute. :param value: Frame value to set. :raise ReassignmentError: There is a call to change the value after the initial assignment (in __init__). """ try: self.__getattribute__("_AbstractUdsPacketRecord__frame") except AttributeError: self.__validate_frame(value) self.__frame = value else: raise ReassignmentError("You cannot change value of 'frame' attribute once it is assigned.") @property def direction(self) -> TransmissionDirection: """Information whether this packet was transmitted or received.""" return self.__direction @direction.setter def direction(self, value: DirectionMemberTyping): """ Set value of direction attribute. :param value: Direction value to set. :raise ReassignmentError: There is a call to change the value after the initial assignment (in __init__). """ try: self.__getattribute__("_AbstractUdsPacketRecord__direction") except AttributeError: TransmissionDirection.validate_member(value) self.__direction = TransmissionDirection(value) else: raise ReassignmentError("You cannot change value of 'direction' attribute once it is assigned.") @property @abstractmethod def raw_data(self) -> RawBytesTuple: """Raw bytes of data that this packet carried.""" @property @abstractmethod def addressing(self) -> AddressingType: """Addressing type over which this packet was transmitted.""" @property # noqa: F841 @abstractmethod def transmission_time(self) -> TimeStamp: """Time stamp when this packet was fully transmitted on a bus.""" @property # noqa: F841 @abstractmethod def packet_type(self) -> AbstractUdsPacketType: """UDS packet type value - N_PCI value of this N_PDU."""
PacketTypesTuple = Tuple[AbstractUdsPacketType, ...] """Typing alias of a tuple filled with :class:`~uds.messages.uds_packet.AbstractUdsPacketType` members.""" PacketsDefinitionTuple = Tuple[AbstractUdsPacket, ...] """Typing alias of a tuple filled with :class:`~uds.messages.uds_packet.AbstractUdsPacket` instances.""" PacketsDefinitionSequence = Union[PacketsDefinitionTuple, List[AbstractUdsPacket]] """Typing alias of a sequence filled with :class:`~uds.messages.uds_packet.AbstractUdsPacket` instances.""" PacketsRecordsTuple = Tuple[AbstractUdsPacketRecord, ...] """Typing alias of a tuple filled with :class:`~uds.messages.uds_packet.AbstractUdsPacketRecord` instances.""" PacketsRecordsSequence = Union[PacketsRecordsTuple, List[AbstractUdsPacketRecord]] """Typing alias of a sequence filled with :class:`~uds.messages.uds_packet.AbstractUdsPacketRecord` instances.""" PacketTyping = Union[AbstractUdsPacket, AbstractUdsPacketRecord] """Typing alias of UDS packet.""" PacketsTuple = Union[PacketsDefinitionTuple, PacketsRecordsTuple] # noqa: F841 """Typing alias of a tuple filled with UDS packets.""" PacketsSequence = Union[PacketsDefinitionSequence, PacketsRecordsSequence] """Typing alias of a sequence filled with UDS packets."""