def test_addr_claim_fixed(self): """Test CA Address claim on the bus with fixed address This test runs a "Single Address Capable" claim procedure with a fixed address of 128. """ self.can_messages = [ (TestCA.MsgType.CANTX, 0x18EEFF80, [83, 54, 201, 130, 83, 82, 214, 135], 0.0), # Address Claimed ] name = j1939.Name(arbitrary_address_capable=0, industry_group=j1939.Name.IndustryGroup.Industrial, vehicle_system_instance=2, vehicle_system=155, function=201, function_instance=16, ecu_instance=2, manufacturer_code=666, identity_number=1234567) # create new CA on the bus with given NAME and ADDRESS new_ca = self.ecu.add_ca(name=name, device_address=128) # by starting the CA it announces the given ADDRESS on the bus new_ca.start() # wait until all messages are processed asynchronously while len(self.can_messages) > 0: time.sleep(0.500) # wait for final processing time.sleep(0.500) self.assertEqual(new_ca.state, j1939.ControllerApplication.State.NORMAL)
def _process_addressclaim(self, mid, data, timestamp): """Processes an address claim message :param j1939.MessageId mid: A MessageId object holding the information extracted from the can_id. :param bytearray data: The data contained in the can-message. :param float timestamp: The timestamp the message was received (mostly) in fractions of Epoch-Seconds. """ src_address = mid.source_address logger.debug("Received ADDRESS CLAIMED message from source '%d'", src_address) # are we awaiting this address claimed message? if (0 or (self._device_address_state == ControllerApplication.State.NORMAL and src_address == self._device_address) or (self._device_address_state == ControllerApplication.State.WAIT_VETO and src_address == self._device_address_announced) ): logger.info("Received ADDRESS CLAIMED message with conflicting address '%d'", src_address) contenders_name = j1939.Name(bytes = data) if self._name.value > contenders_name.value: # we have to release our address and claim another one logger.info("We have to release our address '%d' because the contenders name is less than ours", src_address) # TODO: are there any state variables we have to care about? self._device_address = j1939.ParameterGroupNumber.Address.NULL # TODO: maybe we should call an overloadable function here if self._name.arbitrary_address_capable == False: # bad luck logger.error("After releasing our address we are configured to stop operation (CANNOT CLAIM)") self._device_address_state = ControllerApplication.State.CANNOT_CLAIM self._device_address = None self._send_address_claimed(j1939.ParameterGroupNumber.Address.NULL) # send CANNOT CLAIM else: # TODO: we should check the address range here self._device_address_announced += 1 logger.info("Try the next address '%d'", self._device_address_announced) self._send_address_claimed(self._device_address_announced) # TODO: it's not possible to set the VETO-Timeout from here self._device_address_state = ControllerApplication.State.WAIT_VETO else: # we have higher prio - repeat our claim message logger.info("Contender lost the competition - we can keep our address") if self._device_address_state == ControllerApplication.State.NORMAL: # we own our address already self._send_address_claimed(self._device_address) else: # we are in the middle of the claim-process self._send_address_claimed(self._device_address_announced)
def main(): print("Initializing") # create the ElectronicControlUnit (one ECU can hold multiple ControllerApplications) ecu = j1939.ElectronicControlUnit() # Connect to the CAN bus # Arguments are passed to python-can's can.interface.Bus() constructor # (see https://python-can.readthedocs.io/en/stable/bus.html). # ecu.connect(bustype='socketcan', channel='can0') # ecu.connect(bustype='kvaser', channel=0, bitrate=250000) ecu.connect(bustype='pcan', channel='PCAN_USBBUS1', bitrate=250000) # ecu.connect(bustype='ixxat', channel=0, bitrate=250000) # ecu.connect(bustype='vector', app_name='CANalyzer', channel=0, bitrate=250000) # ecu.connect(bustype='nican', channel='CAN0', bitrate=250000) # subscribe to all (global) messages on the bus ecu.subscribe(on_message) # name descriptor for the ca CA_NAME = j1939.Name(arbitrary_address_capable=0, industry_group=j1939.Name.IndustryGroup.Industrial, vehicle_system_instance=1, vehicle_system=1, function=1, function_instance=1, ecu_instance=1, manufacturer_code=666, identity_number=1234567) ca = j1939.ControllerApplication(CA_NAME, 0xF1) # add CA to the ECU ecu.add_ca(controller_application=ca) # by starting the CA it starts the address claiming procedure on the bus ca.start() # create the instance of the Dm1 to be able to receive active DTCs Dm1_rec = j1939.Dm1(ca) # subscribe to DM1-messages on the bus Dm1_rec.subscribe(dm1_receive) # create the instance of the Dm1 to be able to send active DTCs Dm1_snd = j1939.Dm1(ca) # start sending Dm1-message from source-id 10 Dm1_snd.start_send(callback=dm1_before_send) time.sleep(120) print("Deinitializing") ecu.disconnect()
def test_addr_claim_arbitrary_veto_lose(self): """Test CA Address claim on the bus with arbitrary capability a veto counterpart This test runs a "Arbitrary Address Capable" claim procedure with an address of 128. A counterpart on the bus declines the address claimed message with a veto and we lose our address. Our device should claim the next address (129) automatically. """ self.can_messages = [ (TestCA.MsgType.CANTX, 0x18EEFF80, [211, 54, 201, 130, 83, 82, 214, 135], 0.0), # Address Claimed 128 (TestCA.MsgType.CANRX, 0x18EEFF80, [83, 54, 111, 130, 83, 82, 214, 135], 0.0), # Veto from Counterpart with lower name (TestCA.MsgType.CANTX, 0x18EEFF81, [211, 54, 201, 130, 83, 82, 214, 135], 0.0), # Address Claimed 129 ] name = j1939.Name(arbitrary_address_capable=1, industry_group=j1939.Name.IndustryGroup.Industrial, vehicle_system_instance=2, vehicle_system=155, function=201, function_instance=16, ecu_instance=2, manufacturer_code=666, identity_number=1234567) # create new CA on the bus with given NAME and ADDRESS new_ca = self.ecu.add_ca(name=name, device_address=128) # by starting the CA it announces the given ADDRESS on the bus new_ca.start() # wait until all messages are processed asynchronously while len(self.can_messages) > 0: time.sleep(0.500) # wait for final processing time.sleep(0.500) self.assertEqual(new_ca.state, j1939.ControllerApplication.State.NORMAL)
def main(): print("Initializing") # create the ElectronicControlUnit (one ECU can hold multiple ControllerApplications) ecu = j1939.ElectronicControlUnit() # Connect to the CAN bus # Arguments are passed to python-can's can.interface.Bus() constructor # (see https://python-can.readthedocs.io/en/stable/bus.html). # ecu.connect(bustype='socketcan', channel='can0') # ecu.connect(bustype='kvaser', channel=0, bitrate=250000) ecu.connect(bustype='pcan', channel='PCAN_USBBUS1', bitrate=250000) # ecu.connect(bustype='ixxat', channel=0, bitrate=250000) # ecu.connect(bustype='vector', app_name='CANalyzer', channel=0, bitrate=250000) # ecu.connect(bustype='nican', channel='CAN0', bitrate=250000) # ecu.connect('testchannel_1', bustype='virtual') # compose the name descriptor for the new ca name = j1939.Name(arbitrary_address_capable=0, industry_group=j1939.Name.IndustryGroup.Industrial, vehicle_system_instance=1, vehicle_system=1, function=1, function_instance=1, ecu_instance=1, manufacturer_code=666, identity_number=1234567) # create derived CA with given NAME and ADDRESS ca = OwnCaToProduceCyclicMessages(name, 128) # add CA to the ECU ecu.add_ca(controller_application=ca) # by starting the CA it starts the address claiming procedure on the bus ca.start() time.sleep(120) print("Deinitializing") ca.stop() ecu.disconnect()
def __init__(self, cfg, rxqueue, mapper): # compose the name descriptor for the new ca name = j1939.Name(arbitrary_address_capable=0, industry_group=j1939.Name.IndustryGroup.Industrial, vehicle_system_instance=1, vehicle_system=1, function=1, function_instance=1, ecu_instance=1, manufacturer_code=666, identity_number=1234567) device_address_preferred = 128 # old fashion calling convention for compatibility with Python2 j1939.ControllerApplication.__init__(self, name, device_address_preferred) # adaptation self.queue = rxqueue self.cfg = cfg self.db = cantools.database.load_file(cfg['vss.dbcfile']) self.mapper = mapper self.canidwl = self.get_whitelist() self.parseErr = 0
import logging import time import can import j1939 logging.getLogger('j1939').setLevel(logging.DEBUG) logging.getLogger('can').setLevel(logging.DEBUG) # compose the name descriptor for the new ca name = j1939.Name( arbitrary_address_capable=0, industry_group=j1939.Name.IndustryGroup.Industrial, vehicle_system_instance=1, vehicle_system=1, function=1, function_instance=1, ecu_instance=1, manufacturer_code=666, identity_number=1234567 ) # create the ControllerApplications ca = j1939.ControllerApplication(name, 128) def ca_receive(priority, pgn, source, timestamp, data): """Feed incoming message to this CA. (OVERLOADED function) :param int priority: Priority of the message :param int pgn: