Code Monkey home page Code Monkey logo

can-isotp-modules's Introduction

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

CAN ISO-TP has moved to https://github.com/hartkopp/can-isotp.git
This repository is not maintained anymore.

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

README.isotp

DOWNLOAD and BUILD

1. Download repository

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

2. Build ISO-TP kernel module

   cd can-isotp-modules/net/can
   ./make_isotp.sh

   Remark: The other CAN sources are out of date and will not compile with
           recent Linux versions. make_isotp.sh compiles can-isotp.ko only.

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

   insmod ./can-isotp.ko

----------------------------------------------------------------------------

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


* WARNING: This is ALPHA code for discussions and first tests that should
*          not be used in production environments.
*
* In the discussion the Socket-API to the userspace or the ISO-TP socket
* options or the return values we may change! Current behaviour:
*
* - no ISO-TP specific return values are provided to the userspace
* - when a transfer (tx) is on the run the next write() blocks until it's done
* - no support for sending wait frames to the data source in the rx path


  1 What is ISO-TP for CAN

  2 Tools and Examples
    2.1 isotpsend - send PDUs from stdin to CAN
    2.2 isotprecv - print received PDU on stdout
    2.3 isotpdump - dump CAN frames with PCI decoding (using CAN_RAW socket)
    2.4 isotpsniffer - dump reassembled ISO-TP PDUs (using CAN_ISOTP socket)
    2.5 isotptun - create an IP tunnel over unreliable ISO-TP PDUs

  3 Remarks
    3.1 tx_queue_len on real CAN busses (!!!)
    3.2 State of the Socket API & Discussion

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 BerliOS SVN repository
  http://developer.berlios.de/svn/?group_id=6475 in trunk/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] <CAN interface>
  Options: -s <can_id>  (source can_id. Use 8 digits for extended IDs)
           -d <can_id>  (destination can_id. Use 8 digits for extended IDs)
           -x <addr>    (extended addressing mode. Use 'any' for all addresses)
           -p <byte>    (set and enable padding byte)
           -P <mode>    (check padding in FC. (l)ength (c)ontent (a)ll)
           -t <time ns> (transmit time in nanosecs)

  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

  isotpsend gives this help when invoked without any parameters:

  Usage: isotprecv [options] <CAN interface>
  Options: -s <can_id>  (source can_id. Use 8 digits for extended IDs)
           -d <can_id>  (destination can_id. Use 8 digits for extended IDs)
           -x <addr>    (extended addressing mode.)
           -p <byte>    (set and enable padding byte)
           -P <mode>    (check padding in SF/CF. (l)ength (c)ontent (a)ll)
           -b <bs>      (blocksize. 0 = off)
           -m <val>     (STmin in ms/ns. See spec.)
           -w <num>     (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] <CAN interface>
  Options: -s <can_id> (source can_id. Use 8 digits for extended IDs)
           -d <can_id> (destination can_id. Use 8 digits for extended IDs)
           -x <addr>   (extended addressing mode. Use 'any' for all addresses)
           -c          (color mode)
           -a          (print data also in ASCII-chars)
           -t <type>   (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] <CAN interface>
  Options: -s <can_id> (source can_id. Use 8 digits for extended IDs)
           -d <can_id> (destination can_id. Use 8 digits for extended IDs)
           -x <addr>   (extended addressing mode.)
           -c          (color mode)
           -t <type>   (timestamp: (a)bsolute/(d)elta/(z)ero/(A)bsolute w date)
           -f <format> (1 = HEX, 2 = ASCII, 3 = HEX & ASCII - default: 3)
           -h <len>    (head: print only first <len> 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] <CAN interface>

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

  Options: -s <can_id>  (source can_id. Use 8 digits for extended IDs)
           -d <can_id>  (destination can_id. Use 8 digits for extended IDs)
           -x <addr>    (extended addressing mode.)
           -p <byte>    (padding byte rx path)
           -q <byte>    (padding byte tx path)
           -P <mode>    (check padding. (l)ength (c)ontent (a)ll)
           -t <time ns> (transmit time in nanosecs)
           -b <bs>      (blocksize. 0 = off)
           -m <val>     (STmin in ms/ns. See spec.)
           -w <num>     (max. wait frame transmissions.)
           -h           (half duplex mode.)
           -v           (verbose mode. Print symbols for tunneled msgs.)

  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 [email protected]
  scp [email protected]: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 ...

  - it needs to fit into a standard socket API
  - datagram sockets should always behave similar (e.g. like UDP/IP)
  - reduce user interaction to a minimal absolutely required level
  - reduce user programming interface to a minimal absolutely required level

  In the real world applications using unreliable datagram protocols recognize
  problems via timeouts. So do ISO-TP applications. So the questions is:
  What does it help for the application to know, that someone 'dropped a PDU
  in the receive path due to wrong SequenceNumbers'?

  The application does not know the (so far received) content and therefore
  gets this completely useless information to do *what* with it?

  From current applications perspective the things that have not been
  implemented have not been required so far. So this might become the
  discussion upon this implementation:

  - what is really needed and for what use-case?
  - how does this fit into standard networking and socket philosophy?

Oliver Hartkopp (2008-11-05)

can-isotp-modules's People

Contributors

grandwolf avatar hartkopp avatar marckleinebudde avatar rschwebel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

can-isotp-modules's Issues

can isotp error handler

I am wondering how we could check if an error has been occurred while sending or receiving a isotp message ?
I wasn't able to find any doc about the error handler.
Thanks

ISO-TP addressing / Identifier

I was testing the isotp kernel module with the shell tools from the can-utils package and compared the behavior with the ISO 15765-2:2016(E) (third edition).
As far as I understood from the ISO standard, when using the 29 bit CAN Identifier with ISO-TP the identifier should contain a fixed bit-order from 28 to 16 followed by 1 byte for the target address and 1 byte for the source address. From my understanding this CAN Identifier is the same for the FF, FC and CF messages of one specific transfer.
The isotprecv and isotpsend (from can-utils) are using only the destination address as identifier as far as I saw. The identifier from the FC message also differs to the FF and CF identifier (makes sense in this implementation where the identifier describes the destination only)

What I would like to know and couldn’t find until now:

  • Is this behavior known/wanted?
  • What was the use-case for this implementation?

How to create an ISOTP socket?

The message I send from one host(slcan0) using isotpsend is not received at the other host(slcan1) when I give isotprecv.But I am able to send and receive a message in the same host either slcan0 or slcan1. Initially, I had the same issue for sending standard 8 bytes CAN message from one host to other then I created a socket using the following program

#!/bin/env python
import socket
import struct

canformat = '<IB3x8s'

class CanBridge():
    def __init__(self, interface_from, interface_to):
        self.interface_from = interface_from
        self.interface_to = interface_to
        self.canSocket_to = socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
        self.canSocket_from = socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
        try: 
            self.canSocket_to.bind((self.interface_to,))
            self.canSocket_from.bind((self.interface_from,))
        except OSError: 
            print("Could not bind to interfaces")
        #put the sockets in blocking mode.
        self.canSocket_to.settimeout(None)
        self.canSocket_from.settimeout(None)

    def run(self):
        while True:
            raw_bytes = self.canSocket_from.recv(512)
            try:
                self.canSocket_to.send(raw_bytes)
            except OSError: #Buffer overflow usually from lack of connection.
                pass

            rawID,DLC,candata = struct.unpack(canformat,raw_bytes)
            canID = rawID & 0x1FFFFFFF
            candata_string = " ".join(["{:02X}".format(b) for b in candata])
            print("{:08X} {}".format(canID, candata_string))

if __name__ == '__main__':
    bridge = CanBridge('slcan1','slcan0')
    bridge.run()

Likewise how to create a socket for ISOTP ?I used the following code to create a socket for ISOTP but it doesnt seem to work

SOL_CAN_ISOTP = 106 # These constants exist in the module header, not in Python.
CAN_ISOTP_RECV_FC = 2
# Many more exists.
import socket
import struct
s = socket.socket(socket.AF_CAN, socket.SOCK_DGRAM, socket.CAN_ISOTP)
s2 = socket.socket(socket.AF_CAN, socket.SOCK_DGRAM, socket.CAN_ISOTP)
# Configuring the sockets with ugly struct.pack() that requires knowledge of the LKM
˓ → structure
s.setsockopt(SOL_CAN_ISOTP, CAN_ISOTP_RECV_FC, struct.pack("=BBB", 0x10, 3,0)) #bs,
˓ → stmin, wftmax
#s.setsockopt(SOL_CAN_ISOTP, CAN_ISOTP_OPTS, struct.pack(...))
#s.setsockopt(SOL_CAN_ISOTP, CAN_ISOTP_LL_OPTS, struct.pack(...))
s.bind(("slcan0", 0x123, 0x456)) #rxid, txid with confusing order.
s2.bind(("slcan0", 0x456, 0x123)) #rxid, txid
s2.send(b"Hello, this is a long payload sent in small chunks of 8 bytes.")
print(s.recv(4095))

OR

import isotp
s = isotp.socket()
s2 = isotp.socket()
# Configuring the sockets.
s.set_fc_opts(stmin=5, bs=10)
#s.set_general_opts(...)
#s.set_ll_opts(...)
s.bind("slcan0" isotp.Address(rxid=0x123 txid=0x456))
s2.bind("slcan0", isotp.Address(rxid=0x456, txid=0x123))
s2.send(b"Hello, this is a long payload sent in small chunks of 8 bytes.")
print(s.recv())

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.