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
239 stars 69 forks source link

============================================================================

README.isotp

CREDITS

This repository contains a rework to simplify the build of the former ISO-TP development repository at https://github.com/hartkopp/can-isotp-modules.

The build and repository cleanup provided by Nathan L. Conrad was merged from https://github.com/downwith/linux-isotp . Thanks Nathan!

DOWNLOAD and BUILD

  1. Download repository and enter the repositories root directory

    git clone https://github.com/hartkopp/can-isotp.git

    cd can-isotp

  2. Build ISO-TP kernel module

    Ensure build dependencies are installed. E.g. for Debian (or Ubuntu):

    sudo apt-get install build-essential linux-headers-$(uname -r)

    To build:

    (you need to be in the repositories root path)

    make

    To install (optional):

    sudo make modules_install

  3. When the PF_CAN core module is loaded ('modprobe can') the ISO-TP module can be loaded into the kernel with

    insmod ./net/can/can-isotp.ko

    When the can-isotp.ko module has been installed into the Linux Kernels modules directory (e.g. with 'make modules_install') the module should load automatically when opening a CAN_ISOTP socket.

    Note: on UEFI systems with Secure Boot enabled, it is not possible to insert unsigned kernel modules. One option is to sign them manually. The comments linked below can help you in the process: https://github.com/hartkopp/can-isotp/issues/25#issuecomment-621518694 https://github.com/hartkopp/can-isotp/issues/25#issuecomment-627090876


Readme file for ISO 15765-2 CAN transport protocol for protocol family CAN

1 What is ISO-TP for CAN

CAN Transport Protocols offer support for segmented Point-to-Point communication between CAN nodes via two defined CAN Identifiers. This protocol driver implements data transfers according ISO 15765-2.

CAN ISO-TP is an unreliable datagram protocol and is implemented like this. For that reason error indications, like 'dropped PDUs in the receive path due to wrong SequenceNumbers' are intentionally not supported. See discussion in section 3.2

Code examples of how to use ISO-TP sockets can be found in the source code of the available tools described below. The API is still a RFC and will be described in detail later, when it's finalized.

2 Tools and Examples

The source code of these tools can be found in the can-utils repository on GitHub at https://github.com/linux-can/can-utils

For the examples below we assume a test setup with two hosts:

     _______          _______ 
    |       |        |       |
    | Host1 |        | Host2 |
    |       |        |       |
    | can1  |        | can2  |
    |_______|        |_______|
        |                |
 |------------------------------| CAN bus

2.1 isotpsend - send PDUs from stdin to CAN

isotpsend gives this help when invoked without any parameters:

Usage: isotpsend [options] Options: -s (source can_id. Use 8 digits for extended IDs) -d (destination can_id. Use 8 digits for extended IDs) -x (extended addressing mode. Use 'any' for all addresses) -p (set and enable padding byte) -P (check padding in FC. (l)ength (c)ontent (a)ll) -t

CAN IDs and addresses are given and expected in hexadecimal values. The pdu data is expected on STDIN in space separated ASCII hex values.

Example (send ISOTP PDU from Host2 to Host1): echo 11 22 33 44 55 66 DE AD BE EF | isotpsend -s 321 -d 123 can2

2.2 isotprecv - print received PDU on stdout

isotprecv gives this help when invoked without any parameters:

Usage: isotprecv [options] Options: -s (source can_id. Use 8 digits for extended IDs) -d (destination can_id. Use 8 digits for extended IDs) -x (extended addressing mode.) -p (set and enable padding byte) -P (check padding in SF/CF. (l)ength (c)ontent (a)ll) -b (blocksize. 0 = off) -m (STmin in ms/ns. See spec.) -w (max. wait frame transmissions.) -l (loop: do not exit after pdu receiption.)

CAN IDs and addresses are given and expected in hexadecimal values. The pdu data is written on STDOUT in space separated ASCII hex values.

Example (receive ISOTP PDU from Host2 on Host1): isotprecv -s 123 -d 321 -l can1

In this example '-l' is set which causes isotprecv to continue listening on the given connection after printing a received PDU.

2.3 isotpdump - dump CAN frames with PCI decoding (using CAN_RAW socket)

isotpdump gives this help when invoked without any parameters:

Usage: isotpdump [options] Options: -s (source can_id. Use 8 digits for extended IDs) -d (destination can_id. Use 8 digits for extended IDs) -x (extended addressing mode. Use 'any' for all addresses) -c (color mode) -a (print data also in ASCII-chars) -t (timestamp: (a)bsolute/(d)elta/(z)ero/(A)bsolute w date)

CAN IDs and addresses are given and expected in hexadecimal values.

Example (dump CAN Frames on Host1): isotpdump -s 123 -d 321 -c -ta can1

2.4 isotpsniffer - dump reassembled ISO-TP PDUs (using CAN_ISOTP socket)

The difference to isotpdump is, that isotpsniffer opens two CAN_ISOTP sockets and sets the CAN_ISOTP_LISTEN_MODE flag on both of these sockets. This causes the ISO-TP protocol driver to reassemble the received data but not send and flow control frames on the CAN bus.

isotpsniffer gives this help when invoked without any parameters:

Usage: isotpsniffer [options] Options: -s (source can_id. Use 8 digits for extended IDs) -d (destination can_id. Use 8 digits for extended IDs) -x (extended addressing mode.) -c (color mode) -t (timestamp: (a)bsolute/(d)elta/(z)ero/(A)bsolute w date) -f (1 = HEX, 2 = ASCII, 3 = HEX & ASCII - default: 3) -h (head: print only first bytes)

CAN IDs and addresses are given and expected in hexadecimal values.

Example (dump reassembled ISO-TP PDUs on Host1): isotpsniffer -s 123 -d 321 -c -ta can1

2.5 isotptun - create an IP tunnel over unreliable ISO-TP PDUs

The ISO-TP provides an unreliable datagram protocol with PDU sizes up to 4095 bytes. Having Linux tunnel driver in mind creating an IP over ISO-TP tunnel became obvious - so here it is ;-)

From linux/Documentation/networking/tuntap.txt: TUN/TAP provides packet reception and transmission for user space programs. It can be seen as a simple Point-to-Point or Ethernet device, which, instead of receiving packets from physical media, receives them from user space program and instead of sending packets via physical media writes them to the user space program.

isotptun gives this help when invoked without any parameters:

Usage: isotptun [options]

This program creates a Linux tunnel netdevice 'ctunX' and transfers the ethernet frames inside ISO15765-2 (unreliable) datagrams on CAN.

Options: -s (source can_id. Use 8 digits for extended IDs) -d (destination can_id. Use 8 digits for extended IDs) -x (extended addressing mode.) -p (padding byte rx path) -q (padding byte tx path) -P (check padding. (l)ength (c)ontent (a)ll) -t

CAN IDs and addresses are given and expected in hexadecimal values. Use e.g. 'ifconfig ctun0 123.123.123.1 pointopoint 123.123.123.2 up' to create a point-to-point IP connection on CAN.

Example:

on Host1 run as root: isotptun -s 123 -d 321 -v can1 (this blocks, so use a separate terminal)

ifconfig ctun0 123.123.123.1 pointopoint 123.123.123.2 up

on Host2 run as root: isotptun -s 321 -d 123 -v can2 (this blocks, so use a separate terminal)

ifconfig ctun0 123.123.123.2 pointopoint 123.123.123.1 up

Have fun (like in early modem dialup days): ping 123.123.123.1 ssh user@123.123.123.1 scp user@123.123.123.1:myfile.tar.gz .

scp get's about 27kByte/s over a 500kbit/s CAN interface.

3 Remarks

3.1 tx_queue_len on real CAN busses (!!!)

The blocksize (BS) splits the CAN frame stream into chunks that need to be acknowledged on the receiver side with a flow control frame. In the case the blocksize is set to zero the protocol does not wait for flow control frames and sends all the CAN frames for the ISO-TP PDU in one burst.

In the case of a 4095 bytes PDU the protocol driver must create 586(!) CAN frames, that are pushed into the CAN network device. This is no problem with virtual CAN devices (vcan) but for real CAN devices with real bus timings. Even though the frame_txtime (N_As/N_Ar) can be set in the ISO-TP socket options, it is recommended to have an appropriate tx queue available in the CAN driver, e.g.:

echo 4000 > /sys/class/net/can0/tx_queue_len

or with the 'ip' tool from the iproute2 package

ip link set can0 txqueuelen 4000

3.2 State of the Socket API for this Linux CAN ISO-TP implementation

Implementing transport protocol drivers in userspace on top of a CAN_RAW socket is possible but has massive drawbacks for fullfilling timing constrains and multi-user handling. Implementing a CAN transport protocol inside the Kernel brings different requirements, as ...

Oliver Hartkopp (2017-11-06)