I used following code: import isotp import time s = isotp.socket() s._socket.settimeout(2) s.set_opts(s.flags.WAIT_TX_DONE) s.bind("can0", isotp.Address(rxid=1, txid=2)) s.send(b"aaaaaaaaa") -> returns immediately with number of bytes s.send(b"aaaaaaaaa") -> same OS error as above (Error 70) pt., 7 maj 2021 o 09:59 Patrick Menschel <menschel.p@xxxxxxxxx> napisał(a): > > Am 07.05.21 um 09:24 schrieb Bartosz Zdanowicz: > > pt., 7 maj 2021 o 09:02 Patrick Menschel <menschel.p@xxxxxxxxx> napisał(a): > >> > >> Am 06.05.21 um 23:28 schrieb Bartosz Zdanowicz: > >>>> Can you create a candump log from vcan0 to see, what's going on the bus? > >>>> > >>> On RPI after first send I got > >>> pi@raspberrypi:~ $ candump can0 > >>> can0 002 [8] 10 09 41 41 41 41 41 41 > >>> > >>> After the second message I got mentioned OSError and there is no data > >>> on candump. Sending again I received next frame: > >>> pi@raspberrypi:~ $ candump can0 > >>> can0 002 [8] 10 09 41 41 41 41 41 41 > >>> can0 002 [8] 10 09 41 41 41 41 41 41 > >>> > >>> On my local PC where I get no system Error I got one frame per every send: > >>> bartosz ~/Work/DeltaThermal/can-isotp master candump vcan0 > >>> vcan0 002 [8] 10 09 41 41 41 41 41 41 > >>> vcan0 002 [8] 10 09 41 41 41 41 41 41 > >>> vcan0 002 [8] 10 09 41 41 41 41 41 41 > >>> vcan0 002 [8] 10 09 41 41 41 41 41 41 > >>> vcan0 002 [8] 10 09 41 41 41 41 41 41 > >>> vcan0 002 [8] 10 09 41 41 41 41 41 41 > >>>> > >>>> ... > >>>> So how is Python getting this information? > >>>> > >>> In general, that's the biggest issue for me. Because in my real > >>> application I'm using python select() and recv() on that socket. When > >>> this error is raised, my select() on socket deduce something is > >>> received and recv() function also throws an error. I just tried to get > >>> a minimal example that reproduces the issue which is above. In those > >>> cases I would expect timeout, not OSError. > >> > >> > >> As expected, timeout error on missing flow control. Since it's tx side > >> it just tells -ECOMM instead of -ETIMEDOUT . > >> > >> https://github.com/raspberrypi/linux/blob/rpi-5.10.y/net/can/isotp.c#L10 > >> https://github.com/raspberrypi/linux/blob/rpi-5.10.y/net/can/isotp.c#L755 > >> > >> Is there a specific reason why you use select.select() instead of > >> Socket.recv(timeout) / Socket.send() ? > >> > >> Best Regards, > >> Patrick > > > > I have a seperate thread that waits and process data, since I have > > multiple sockets opened I want to wait for any of them: > > > > while True: > > ready_sockets = select.select(self.sockets, [], [], self.timeout)[0] > > if not ready_sockets: > > logging.info("No data received") > > continue > > for socket in ready_sockets: > > self.process_data(socket=socket) > > > > In process_data I call: > > > > received = socket.recv() > > if received: > > #process data > > > > My main thread is sending data on those sockets: > > schedule.every(X).seconds.do(request_that_sends_using_socket.send(), > > socket=socket) > > > > So the flow is that my thread sends data to another device, and the > > processing thread is waiting for data. When I don't send any data I > > get only prints "No data received" which is expected cause no device > > is responding (no device is running). When I send data (no other > > device is running) I get an error on send AND my select() is finished > > with an error socket inserted to ready_sockets. That means I enter > > self.process_data() function with socket and also recv() fails. So it > > seems it's not only that OSError is raised but also that socket is > > somehow "invalid" because it triggers select() which should not be > > triggered (no data was received). > > > Ok, > > try to enable CAN_ISOTP_WAIT_TX_DONE via socket.setsockopt() . > https://github.com/raspberrypi/linux/blob/rpi-5.10.y/net/can/isotp.c#L14 > > https://gitlab.com/Menschel/socketcan/-/blob/master/socketcan/socketcan.py#L583 > > and wrap tx into a try-except block. > > try: > self.process_data(socket=socket) > except OSError as e: > print(e) > > With this you actually have a chance to do error handling on tx path > instead of hitting an already present error of the previous op. > > Regards, > Patrick >