How to use the udsoncan.DidCodec function in udsoncan

To help you get started, we’ve selected a few udsoncan examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github pylessard / python-udsoncan / test / client / test_read_data_by_identifier.py View on Github external
from udsoncan.client import Client
from udsoncan import services
from udsoncan.exceptions import *
from udsoncan import DidCodec, AsciiCodec
import struct

from test.ClientServerTest import ClientServerTest


class StubbedDidCodec(DidCodec):
    def encode(self, did_value):
        return struct.pack('B', did_value+1)

    def decode(self, did_payload):
        return struct.unpack('B', did_payload)[0] - 1

    def __len__(self):
        return 1

class TestReadDataByIdentifier(ClientServerTest):
    def __init__(self, *args, **kwargs):
        ClientServerTest.__init__(self, *args, **kwargs)

    def postClientSetUp(self):
        self.udsclient.config["data_identifiers"] = {
                1 : '>H',
github pylessard / python-udsoncan / test / test_helper_class.py View on Github external
def test_DIDCodec_bad_values(self):
        with self.assertRaises(NotImplementedError):
            codec = DidCodec();
            codec.encode("asd")

        with self.assertRaises(NotImplementedError):
            codec = DidCodec();
            codec.decode(b"asd")

        with self.assertRaises(ValueError):
            DidCodec.from_config("")
github pylessard / python-udsoncan / test / client / test_io_control.py View on Github external
from udsoncan import IOValues, IOMasks
import struct

from test.ClientServerTest import ClientServerTest

class StubbedCodec(DidCodec):
    def encode(self, did_value):
        return struct.pack('B', did_value+1)

    def decode(self, did_payload):
        return struct.unpack('B', did_payload)[0] - 1

    def __len__(self):
        return 1

class StubbedCompositeCodec(DidCodec):
    def encode(self, IAC_pintle, rpm, pedalA, pedalB, EGR_duty):
        pedal = (pedalA << 4) | pedalB
        return struct.pack('>BHBB', IAC_pintle, rpm, pedal, EGR_duty)

    def decode(self, payload):
        vals = struct.unpack('>BHBB', payload)
        return {
                'IAC_pintle': vals[0],
                'rpm' 		: vals[1],
                'pedalA' 	: (vals[2] >> 4) & 0xF,
                'pedalB' 	: vals[2] & 0xF,
                'EGR_duty' 	: vals[3]
        }

    def __len__(self):
        return 5
github pylessard / python-udsoncan / testconfig.py View on Github external
import struct
from udsoncan import DidCodec

def test_algo(seed):
	key = bytearray(seed)
	for i in range(len(key)):
		key[i] ^= 0xFF	
	return key

class MyDidCodec(DidCodec):
	def encode(self, did_value):
		return struct.pack('B', did_value+1)

	def decode(self, did_payload):
		return struct.unpack('B', did_payload)[0] - 1

	def __len__(self):
		return 1

client_config  = {
	'security_algo' : test_algo,
	'data_identifiers' : {
		1 : '>H',
		2 : '
github pylessard / python-udsoncan / test / client / test_write_data_by_identifier.py View on Github external
from udsoncan.client import Client
from udsoncan import services
from udsoncan.exceptions import *
from udsoncan import DidCodec
import struct

from test.ClientServerTest import ClientServerTest


class StubbedDidCodec(DidCodec):
    def encode(self, did_value):
        return struct.pack('B', did_value+1)

    def decode(self, did_payload):
        return struct.unpack('B', did_payload)[0] - 1

    def __len__(self):
        return 1

class StubbedCodecThatExpectTuple(DidCodec):
    def encode(self, the_tuple):
        if not isinstance(the_tuple, tuple):
            raise ValueError('Given value is not a tuple')
        return struct.pack('BB', the_tuple[0], the_tuple[1])

    def decode(self, did_payload):
github pylessard / python-udsoncan / test / client / test_io_control.py View on Github external
from udsoncan.client import Client
from udsoncan import services
from udsoncan.exceptions import *
from udsoncan import DidCodec
from udsoncan import IOValues, IOMasks
import struct

from test.ClientServerTest import ClientServerTest

class StubbedCodec(DidCodec):
    def encode(self, did_value):
        return struct.pack('B', did_value+1)

    def decode(self, did_payload):
        return struct.unpack('B', did_payload)[0] - 1

    def __len__(self):
        return 1

class StubbedCompositeCodec(DidCodec):
    def encode(self, IAC_pintle, rpm, pedalA, pedalB, EGR_duty):
        pedal = (pedalA << 4) | pedalB
        return struct.pack('>BHBB', IAC_pintle, rpm, pedal, EGR_duty)

    def decode(self, payload):
        vals = struct.unpack('>BHBB', payload)
github pylessard / python-udsoncan / udsoncan / services / WriteDataByIdentifier.py View on Github external
:param value: Value given to the :ref:`DidCodec `.encode method. If involved codec is defined with a pack string (default codec), multiple values may be passed with a tuple.
        :type value: object

        :param didconfig: Definition of DID codecs. Dictionary mapping a DID (int) to a valid :ref:`DidCodec ` class or pack/unpack string 
        :type didconfig: dict[int] = :ref:`DidCodec `

        :raises ValueError: If parameters are out of range, missing or wrong type
        :raises ConfigError: If ``didlist`` contains a DID not defined in ``didconfig``
        """	

        from udsoncan import Request, DidCodec
        ServiceHelper.validate_int(did, min=0, max=0xFFFF, name='Data Identifier')
        req = Request(cls)
        didconfig = ServiceHelper.check_did_config(did, didconfig=didconfig)	# Make sure all DIDs are correctly defined in client config
        req.data = struct.pack('>H', did)	# encode DID number
        codec = DidCodec.from_config(didconfig[did])
        if codec.__class__ == DidCodec and isinstance(value, tuple):
            req.data += codec.encode(*value)    # Fixes issue #29
        else:
            req.data += codec.encode(value)

        return req
github pylessard / python-udsoncan / udsoncan / services / ReadDTCInformation.py View on Github external
# For each DID
                for i in range(number_of_did):
                    remaining_data = response.data[actual_byte:]
                    snapshot = Dtc.Snapshot()	# One snapshot epr DID for convenience
                    snapshot.record_number = record_number

                    # As standard does not specify the length of the DID, we craft it based on a config 
                    did = 0
                    for j in range(dtc_snapshot_did_size):
                        offset = dtc_snapshot_did_size-1-j
                        did |= (remaining_data[offset] << (8*j))

                    # Decode the data based on DID number.
                    snapshot.did = did
                    didconfig = ServiceHelper.check_did_config(did, didconfig)
                    codec = DidCodec.from_config(didconfig[did])

                    data_offset =  dtc_snapshot_did_size;
                    if len(remaining_data[data_offset:]) < len(codec):
                        raise InvalidResponseException(response, 'Incomplete response. Data for DID 0x%04x is only %d bytes while %d bytes is expected' % (did, len(remaining_data[data_offset:]), len(codec)))

                    snapshot.raw_data = remaining_data[data_offset:data_offset + len(codec)]
                    snapshot.data = codec.decode(snapshot.raw_data)

                    dtc.snapshots.append(snapshot)

                    actual_byte += dtc_snapshot_did_size + len(codec)

                response.service_data.dtcs.append(dtc)
            response.service_data.dtc_count = len(response.service_data.dtcs)

        # These subfunctions include DTC ExtraData. We give it raw to user.
github pylessard / python-udsoncan / udsoncan / services / ReadDataByIdentifier.py View on Github external
break	# Done

            if len(response.data) <= offset +1:
                if tolerate_zero_padding and response.data[-1] == 0:	# One extra byte, but it's a 0 and we accept that. So we're done
                    break
                raise InvalidResponseException(response, "Response given by server is incomplete.")

            did = struct.unpack('>H', response.data[offset:offset+2])[0]	# Get the DID number
            if did == 0 and did not in didconfig and tolerate_zero_padding: # We read two zeros and that is not a DID bu we accept that. So we're done.
                if response.data[offset:] == b'\x00' * (len(response.data) - offset):
                    break

            if did not in didconfig:	# Already checked in check_did_config. Paranoid check
                raise ConfigError(key=did, msg='Actual data identifier configuration contains no definition for data identifier 0x%04x' % did)

            codec = DidCodec.from_config(didconfig[did])
            offset+=2

            if len(response.data) < offset+len(codec):
                raise InvalidResponseException(response, "Value for data identifier 0x%04x was incomplete according to definition in configuration" % did)

            subpayload = response.data[offset:offset+len(codec)]
            offset += len(codec)	# Codec must define a __len__ function that matches the encoded payload length.
            val = codec.decode(subpayload)
            response.service_data.values[did] = val

        return response
github pylessard / python-udsoncan / udsoncan / services / InputOutputControlByIdentifier.py View on Github external
raise ValueError("masks must be an instance of IOMask or a boolean value")

        if values is None and masks is not None:
            raise ValueError('An IOValue must be given if a IOMask is provided.')	

        request = Request(service=cls)		

        request.data = b''
        ioconfig = ServiceHelper.check_io_config(did, ioconfig)	# IO dids are defined in client config.
        request.data += struct.pack('>H', did)

        # This parameter is optional according to standard
        if control_param is not None:
            request.data += struct.pack('B', control_param)

        codec = DidCodec.from_config(ioconfig[did])	# Get IO codec from config

        if values is not None:
            request.data += codec.encode(*values.args, **values.kwargs)

        if masks is not None: # Skip the masks byte if none is given.
            if isinstance(masks, bool):
                byte = b'\xFF' if masks == True else b'\x00'
                if 'mask_size' in  ioconfig[did]:
                    request.data += (byte * ioconfig[did]['mask_size'])
                else:
                    raise ConfigError('mask_size', msg='Given mask is boolean value, indicating that all mask should be set to same value, but no mask_size is defined in configuration. Cannot guess how many bits to set.')

            elif isinstance(masks, IOMasks):
                if 'mask' not in ioconfig[did]:
                    raise ConfigError('mask', msg='Cannot apply given mask. Input/Output configuration does not define their position (and size).')
                masks_config = ioconfig[did]['mask']