linklayer / cantact

Drivers and Command Line Interface for CANtact tools
http://cantact.io
MIT License
46 stars 11 forks source link

Failed ECUReset and app.shutdown() brings down cantact can0 SocketCAN interface? #18

Closed brainstorm closed 3 weeks ago

brainstorm commented 3 years ago

After running this simple UDS code mostly borrowed from the official python-isotp documentation, with the only caveat that I'm using Extended_29bits addressing instead of Normal_11bits... @ericevenchick did you test your example code with Extended_29bits?:

#!/usr/bin/env python3
import time
import logging
import threading

import can
import isotp
import udsoncan

from udsoncan.connections import PythonIsoTpConnection
from udsoncan.client import Client, Response, Request
from udsoncan.exceptions import *
from udsoncan.services import *

from can.interfaces.socketcan import SocketcanBus

udsoncan.setup_logging()

BUILTIN_CANID=0xBEEEBEEE
OEM_CANID_TX=0xCAFECAFE
OEM_CANID_RX=0xBEEFBEEF

#bus = can.interface.Bus(bustype="cantact", channel="0", bitrate=500000)
#addr = isotp.Address(addressing_mode=isotp.AddressingMode.Extended_29bits, txid=OEM_CANID_TX, rxid=OEM_CANID_RX)
#tp = isotp.CanStack(bus, address=addr)
#conn = PythonIsoTpConnection(tp)
#client = Client(conn)

#conn.open()
#client.ecu_reset(ECUReset.ResetType.hardReset) <--- hangs cantact/disassociates SocketCAN interface
#client.ecu_reset(ECUReset.ResetType.softReset)
#print("done")
#conn.close()

class ThreadedApp:
   def __init__(self):
      self.exit_requested = False
      self.bus = can.interface.Bus(bustype="cantact", channel="0", bitrate=500000)
      #self.bus = SocketcanBus(channel='can0')
      addr = isotp.Address(isotp.AddressingMode.Extended_29bits, target_address=0,
                                                                 #rxid=OEM_CANID_RX,
                                                                 #txid=OEM_CANID_TX)
                                                                 rxid=BUILTIN_CANID,
                                                                 txid=OEM_CANID_TX)
      self.stack = isotp.CanStack(self.bus, address=addr, error_handler=self.my_error_handler)

   def start(self):
      self.exit_requested = False
      self.thread = threading.Thread(target = self.thread_task)
      self.thread.start()

   def stop(self):
      self.exit_requested = True
      if self.thread.isAlive():
         self.thread.join()

   def my_error_handler(self, error):
      logging.warning('IsoTp error happened : %s - %s' % (error.__class__.__name__, str(error)))

   def thread_task(self):
      while self.exit_requested == False:
         self.stack.process()                # Non-blocking
         time.sleep(self.stack.sleep_time()) # Variable sleep time based on state machine state

   def shutdown(self):
      self.stop()
      self.bus.shutdown()

if __name__ == '__main__':
   app = ThreadedApp()
   app.start()

   print('Waiting for payload - maximum 5 sec')
   t1 = time.time()
   while time.time() - t1 < 5:
      if app.stack.available():
         payload = app.stack.recv()
         print("Received payload : %s" % (payload))
         break
      time.sleep(0.2)

   print("Exiting")
   app.shutdown()

The application runs successfully until the end but udsoncan.log reads:

2021-08-28 21:39:37 [INFO] Connection: Connection opened
2021-08-28 21:39:37 [INFO] UdsClient: ECUReset<0x11> - Requesting reset of type 0x03 (softReset)
2021-08-28 21:39:37 [DEBUG] Connection: Sending 2 bytes : [b'1103']
2021-08-28 21:39:37 [DEBUG] Connection: Received 3 bytes : [b'7f117f']
2021-08-28 21:39:37 [WARNING] UdsClient: [NegativeResponseException] : ECUReset service execution returned a negative response ServiceNotSupportedInActiveSession (0x7f)

After that, the status lights on the Cantact PRO turn off and the SocketCAN can0 interface is gone and it cannot be brought back until a reboot is performed:

$ ip link show can0
Device "can0" does not exist.

$ cat can_start.sh
#!/bin/sh -x

sudo ip link set can0 type can bitrate 500000
sudo ifconfig can0 up

$ ./can_start.sh
+ sudo ip link set can0 type can bitrate 500000
Cannot find device "can0"
+ sudo ifconfig can0 up
can0: ERROR while getting interface flags: No such device

If all the lights turn off, this sounds like a firmware issue? I'll execute step by step next, but app.shutdown() seems to be the culprit because the latest print("Exiting") is displayed right before all the lights in the Cantact PRO go off.

@ericevenchick Could you please use this specific example on your end? I'm running all this on a Raspberry Pi 1 with the latest cantact release and pyton-isotp 1.7 and ... well, following all the installation instructions on the README to the letter :)