hartkopp / can-isotp Goto Github PK
View Code? Open in Web Editor NEWLinux 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
License: Other
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
License: Other
Hi everyone,
I'm trying to use this library on a Jetson TX2 Board (arm architecture if that matters) inside of an docker container.
If I test the following code from the docs:
import isotp
s = isotp.socket()
s2 = isotp.socket()
# Configuring the sockets.
s.set_fc_opts(stmin=5, bs=10)
s.bind("vcan0", isotp.Address(rxid=0x123 txid=0x456))
s2.bind("vcan0", 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())
I get the following error message:
root@d1a297bae985:/# python3.7 test.py
Traceback (most recent call last):
File "test.py", line 3, in
s = isotp.socket()
File "/usr/local/lib/python3.7/site-packages/isotp/tpsock/init.py", line 74, in init
self._socket = socket_module.socket(socket_module.AF_CAN, socket_module.SOCK_DGRAM, socket_module.CAN_ISOTP)
File "/usr/local/lib/python3.7/socket.py", line 151, in init
_socket.socket.init(self, family, type, proto, fileno)
OSError: [Errno 97] Address family not supported by protocol
I already searched the internet but didn't find anything helping me in this context. I am not sure why it isn't working (it worked before on a RPI3). Ifconfig shows both interfaces, can0 and can1.
I would really appreciate any help!
Hi, I recently discovered an error during receive. This error was discovered during some tests from Scapy.
Here is a log from python:
>>> load_contrib("isotp")
>>> s = ISOTPNativeSocket("vcan0", did=0x587, sid=0x607)
>>> s.recv()
WARNING: Captured no data. [Errno 84] Invalid or incomplete multibyte or wide character
Traceback (most recent call last):
File "/home/nils/PycharmProjects/secdev_scapy/scapy/contrib/isotp/isotp_native_socket.py", line 332, in recv_raw
pkt, _, ts = self._recv_raw(self.ins, x)
File "/home/nils/PycharmProjects/secdev_scapy/scapy/supersocket.py", line 130, in _recv_raw
pkt, ancdata, flags, sa_ll = sock.recvmsg(x, flags_len)
OSError: [Errno 84] Invalid or incomplete multibyte or wide character
Anyway, I could track this error down and found a way to reproduce it. Here is a candump file, which triggers this error.
candump_error.log
This error can even be triggered on isotprecv
. I've attached a patch to show this error.
isotprecv.patch.txt
This patch produces the following output:
./isotprecv -d 587 -s 607 vcan0
received -1, 84
I've sent the malformed CAN messages with canplayer like this:
canplayer -I candump_error.log vcan0=can1
From my first quick analysis, this bug comes from somewhere underneath the isotp-kernel module.
Hi,
I am trying to build CAN-ISOTP module by refering the link https://github.com/hartkopp/can-isotp and facing problem with installing Kernel headers
Error log for command : sudo apt-get install build-essential linux-headers-$(uname -r)
pi@raspberrypi:~/ISOTP/can-isotp $ sudo apt-get install build-essential linux-headers-$(uname -r)
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package linux-headers-5.4.44-v7l
E: Couldn't find any package by glob 'linux-headers-5.4.44-v7l'
E: Couldn't find any package by regex 'linux-headers-5.4.44-v7l'
kindly suggest how to build for RPI because i am new to these things
Thanks in advance
hi,
first, I have a question, what if I use read() and Incoming len parameter more than upcoming cantp message length, weather sure to be able to guarantee read() function recevie the whole cantp message?
then, when develop uds with can-isotp base linux , P2client's definition is shown in the figure below. But when I read can-isotp source code, i cannot find can-isotp support user get this event. This is caused by my ignorance or not implement it. Is it possible to add this if not implemented? Because I don't understand linux kernel development, even if I have ideas(register callback and i can implement it), I don't know how to do it. Similarly, can some cantp error(e.g. SF_DL error handling, FF_DL error handling and so on) be notified to the upper layer.
I followed the instructions to install the module, in which I get a warning and the module isn't installed.
I am on a beagle bone black with kernel 4.19.24-ti-r10
this is what I get after running sudo make modules install
make -C /lib/modules/4.19.24-ti-r10/build M=/home/debian/can-isotp modules_install
make[1]: Entering directory '/usr/src/linux-headers-4.19.24-ti-r10'
INSTALL /home/debian/can-isotp/net/can/can-isotp.ko
DEPMOD 4.19.24-ti-r10
Warning: modules_install: missing 'System.map' file. Skipping depmod.
make[1]: Leaving directory '/usr/src/linux-headers-4.19.24-ti-r10'
make -C /lib/modules/5.3.0-28-generic/build M=/home/xyz/candemo/can-isotp modules_install
make[1]: Entering directory '/usr/src/linux-headers-5.3.0-28-generic'
INSTALL /home/xyz/candemo/can-isotp/net/can/can-isotp.ko
At main.c:160:
similiar to #15 (comment)
I can receive first frame, I can't receive consecutive frames over isotp. Anyone could help to fix it?
The commit that set MAX_MSG_LENGTH to 66000 is missing from this repo. Can this commit be added in?
For reference: https://elixir.bootlin.com/linux/v5.18-rc1/source/net/can/isotp.c#L91
Hi,
I am using your library for quite a time and it was working fine until yesterday. I already opened an issue here: pylessard/python-can-isotp#37
I thought that I inserted the kernel module as described in the description the correct way (and I did since it was working fine). Now I faced the mentioned issue and discovered that I get an error inserting the module:
After using
dmesg
I can see that there is a problem with my kernel version:
I already did the standard procedure
sudo apt-get update & sudo apt-get upgrade
And tried to manually get the correct version from https://packages.ubuntu.com/bionic/linux-image-generic and updated my ubuntu version from 18.04 to 20 but its still not working.
Do you have any suggestions how to solve this?
Edit:
I also tried to remove the false version by hand and install the required kernel header, but its still not possible to insert the kernel module:
Best regards,
What data can I provide for you?
$ candump can0
can0 7E5 [8] 02 10 03 55 55 55 55 55
can0 7E5 [8] 02 10 03 55 55 55 55 55
can0 7E5 [8] 02 10 03 55 55 55 55 55
can0 7E5 [8] 02 10 03 55 55 55 55 55
$ isotpdump -s 7e5 -d 7ed can0
can0 7E5 [8] [SF] ln: 2 data: 10 03 55 55 55 55 55
$ isotprecv -s 7e5 -d 7ed can0
never returns a frame, no matter how many times I resend it (yet it still shows up in isotpdump + candump while isotprecv is running + waiting)
isotpdump doesn't look right; do you have any screenshots of examples showing what the -s and -d (and results) should look like?
Hello and thank you for your work on this kernel module. I appreciate being able to make a high quality system with it.
I have an issue that is probably a python issue, but I am hoping you may know something about it. I have a full write up at the following link:
pylessard/python-can-isotp#80
Basic details:
I am using the python-can-isotp library as a helper library to create a connection to the socketcan interface on my raspberry pi CM4 with MCP2515 chip onboard. This kernel module is running on the raspberry pi.
Everything works fine with a short delay between new calls to send, but if I send data too quickly the python socket will eventually enter a condition where it starts exclusively throwing socket.timeout errors on every call to send, never sending another packet again. If I try to close the socket the program locks up. During this error condition I am still able to send frames over that same CAN connection using isotpsend from another terminal window even as the python program repeatedly throws socket.timeout errors.
If I create the socket with the WAIT_TX_DONE flag, then when this error occurs it will lock up my entire python program and I will have to kill the program from another terminal. The timeout is only 100 milliseconds so I don't understand why this would lock up, and if this is a bug or I am simply misusing it.
Since I can use isotpsend from another terminal window during this lockup, this shows me that the actual CAN link is fine. So the problem should be between your kernel module and the python socket. Thus I should probably ask the python-help list for assistance, but I worry that concerns about CAN bus may be too specialized, or that such an email would only get routed to you anyway.
Here is what the system says about the link when my python program is locked up:
acorn@acornv2:~$ ip -details -statistics link show can1
4: can1: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP mode DEFAULT group default qlen 20000
link/can promiscuity 0 minmtu 0 maxmtu 0
can state ERROR-ACTIVE restart-ms 0
bitrate 500000 sample-point 0.875
tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
clock 8000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 0 0 0 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
RX: bytes packets errors dropped missed mcast
1509504 188688 0 0 0 0
TX: bytes packets errors dropped carrier collsns
6484689 891876 0 0 0 0
I would like to find out what is actually happening when it locks up, but I don't know how to debug that. I would also like to know how I can check the socket to confirm it is safe to send without having to hard code a wait, and finally I would like to know how to recover from this condition.
Any and all help is greatly appreciated. If I should take my question to python-help please let me know. Thank you!
While going through a solution for stmin discrepancy like it was not consistent with stmin timings , I came across yours and pylessard's python-can-istotp.
please can you highlight implementation and what would be the best solution in order to use flow control for multiframe which is having stmin.
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.
In my current set up I am running a real CAN-bus with three different devices to produce ISO-TP messages and one Ethernet adapter used as a sink for those messages.
$ isotprecv -s 7E0 -d 7E8 can0 -p 0 -l
$ candump -L can0,7FF:700
(0000012752.119897) can0 7DF#0209020000000000
(0000012752.121322) can0 7E8#1014490201574458
(0000012752.121678) can0 7E0#3000000000000000
(0000012752.122951) can0 7E8#212D53494D303031
(0000012753.171596) can0 7E8#2239323132333435
$ isotpsniffer -s 7E0 -d 7E8 can0
can0 7E8 [20] 49 02 01 57 44 58 2D 53 49 4D 30 30 31 39 32 31 32 33 34 35 - 'I..WDX-SIM0019212345'
This issue was opened after an exchange of emails with @hartkopp
I had a question concerning the behavior when sending a multi-frame packet. When I (client side) send a large chunk of data to the server (ECU), and the server does not send a Flow Control frame back to the client, the write(2)
operation does not return any clue about this misbehaving transaction (no error returned, and the number of bytes sent corresponds to the size of the packet).
I wanted to know if there is a way to know when the client enters in such a state.
I digged into the examples but did not found such a use-case.
When there's no FC we run into a timeout here:
https://elixir.bootlin.com/linux/v5.11.10/source/net/can/isotp.c#L751
I wanted to know if there is a way to know when the client enters in
such a state.
Good point. Usually you catch these errors by monitoring for a timeout on application(!) level as ISO-TP is an unreliable datagramm protocol anyway (like UDP).
Btw. there is a 'blocking write' feature with the CAN_ISOTP_WAIT_TX_DONE flag. This only returns from the write call when either the transmission is completed OR there has been a problem (e.g. timeout).
In the 'problem' case the sk_error is set.
But looking at the code here ...
https://elixir.bootlin.com/linux/v5.11.10/source/net/can/isotp.c#L955
... it always seems to return the original length value. And I did not test how the sk_error is propagated to the user.
Hm - maybe we can both take a look at this.
Did you try CAN_ISOTP_WAIT_TX_DONE?
Without CAN_ISOTP_WAIT_TX_DONE the errors can not be assigned to a specific PDU.
Hi,
I try to send the consecutive frame as fast as possible. (stmin =0 in the receiver)
I am noticing when using this ISTOP stack the best rate I can get is : Sending a consecutive frame each 350us.
But I can get up about 15us when using another ISTOP stack (running on windows)
Wondering what could cause this delay?
System information :
kernel : 5.10.90
CPU usage < 15%
Tx buffer 4000
Bit Rate 500kBit/s
How to preproduce the issue :
Send more few conductive frames using isotpsend where set stmin to 0 in the receiver.
Hi @hartkopp, I'm not sure if this is the proper venue to ask, but are there any plans for mainline?
thanks!
I am trying to create a deb
package for this module. I can successfully create the package, but I get this compilation error when trying to install it:
gcc -Wp,-MD,/var/lib/dkms/can-isotp/0.1.0/build/net/can/.isotp.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/4.8/include -I./arch/x86/include -Iarch/x86/include/generated/uapi -Iarch/x86/include/generated -Iinclude -I./arch/x86/include/uapi -Iarch/x86/include/generated/uapi -I./include/uapi -Iinclude/generated/uapi -include ./include/linux/kconfig.h -Iubuntu/include -D__KERNEL__ -fno-pie -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-PIE -fno-pie -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -DRETPOLINE -fno-delete-null-pointer-checks -Wno-maybe-uninitialized -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector -Wno-unused-but-set-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -pg -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -I/include/uapi -DMODULE '-DKBUILD_STR(s)=#s' '-DKBUILD_BASENAME=KBUILD_STR(isotp)' '-DKBUILD_MODNAME=KBUILD_STR(can_isotp)' -c -o /var/lib/dkms/can-isotp/0.1.0/build/net/can/.tmp_isotp.o /var/lib/dkms/can-isotp/0.1.0/build/net/can/isotp.c
/var/lib/dkms/can-isotp/0.1.0/build/net/can/isotp.c:74:29: fatal error: linux/can/isotp.h: No such file or directory
#include <linux/can/isotp.h>
^
compilation terminated.
make[2]: *** [/var/lib/dkms/can-isotp/0.1.0/build/net/can/isotp.o] Error 1
make[1]: *** [/var/lib/dkms/can-isotp/0.1.0/build/net/can] Error 2
make: *** [_module_/var/lib/dkms/can-isotp/0.1.0/build] Error 2
make: Leaving directory `/usr/src/linux-headers-4.4.0-116-generic'
Based on -I/include/uapi
in the gcc
command, I believe that the failure is because PROJECT_DIR
is unset in net/can/Makefile
. Presumably this is because the kernel's Makefile
does not propagate PROJECT_DIR
during the second-pass invocation of can-isotp
's top-level Makefile
...?
The package installs correctly if I change net/can/Makefile
to use this instead:
ccflags-y += -I$(M)/include/uapi
However, I am unfamiliar with best practices so I'm not sure whether this is the best fix. Suggestions?
Hello !
I used to make an application that sends a lot of CAN frames (encapsulating UDS requests) with the write() function using the ISO-TP driver through a peak-can device to an ECU that responds with the appropriate CAN frame/frames and i should get those responses each time i send a request using the read() function...the sending/receiving of requests/responses is done inside a while() loop, i extract the requests from a text file which has a structure like:
SID1 DID11 DID21
SID1 DID12 DID22
SID1 DID13 DID23
.....
SID2 DID11 DID21
SID2 DID12 DID22
SID2 DID13 DID23
....
then when getting the responses i write them in an xml file, the problem when i launch the app, it starts correctly and makes the necessary send/receive until it blocks after a while, (it can blocks in any part of the whole number of requests, it can be just in the beginning (after sending/receiving 6to9 requests/responses) , in the middle or just before finishing, there is no particular position), this picture show one of those blocking scenarios :
the red lines corresponds to the requests and the blue ones are the responses,
i fetched the code and i found that the read() function is causing the block situation, normally if the ECU didn't response in a certain timeout the read() must not stay waiting and blocking the whole program no ?
i have the an Ubuntu 14.04, i used the isotp module to handle the socketCAN just the way like the isotp utilies (isotpdump, isotprecv, ..)
does the ISO-TP driver handle any sort of timeout when getting stacked in a such situation, knowing that, when i open a terminal in parallel when the app get blocked and send a random request using isotpsend, the app gets out of the blocking situation and continue to send but then it blocks again !
Thank you very much !
akast@ubuntu:~/can-isotp/net/can$ make
make -C /lib/modules/4.10.0-19-generic/build M=/home/akast/can-isotp/net/can modules
make[1]: Entering directory '/usr/src/linux-headers-4.10.0-19-generic'
CC [M] /home/akast/can-isotp/net/can/isotp.o
/home/akast/can-isotp/net/can/isotp.c:68:29: fatal error: linux/can/isotp.h: No such file or directory
#include <linux/can/isotp.h>
^
compilation terminated.
Hi,
Just wanted to check utils' source code on the link that you provided in howto, but I wasn't able to make my browser to resolve it.
Does this site still exist and up?
When specifying a value for stmin, some CAN frame seems to be lost. candump shows missing frames. Reading with a CAN_RAW socket shows the same behaviour. Strangely, isotprecv
has a complete payload.
I ran :
isotprecv -s 701 -d 700 -m 64 vcan0
then
python3 -c "print(' '.join(['%02x' % x for x in range(100)]))" | isotpsend -s 700 -d 701 vcan0
This not only happen with isotpsend
and isotprecv
. I can reproduce the same behaviour by sending through a socket in Python.
If I set StMin = 0. I get this good behaviour
Interestingly, I can write this data successfully on the sender socket, but I cannot receive the same data on the receiver socket.
It appears that the container_of
function is returning an isotp_sock
struct with rx.state == ISOTP_WAIT_DATA
here in the source.
When I run candump I don't see all frames. Please note that this is all happening on a vcanX interface.
Hi once again :)
I got the following Use-Case:
This is problematic as it forces me to open another socket to send those functional requests. That socket needs an RX address for which I have to pick some, hopefully not otherwise used, address/ID, while it actually should never receive something.
Is there/could there be a way to bind to a "I-don't-care" address, have an "only-sending" socket mode or anything along those lines?
Hello,
I'm using an UDS client that uses the can-isotp Linux kernel module as the transport layer to carry out a firmware update on an ECU.
After requesting a download and receiving a confirmation from the ECU I proceed to transfer blocks of 3074 bytes over CAN-ISOTP to deliver the firmware to the ECU. For this, I call write(int fd, const void *buf, size_t count)
with the file descriptor obtained from calling socket(AF_CAN, SOCK_DGRAM | SOCK_NONBLOCK, CAN_ISOTP)
and bound to an specified address. This transfer is performed by a development board with a Linux Gateway (to which I'm connected over SSH) to the ECU. I sniff out the whole bus traffic with the PCAN-USB adapter (https://www.peak-system.com/PCAN-USB.199.0.html?&L=1) connected to an Ubuntu VM with the candump
command from can-utils.
That's when I observe that after the eleventh consecutive frame (CF) is sent, the next sequence number is not right (0x0
instead of 0xC
) and further down it gets even worse; some sequence numbers get sent twice or three times. It also does not transmit all required 3074 bytes. Here the example "candumped" trace (IDs hidden):
(255.316173) can0 18DAXXF1 [8] 1C 02 36 01 5B 47 65 6E // start of transfer, (0xC02) is for 3074 bytes
(255.318129) can0 18DAF1XX [8] 30 00 00 FF FF FF FF FF // flow control from ECU
(255.319999) can0 18DAXXF1 [8] 21 65 72 61 6C 49 6E 66 // sending consecutive frames
(255.319999) can0 18DAXXF1 [8] 22 6F 5D 0D 0A 54 59 50
(255.322550) can0 18DAXXF1 [8] 23 45 20 3D 20 30 78 30
(255.324832) can0 18DAXXF1 [8] 24 30 30 38 0D 0A 42 4F
(255.327750) can0 18DAXXF1 [8] 25 41 52 44 20 3D 20 22
(255.327750) can0 18DAXXF1 [8] 26 78 43 55 2D 54 48 48
(255.327751) can0 18DAXXF1 [8] 27 22 0D 0A 5B 4D 53 57
(255.330786) can0 18DAXXF1 [8] 28 43 6F 6E 74 65 6E 74
(255.330787) can0 18DAXXF1 [8] 29 5D 0D 0A 3A 32 30 30
(255.333698) can0 18DAXXF1 [8] 2A 30 30 30 30 30 37 34
(255.333698) can0 18DAXXF1 [8] 2B 37 34 35 46 36 36 37 // all sequence numbers were alright until here
(255.335666) can0 18DAXXF1 [8] 20 30 32 30 30 30 30 36
(255.335667) can0 18DAXXF1 [8] 26 31 46 41 35 44 33 34
(255.335667) can0 18DAXXF1 [8] 23 33 41 44 45 44 43 46
(255.337927) can0 18DAXXF1 [8] 21 39 34 43 39 43 35 34 // sequence number 1 three times
(255.337928) can0 18DAXXF1 [8] 21 30 41 30 30 30 32 32
(255.337928) can0 18DAXXF1 [8] 21 32 33 38 38 36 31 44
(255.340456) can0 18DAXXF1 [8] 20 32 46 39 43 32 39 43 // sequence number 0 two times
(255.340456) can0 18DAXXF1 [8] 20 30 44 33 39 30 41 34
(255.342514) can0 18DAXXF1 [8] 2F 44 33 37 44 39 41 39
(255.342514) can0 18DAXXF1 [8] 20 45 42 32 31 45 33 42
I have come to a few ideas why this might not be working like e.g. that there is maybe interference on the CAN bus (physical reason) because I don't want to think that there might be something wrong with this kernel module. After double-checking my code I came to the realization that it all happens after the already mentioned write()
call and then the kernel module takes care of the ISOTP part of the transfer.
I would highly appreciate any input as to why this might be happening - hardware or software related. Thanks in advance!
I am on ubuntu 18.04 and can-isotp did not work unless I also ran sudo depmod -a
after installing.
You may want to add this step to the installation instructions.
It's possible that this was required as a byproduct of #7 , which I resolved by generating a signing key. I am not sure if the initial install attempts without the signing key created a messed up install that was not completely overwritten by subsequent install attempts with the signing key present (and I don't know how to uninstall, so I can't try again to be sure!).
Either way, I don't think running sudo depmod -a
hurts anything, so why not add it to the install instructions?
Hi @hartkopp , first of all thanks for the library. I used on my RPI3 where I did not have any problems. Now I switched to a Jetson TX2 and got the known [OSError: [Errno 93] Protocol not supported] issue.
I read about the kernel module https://github.com/hartkopp/can-isotp-modules, but get the following error messages during the procedure:
ccd3@ccd3-desktop:~/can-isotp-modules/net/can$ ./make_isotp.sh
CAN ISO-TP has moved to https://github.com/hartkopp/can-isotp.git
This repository is not maintained anymore.
Are you sure you want to continue the build? (if so press ENTER)
make -C /lib/modules/4.9.140-tegra/build M=/home/ccd3/can-isotp-modules/net/can modules TOPDIR=/home/ccd3/can-isotp-modules/net/can/../..
make[1]: Entering directory '/usr/src/linux-headers-4.9.140-tegra-ubuntu18.04_aarch64/kernel-4.9'
arch/arm64/Makefile:49: LSE atomics not supported by binutils
make[1]: *** No rule to make target 'before'. Stop.
make[1]: Leaving directory '/usr/src/linux-headers-4.9.140-tegra-ubuntu18.04_aarch64/kernel-4.9'
Makefile:12: recipe for target 'modules' failed
make: *** [modules] Error 2
I tried to find somethong about this issue and some information if it may is a NVIDIA TX2 issue but wasn't able to find anything about it.
I would be very happy about every hint, how to install the kernel module in my case. Best regards!
hello
because is to hard to find real examples and options is to complicated here is real example from beaglebone black - Linux beaglebone 4.14.49-ti-r54 - with BMW car connected to diagnostic bus talking to ecu 0x40 (CAS) with tester address 0xF1:
echo "22 31 01" | isotpsend -s 6F1 -d 640 -x 640 can1
isotprecv -s 6F1 -d 640 -x 640:6F1 -l can1
62 31 01 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 30 18 00 00 00 50 50 00 00 00 E7 70 00 00 20 00 00 00 00 00 00 00 14 A0 13 A0 00 00 00 00 00 00 04 50 18 00 00 00 50 50 00 00 00 E7 70 00 00 20 00 00 00 00 00 00 00 14 A0 13 A0 00 00 00 00 00 00 04 50 18 00 00 00 50 50 00 00 00 E7 70 00 00 20 00 00 00 00 00 00 00 14 A0 13 A0 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
isotpdump -s 6F1 -d 640 -x 640 can1
can1 6F1{40} [5] [SF] ln: 3 data: 22 31 01
can1 640{F1} [8] [FF] ln: 234 data: 62 31 01 08 00
can1 6F1{40} [4] [FC] FC: 0 = CTS # BS: 0 = off # STmin: 0x00 = 0 ms
can1 640{F1} [8] [CF] sn: 1 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 2 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 3 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 4 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 5 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 6 data: 00 08 00 00 00 00
can1 640{F1} [8] [CF] sn: 7 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 8 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 9 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: A data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: B data: 00 00 00 00 08 00
can1 640{F1} [8] [CF] sn: C data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: D data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: E data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: F data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 0 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 1 data: 00 03 30 18 00 00
can1 640{F1} [8] [CF] sn: 2 data: 00 50 50 00 00 00
can1 640{F1} [8] [CF] sn: 3 data: E7 70 00 00 20 00
can1 640{F1} [8] [CF] sn: 4 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 5 data: 14 A0 13 A0 00 00
can1 640{F1} [8] [CF] sn: 6 data: 00 00 00 00 04 50
can1 640{F1} [8] [CF] sn: 7 data: 18 00 00 00 50 50
can1 640{F1} [8] [CF] sn: 8 data: 00 00 00 E7 70 00
can1 640{F1} [8] [CF] sn: 9 data: 00 20 00 00 00 00
can1 640{F1} [8] [CF] sn: A data: 00 00 00 14 A0 13
can1 640{F1} [8] [CF] sn: B data: A0 00 00 00 00 00
can1 640{F1} [8] [CF] sn: C data: 00 04 50 18 00 00
can1 640{F1} [8] [CF] sn: D data: 00 50 50 00 00 00
can1 640{F1} [8] [CF] sn: E data: E7 70 00 00 20 00
can1 640{F1} [8] [CF] sn: F data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 0 data: 14 A0 13 A0 00 00
can1 640{F1} [8] [CF] sn: 1 data: 00 00 00 00 08 00
can1 640{F1} [8] [CF] sn: 2 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 3 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 4 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 5 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 6 data: 00 00 00 00 00 00
can1 640{F1} [8] [CF] sn: 7 data: 00 FF FF FF FF FF
isotpsniffer -s 640 -d 6F1 -x 6F1 -X 640 -f 1 can1
can1 6F1 [3] 22 31 01
can1 640 [234] 62 31 01 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 30 18 00 00 00 50 50 00 00 00 E7 70 00 00 20 00 00 00 00 00 00 00 14 A0 13 A0 00 00 00 00 00 00 04 50 18 00 00 00 50 50 00 00 00 E7 70 00 00 20 00 00 00 00 00 00 00 14 A0 13 A0 00 00 00 00 00 00 04 50 18 00 00 00 50 50 00 00 00 E7 70 00 00 20 00 00 00 00 00 00 00 14 A0 13 A0 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
to work isotpsniffer and isotpdump - isotprecv must be running to send FC frames.
Hi
I guess this question applies to sockets in general, but I figured I'd ask here anyway.
Is there a way to get a status of the transmission after writing to the socket? The goal would be to know if the last frames has been sent.
The rationale behind this is that UDS protocol has some reply timeout values defined and they appear to be relative to the moment a request has been completely sent. For large request, it can takes seconds to get the whole payload transmitted. If I want to check the timeout correctly, I have to start counting from the end of that delay, not from the moment I write to the socket.
Any idea how this could be handled with your module?
There appears to be a ~5ms delay introduced between consecutive frames when sending a large message, and the ECU has responded with a st_min of 0 (30 00 00).
This seems to be around the check for so->tx_gap (which was so->tx_gap.tv64). iosotp_tx_burst. Have made a quick change to look at the st_min rather than the tx_gap which is working for now. Not a kernel expert so unsure if this would have any side effects.
I am enabling the wait_tx_done
flag via python-can-isotp project and if I read back the socket opts it is showing as set:
<OPTS_GENERAL: optflag=0x404, frame_txtime=0x0, ext_address=0x0, txpad=0x0, rxpad=0xcc, rx_ext_address=0x0>
However, when I test sending a large message (>3kB), the send returns almost immediately (within ~2ms).
The kernel I have is: 5.13.0-1016-raspi
Is there a way to know if the can-isotp I have supports the wait_tx_done
flag? And, if so, any idea why this might not be working for me?
Hello ,
i am trying to build the ISO TP for the R-PI, But i am getting the error like below when I am executing the command :
sudo apt-get install build-essential linux-headers-$(uname -r)
kindly help me with this I am really new to this.
pi@raspberrypi:~/can-isotp $ sudo apt-get install build-essential linux-headers-$(uname -r)
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package linux-headers-5.10.17-v7l
E: Couldn't find any package by glob 'linux-headers-5.10.17-v7l'
E: Couldn't find any package by regex 'linux-headers-5.10.17-v7l'
Hardware Details :
R-PI 4 .
OS : rasbian deb_buster version
Regards,
Kallappa
With Linux 4.4.67, I get this error:
net/can/isotp.c: In function ‘isotp_bind’:
net/can/isotp.c:1120:2: error: too few arguments to function ‘can_rx_register’
can_rx_register(dev, addr->can_addr.tp.rx_id,
^
In file included from net/can/isotp.c:67:0:
include/linux/can/core.h:48:5: note: declared here
int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
^
scripts/Makefile.build:258: recipe for target 'net/can/isotp.o' failed
make[2]: *** [net/can/isotp.o] Error 1
Apparently, the kernel API of can_rx_register() was changed in 4.4.50, not 4.9.11. I commented in downwith's repo here:
downwith/linux-isotp@d3bb87f#commitcomment-23411680
The upstream commit which changed it was this:
torvalds/linux@e6c654c
Too bad both you and downwith chose to copy over the code (that's so 20th century ;-)), instead of doing github-internal forks. With the latter solution, we could have tracked history through all of the development.
I run the make command and this is the answer that I receive is:
make -C /lib/modules/3.16.0-8-amd64/build M=/home/rubio/can-isotp modules
make[1]: Entering directory '/usr/src/linux-headers-3.16.0-8-amd64'
make[1]: Entering directory `/usr/src/linux-headers-3.16.0-8-amd64'
CC [M] /home/rubio/can-isotp/net/can/isotp.o
/home/rubio/can-isotp/net/can/isotp.c: In function ‘isotp_bind’:
/home/rubio/can-isotp/net/can/isotp.c:1141:2: error: too few arguments to function ‘can_rx_register’
can_rx_register(dev, addr->can_addr.tp.rx_id,
^
In file included from /home/rubio/can-isotp/net/can/isotp.c:67:0:
/usr/src/linux-headers-3.16.0-8-common/include/linux/can/core.h:48:5: note: declared here
int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
^
/usr/src/linux-headers-3.16.0-8-common/scripts/Makefile.build:262: recipe for target '/home/rubio/can-isotp/net/can/isotp.o' failed
make[5]: *** [/home/rubio/can-isotp/net/can/isotp.o] Error 1
/usr/src/linux-headers-3.16.0-8-common/scripts/Makefile.build:409: recipe for target '/home/rubio/can-isotp/net/can' failed
make[4]: *** [/home/rubio/can-isotp/net/can] Error 2
/usr/src/linux-headers-3.16.0-8-common/Makefile:1362: recipe for target 'module/home/rubio/can-isotp' failed
make[3]: *** [module/home/rubio/can-isotp] Error 2
Makefile:181: recipe for target 'sub-make' failed
make[2]: *** [sub-make] Error 2
Makefile:8: recipe for target 'all' failed
make[1]: *** [all] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-3.16.0-8-amd64'
Makefile:21: recipe for target 'modules' failed
make: *** [modules] Error 2
I have tried to upgrade my kernel and also y update can-utils but I still receiving the same error.
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!
akast@ubuntu:~/can-isotp$ sudo make modules_install
make -C /lib/modules/4.10.0-19-generic/build M=/home/akast/can-isotp modules_install
make[1]: Entering directory '/usr/src/linux-headers-4.10.0-19-generic'
INSTALL /home/akast/can-isotp/net/can/can-isotp.ko
At main.c:158:
I want to learn can fd unfortunately I have pi can2 bord which does not support can fd. I am wondering if I can use virtual can for canfd?
Hey everyone!
I have a simple can client server, that uses can-isotp to send data, and I want to know if there's any way of finding if the message was fully sent, if there's any packet loss, or any sort of callback that helps me lead with message recovery.
Thanks is advance!
Alfonso
In the main()
, I'm opening a can-isotp socket, and I perform write()
operation on it. This part is working, the expected CAN frames are sent on the bus.
Now, I'm performing a blocking call to read()
on a separated thread. This part is also working, I'm receiving the expected CAN frames.
The issue arises when I'm calling close()
on the main()
function. I would expect the read()
function to return an error (such as EBADF
or something similar), but instead of this, it keeps blocking, while the close()
function returns 0.
Is it the expected behaviour? If it is the case, what is the proper way to exit from a blocking read()
?
Searching for compatibility issues I have (probably on my side may come back later if I can't resolve them :D), I found this #include "compat.h"
in isotp.c
which seems to be something from the old repository but isn't needed anymore?!
I did tried to compile on raspberry pi jessie and observed following error:
make -C /lib/modules/4.9.78-v7+/build M=/home/pi/socCan/can-isotp PROJECT_DIR=/home/pi/socCan/can-isotp modules
make[1]: *** /lib/modules/4.9.78-v7+/build: No such file or directory. Stop.
Makefile:21: recipe for target 'modules' failed
make: *** [modules] Error 2
I did tried to fix this using apt update and upgrade but issue is not getting fixed.
Following is my system configuration
Linux pilinux 4.9.78-v7+ #1084 SMP Thu Jan 25 18:05:49 GMT 2018 armv7l GNU/Linux
Can someone please help me to resolve this issue?
Recently, I updated to the kernel 5.2.1-1-MANJARO
.
Since then ISOTP socket throw an error. With 5.1.18-1-MANJARO
the error does not appear.
Program to reproduce:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#define CAN_ISOTP 6
int main() {
int fd = socket(AF_CAN, SOCK_DGRAM, CAN_ISOTP);
struct timeval tv;
int res = ioctl(fd, SIOCGSTAMP, &tv);
printf("error code: %d\nerrorno: %d\n", res, errno);
perror("ioctl() failed");
close(fd);
return 0;
}
Output:
~ $ ./test
error code: -1
errorno: 25
ioctl() failed: Inappropriate ioctl for device
With 5.1.18-1-MANJARO
the output is:
~ $ ./test
error code: -1
errorno: 2
ioctl() failed: No such file or directory
Which is fine because no packet has been received.
This commit might be related to this problem:
torvalds/linux@c7cbdbf#diff-35a396ec1d0c44b5f7a45af70ec25268
This issue is a mix of requirements and questions that arise maybe from my limited knowledge of the Linux kernel. I have been facing many times in the past a situation where I open many IsoTP socket and don't close them properly and end up not being able to use a specific socket address.
Basically, I try to create a new socket using the same txid and rxid of the previous unclosed socket and the result is that I cannot changes its parameters (stmin, bs, wftmax) and reception is working interrmitently, (just like if 2 sockets were emptying the same buffer).
I know I created that problem by mishandling the sockets, but when that happens, I have found no other solution than rebooting my mahcine to clean that up. I've tried resetting the networking services, putting down/up the vcan interface, unloading the kernel module. None works.
Is there a way to reset the state of the kernel module?
I am convinced that I installed and made can-isotp properly, but for some reason, I'm not able to rock with isotpsniffer. Please advise.
When I sudo insmod ./net/can/can-isotp.ko ,terminal print “insmod: ERROR: could not insert module ./net/can/can-isotp.ko: Unknown symbol in module”.
The results of "dmesg | tail -n 1" is "can_isotp: Unknown symbol can_rx_register (err -2)".
I want to load this on raspiberry pi 3b+.
The result of "uname -a" is "Linux raspberrypi 4.19.75-v7+ #1270 SMP Tue Sep 24 18:45:11 BST 2019 armv7l GNU/Linux".
The result of "file net/can/can-isotp.ko" is "net/can/can-isotp.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=f52ef777e54005ea9204e616f0fb5a7335f543a8, not stripped".
What should I do to solve this problem ? thanks.
Hi!
I'm working on including your kernel module into an embedded distribution build framework (OpenEmbedded). I noticed there is no reference to the license this code is available under. I'd expect it to be GPLv2, but having it clearly stated would be much appreciated. If that's the case, could you please add the GPLv2 COPYING
file to the repo?
Hi,
I've been flagged an issue with my Python Iso-TP module (pylessard/python-can-isotp#22) regarding a backward compatibility issue. After diving into it, I believe the issue is a conflict between Python and this module.
Apparently, opening an ISOTP socket with Python 3.7.6 and a can-isotp.ko built under Linux 5.4 doesn't work. I believe the problem arise from the addition of J1939 support that modified the size of the sockaddr_can
structure (change acknowledges by yourself :) ).
Python create the address object for the user and deduce the length of the address object by using sizeof(*addr)
. If Python has been compiled with a headers of Linux 5.3, then the this value should be smaller than what one would get with Linux headers of Linux 5.4+.
This line here, checks for conflicts by validating the size of the address object. This verification will prevent the creation of ISO-TP socket if an older Python is used with a freshly compiled kernel module.
Is there a way to be backward compatible with this or should one make sure to keep his Python version aligned with his Kernel version?
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.