Connecting to the infotainment CAN network

Francesco Montefoschi
5 min readJul 14, 2019

--

On the previous post I have introduced Fiat Blue&Me infotainment system. In this episode we will connect to the CAN network. I am talking about the slow-speed CAN bus where the infotainment is connected, not the high-speed bus for the engine, brakes, etc. The first step is to analyze the 32-pin ECU connector:

Blue&Me ECU 32-pin connector for power, USB, CAN, audio in/out

Fiat eLearn is not useful in this case, it just explains where every signal is connected to, not what a wire it is. The most useful info were found on forums (sorry, I’ve lost the links). This is the pinout (unlisted pins are not connected according to eLearn):

The first try would be to MITM the ECU. The connector is a standard 2.54, so I interposed male/female jumperwires for audio and USB (I’m not interested in those for now). CAN and power lines were connected to homemade Y-jumperwires (two females - one male) so I could both steal power and access the CAN network while providing all the signals to the ECU.

I wiretapped the ECU using crappy jumperwires. This looks solid and ready for a certification, isn’t it?

It’s time to power-on a SBC to connect to the CAN network. In our lab we had a spare SECO A62-J, an iMX6Q board with onboard CAN transcievers. I have built the bootloader (U-Boot 2018.03) and the kernel (Linux 4.14), and flashed everything on a SD card with a Ubuntu 18.04 root filesystem.

SECO SBC-A62-J, with CAN (top-right connector) and USB (for shell access) connected

Before accessing the CAN network, it is necessary to configure the interface. The B-CAN is clocked at 50kbaud:

ip link set can0 type can bitrate 50000
ip link set up can0

It’s time to verify if the connections are correct:

root@A62:~# candump can0
(1562344199.459239) can0 0E094000#001C00000001
(1562344199.515402) can0 0E094000#001E00000001
(1562344199.520484) can0 0E094003#003A
(1562344199.522274) can0 0E094005#0002
(1562344199.530656) can0 04394000#000000C5
(1562344199.538632) can0 0E09401A#000C
(1562344199.541168) can0 02214000#000000000000
(1562344199.544026) can0 0621401A#A000000080000000
(1562344199.547579) can0 0A194005#00000000000080
(1562344199.551361) can0 06214000#2104480000000F00
(1562344199.560340) can0 06254000#00000000
^C

Eureka! As you can see there are a lot of messages (~10 messages in ~100ms). That’s too much, and a lot of messages are just repeating with the same values. Fortunately there is cansniffer that highlights the differences. Unfortunately, it does not work with those 29-bit IDs, it just does not print anything. Searching online I have found an implementation that adds support for long IDs. I don’t know if it is perfect, but it looks to work really well!

Other than doing simple actions (like pressing buttons) to see the outcome on cansniffer, I have recorded the CAN traces on text files using candump -l can0. In this way the CAN messages can be analyzed later on.. it is more comfortable to use a computer on a desk rather then on the car!

With this first approach, documented on the Car Hacker’s Handbook, I was able to find out the messages related to the steering buttons:

06354000#0000         No key pressed
06354000#8000 Volume +
06354000#4000 Volume -
06354000#1000 Up
06354000#0800 Down
06354000#0080 Menu
06354000#0400 Src
06354000#0040 Windows
06354000#2000 Mute

Skimming the logs, this message broadcasted every second caught my attention:

0C214003#183810072019

It uses hex chars to encode the date and time (18:38 10 July 2019). This is a rarity. Messages in general are binary-encoded and must be somehow decoded. Playing music generates a lot of messages. When turning on the key the network is woken up, and a lot of traffic is produced. The same for turning on the engine and other actions. Even doing apparently nothing produces traffic, both for repeating messages with the same values, and for ping/keepalive messages, like those:

➜  ~/bm/can/traces grep -RI 0A014021 BBB/03.play.log
(1562776706.910158) can0 0A014021#4000000000000002
(1562776706.929320) can0 0A014021#5000000000000002
(1562776707.909911) can0 0A014021#4000000000000002
(1562776707.928853) can0 0A014021#5000000000000002
(1562776708.910739) can0 0A014021#4000000000000002
(1562776708.929513) can0 0A014021#5000000000000002
(1562776709.914514) can0 0A014021#4000000000000002

Before trying to decode the values, let’s see who is speaking on the bus, grepping ~8MB of candump log files:

➜  ~/bm/can/traces grep -R can0 . |awk '{print $3}' | cut -f1 -d"#" |sort -u   
02214000
02294000
04214001
04214006
04294001
04394000
06214000
0621401A
06254000
06314000
06314003
06314005
06314021
06354000
063D4000
08094021
08194003
08194005
0A014021
0A094005
0A114000
0A114005
0A194005
0A394021
0C014003
0C114003
0C194003
0C214003
0C2D4003
0C394003
0C3D4000
0E094000
0E094003
0E094005
0E09401A
0E094021
1E114000
1E114003
1E11401A
1E114021

The first thing you can notice is that the first 2 and the last 2 bytes are often repeating. Let’s split the IDs in the half:

➜  ~/bm/can/traces grep -R can0 . |awk '{print $3}' | cut -f1 -d"#" | cut -c -4 |sort -u     
0221
0229
0421
0429
0439
0621
0625
0631
0635
063D
0809
0819
0A01
0A09
0A11
0A19
0A39
0C01
0C11
0C19
0C21
0C2D
0C39
0C3D
0E09
1E11
➜ ~/bm/can/traces grep -R can0 . |awk '{print $3}' | cut -f1 -d"#" | cut -c 5- |sort -u
4000
4001
4003
4005
4006
401A
4021

Maybe I am totally wrong, however merging this with a quick skimming on log files, it looks like that the first 2 bytes encode a topic, while the last 2 bytes represents the device.
This makes sense since, according to the CAN protocol, messages with lower IDs gets priority in case of a collision on the bus. In this way every device gets the possibility to publish both urgent and deferrable messages. Swapping the topic and the device in the IDs would exclusively prioritize a device upon another one.
Another supposition about the device ID: they all start with 0x40, probably because when the gateway (the body computer) needs to forward some messages on other networks, it can just republish the messages without altering them, still avoiding ID collisions.

In the next episode we will try to isolate the Blue&Me ECU, hoping to see less noise and to understand more messages.

--

--