Ok, so we have an OBD port/connector on our cars that connects directly to the ECU. How are we going to figure out how to talk the right communications protocols to the car to get at its internal data?
We need a test rig to do some experiments with.
If you're looking for a post about "How to..." set all this up then that will be coming at the end of this series of posts in a "How to set up a Raspberry Pi to talk to a Caterham" post
After a bit of research over the years I’d already purchased a few bits and pieces to connect to a CAN bus. There are many ways of doing this but I settled on the following approach from my box of bits and pieces.
Here’s a schematic view of the setup…
And then this is what it looked like in real life, Easimap is running in the top left corner on the screen of the MacBook. The Raspberry Pi and PiCAN are propped against the front left of the laptop.
So what is all that doing? Firsly, lets give a quick run-down on all the bits and pieces:
Raspberry Pi: This is a Raspberry Pi 4, but anything from a Raspberry Pi 2 onwards is probably ok. Certainly a 3 or 4 are great. The Raspberry Pi is running Linux and can interface to the PiCAN to extract CAN bus frames.
PiCAN: Is an interface card that plugs on top of the Raspberry Pi. The PiCAN2 SMPS (switched mode power supply) can also provide power from the CANbus to the PI. If you have a Pi4 and want it to be powered from the CANbus then you’ll need the PiCAN3.
Wireshark/Tshark: Wireshark is a Network Protocol Analyzer or packet sniffer application that can intercept packets on a network and decode them into a human readable form. It runs on Windows, MacOS and Linux and can decode, or dissect as its known, hundreds of different network protocols and is immensely useful in today’s world of computing. Tshark is the command line version of Wireshark (built from the same source code) and is what I used in this test setup. I used tshark because I was running my Raspberry Pi with no graphical user interface, just remote command line access using ssh from my MacBook. Tshark allows you to capture and view packets just like Wireshark but without the graphical interface.
We’ll be talking about Wireshark in a future post as it soon became apparent that Wireshark wasn’t properly able to decode the CAN bus communications from my car, but more on that in the next post!
Easimap: A windows application from SBD that can interface with a 9A4 ECU and extract data. For unlocked ECU’s (not the standard Caterham one) it can also extract/load Maps, and download/upload ECU images (the whole software and data setup of the ECU). Easimap can graphically show ECU data in real-time. Easimap runs on Windows but in this test I was running Windows in a Virtual Machine on a MacBook Pro.
MBE985: This is an interface device that converts CANbus data into a USB format that a Windows PC can access using Easimap. Easimap sends commands to the car and receives data back by communicating through the MBE985 over USB which then sends the communications over the CAN bus.
For this of a curious nature, I pulled my MBE 985 apart to see what made it tick. We were wondering if there was much translation going on between what we had seen on the USB interface and what was being sent to the CAN bus. As you can see from the picture below, the MBE 985 is a reasonably complicated interface – more than you might expect in a CAN bus to USB interface.
The interface is using a 25Mhz Infineon processor that has a CAN bus interface built in. It also has a 4Mb Flash chip on the board. So this interface is doing some reasonably serious processing!
OBD Y-Cable: In my setup I used this Y-cable to connect everything together. It allows the Easimap/MBE985 combo to connect to the ECU but also allows the Raspberry Pi/ PiCAN to “see” the communication between Easimap and the ECU – it allows the Raspberry Pi to “sniff” the CANbus traffic. Another way of putting it is to say that the Easimap and Raspberry Pi are “in parallel” with each other and both able to see the communications to the car at the same time. The MBE 985, PiCAN and ECU are now three devices on the CAN bus.
MacBook Pro Laptop: I used a MacBook as the host to run the Easimap Software but which actually only runs on Windows. And in order to get around that small niggle, I had to use Parallels Virtual Machine software to run Windows on the Mac as a “Virtual Machine Host” and then to run Easimap inside that Windows virtual machine. If MS Windows it your thing then you could replace this Mac/Parallels/Windows/Easimap configuration with a PC/Windows/Easimap setup.
Parallels: This is a Virtual Machine application that allows a Mac to run other operating systems “on top” of MacOS. It can run Windows, Linux and even another copy of MacOS. You don’t need this if you’re running Windows on the bare metal (i.e. Windows directly on the computer).
With all that connected up we can start to investigate how Easimap talks to the car’s ECU.
I guess there are a number of ways of figuring out what Easimap was doing. For instance, we could have had go at disassembling the Easimap software… But that would have been a massive task and very unlikely to yield any results in a non-geological time frame. I’ve disassembled other people’s code in the past… and it took months.
The best approach was probably going to be a technique called “packet sniffing”. And we had two points of entry there too to think about.
One approach that was tried was to “sniff” the packets being sent by Easimap to the MBE985. That would mean sniffing the USB connection between Easimap and the MBE985 and Wireshark is a great way of doing that. James (Aerobod) on Blatchat had been doing this and got some good background info…
But that wasn’t going to be my approach…
I wanted to get direct access to the CANbus. I wanted to see what I would have to signal on the CAN bus itself if I was going to replace Easimap. That meant sniffing the CAN bus frames and pulling apart the communications at that level.
And now to some Packet Sniffing
Ok, so now we have our hardware and software all set up to capture some of the communication between Easimap and the car.
The process will be to:
- Connect all the hardware and turn it on
- Run the tshark packet capture on the Raspberry Pi
- Start up Easimap on the Windows Virtual Machine
- Now turn on the car (my car has a battery isolator) and then put the car into ignition switch position 2 – that seems to keep the ECU talking
- Stop the capture and transfer the capture file (.pcapng) over to my Mac for review
I spent about 10 minutes one evening taking a few initial captures, and those files kept me going for over a week. That’s often the way with these things. There’s so much to learn in the initial investigation, that you spend ages looking at just a few seconds worth of data.
Once I had the captures on my laptop I could review and anaylize them with the car and the Raspberry Pi off.
Initial Results – MBE-Broadcast
The CANbus frames I’m going to show now just contain the ID and data parts. The captures also contain the error, extension, etc flags that we talked about in a previous post… but there’s nothing interesting in those bits of the frames now we know we have some good communication between PiCAN2 and the car, so I won’t show them here.
To get a capture on the raspberry Pi we just run the following command. There’s a whole setup process for the Pi that I’ll talk about in its own post and put a link [here] when it’s done. But once that’s done we just run this command.
-> sudo tshark -i can0
And if we want to capture the packets to a file then we could supply a file like this:
-> sudo tshark -i can0 -w /tmp/mycapture.pcapng
When the car is first turned on it starts churning out the following packets:
# Time ID Data
8 0.069921880 0x0cbb0001 04 95 ff 28 00 00 00 00
9 0.079854830 0x0cbb0001 03 27 00 1e 00 1e 00 00
10 0.089837445 0x0cbb0001 02 aa aa 00 af d6 00 00
11 0.100195073 0x0cbb0001 01 50 00 00 39 00 95 48
12 0.110361352 0x0cbb0001 ff 00 00 00 00 00 00 00
13 0.119903104 0x0cbb0001 ff 00 00 00 00 00 00 00
14 0.129903793 0x0cbb0001 ff 48 00 00 00 00 00 00
15 0.139997221 0x0cbb0001 ff 95 00 00 00 00 00 00
Those 8 packets get repeated continuously… non-stop… without the Easimap software running.
A quick description of what we’re seeing here, the columns of data represent:
- # is packet number
- Time is the number of seconds since the tshark capture started
- ID is the CAN bus ID (arbitration field / address)
- Data is the 8 bytes of data for each frame (in hexadecimal).
Not a lot of that made sense. And to honest we haven’t really dug into this data stream. My car’s engine wasn’t running here, so there’s probably even less of interest in those packets above. It seems to be something proprietary to MBE though and I suspect has some useful information in the stream but because the data is so limited we didn’t delve into it. I’ve called this data stream “MBE Simple” (because it comes from the MBE 9A4 ECU) and is characterised by the CANbus ID of 0x0cbb0001 and doesn’t have the same depth of info as the next protocol we’ll look at.
At first we thought these messages were all we were going to receive. There was talk on the forums that you needed to send an “unlock” frame to the car and then it would add more data to this Simple data stream. That turned out to be a red herring but initially we thought that the unlock code was in some way opening a CANbus bridge and we’d see more data once it was opened… that isn’t the case as we’ll see later.
We’ll come back to this protocol in a full post on the MBE Simple protocol later on.
Next Level of Results – MBE ISOTP
So, we’re not so interested in the MBE Simple protocol. Before we had Easimap running we did spend a couple of days trying to figure out if it was useful. But as soon as we got sniffing Easimap communications we knew we wanted to move on.
I’ve called this next protocol “MBE ISOTP” and we’ll have to wait for a future post on exactly why I’ve called it that, but suffice to say, this is the protocol that Easimap uses to talk to the car.
As soon as Easimap starts up, it begins to talk to the car… and we get this initial communication that doesn’t repeat (at least not for a long period after the car starts up):
# Time ID Data
28 0.265548270 0x0cbe1101 03 04 00 0d 26 40 42 43
29 0.266543253 0x0cbe0111 10 0d e4 00 0d 23 39 41
30 0.266872637 0x0cbe0111 21 34 62 65 35 33 30 00
37 0.326052544 0x0cbe1101 03 04 00 5e 26 40 42 43
38 0.327045620 0x0cbe0111 07 e4 00 5e 2b 07 01 00
Then we get this set of 31 packets that repeat continually:
# Time ID Data
80 0.736160089 0x0cbe1101 10 0a 01 00 00 00 00 12
81 0.736958836 0x0cbe1101 21 66 67 a8 a9 00 00 12
82 0.738230722 0x0cbe0111 05 81 aa aa 16 00 12 66
84 0.749027454 0x0cbe1101 10 09 01 00 00 00 00 1a
85 0.749733313 0x0cbe1101 21 52 5c 5d 00 00 00 1a
86 0.750875498 0x0cbe0111 04 81 84 00 00 00 1a 52
89 0.767924313 0x0cbe1101 10 0a 01 00 00 00 00 e2
90 0.768777632 0x0cbe1101 21 cc cd ce cf 00 00 e2
91 0.769825875 0x0cbe0111 05 81 ff ff ff 07 e2 cc
93 0.780880102 0x0cbe1101 10 23 01 00 00 00 00 f8
95 0.781565869 0x0cbe1101 21 30 31 36 37 44 45 4c
96 0.782301116 0x0cbe1101 22 4d 4e 4f 50 51 5a 5b
97 0.783061863 0x0cbe1101 23 5c 5d 64 6a 6b 7c 7d
98 0.783818702 0x0cbe1101 24 9e 9f a0 a1 d8 d9 da
99 0.784526524 0x0cbe1101 25 db 9f a0 a1 d8 d9 da
100 0.785768596 0x0cbe0111 10 1e 81 5e 39 cc 48 dc
101 0.786095776 0x0cbe0111 21 50 9c 89 1e 85 5e 39
102 0.786437863 0x0cbe0111 22 a8 0d 66 a0 00 b0 4f
103 0.786777913 0x0cbe0111 23 00 00 56 95 80 09 00
104 0.787102630 0x0cbe0111 24 80 00 80 a1 d8 d9 da
106 0.798260523 0x0cbe1101 10 0a 01 00 00 00 00 f9
107 0.799080454 0x0cbe1101 21 ba bb bc bd 00 00 f9
108 0.800070197 0x0cbe0111 05 81 78 1e dc 1e f9 ba
110 0.810033090 0x0cbe1101 10 09 01 00 00 00 00 fa
111 0.810853632 0x0cbe1101 21 64 65 6c 00 00 00 fa
113 0.812042780 0x0cbe0111 04 81 8c 1e 00 00 fa 64
115 0.821498922 0x0cbe1101 10 0e 01 00 00 00 00 fd
116 0.822377593 0x0cbe1101 21 20 24 25 26 40 42 43
117 0.823099192 0x0cbe1101 22 4d 24 25 26 40 42 43
118 0.824343987 0x0cbe0111 10 09 81 40 00 00 01 80
119 0.824665352 0x0cbe0111 21 b0 40 40 26 40 42 43
Ok, so we got a good dump of data from the car, but what does it all mean? We were baffled. You can see the packet numbers here aren’t contiguous… in-between these MBE ISOTP packets are the MBE Simple packets – interspersed – I’ve removed them here so you can see the “raw” MBE ISOTP packets and what we were now trying to decipher.
Those 31 repeating packets were all being sent and received within a 100ms time frame. And they repeat almost instantly. That implies that Easimap is updating its graphical display 10 times a second. At least that sets us a reasonable rate at which we might be able to do the same. A rev-counter display or something similar will be more than responsive enough if we can refresh it at that rate.
Now… Before we can move onto decoding this some more, we need to take a bit of a diversion back into Wireshark, because things weren’t adding up there at the moment.