hartkopp / can-isotp

Linux Kernel Module for ISO 15765-2:2016 CAN transport protocol PLEASE NOTE: This module is part of the mainline Linux kernel since version 5.10
Other
248 stars 71 forks source link

FlowControl frame address tx_id vs. rx_id - 8? #55

Closed camercu closed 2 years ago

camercu commented 2 years ago

This is more of a question than an issue. I'm new to ISO-TP, so please forgive my ignorance. Should the ArbID of the FlowControl frame be the tx_id, or should it be the rx_id - 8?

When my scan tool sends OBD-2 messages, it uses a tx_id of 7DF, and listens for responses from 7E8-7EF. However, whenever it needs to send a FlowControl frame, it sends the FC frame with an ArbID that is the ECU response ID minus 8 (e.g. ECU responds on 7E8, FC frame sent with ArbID 7E0). I see the same behavior when looking at the uds.py code for the panda.

If I create an ISOTP socket using this kernel module, I cannot use just a single socket to request the VIN (OBD2 Service 09, PID 02) because my car expects the FC frame to be sent with ArbID = rx_id - 8. I have to create 2 sockets, one to send the request, and one to listen for the response. This doesn't seem to me like normal use, but like I said, I'm new to this, so I'm happy to learn.

Thanks!

hartkopp commented 2 years ago

I have to create 2 sockets, one to send the request, and one to listen for the response. This doesn't seem to me like normal use,

It is ;-)

The difference is: With the so called 'functional addressing' you (as a diag tester) send a broadcast command to all ECUs. As this is a broadcast ( 1-to-n) it has to fit in ONE CAN frame (no segmentation, no FC frame). In your example you send this 'functional broadcast' with CAN ID 0x7DF.

After sending that message the ECUs start sending on a 'normal' point-to-point (1-to-1) ISO-TP channel.

And this channel needs two CAN ID, e.g. 0x7E8 and 0x7E0.

Even if it sounds strange: For your use-case you need to open eight ISO-TP sockets that virtually 'establish' the 1-to-1 ISO-TP channels.

Then you send the functional command with CAN ID 0x7DF and you can see the responses arriving on these sockets (you can use select() to read from multiple sockets at a time).

I assume establishing the Linux isotp socket after getting the first answer (like in the panda code) would be too late (as the isotp state machine then would miss the first CAN frame).

camercu commented 2 years ago

Thank you SO much for that clarification! I really appreciate you helping me learn and understand this material!