hartkopp/can-isotp

FlowControl: isotp vs. "real" OBD2 adapter behavior

Closed this issue · 4 comments

I'm running this question through here to solicit feedback before adressing the can-devel mailing list, since I'm not sure whether you would consider this as an issue or not.

I'm working on a custom CANbus adapter based on Linux. This adapter is specialized for UDS (in particular for reprogramming ECUs), but should also work with the usual set of OBD2 commands. In general, everything works great with the isotp module, however I noticed a behavioral difference to a "real" OBD2 adapter:

When talking via CAN broadcast addresses, isotp sends flow control frames to the (functional) broadcast address instead of using the (computed) physical device address.

Here's the beginning of an isotp exchange when querying 0902 with an off-the-shelve OBD2 adapter:

(004.597396)  toucan2  7DF   [8]  02 09 02 00 00 00 00 00   '........'
(000.001399)  toucan2  7E8   [8]  10 14 49 02 01 57 44 58   '..I..WDX'
(000.000408)  toucan2  7E0   [8]  30 00 00 00 00 00 00 00   '0.......'

Here's the same with my linux device and the isotp module:

(016.312861)  toucan2  7DF   [8]  02 09 02 AA AA AA AA AA   '........'
(000.001555)  toucan2  7E8   [8]  10 14 49 02 01 57 44 58   '..I..WDX'
(000.000897)  toucan2  7DF   [8]  30 20 00 AA AA AA AA AA   '0 ......'

Can you spot the difference (not the padding bytes)? Although we are communicating via the CAN 11-bit broadcast address, the OBD2 adapter computes the address of the device that sent the FF. Whereas the isotp module "just" continues using the broadcast address.

I wonder whether we could improve isotp by allowing to set up an additional CAN address that is being used only for the flow control frames.

When talking via CAN broadcast addresses, isotp sends flow control frames to the (functional) broadcast address instead of using the (computed) physical device address.

Can you tell, which Linux Kernel version you are currently using?

The problem is, that we didn't manage to get the CAN_ISOTP_SF_BROADCAST into Linux 5.10.x
So this option is available in mainline 5.11+ and backported to this repo - but not in the 5.10.x which is used e.g. on RasPi.

Ah, I'm indeed using Linux 5.10 as my prototype hardware is based on a RasPi Zero 2.

I'm not entirely sure I understand how CAN_ISOTP_SF_BROADCAST would solve my problem though, since I don't want isotp to fallback on the SF behavior. I just want it to perform an "address correction" for flow control frames when being addressed via broadcast. Or am I misunderstanding what the flag does?

The CAN_ISOTP_SF_BROADCAST is just a convenience functionality to be able to send 'SF' broadcast frames without forging that frame 'by hand' and send it on a CAN_RAW socket.

Therefore CAN_ISOTP_SF_BROADCASTonly needs one CAN-ID (for sending) and does not register for any CAN-ID to receive content or flow controls.

All other isotp sockets are point-to-point which requires TWO CAN-IDs for bi-directional content and flow control exchange.
So when you define these two CAN-IDs the isotp stack acts accordingly.

I understand now. Thanks for explaining!