def _test_read_file_extra_bytes_response_zero_padding_not_ok(self):
     self.udsclient.config['tolerate_zero_padding'] = False
     with self.assertRaises(InvalidResponseException):
         self.udsclient.read_file("my_file.txt", dfi= DataFormatIdentifier(compression=5, encryption=2))
 def _test_read_file_invalid_length(self):
     for i in range(11):
         with self.assertRaises(InvalidResponseException):
             self.udsclient.read_file("my_file.txt", dfi= DataFormatIdentifier(compression=5, encryption=2))
 def _test_read_file_extra_bytes_response(self):
     with self.assertRaises(InvalidResponseException):
         self.udsclient.read_file("my_file.txt", dfi= DataFormatIdentifier(compression=5, encryption=2))
 def _test_read_file_bad_moop_echo_no_exception(self):
     self.udsclient.config['exception_on_unexpected_response'] = False        
     response = self.udsclient.read_file("my_file.txt", dfi= DataFormatIdentifier(compression=5, encryption=2))
     self.assertTrue(response.valid)
     self.assertTrue(response.positive)
     self.assertTrue(response.unexpected)
 def _test_read_file_zerolen_length_fsodipl(self):
     with self.assertRaises(InvalidResponseException):
         self.udsclient.read_file("my_file.txt", dfi= DataFormatIdentifier(compression=5, encryption=2))            
    def interpret_response(cls, response, tolerate_zero_padding=True):
        """
        Populates the response ``service_data`` property with an instance of :class:`RequestFileTransfer.ResponseData<udsoncan.services.RequestFileTransfer.ResponseData>`

        :param response: The received response to interpret
        :type response: :ref:`Response<Response>`

        :raises InvalidResponseException: If length of ``response.data`` is too short or payload does not respect ISO-14229 specifications
        :raises NotImplementedError: If the MaxNumberOfBlock or fileSizeUncompressedOrDirInfoLength value is encoded over more than 8 bytes.
        """
        from udsoncan import Filesize, DataFormatIdentifier
        response.service_data = cls.ResponseData()
        if len(response.data) < 1:
            raise InvalidResponseException(
                response, 'Response payload must be at least 1 byte long')
        response.service_data.moop_echo = int(response.data[0])

        has_lfid = response.service_data.moop_echo in [
            cls.ModeOfOperation.AddFile, cls.ModeOfOperation.ReplaceFile,
            cls.ModeOfOperation.ReadFile, cls.ModeOfOperation.ReadDir
        ]
        has_dfi = response.service_data.moop_echo in [
            cls.ModeOfOperation.AddFile, cls.ModeOfOperation.ReplaceFile,
            cls.ModeOfOperation.ReadFile, cls.ModeOfOperation.ReadDir
        ]
        has_filesize_length = response.service_data.moop_echo in [
            cls.ModeOfOperation.ReadFile, cls.ModeOfOperation.ReadDir
        ]
        has_uncompressed_filesize = response.service_data.moop_echo in [
            cls.ModeOfOperation.ReadFile, cls.ModeOfOperation.ReadDir
        ]
        has_compressed_filesize = response.service_data.moop_echo in [
            cls.ModeOfOperation.ReadFile
        ]

        cursor = 1
        if has_lfid:
            if len(response.data) < 2:
                raise InvalidResponseException(
                    response,
                    'Response payload must be at least 2 byte long for Mode of operation %d'
                    % response.service_data.moop_echo)
            lfid = int(response.data[1])
            cursor = 2

            if lfid > 8:
                raise NotImplementedError(
                    'This client does not support number bigger than %d bits, but MaxNumberOfBlock is encoded on %d bits'
                    % ((8 * 8), (lfid * 8)))

            if lfid == 0:
                raise InvalidResponseException(
                    response,
                    'Received a MaxNumberOfBlockLength of 0 which is impossible'
                )

            if len(response.data) < 2 + lfid:
                raise InvalidResponseException(
                    response,
                    'Response payload says that MaxNumberOfBlock is encoded on %d bytes, but only %d bytes are present'
                    % (lfid, (len(response.data) - 2)))

            todecode = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
            for i in range(1, lfid + 1):
                todecode[-i] = response.data[cursor + lfid - i]
            response.service_data.max_length = struct.unpack('>q', todecode)[0]
            cursor += lfid

        if has_dfi:
            if len(response.data) < cursor + 1:
                raise InvalidResponseException(
                    response,
                    'Missing DataFormatIdentifier in received response')

            response.service_data.dfi = DataFormatIdentifier.from_byte(
                response.data[cursor])
            cursor += 1
            dfi = response.service_data.dfi.get_byte_as_int()

            if response.service_data.moop_echo == cls.ModeOfOperation.ReadDir and dfi != 0:
                raise InvalidResponseException(
                    response,
                    'DataFormatIdentifier for ReadDir can only be 0x00 as per ISO-14229, but its value was set to 0x%02x'
                    % (dfi))

        if has_filesize_length:
            if len(response.data) < cursor + 2:
                raise InvalidResponseException(
                    response,
                    'Missing or incomplete FileSizeOrDirInfoParameterLength in received response'
                )
            fsodipl = struct.unpack('>H', response.data[cursor:cursor + 2])[0]
            cursor += 2

            if fsodipl > 8:
                raise NotImplementedError(
                    response,
                    'This client does not support number bigger than %d bits, but FileSizeOrDirInfoLength is encoded on %d bits'
                    % ((8 * 8), (fsodipl * 8)))

            if fsodipl == 0:
                raise InvalidResponseException(
                    response,
                    'Received a FileSizeOrDirInfoParameterLength of 0 which is impossible'
                )

            if has_uncompressed_filesize:
                if len(response.data) < cursor + fsodipl:
                    raise InvalidResponseException(
                        response,
                        'Missing or incomplete fileSizeUncompressedOrDirInfoLength in received response'
                    )

                todecode = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
                for i in range(1, lfid + 1):
                    todecode[-i] = response.data[cursor + fsodipl - i]
                uncompressed_size = struct.unpack('>q', todecode)[0]
                cursor += fsodipl
            else:
                uncompressed_size = None

            if has_compressed_filesize:
                if len(response.data) < cursor + fsodipl:
                    raise InvalidResponseException(
                        response,
                        'Missing or incomplete fileSizeCompressed in received response'
                    )

                todecode = bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')
                for i in range(1, lfid + 1):
                    todecode[-i] = response.data[cursor + fsodipl - i]
                compressed_size = struct.unpack('>q', todecode)[0]
                cursor += fsodipl
            else:
                compressed_size = None

        if has_uncompressed_filesize and response.service_data.moop_echo == cls.ModeOfOperation.ReadDir:
            response.service_data.dirinfo_length = uncompressed_size
        else:
            if has_uncompressed_filesize or has_compressed_filesize:
                response.service_data.filesize = Filesize(
                    uncompressed=uncompressed_size, compressed=compressed_size)

        if len(response.data) > cursor:
            if response.data[cursor:] == b'\x00' * (
                    len(response.data) - cursor) and tolerate_zero_padding:
                pass
            else:
                raise InvalidResponseException(
                    response,
                    'Response payload has extra data that has no meaning')

        response.service_data = response.service_data
 def _test_read_file_bad_moop_echo(self):
     with self.assertRaises(UnexpectedResponseException):
         self.udsclient.read_file("my_file.txt", dfi= DataFormatIdentifier(compression=5, encryption=2))
 def _test_replace_file_extra_bytes_response_zero_padding_not_ok(self):
     self.udsclient.config['tolerate_zero_padding'] = False
     with self.assertRaises(InvalidResponseException):
         self.udsclient.replace_file("my_file.txt", dfi= DataFormatIdentifier(compression=5, encryption=2), filesize = Filesize(uncompressed=0x222, compressed=0x111, width=4))              
 def _test_read_file_negative_response(self):
     with self.assertRaises(NegativeResponseException):
         self.udsclient.read_file("my_file.txt", dfi= DataFormatIdentifier(compression=5, encryption=2))
 def _test_replace_file_negative_response_no_exception(self):
     self.udsclient.config['exception_on_negative_response'] = False
     response = self.udsclient.replace_file("my_file.txt", dfi= DataFormatIdentifier(compression=5, encryption=2), filesize = Filesize(uncompressed=0x222, compressed=0x111, width=4))
     self.assertTrue(response.valid)
     self.assertFalse(response.positive)           
 def _test_replace_file_extra_bytes_response(self):
     with self.assertRaises(InvalidResponseException):
         self.udsclient.replace_file("my_file.txt", dfi= DataFormatIdentifier(compression=5, encryption=2), filesize = Filesize(uncompressed=0x222, compressed=0x111, width=4))              
 def test_str_repr(self):
     dfi = DataFormatIdentifier(compression=1, encryption=2)
     str(dfi)
     dfi.__repr__()
 def test_dfi2(self):
     dfi = DataFormatIdentifier(compression=15, encryption=15)
     self.assertEqual(dfi.get_byte(), b'\xFF')
 def test_dfi(self):
     dfi = DataFormatIdentifier(compression=1, encryption=2)
     self.assertEqual(dfi.get_byte(), b'\x12')
 def _test_add_file_bad_dfi(self):
     with self.assertRaises(UnexpectedResponseException):
         self.udsclient.add_file("my_file.txt", dfi= DataFormatIdentifier(compression=5, encryption=2), filesize = 0x100)
 def _test_read_file_negative_response_no_exception(self):
     self.udsclient.config['exception_on_negative_response'] = False
     response = self.udsclient.read_file("my_file.txt", dfi= DataFormatIdentifier(compression=5, encryption=2))
     self.assertTrue(response.valid)
     self.assertFalse(response.positive)           
Exemple #17
0
	def _test_request_download_success_dfi(self):
		memloc = MemoryLocation(address=0x1234, memorysize=0xFF, address_format=16, memorysize_format=8)
		dfi  =DataFormatIdentifier(compression=5, encryption=2)
		response = self.udsclient.request_download(memory_location=memloc, dfi=dfi)
		self.assertEqual(response.service_data.max_length,0xabcd)
Exemple #18
0
 def test_from_byte(self):
     dfi = DataFormatIdentifier.from_byte(0xAB)
     self.assertEqual(dfi.compression, 0xA)
     self.assertEqual(dfi.encryption, 0xB)