Hacking into a Vehicle CAN bus (Toyothack and SocketCAN)

CAN bus is an automation fieldbus commonly used in the automotive industry as the main network bus to allow communications between the many on-board ECUs on modern vehicles.

The Linux kernel has native CAN bus support at network layer since some years, with a lot of drivers for both embedded and USB CAN bus controllers, so it’s now fairly easy to add a CAN bus interface to any Linux laptop and have a playaround with it.

In this post I’ll show how to tap into a modern car local bus, dump a bunch of data and analyze the trace offline to write a decoder from scratch using the SocketCAN APIs and utilities.

This is based on my experiences hacking into my Toyota… Toyothack!


http://fabiobaltieri.files.wordpress.com/2013/07/toyothack-intro.png?w=630

CAN bus Network Model

If you are new to field busses, CAN bus may appear weird at first sight. The bus is physically deployed as a terminated differential twisted pair with a ground reference, and it’s usually in a trunk-drop topology, where many nodes are connected to a main trunk cable with short drop lines, sometimes using T junctions. The bus runs up to 1Mbps, and the speed directly influences the max bus length.

http://fabiobaltieri.files.wordpress.com/2013/07/toyothack-trunkdrop.png?w=630

(Image from Maxim MAX3051 datasheet)

What is really interesting about CAN bus is the actual usage model: each packet has single address of either 11 or 29 bits (the latter is called extended frame), and a maximum payload of 8 bytes. The unusual thing is that we think of frame address, not source or destination address, in fact CAN bus nodes does not have an address at all!

http://fabiobaltieri.files.wordpress.com/2013/07/toyothack-canframe.png?w=630

(Image from Analog Devices AN-1123 Application Note datasheet)

The idea behind this is that address are used to identify the type of frame (i.e. what’s the meaning of the payload), and all nodes on the bus can send and receive any type of frame. As the bus can have a lot of traffic on it, but most nodes only care about some specific frame IDs and does not have the computational resources to handle the full traffic, each CAN bus controller implements some sort of “acceptance filter”, which is usually a bitmask to decide which range of frame addresses should be received by the node, while all the others are discarded silently.

What this means that while the bus is physically a broadcast (all the nodes are connected to the same cable), the protocol makes it work logically as multicast.

This makes the bus very well suitable in automotive and automation environment, where some sensor may put data on the bus that is used by many processors or actuators, and allows to mix nodes with different computing power on the same bus.

At the same time, nothing prohibit the designer to assign some frame addresses for a logically point-to-point communication between two specific nodes, and implement a stream protocol no top of it: in fact that’s what is done in the standard ISO-TP protocol, and there even is a SocketCAN example application to run a full Linux netdevice on top of it.

One additional feature is that the bus is designed so that lower frame addresses have an higher priority when contending for the bus. This should be kept into account when designing the high level protocol, where often the address is segmented into fields, dedicating an higher portion as a “priority” indication.

CAN bus in Automotive

CAN bus was designed for the automotive environment, and that’s where it’s still widely deployed. A modern car have many different ECUs and sensors, and the multicast nature of CAN bus makes it ideal to distribute the data as needed.

Let’s take vehicle speed as an example, it is transmitted just once on the bus by some wheel sensor, and may be used at the same time by the dashboard, ABS, cruise control, radio/navigation and other devices.

Of course, some data and some nodes are more important than the others, and while CAN bus controller implements some safety features such as error counters to self-disconnect from the bus in case of errors, the bus itself can still suffer from a catastrophic failure, such as a cable short or a cut in the middle.

For this reason, complex cars usually have more than one bus, often running at different speed. As an example that I found on a FIAT car, one bus is running at a relatively high speed (500kbps) and it’s wired only on the front of the car connecting critical systems, such as engine control, ABS, power steering and so on. An additional bus runs at a much lower speed (50kbps), allowing for longer connection segments, and it’s only used by the non critical equipments, such as dashboard, stereo, electric windows, lights, parking sensors etc. This one is also wired into the CAN pair of the OBD diagnostic connector, making this easier to tap into.

All vehicle busses are usually connected to a common ECU at some point, which may be used as a proxy to selectively transport some information between busses, while keeping the physical isolation for safety reasons.

How the bus is laid out is specific to each car, so you may want to search for the service manual of a specific model, where you can usually found information on the physical bus topology. Some really complex installation may also spot additional LIN busses behind CAN bus nodes… Do your own research!

On-Board What??

OBD, or On-board Diagnostics, is a set of standards to provide diagnosis and error reporting from the vehicle ECU.

The idea behind OBD is that as modern vehicles rely heavily on electronics and have a many self test capability, a common protocol should allow a service center to read some standard error code to help troubleshooting. Once an ECU detect some sensor value is out of a “safe” range, the system can store an error code and alert the driver by lighting up the well known “check engine” yellow light. At this point, a service center should be able to connect a generic scanner to the vehicle standard OBD port, and that should give a indication of what have failed in the vehicle history.

How’s that related to CAN bus? The OBD was originally implemented through some simple vendor-specific protocol, at the point that when the standard OBD-II connector was defined many different busses, including CAN bus, were supported on the same cable, and a generic scanner needed to support all of those and guess which one is used on a specific vehicle (see ELM327).

Luckily enough, vehicle regulations become more specific over time, to the point that since 2008, all car sold in the USA are required to implement OBD-II in the CAN bus signaling variant.

This means that in most (possibly all) modern cars, you can find a standard diagnostic connector accessible somewhere near the dashboard, and on this connector you are sure to get access to one of the vehicle CAN bus.

So, what can you expect to find once you tap into that bus with your CAN bus interface? You can’t tell until you try, because apart from OBD data (which doesn’t send anything on it’s own anyway), the bus can be used by the vendor for anything else: it may be the only bus of the car – in which case you get lots of data – or it may be dedicated for diagnosis, and in this case you get nothing at all.

If you are reading this just to have some fun and learn more about your car digital guts, you’ll not find OBD data that interesting, as that’s mostly diagnostic stuff. On the other side, if you manage to attach and configure your interface correctly, turn on the ignition and see a flow of data, that means the bus you’re on is also shared with other vehicle ECUs, and that’s where the fun begins!

So, to sum up: most modern car have many digital busses, and at least one is a CAN bus and exposed on the standard diagnostics connector. You can attach a generic interface on it and send access generic OBD data, but if the vendor decided to use that bus for something else, you’ll also find a stream of vendor-specific frames, with real time sensor and control information, waiting to be reverse engineered.

SocketCAN

On a CAN bus system you have a lot of self-contained microcontroller/DSP based units connected together, each one with its own acceptance filter and possibly injecting some information on the bus, but how does it step-up to be used on a complex operating system? Enter SocketCAN.

SocketCAN is CAN bus stack for the Linux kernel, contributed by a team at Volkswagen Research (well done VW!), and it’s really ingenious in that it implements CAN bus as a network device, exploiting many existing features of the Linux network stack.

What this means practically is that you are going to see your CAN bus controller as a network device, controlled by the “ip” system command.

That’s an example of how a CAN bus device appears on the system:

# ip link show dev can0
9: can0: <NOARP,UP,LOWER_UP> mtu 16 qdisc noqueue state UNKNOWN mode DEFAULT
    link/can

From an application point-of-view this great news, as it means that CAN bus is handled by the well know Berkley sockets APIs and you have full software portability: there is no API difference between an USB interface connected to a big workstation or a memory mapped interface on a small ARM SoC. The main “trick” is that when using a socketcan interface, the application actually send and receive a specific can_frame structure, defined as:

#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */
#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
#define CAN_ERR_FLAG 0x20000000U /* error message frame */

typedef __u32 canid_t;

#define CAN_MAX_DLC 9
#define CAN_MAX_DLEN 8

struct can_frame {
        canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
        __u8    can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
        __u8    data[CAN_MAX_DLEN] __attribute__aligned(8);
};

At system level, it means that your applications behave like nodes on the bus: they can be attached to a “virtual” interface and exchange frames with any other node, without knowing if those are real devices on an external bus or other applications running locally on the same virtual interface.

At a low level, this also means that the interface driver is running with fully open acceptance filter, so the kernel actually receives all the bus data and decides whether or not to send frames to any application depending a higher level software filter, but that’s usually not a problem as modern Linux enabled SoCs are powerful enough to handle the full traffic anyway.

At this point you may be interested into how to find a list of supported USB-to-CANBUS devices to play with, and that’s quite easy as all of those are in a dedicated directory in the kernel sources. Either way, this is a quick list:

Of all of this, I’ve only had experiences the EMS one, but that’s quite expensive and maybe harder to obtain, so the one I would buy right now is the USB2CAN from 8 devices: it’s cheap, you can get one from the webstore and they provide full schematics and firmware upgrades. There is also a repository with the actual device source code, but that’s hardly of any use without the correct programming environment.

As for my setup, I’m using my own open hardware USB AVR + MCP2515 interface. You can find the repository for my design here, but the performances are not that good above 250kbps, so I’m planning a complete redesign in the future.

What if I’m Stuck on Windows?

While I don’t usually consider this case, I’ve seen CANviaUSB used in the development on a critical project and seems to be a great tool. So, if you really can’t avoid Windows, CANviaUSB is probably the free tool for you (the homepage contains a list of supported device).

Hacking Into the Bus

If you’ve read all the way through here I hope you’ve understood that you will have no idea of what’s attached to the bus until you’ve analyzed it. This also means that you don’t know what can break once you start poking on it, so this may be a good time for a bit of a disclaimer:

You shouldn’t mess with your vehicle bus while it’s moving unless you are 100% sure of what’s going on. The chance of breaking something critical is high and you can hurt someone (possibly yourself) if you mess up.

The first thing you need other than a laptop and the CAN bus interface is a matching cable for the OBD-II port. I have an OBD to DE-9 cable from SparkFun, but you may also find a suitable one from your CAN bus interface vendor. As with my interface I used a custom 8P8C based connector, I’ve actually cut my DE-9 side of the cable and crimped the wires to a standard Ethernet Jack.

http://fabiobaltieri.files.wordpress.com/2013/07/toyothack-sfcable.jpg?w=630

(Image from Sparkfun)

You should check the cable and interface pinout twice before attaching to the vehicle, as there are many signals on the connector, including a +12V and possibly some vendor specific ones.

http://fabiobaltieri.files.wordpress.com/2013/07/toyothack-obdpinout.png?w=630

(Image from Wikipedia)
– pin 4: chassis ground
– pin 5: signal ground
– pin 6: CANH
– pin 14: CANL
– pin 16: Battery Voltage

This is the actual connector pinout. Be sure to connect the CANH, CANL and GND signals. Shielding and +12V may be useful too but the other lines should be left unconnected.

Next, you should find the connector in the vehicle. The shape is easy to spot but it may actually be hidden under the dashboard, in an internal fuse box or under the ashtray or some other removable feature.

Don’t force the connector too much, many of those cheap cables are badly designed and fits too tight, I actually had to chop off some plastic from mine.

Also, make sure to connect the car while the ignition is OFF for thirty seconds or so – I found my car transmits data for some time even when everything should be shut off.

Device Configuration and Dumpting the Stream

Time to dump some data, but the interface have to be configured first!

The standard command to configure a CAN bus interface is ip, as in:

# ip link set can0 type can help
Usage: ip link set DEVICE type can
        [ bitrate BITRATE [ sample-point SAMPLE-POINT] ] |
        [ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1
          phase-seg2 PHASE-SEG2 [ sjw SJW ] ]

        [ loopback { on | off } ]
        [ listen-only { on | off } ]
        [ triple-sampling { on | off } ]
        [ one-shot { on | off } ]
        [ berr-reporting { on | off } ]

        [ restart-ms TIME-MS ]
        [ restart ]

        Where: BITRATE       := { 1..1000000 }
               SAMPLE-POINT  := { 0.000..0.999 }
               TQ            := { NUMBER }
               PROP-SEG      := { 1..8 }
               PHASE-SEG1    := { 1..8 }
               PHASE-SEG2    := { 1..8 }
               SJW           := { 1..4 }
               RESTART-MS    := { 0 | NUMBER }

Here you need to set the bitrate to match the one used in your target bus. As you probably don’t know that before starting, you have to take a guess (or probe it with an oscilloscope).

As CAN bus sends error frames if misconfigured, you most likely want to keep the interface in listen-only mode for all the time, so that other nodes does not notice that something weird is happening. Just as you know, what may happen if you forget to do so is that something on the bus notices the problem and either display (like in the car stereo) or records the error.

This is how you set the can0 interface at 500kbps in listen only mode:

# ip link set can0 type can bitrate 500000 listen-only on

If there are no errors you can now bring the interface up and start dumping frames:

# ip link set can0 up
# candump -cae can0,0:0,#FFFFFFFF

At this point, you are receiving everything that is happening on the bus, including errors. You should try doing something on the car, like closing a door or turning on the ignition.

If your bitrate is wrong, you should receive a stream of errors from the CAN bus interface:

$ candump -cae can0,0:0,#FFFFFFFF
  can0  20000008  [8] 00 00 04 00 00 00 00 00   ERRORFRAME
        protocol-violation{{bit-stuffing-error}{}}
...

In this case, bring the interface back down, and try with a different bit-rate. Most common ones are 500kbps, 250kbps and 50kbps.

If you are lucky, you’ll eventually find the correct configuration, and get a lot of valid frames from candump:

balto@balto:~$ candump -cae any,0:0,#FFFFFFFF
  can0  440  [8] 40 00 80 00 00 00 00 00   '@.......'
  can0  442  [8] 42 00 80 00 00 00 00 00   'B.......'
  can0  440  [8] 40 01 80 00 00 00 00 00   '@.......'
  can0  620  [8] 10 80 00 00 00 40 00 80   '.....@..'
  can0  442  [8] 42 01 80 00 00 00 00 00   'B.......'
  can0  440  [8] 42 02 00 00 00 00 00 00   'B.......'
  can0  442  [8] 40 02 00 00 00 00 00 00   '@.......'
  can0  440  [8] 42 02 00 00 00 00 00 00   'B.......'
  can0  620  [8] 10 00 00 00 00 40 00 80   '.....@..'
  can0  442  [8] 40 02 00 00 00 00 00 00   '@.......'
...

Now that you have the data, this probably looks like noise to you, as that’s all part of proprietary protocols used by your vehicle ECUs. If you plan to do some reverse engineering on it, the best thing to do is to record all the data for offline playback, but also to setup a camera in the car to record what’s happening on the dashboard and on the road. Be sure to record so that you can easily identify when you started dumping so that the video can be easily synchronized.

This is how to instruct candump to save all the received packets for offline analysis:

$ candump -l can0,0:0,#FFFFFFFF
Disabled standard output while logging.

Enabling Logfile 'candump-2013-05-06_190603.log'

This leads to a log file with a series precisely timestamped packet dumps:

$ head -n5 candump-2013-05-06_190603.log
(1367859965.231495) can0 440#4000800000000000
(1367859965.249499) can0 442#4200800000000000
(1367859965.330495) can0 440#4001800000000000
(1367859965.335500) can0 620#1080000000400080
(1367859965.349499) can0 442#4201800000000000

Stream Playback on Virtual Device

Now that you have an offline stream, you can replay it on a virtual interface for realtime analysis.

To do that, first create and bring up a new virtual interface with:

# modprobe vcan
# ip link add vcan0 type vcan
# ip link set vcan0 up

Now you can run canplayer feeding in the original dump, but you also need to specify the mapping between the interface name used when recording and the new one, as in:

$ canplayer vcan0=can0 < candump-2013-05-06_190603.log

At this point, if you have a candump instance running on vcan0, you should see packet flowing with the same timings of the original recording.

If you recorded a video stream of the car while dumping, this is a good time to find some way to synchronize it, possibly by cutting the video to the start of dumping. What I actually did was using the -ss option of mplayer to get it to the right point, and start it simultaneously with candump:

$ canplayer  < candump-2013-05-06_190603.log & mplayer SMOV0087.AVI -ss 1:17

Reverse Engineering of CAN bus Frames

Now that you have the packet stream synchronized with a real world image, you can start reverse engineering some frame. I found that my car only have one bus, and there are as many as 41 different frame types on it.

You should try to use cansniffer to get a first overview of the traffic, but that’s not really helping much.

What you should do instead is to prepare a basic application to quickly try and decode a frame and focus on one frame at a time.

First, you dump all frames with a specific ID, this is an example for 0x2c4:

$ candump -cae vcan0,2c4:7ff
  vcan0  2C4  [8] 0A C5 00 18 00 00 92 47   '.......G'
  vcan0  2C4  [8] 0A C8 00 18 00 00 92 4A   '.......J'
  vcan0  2C4  [8] 0A D0 00 18 00 00 92 52   '.......R'
  vcan0  2C4  [8] 0A DC 00 18 00 00 92 5E   '.......^'
  vcan0  2C4  [8] 0A E1 00 18 00 00 92 63   '.......c'
  vcan0  2C4  [8] 0A EB 00 18 00 00 92 6D   '.......m'
  vcan0  2C4  [8] 0A F0 00 18 00 00 92 72   '.......r'
  vcan0  2C4  [8] 0A F2 00 18 00 00 92 74   '.......t'
  vcan0  2C4  [8] 0A F3 00 18 00 00 92 75   '.......u'

What to look for is how the data is packed up: by looking at the dump changing you should try to guess for each byte if it contains flags or if it’s part of a signed or unsigned 8, 16 or 32 bits number. This is easier than it seems, but a bit time consuming.

Once you have that, you can write a data structure to represent the information and print it out in your test application in a readable format, such as:

struct __packed {
        uint16_t unk0; /* in BE on the bus, use be16toh */
        uint8_t _pad0;
        uint8_t unk1;
        uint8_t _pad1;
        uint8_t _pad2;
        uint8_t unk2;
        int8_t unk3;
} test;

...

mvprintw(1, 1, "test: unk0=%5hd unk1=%3d unk2=%3d, unk3=%3hhd",
        be16toh(toy->test.unk0),
        toy->test.unk1,
        toy->test.unk2,
        toy->test.unk3);

If you look at the numbers changing in realtime with the video, you may now be able to make some sense out of those: in this case it turns out that the first number is the actual RPM of the engine, so the structure can be modified into:

struct __packed {
        uint16_t rpm;
        uint8_t _pad0;
        uint8_t unk0;
        uint8_t _pad1;
        uint8_t _pad2;
        uint8_t unk1;
        int8_t unk2;
} engine;

...

mvprintw(1, 1, "engine: rpm=%5hd unk0=%3d unk1=%3d, unk2=%3hhd",
                be16toh(toy->engine.rpm),
                toy->engine.unk0,
                toy->engine.unk1,
                toy->engine.unk2);

Now that you know that the frame contains engine information, you can assume that other fields of the same frame are somehow related, as those come from the same ECU.

In my case I was able to identify some data such as throttle position, speed, rpm, mileage counters and the speed of individual wheels. I wrote a simple application to open the CAN bus interface, read the frames and decode the supported ones. You can use it as a base to write your own packet decoders, it’s easy to hack, ncurses based and gives a list of unknown packets… Grab it on GitHub!


GitHub

Finally, this is a video of what the final result looks like:

About these ads

34 Responses to Hacking into a Vehicle CAN bus (Toyothack and SocketCAN)

  1. Love it!!! *___*

  2. Daniel says:

    Great job, I really admire all your projects, ideas and, of course, skills.

  3. mangodan2003 says:

    Hi there, great writeup! I am very interested in your open-usb-can project.

    I have different hardware, an STM32f4 with 2 can controllers, I plan to eventually use both by making my firmware present 2 USB interface descriptors .

    For now I have been coding firmware in the hope that I can just use your kernel module, by making my hardware appear to be the same as yours from the host’s point of view.

    I have got the device/interface/endpoint descriptors working, and can set the hw config, and start the interface. But I cannot figure out how you start the data flow. The urb’s callbacks in the kernel module do not seem to ever be called.

    I can make data go out, for a short while using cangen, but never get anything back in.

    I can see in the ep0.c control values that do not seem to ever be sent by the driver. But which appear to be needed to start the data flow.

    ATUSB_SPI_WRITE1/ATUSB_SPI_WRITE2
    and
    ATUSB_SPI_READ1/ATUSB_SPI_READ2

    The Write one seems to be the only place the ep in callback gets set.

    Am I missing something?

    Are these parts of the code actually used?

    Thanks in advance, Dan

    • Hi Dan!

      I was actually in the process of redesigning my open-usb-can with an STM32F103, as I abandoned the AVR based design for performance reasons, but then I stalled the project to work on other stuff…

      Anyway, I’m happy that you’re using my kernel module as a base! That’s actually quite simple because the firmware uses socketcan compatible data structures and you can easily do the same. You may also be interested into a discussion on the linux-can list about USB-CAN protocols (http://article.gmane.org/gmane.linux.can/2004) and maybe even join the list!

      The firmware code is actually based on the ATUSB Ben-WPAN project (http://en.qi-hardware.com/wiki/Ben_WPAN) so you may find some debugging/helper code still there and not used by the kernel module, and that’s the case for the ATUSB_SPI_* calls – the AVR to CAN controller SPI data is not exposed on the USB side for normal operation.

      As for the data flow, the stuff you find in ep0.c is only for the control endpoint (&eps[0]), and that’s used only for device configuration/start/stop. The actual bulk traffic is handled in buffer.c, where you can find references to usb_send(&eps[2], …) and usb_recv[&eps[1], …). Those two maps to the two kernel queues: usb_sndbulkpipe(dev->udev, 1) and usb_rcvbulkpipe(dev->udev, 2) and relative callbacks.

      There may be a *ton* of reasons why your traffic doesn’t go trough, and you may want to double check your descriptors and the hardware USB controller configuration on the STM32, especially for the endpoint sizes.

      In this situation I would search for an working example project to run on the STM32 that uses bulk endpoint and adapt it to your configuration until you find what breaks. On the Linux side you can use the usbmon module to see the raw traffic. Also, one of my favorite utilities for hacking on USB is the usbtool application from the v-usb package, you can find it here https://github.com/obdev/v-usb hidden into the examples/usbtool directory. It allows you send and receive arbitrary USB traffic, it uses libusb internally. If you use that just keep in mind that it doesn’t flip between the DATA0/1 packet id, so it will actually work only for the first packet… but that’s often enough! :-)

      • mangodan2003 says:

        Thankyou for such an in depth reply.

        I have managed to get data flowing to the host, it was something to do with the FIFO buffer settings, I do not fully understand how these are allocated and used at present so need to investigate.
        I had based my CAN vender specific driver on the stm cdc example class, removing the command endpoint so I just have the control endpoint and two bulk end points as you do, but had over looked the FIFO settings.
        I have used lsusb with -v option to confirm the descriptors are all correct.

        Although data flows to the host it is presently split in to tiny packets, I am only sending 17 bytes and it seems to send this as 12 bytes followed by the remaining 5 bytes.My wxPacket sizes for both the in and out Endpoint are set way higher than this, 64 and 32 bytes. So I have some work todo to find out why this is happening, but once resolved I am nearly there :).

        I have been using usbmon module with wireshark, and also a libusb test program adapted from something else I found online. I will investigate the other things you suggested.

        Thanks again

        Dan

    • ZeroAviation says:

      What kind of FIFO settings were you missing? I’m facing a similar problem.

  4. Arnold says:

    Hello.

    Question: Can all cars engine be started by the OBD-2 Conector using CAN bus protocol?

    • Hi Arnold, I think quite the opposite: *maybe* some car can be started with some can packet! Most cars probably still have a dedicated ignition circuit, and that’s even without accounting for some key authentication, immobilizer etc… :)

  5. Sam Crooks says:

    Fabio:

    You might consider using a Beagle Bone Black with a CAN cape. You can then directly wire into the CAN networks in the car permanently (all of them) and dump continuously, automate data collection, and also not block the OBD-II port… Useful if you want to sniff out what dealer diagnostic tools are sending on the network, or ECU flash programmers. See my website for my project notes on taking this approach

    http://the8thlayerof.net

    Sam

    • Sure thing! The BBB is a great board for this kind of hacks and has a very capable CPU and a good design in general as you would expect from TI.

      I actually worked in the past with the standard BB and with the AM335x CPU in general, and I still think that it’s one of the best general purpose board/CPU available.

      Thanks for the link! :-)

  6. Chad Gibbons says:

    Great post and information. You inspired me to do something similar to my Jeep and the results re here: http://chadgibbons.com/2013/12/29/hacking-the-jeep-interior-can-bus/

  7. javad says:

    hi fabio
    I want send and recieve can data, but when this command ” ip link set can0 type can” is ok but when I run this command “ip set link can0 type can listen-onl on” , operatiopn nor supporeted :-(
    can you help me?

    • Hi, looks like the device you are using does not support listen-only mode. That’s implemented in the driver so you need an updated version or to do your own implementation.

  8. Sarthak says:

    Hey Fabio,

    How you doing? The work you have done is fantastic and exciting. Actually, I am trying to get access to the CAN packets transferred among different ECUs. I am not sure what hardware you are exactly using. From the blog, I guess that you are using an OBD to DB9 cable, a laptop but what to connect the laptop and cable. Is it RJ45 port of the laptop you are using ? Please help !!
    Thank you !!

    • Hi Sarthak, that’s explained in the post, my specific setup is a laptop, a custom usb-to-canbus interface and a modified OBD cable that fits my CAN interface (which happens to have an 8P8C connector but of course is not Ethernet). The software part is just the socketcan and my test application.

      You need to grab a CAN interface of some kind (USB are common nowadays) and an OBD cable, and modify the cable to fit the CAN interface pinout.

  9. Sarthak says:

    Yes, I am using an OBD-II UART board, FTDI Basic, Laptop and a standard OBD to DB9 cable. But I am not able to figure out that when I will connect the USB port to the laptop, then how will I link the USB port i.e.COM1(for ex) with the the commands you mentioned in your blog to start the session. Please suggest.

    Thank You !

    • I think you have an ELM327 based board, that’s actualy designed to handle the OBD protocol on-chip and communicate with the host PC using AT commands. I think that some version is able to inject raw CAN frames, but AFAIK it does not work with SocketCAN, so it’s totally a different thing from what I cover in the post.

      If you are looking into OBD you should search for some ELM327 specific tutorial, but if you are interested into raw CAN stuff and socketcan you should get a different CAN interface.

  10. Yousef says:

    Hi Fabio
    I work with “PEAK-SYSTEM- CAN card ” , I can connect two can interface, I generate CAN data in one can interface and dump can data in other inteface.
    but I want reverse engineering on PLD engine controller and dump can data in this controller. you can find specific of this controller in this link
    (http://www.scribd.com/doc/57350358/PLD-Manual-MERCEDES-INJECTORS-FUEL-SYSTEM)
    but I can not receive any data with my interface! however I can connect it with car diagnostic and receive CAN data! I try to determine output signal with oscilloscope and saw voltage level of this controller are 9 V & 12 V for CAN-H and CAN-L . but in my interface output level are -1.5 and +1.5 V . if I can connect this controller with my interface ? how I should connect this controller physically? if I should run specific command for connect and dump CAN data without “candump can0″? please help me :-)
    thanks a lot.

    • Hi Yousef,

      there are many things you should check to troubleshoot the problem: first make sure that you are able to display error messages from the CAN interface (candump has some specific flags), then it may be possible that the bus you are using generates data only when triggered (check for activity with the scope). It may be useful for you to build a split cable to connect the diagnostic tool and your CAN interface at the same time, so that you can check if you receive the same data from both.

      For the voltage level, is actually quite high and may be saturating the transceiver. You should check which transceiver p/n is used in your CAN interface, and make sure it works with common mode voltage as high as ~10V. Ideally you would also use an isolated interface (if you are on a laptop using it from the battery may be enough).

      • Yousef says:

        Hi Fabio
        thanks a lot for you answers. I want connect to Mercedes Benz BUS and read CAN data from diagnostic connector. In your opinion are there difference between CAN bus configuration of Buses and cars? can I receive CAN data similar way ?
        thanks a lot.
        Yousef

  11. jon says:

    How could I control the climate in my Lexus Lx470? I am a beginner with Can-bus and not sure where to begin.

    • Well, that’s a long shot, I would not suggest you to wire up stuff to your car unless you know what your are doing. :-)

      That said, it’s hard to say, if you can equip with the proper tools you would have to find the correct bus, decode some control data and – if the protocol design allows – try to reinject it to control what you need.

  12. marius says:

    Firstly, what a great post. Thanks very much! I have quite a bit of experience with CAN, and always get the question how to read fuel consumption from many different manufacturer’s CAN bus. Yet, this signal is very difficult to reverse-engineer, I find, because many other signals (engine torque for example) look very similar. I see you have fuel usage identified on the toyota. How could you be sure it is the right signal? Any tips will be greatly appreciated! :-) Again, thanks very much for an excellent article.

    • Hello Marius!

      Thanks for the comment, I agree that most of this is very hard to reverse engineer… Even after you isolated some counter, everything spins up as soon as you rev up the engine! :-)

      For the fuel consumption I’m afraid I found a hint on some other website for similar projects on other Toyotas, and the value seems to change together with the instant consumption on the dashboard. My first idea would be to try to see if the those two updates together but if that doesn’t work I guess you should compare with some other car diagnostic tool.

      Cheers!

  13. Per says:

    Nice job on decoding the CAN-frames.

    Now that you have a CAN-OBD-interface it would be really simple to add functionality to also log supported OBD-PIDS for your vehicle

    Have a look at http://en.wikipedia.org/wiki/OBD-II_PIDs for a very nice guide. Basically, for the supported PIDS of your vehicle you just send a CAN-message and wait for respeonse. The list of supported PIDS is obtained by simpy asking, which is always supported (for non-electric vehicle).

    Example:

    Supported PIDs are obtained by sending a can message with [02,01,00,0,0,0,0,0], respone contains PIDS-supported.

    Lets say PID=0x0A (fuel pressure) is supported, just send [02,01,0A,0,0,0,0,0] and wait for response. Response should be something like: CAN-Sender-ID=0x7E8 (message from main ecu), [numBytes, 0x41, PID=0x0A, A, B, C ,D, E, ...] and actual fuel pressure is A*3 according to wikipedia.

    • Hi Per!

      You’re right, I was more interested into reversing some vehicle specific data but at this point it would be cool to have a socket-can based OBD scanner like you described… Only problem with that: in the meantime I moved to Ireland and I don’t have a car anymore! :)

      Thanks for the followup though, feel free to drop a link if you have a chance of writing something for socketcan + OBD, I’m not aware of any free software to do that and it would be great to start one!

      Cheers,
      Fabio

  14. Micheal Dada says:

    Great job! really like your project. I have a project i’m actually working on, it’s all about acquiring odometer protocols from canbus, was able to acquire protocols for some vehicles but still have problem getting from vehicles like toyota hilux, toyota hiace, mistibushi l200, mistibushi lancer, ford ranger and other ford series. Kindly help with tips on resolving these.

  15. Bill K says:

    Thank you for this informative post. Although as a medical diagnostic imaging engineer I am familiar with CAN bus, what I am working with is pretty much presented by the manufacturers in hardware and software, as is the case with OBD II and OBD II readers. Your presentation differs in that it probes down to the signal level, which then may determine if a component is actually bad or if the signal is just bad. Am I right?
    I wish you had described a step by step use of the “socket can” for us who are less familiar with programming.
    Have you done any work into hacking the other CAN bus in cars, namely the Navigation-Radio-CD changer-Telephone-etc. can bus? From following the various automotive forums there seems to be an awful lot of problems in that area. I wonder why the power train CAN is so reliable and the entertainment CAN is not. (Greater product liability?)

    • Hi Bill! Yes you are just about right, I would not really say “signal” though as I did not really put too much effort on electrical signals but rather at the lowest digital layer – the raw transmission and receiving of CAN frames, such as if they were IP packets.

      The socketcan part is actually easy if you get familiar with normal “internet” sockets before, and that is just the API used to interface applications with TCP and UDP (and more!) streams. SocketCAN is just an extension of that to use CAN frames with the well-known socket API, and it’s actually a huge step forward compared to previous implementation of low level CAN APIs in Linux, which would not do too much other than exposing the controller to the application.

      I did not really do much in cars other than what I described here, and I think CAN it’s used for infotrainment devices just because “it’s already there”… One problem is that there is still low interoperability between devices, since even if they share the bus they still implement vendor specific protocols on top of it (think of after-market stereo or dashboards).

      If you hear about reliability problems it’s probably juts because those are just less important busses and receive less attention to reliable design as a consequence… Maybe the cables and connectors are lower quality (gauge, twisting…), have longer trunks (worse signal integrity), moves through hinges and other stuff. I’m sure the drivetrain bus receive more attention and there’s much more than the protocol itself in designing a reliable field bus system.

      Cheers!

  16. xarxer says:

    Hi Fabio,

    I just ordered an OBD-II to DE-9 cable to do some car hacking, but I’d like to get started right away, so I was wondering if maybe you still have your recorded data? If so, I could use it to get the basics done of an application that utilizes it!

    Thanks in advance!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s