linux-can.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: CAN ISO-TP
       [not found] <CAERdor5nY73X4qip=up8fNU=xT+H7r2XnKiob66=4DxovkBiGw@mail.gmail.com>
@ 2021-05-06 18:01 ` Oliver Hartkopp
  2021-05-06 20:52   ` Patrick Menschel
  2021-05-06 21:28   ` Bartosz Zdanowicz
  0 siblings, 2 replies; 12+ messages in thread
From: Oliver Hartkopp @ 2021-05-06 18:01 UTC (permalink / raw)
  To: Bartosz Zdanowicz; +Cc: linux-can

+CC Linux CAN ML

Hi Bartosz,

On 06.05.21 19:28, Bartosz Zdanowicz wrote:

> I'm not sure if you prefer e-mail message, but I don't want to raise 
> GitHub Issue yet.
> 

Raising a GitHub issue is generally a good idea as it may help other 
people too.

But asking on the Linux CAN mailing list is even better ;-)

> I'm using module that you are an author and it's working perfectly on my 
> local PC. I'm using Ubuntu with Kernel version 5.4.0-70-generic

Which branch did you use? master branch?

> I tried to simplify example where I use python wrappers and other things 
> and manage to get minimal example:
> 
> /import socket as s
> socket = s.socket(s.AF_CAN, s.SOCK_DGRAM, s.CAN_ISOTP)
> socket.bind(("vcan0", 1, 2))
> socket.send(b"AAAAAAAAA")
> socket.send(b"AAAAAAAAA")/
> /
> /
> It's working perfectly, even if I don't open receiver socket. It just 
> timeout and there is no issue.

But this should raise an issue as you send 9 bytes which would need 
segmentation.

This should only work with CAN FD frames with a single frame.

Can you create a candump log from vcan0 to see, what's going on the bus?

> I tried to run my application on RPI, when module is already included 
> with kernel version Linux raspberrypi 5.10.17-v7+ #1403 SMP Mon Feb 22 
> 11:29:51 GMT 2021 armv7l GNU/Linux.
> 
> I run above code and first send is working (no receiver as well), 
> timeout, but second one is printing
> 
> OSError: [Errno 70] Communication error on send

That's interesting! We are currently working on creating that kind of 
feedback.

https://lore.kernel.org/linux-can/97e2ddd5-cc8b-9c7b-6198-2eceee39dfd4@hartkopp.net/

So how is Python getting this information?

Regards,
Oliver

> 
> And pattern is repeated. So sending next data works and after those 
> error appears. It seems like sending new data somehow ,,validate" 
> previous send. When I create other socket that reads data it's working 
> perfectly. The issue is, somehow in our architecture other device might 
> be unavailable.
> 
> I checked also dmesg and there is no tips. Is it any known issue, or 
> maybe it's expected?
> 
> Thanks in advance for you reply.
> 
> Best Regards,
> Bartosz Zdanowicz

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: CAN ISO-TP
  2021-05-06 18:01 ` CAN ISO-TP Oliver Hartkopp
@ 2021-05-06 20:52   ` Patrick Menschel
  2021-05-06 21:28   ` Bartosz Zdanowicz
  1 sibling, 0 replies; 12+ messages in thread
From: Patrick Menschel @ 2021-05-06 20:52 UTC (permalink / raw)
  To: Oliver Hartkopp, Bartosz Zdanowicz; +Cc: linux-can

Am 06.05.21 um 20:01 schrieb Oliver Hartkopp:
>> I tried to simplify example where I use python wrappers and other
>> things and manage to get minimal example:
>>
>> /import socket as s
>> socket = s.socket(s.AF_CAN, s.SOCK_DGRAM, s.CAN_ISOTP)
>> socket.bind(("vcan0", 1, 2))
>> socket.send(b"AAAAAAAAA")
>> socket.send(b"AAAAAAAAA")/
>> /
>> /
>> It's working perfectly, even if I don't open receiver socket. It just
>> timeout and there is no issue.
> 
> But this should raise an issue as you send 9 bytes which would need
> segmentation.
> 
> This should only work with CAN FD frames with a single frame.
> 
> Can you create a candump log from vcan0 to see, what's going on the bus?
> 
>> I tried to run my application on RPI, when module is already included
>> with kernel version Linux raspberrypi 5.10.17-v7+ #1403 SMP Mon Feb 22
>> 11:29:51 GMT 2021 armv7l GNU/Linux.
>>
>> I run above code and first send is working (no receiver as well),
>> timeout, but second one is printing
>>
>> OSError: [Errno 70] Communication error on send
> 
> That's interesting! We are currently working on creating that kind of
> feedback.
> 
> https://lore.kernel.org/linux-can/97e2ddd5-cc8b-9c7b-6198-2eceee39dfd4@hartkopp.net/
> 
> 
> So how is Python getting this information?
> 
> Regards,
> Oliver

Hi,

that seems to be my topic.

1. Feel free to use my python module.

https://gitlab.com/Menschel/socketcan#using-a-canisotpsocket

It is in regular pypi and I push new releases from time to time.

pip install socketcan

Don't forget to increase txqueuelen.
https://gitlab.com/Menschel/socketcan#can-isotp-overflows-when-the-tx-queue-is-too-small

2. Concerning errors, they are returned through the socket to user space
and raise OSError by Errno in socket.Socket() class.
If a subclass is implemented for that Errno, that subclass is raised
instead, for example TimeoutError.

The reported scenario may be a delayed stderr message, means it happens
on first attempt and is printed on second attempt.
There are such things when using "python -i".

There is an easy way to verify such a thing. Wrap your socket.send()
statements into a print() statement this will print the number of bytes
sent and these numbers will be printed after the error message.

Regards,
Patrick

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: CAN ISO-TP
  2021-05-06 18:01 ` CAN ISO-TP Oliver Hartkopp
  2021-05-06 20:52   ` Patrick Menschel
@ 2021-05-06 21:28   ` Bartosz Zdanowicz
  2021-05-07  7:02     ` Patrick Menschel
  1 sibling, 1 reply; 12+ messages in thread
From: Bartosz Zdanowicz @ 2021-05-06 21:28 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: linux-can

czw., 6 maj 2021 o 20:01 Oliver Hartkopp <socketcan@hartkopp.net> napisał(a):
>
> +CC Linux CAN ML
>
> Hi Bartosz,
>
> On 06.05.21 19:28, Bartosz Zdanowicz wrote:
>
> > I'm not sure if you prefer e-mail message, but I don't want to raise
> > GitHub Issue yet.
> >
>
> Raising a GitHub issue is generally a good idea as it may help other
> people too.
>
> But asking on the Linux CAN mailing list is even better ;-)
>
Sure, thanks! :)
>
> > I'm using module that you are an author and it's working perfectly on my
> > local PC. I'm using Ubuntu with Kernel version 5.4.0-70-generic
>
> Which branch did you use? master branch?
>
I'm using a master branch on my local PC. I was not able to find which
version of the codebase specific kernel of RaspberryPI is using.
>
> > I tried to simplify example where I use python wrappers and other things
> > and manage to get minimal example:
> >
> > /import socket as s
> > socket = s.socket(s.AF_CAN, s.SOCK_DGRAM, s.CAN_ISOTP)
> > socket.bind(("vcan0", 1, 2))
> > socket.send(b"AAAAAAAAA")
> > socket.send(b"AAAAAAAAA")/
> > /
> > /
> > It's working perfectly, even if I don't open receiver socket. It just
> > timeout and there is no issue.
>
> But this should raise an issue as you send 9 bytes which would need
> segmentation.
>
> This should only work with CAN FD frames with a single frame.
>
So when no receiver socket is opened, it should already raise an
exception after sending more than 8 bytes? I'm using standard CAN
frames (it's virtual can locally but 8 bytes per frame)
>
> 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
>
> > I tried to run my application on RPI, when module is already included
> > with kernel version Linux raspberrypi 5.10.17-v7+ #1403 SMP Mon Feb 22
> > 11:29:51 GMT 2021 armv7l GNU/Linux.
> >
> > I run above code and first send is working (no receiver as well),
> > timeout, but second one is printing
> >
> > OSError: [Errno 70] Communication error on send
>
> That's interesting! We are currently working on creating that kind of
> feedback.
>
> https://lore.kernel.org/linux-can/97e2ddd5-cc8b-9c7b-6198-2eceee39dfd4@hartkopp.net/
>
> 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.
>
> Regards,
> Oliver
>
> >
> > And pattern is repeated. So sending next data works and after those
> > error appears. It seems like sending new data somehow ,,validate"
> > previous send. When I create other socket that reads data it's working
> > perfectly. The issue is, somehow in our architecture other device might
> > be unavailable.
> >
> > I checked also dmesg and there is no tips. Is it any known issue, or
> > maybe it's expected?
> >
> > Thanks in advance for you reply.
> >
> > Best Regards,
> > Bartosz Zdanowicz

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: CAN ISO-TP
  2021-05-06 21:28   ` Bartosz Zdanowicz
@ 2021-05-07  7:02     ` Patrick Menschel
  2021-05-07  7:24       ` Bartosz Zdanowicz
  0 siblings, 1 reply; 12+ messages in thread
From: Patrick Menschel @ 2021-05-07  7:02 UTC (permalink / raw)
  To: Bartosz Zdanowicz, Oliver Hartkopp; +Cc: linux-can

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

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: CAN ISO-TP
  2021-05-07  7:02     ` Patrick Menschel
@ 2021-05-07  7:24       ` Bartosz Zdanowicz
  2021-05-07  7:59         ` Patrick Menschel
  0 siblings, 1 reply; 12+ messages in thread
From: Bartosz Zdanowicz @ 2021-05-07  7:24 UTC (permalink / raw)
  To: Patrick Menschel; +Cc: Oliver Hartkopp, linux-can

pt., 7 maj 2021 o 09:02 Patrick Menschel <menschel.p@posteo.de> 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).

I hope I described it clearly, if any more details are needed I'll try
to provide.

Best Regards,
Bartosz Zdanowicz

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: CAN ISO-TP
  2021-05-07  7:24       ` Bartosz Zdanowicz
@ 2021-05-07  7:59         ` Patrick Menschel
  2021-05-10 10:02           ` Bartosz Zdanowicz
  0 siblings, 1 reply; 12+ messages in thread
From: Patrick Menschel @ 2021-05-07  7:59 UTC (permalink / raw)
  To: Bartosz Zdanowicz; +Cc: Oliver Hartkopp, linux-can

Am 07.05.21 um 09:24 schrieb Bartosz Zdanowicz:
> pt., 7 maj 2021 o 09:02 Patrick Menschel <menschel.p@posteo.de> 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


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: CAN ISO-TP
  2021-05-07  7:59         ` Patrick Menschel
@ 2021-05-10 10:02           ` Bartosz Zdanowicz
  2021-05-10 18:04             ` Patrick Menschel
  0 siblings, 1 reply; 12+ messages in thread
From: Bartosz Zdanowicz @ 2021-05-10 10:02 UTC (permalink / raw)
  To: Patrick Menschel; +Cc: Oliver Hartkopp, linux-can

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@posteo.de> napisał(a):
>
> Am 07.05.21 um 09:24 schrieb Bartosz Zdanowicz:
> > pt., 7 maj 2021 o 09:02 Patrick Menschel <menschel.p@posteo.de> 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
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: CAN ISO-TP
  2021-05-10 10:02           ` Bartosz Zdanowicz
@ 2021-05-10 18:04             ` Patrick Menschel
  2021-05-11 16:37               ` Patrick Menschel
  0 siblings, 1 reply; 12+ messages in thread
From: Patrick Menschel @ 2021-05-10 18:04 UTC (permalink / raw)
  To: Bartosz Zdanowicz; +Cc: Oliver Hartkopp, linux-can

Am 10.05.21 um 12:02 schrieb Bartosz Zdanowicz:
> pt., 7 maj 2021 o 09:59 Patrick Menschel <menschel.p@posteo.de> napisał(a):
>> 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.
>>
> 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)
> 

OK,

this is really strange. I have no clue how that is possible unless it's
on kernel side.

I have to write a test for it later.

Regards,
Patrick

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: CAN ISO-TP
  2021-05-10 18:04             ` Patrick Menschel
@ 2021-05-11 16:37               ` Patrick Menschel
  2021-05-11 17:44                 ` Oliver Hartkopp
  0 siblings, 1 reply; 12+ messages in thread
From: Patrick Menschel @ 2021-05-11 16:37 UTC (permalink / raw)
  To: Bartosz Zdanowicz; +Cc: Oliver Hartkopp, linux-can

Am 10.05.21 um 20:04 schrieb Patrick Menschel:
> Am 10.05.21 um 12:02 schrieb Bartosz Zdanowicz:
>> pt., 7 maj 2021 o 09:59 Patrick Menschel <menschel.p@posteo.de> napisał(a):
>>> 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.
>>>
>> 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)
>>
> 
> OK,
> 
> this is really strange. I have no clue how that is possible unless it's
> on kernel side.
> 
> I have to write a test for it later.

I can confirm this behaviour, it is definetly kernel-side of the socket.

tests/test_socketcan.py::TestCanIsoTpSocket::test_should_fail_missing_flow_control_on_transfer

--------------------------------------------------------------------------------------------------
live log call
--------------------------------------------------------------------------------------------------
2021-05-11 18:14:00 [    INFO] Return value of IsoTpSend without flow
control: 64 (test_socketcan.py:720)
2021-05-11 18:14:01 [   ERROR] Return value of IsoTpSend without flow
control: None, Raised [Errno 70] Communication error on send
(test_socketcan.py:718)

Apparently there is another message thread for this and something was fixed.

https://marc.info/?i=97e2ddd5-cc8b-9c7b-6198-2eceee39dfd4%20()%20hartkopp%20!%20net

Funny thing is, it does not care about the wait_tx_done flag, this
happens with and without it.

Regards,
Patrick

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: CAN ISO-TP
  2021-05-11 16:37               ` Patrick Menschel
@ 2021-05-11 17:44                 ` Oliver Hartkopp
  2021-05-11 19:02                   ` Patrick Menschel
  0 siblings, 1 reply; 12+ messages in thread
From: Oliver Hartkopp @ 2021-05-11 17:44 UTC (permalink / raw)
  To: Patrick Menschel, Bartosz Zdanowicz; +Cc: linux-can



On 11.05.21 18:37, Patrick Menschel wrote:
> Am 10.05.21 um 20:04 schrieb Patrick Menschel:
>> Am 10.05.21 um 12:02 schrieb Bartosz Zdanowicz:
>>> pt., 7 maj 2021 o 09:59 Patrick Menschel <menschel.p@posteo.de> napisał(a):
>>>> 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.
>>>>
>>> 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)
>>>
>>
>> OK,
>>
>> this is really strange. I have no clue how that is possible unless it's
>> on kernel side.
>>
>> I have to write a test for it later.
> 
> I can confirm this behaviour, it is definetly kernel-side of the socket.
> 
> tests/test_socketcan.py::TestCanIsoTpSocket::test_should_fail_missing_flow_control_on_transfer
> 
> --------------------------------------------------------------------------------------------------
> live log call
> --------------------------------------------------------------------------------------------------
> 2021-05-11 18:14:00 [    INFO] Return value of IsoTpSend without flow
> control: 64 (test_socketcan.py:720)
> 2021-05-11 18:14:01 [   ERROR] Return value of IsoTpSend without flow
> control: None, Raised [Errno 70] Communication error on send
> (test_socketcan.py:718)
> 
> Apparently there is another message thread for this and something was fixed.
> 
> https://marc.info/?i=97e2ddd5-cc8b-9c7b-6198-2eceee39dfd4%20()%20hartkopp%20!%20net
> 
> Funny thing is, it does not care about the wait_tx_done flag, this
> happens with and without it.

The error handling was originally intended to be done by simple timeout 
monitoring on application level.

What I assume from the output above:

1st attempt: We have a failure but we happily return that we have send 
64 bytes (which Marc improved with the above referenced patch for 
CAN_ISOTP_WAIT_TX_DONE mode).

(socket remains open?!?)

2nd attempt: The error from the first attempt shows up in the socket 
error message queue?!?

I just did some tests with a modified isotpsend.c which closes the 
socket after the sending operation. This is probably the reason I did 
not see that behaviour ...

Regards,
Oliver

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: CAN ISO-TP
  2021-05-11 17:44                 ` Oliver Hartkopp
@ 2021-05-11 19:02                   ` Patrick Menschel
  2021-05-12 19:15                     ` Patrick Menschel
  0 siblings, 1 reply; 12+ messages in thread
From: Patrick Menschel @ 2021-05-11 19:02 UTC (permalink / raw)
  To: Oliver Hartkopp, Bartosz Zdanowicz; +Cc: linux-can

Am 11.05.21 um 19:44 schrieb Oliver Hartkopp:
> On 11.05.21 18:37, Patrick Menschel wrote:
>> Am 10.05.21 um 20:04 schrieb Patrick Menschel:
>>> Am 10.05.21 um 12:02 schrieb Bartosz Zdanowicz:
>>>> pt., 7 maj 2021 o 09:59 Patrick Menschel <menschel.p@posteo.de>
>>>> napisał(a):
>>>>> 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.
>>>>>
>>>> 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)
>>>>
>>>
>>> OK,
>>>
>>> this is really strange. I have no clue how that is possible unless it's
>>> on kernel side.
>>>
>>> I have to write a test for it later.
>>
>> I can confirm this behaviour, it is definetly kernel-side of the socket.
>>
>> tests/test_socketcan.py::TestCanIsoTpSocket::test_should_fail_missing_flow_control_on_transfer
>>
>>
>> --------------------------------------------------------------------------------------------------
>>
>> live log call
>> --------------------------------------------------------------------------------------------------
>>
>> 2021-05-11 18:14:00 [    INFO] Return value of IsoTpSend without flow
>> control: 64 (test_socketcan.py:720)
>> 2021-05-11 18:14:01 [   ERROR] Return value of IsoTpSend without flow
>> control: None, Raised [Errno 70] Communication error on send
>> (test_socketcan.py:718)
>>
>> Apparently there is another message thread for this and something was
>> fixed.
>>
>> https://marc.info/?i=97e2ddd5-cc8b-9c7b-6198-2eceee39dfd4%20()%20hartkopp%20!%20net
>>
>>
>> Funny thing is, it does not care about the wait_tx_done flag, this
>> happens with and without it.
> 
> The error handling was originally intended to be done by simple timeout
> monitoring on application level.
> 
> What I assume from the output above:
> 
> 1st attempt: We have a failure but we happily return that we have send
> 64 bytes (which Marc improved with the above referenced patch for
> CAN_ISOTP_WAIT_TX_DONE mode).
> 
> (socket remains open?!?)
> 
> 2nd attempt: The error from the first attempt shows up in the socket
> error message queue?!?
> 
> I just did some tests with a modified isotpsend.c which closes the
> socket after the sending operation. This is probably the reason I did
> not see that behaviour ...

I forgot to post my test which produced that result above.

https://gitlab.com/Menschel/socketcan/-/commit/bd7bfebde1d791c7dccb717c849398c0d0f53dcd

I run it on a pi0w with regular raspbian buster and a recent python
3.9.4 installed.
"pytest
tests/test_socketcan.py::TestCanIsoTpSocket::test_should_fail_missing_flow_control_on_transfer"

Regards,
Patrick

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: CAN ISO-TP
  2021-05-11 19:02                   ` Patrick Menschel
@ 2021-05-12 19:15                     ` Patrick Menschel
  0 siblings, 0 replies; 12+ messages in thread
From: Patrick Menschel @ 2021-05-12 19:15 UTC (permalink / raw)
  To: Oliver Hartkopp, Bartosz Zdanowicz; +Cc: linux-can

Am 11.05.21 um 21:02 schrieb Patrick Menschel:
> Am 11.05.21 um 19:44 schrieb Oliver Hartkopp:
>> On 11.05.21 18:37, Patrick Menschel wrote:
>>> Am 10.05.21 um 20:04 schrieb Patrick Menschel:
>>>> Am 10.05.21 um 12:02 schrieb Bartosz Zdanowicz:
>>>>> pt., 7 maj 2021 o 09:59 Patrick Menschel <menschel.p@posteo.de>
>>>>> napisał(a):
>>>>>> 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.
>>>>>>
>>>>> 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)
>>>>>
>>>>
>>>> OK,
>>>>
>>>> this is really strange. I have no clue how that is possible unless it's
>>>> on kernel side.
>>>>
>>>> I have to write a test for it later.
>>>
>>> I can confirm this behaviour, it is definetly kernel-side of the socket.
>>>
>>> tests/test_socketcan.py::TestCanIsoTpSocket::test_should_fail_missing_flow_control_on_transfer
>>>
>>>
>>> --------------------------------------------------------------------------------------------------
>>>
>>> live log call
>>> --------------------------------------------------------------------------------------------------
>>>
>>> 2021-05-11 18:14:00 [    INFO] Return value of IsoTpSend without flow
>>> control: 64 (test_socketcan.py:720)
>>> 2021-05-11 18:14:01 [   ERROR] Return value of IsoTpSend without flow
>>> control: None, Raised [Errno 70] Communication error on send
>>> (test_socketcan.py:718)
>>>
>>> Apparently there is another message thread for this and something was
>>> fixed.
>>>
>>> https://marc.info/?i=97e2ddd5-cc8b-9c7b-6198-2eceee39dfd4%20()%20hartkopp%20!%20net
>>>
>>>
>>> Funny thing is, it does not care about the wait_tx_done flag, this
>>> happens with and without it.
>>
>> The error handling was originally intended to be done by simple timeout
>> monitoring on application level.
>>
>> What I assume from the output above:
>>
>> 1st attempt: We have a failure but we happily return that we have send
>> 64 bytes (which Marc improved with the above referenced patch for
>> CAN_ISOTP_WAIT_TX_DONE mode).
>>
>> (socket remains open?!?)
>>
>> 2nd attempt: The error from the first attempt shows up in the socket
>> error message queue?!?
>>
>> I just did some tests with a modified isotpsend.c which closes the
>> socket after the sending operation. This is probably the reason I did
>> not see that behaviour ...
> 
> I forgot to post my test which produced that result above.
> 
> https://gitlab.com/Menschel/socketcan/-/commit/bd7bfebde1d791c7dccb717c849398c0d0f53dcd
> 
> I run it on a pi0w with regular raspbian buster and a recent python
> 3.9.4 installed.
> "pytest
> tests/test_socketcan.py::TestCanIsoTpSocket::test_should_fail_missing_flow_control_on_transfer"


Just tying some loose ends here.
I rewrote the test to be in line with pytest convention.
"can_interface" is a pytest fixture which will use any CAN interface
that is available. OSError is expected so it fails.

Regards,
Patrick

https://gitlab.com/Menschel/socketcan/-/blob/master/tests/test_socketcan.py#L708

====================================================================================================
FAILURES
=====================================================================================================
______________________________________________________________________
TestCanIsoTpSocket.test_should_fail_missing_flow_control_on_transfer
_______________________________________________________________________

self = <tests.test_socketcan.TestCanIsoTpSocket object at 0xb55d2370>,
can_interface = 'mcp1'

    def test_should_fail_missing_flow_control_on_transfer(self,
can_interface):
        rx_addr = 0x18DA01FA
        tx_addr = 0x18DAFA01
        s = CanIsoTpSocket(interface=can_interface, rx_addr=rx_addr,
tx_addr=tx_addr)
        data = bytes(range(64))
        with pytest.raises(OSError):
>           err = s.send(data)
E           Failed: DID NOT RAISE <class 'OSError'>

tests/test_socketcan.py:714: Failed
________________________________________________________________
TestCanIsoTpSocket.test_should_fail_missing_flow_control_on_transfer_and_wait_tx
_________________________________________________________________

self = <tests.test_socketcan.TestCanIsoTpSocket object at 0xb55d28b0>,
can_interface = 'mcp1'

    def
test_should_fail_missing_flow_control_on_transfer_and_wait_tx(self,
can_interface):
        rx_addr = 0x18DA01FA
        tx_addr = 0x18DAFA01
        s = CanIsoTpSocket(interface=can_interface, rx_addr=rx_addr,
tx_addr=tx_addr, wait_tx_done=True)
        data = bytes(range(64))
        with pytest.raises(OSError):
>           err = s.send(data)
E           Failed: DID NOT RAISE <class 'OSError'>

tests/test_socketcan.py:722: Failed


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-05-12 21:26 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CAERdor5nY73X4qip=up8fNU=xT+H7r2XnKiob66=4DxovkBiGw@mail.gmail.com>
2021-05-06 18:01 ` CAN ISO-TP Oliver Hartkopp
2021-05-06 20:52   ` Patrick Menschel
2021-05-06 21:28   ` Bartosz Zdanowicz
2021-05-07  7:02     ` Patrick Menschel
2021-05-07  7:24       ` Bartosz Zdanowicz
2021-05-07  7:59         ` Patrick Menschel
2021-05-10 10:02           ` Bartosz Zdanowicz
2021-05-10 18:04             ` Patrick Menschel
2021-05-11 16:37               ` Patrick Menschel
2021-05-11 17:44                 ` Oliver Hartkopp
2021-05-11 19:02                   ` Patrick Menschel
2021-05-12 19:15                     ` Patrick Menschel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).