Source code for udsoncan.services.TransferData

import struct
from udsoncan.Request import Request
from udsoncan.Response import Response
from udsoncan.BaseService import BaseService, BaseResponseData
from udsoncan.ResponseCode import ResponseCode
from udsoncan.exceptions import *
import udsoncan.tools as tools

from typing import Optional, cast


class TransferData(BaseService):
    _sid = 0x36
    _use_subfunction = False

    supported_negative_response = [ResponseCode.IncorrectMessageLengthOrInvalidFormat,
                                   ResponseCode.RequestSequenceError,
                                   ResponseCode.RequestOutOfRange,
                                   ResponseCode.TransferDataSuspended,
                                   ResponseCode.GeneralProgrammingFailure,
                                   ResponseCode.WrongBlockSequenceCounter,
                                   ResponseCode.VoltageTooHigh,
                                   ResponseCode.VoltageTooLow
                                   ]

[docs] class ResponseData(BaseResponseData): """ .. data:: sequence_number_echo Requests subfunction echoed back by the server .. data:: parameter_records Optional additional data associated with the response. """ sequence_number_echo: int parameter_records: bytes def __init__(self, sequence_number_echo: int, parameter_records: bytes): super().__init__(TransferData) self.sequence_number_echo = sequence_number_echo self.parameter_records = parameter_records
class InterpretedResponse(Response): service_data: "TransferData.ResponseData"
[docs] @classmethod def make_request(cls, sequence_number: int, data: Optional[bytes] = None) -> Request: """ Generates a request for TransferData :param sequence_number: Corresponds to an 8bit counter that should increment for each new block transferred. Allowed values are from 0 to 0xFF :type sequence_number: int :param data: Optional additional data to send to the server :type data: bytes :raises ValueError: If parameters are out of range, missing or wrong type """ tools.validate_int(sequence_number, min=0, max=0xFF, name='Block sequence counter') # Not a subfunction! if data is not None and not isinstance(data, bytes): raise ValueError('data must be a bytes object') request = Request(service=cls) request.data = struct.pack('B', sequence_number) if data is not None: request.data += data return request
[docs] @classmethod def interpret_response(cls, response: Response) -> InterpretedResponse: """ Populates the response ``service_data`` property with an instance of :class:`TransferData.ResponseData<udsoncan.services.TransferData.ResponseData>` :param response: The received response to interpret :type response: :ref:`Response<Response>` :raises InvalidResponseException: If length of ``response.data`` is too short """ if response.data is None: raise InvalidResponseException(response, "No data in response") if len(response.data) < 1: raise InvalidResponseException(response, "Response data must be at least 1 bytes") response.service_data = cls.ResponseData( sequence_number_echo=response.data[0], parameter_records=response.data[1:] if len(response.data) > 1 else bytes() ) return cast(TransferData.InterpretedResponse, response)