Tuesday, November 6, 2012

Reading between lines

I have been logging CAN bus messages for the past few days, driving around, fiddling with knobs and settings on the car and seeing what kind of messages are sent in the low speed bus. I wrote a linux program (in C) to assist in filtering, since the amount of traffic in the network is huge even when the ignition is off! After few evenings of tinkering with filtering algorithms and heuristics, I managed to reduce the logging to a sensible amount (1-5 messages/sec), a number that now opens possibility to manually watch the log in real time for suspicious activity while at the same poking around with knobs. Thus, I'm able to deduce which message(s) are being sent according to what kind of stimulus.

The general format of the messages is as follows:

0xaa 0xaa 0xaa 0xaa  0xbb 0xbb 0xbb 0xbb  0xbb 0xbb 0xbb 0xbb

4 header bytes followed by 8 data bytes. ELM327 seems to do some header formatting by itself, and it is not very well documented what is the actual structure of the header bytes that ELM outputs (not even in the datasheet itself!). According to CAN bus extended frame format (used by 29-bit messaging), there are 2 bits (SRR&IDE) between Identifier A (11-bit ID) and Identified B (18-bit ID) and they both must be 1. None of the messages intercepted contain sequential ones in appropriate positions, so I must assume ELM327 does not output them. This leaves 32-18-11=3 bits up to speculation. Start-of-frame bit is always 0, and this applies to all messages intercepted. But it would seem weird for ELM to include this redundant bit to its output, so I must assume this is ripped. Thus, it would seem that this is the format of CAN 2.0B header, formatted by ELM327 (subject to change)

  • 11 bits (identifier A)
  • 18 bits (identifier B)
  • RTR bit (remote transmission request)
  • 2 reserved bits 

(total of 32 bits = first 4 bytes)
First I didn't understand where the DLC embedded (data length code) is, but after a while I found out how to force ELM327 (via AT D1-command) to show the data length between header and data. However after extensive logging it seems to be always 8 (even though some messages seem to contain leading zeroes), so I must assume Volvo CAN bus always transmits messages with 8 data bytes, and the actual length of the payload is inherent in the upper level protocol definition or transmitted inside payload itself, perhaps consisting of first few bits of the payload.

According to electronic schematics, there are 14 different electronic modules connected to the low speed bus, of which I have only 12. Here's the list:

Name Id  Description
AUM   16/1  Audio module
CCM   3/112 Climate control module
CEM   4/56  Central electronic module
DIM   5/1   Combined instrument panel (Driver Information Module)
PDM   3/127 Passenger door module
DDM   3/126 Driver door module
PHM   16/60 Integrated mobile telephone
PSM   4/52  Power driver's seat module
REM   4/58  Rear electronic module

SRS   4/9   Supplemental restraint system
SWM   3/130 Steering wheel module
UEM   4/70  Upper electronic module

Here are the optional modules that I don't have.
RTI   16/45 Road traffic information control module
AEM   4/78  Accessory eletronic module


And here's the list of distinct header Ids contained in the millions of messages logged during last few days. 


00 40 00 66 - 00000000 01000000 00000000 01100110 11-addr: 2  SWM (cruise control and audio) 
00 61 3d f8 - 00000000 01100001 00111101 11111000 11-addr: 3  ?
00 c0 00 08 - 00000000 11000000 00000000 00001000 11-addr: 6  PHM (phone module)
01 21 3f fc - 00000001 00100001 00111111 11111100 11-addr: 9  ?
01 40 04 4a - 00000001 01000000 00000100 01001010 11-addr: 10 CCM (climate control) 
01 61 3f fc - 00000001 01100001 00111111 11111100 11-addr: 11 ?
01 80 00 28 - 00000001 10000000 00000000 00101000 11-addr: 12 ?
01 c0 30 a2 - 00000001 11000000 00110000 10100010 11-addr: 14 DDM (left door) 
01 e0 12 66 - 00000001 11100000 00010010 01100110 11-addr: 15 ?
02 00 10 22 - 00000010 00000000 00010000 00100010 11-addr: 16 PDM (right door)
02 20 20 0e - 00000010 00100000 00100000 00001110 11-addr: 17 ?
02 40 10 2a - 00000010 01000000 00010000 00101010 11-addr: 18 ? 
02 61 30 0a - 00000010 01100001 00110000 00001010 11-addr: 19 SWM control stalks 
02 80 14 2a - 00000010 10000000 00010100 00101010 11-addr: 20 ? 
02 a0 30 28 - 00000010 10100000 00110000 00101000 11-addr: 21 ? 
02 c1 34 28 - 00000010 11000001 00110100 00101000 11-addr: 22 CEM->DIM ?
02 e1 0d f4 - 00000010 11100001 00001101 11110100 11-addr: 23 ?
03 00 00 92 - 00000011 00000000 00000000 10010010 11-addr: 24 ? 
03 20 00 08 - 00000011 00100000 00000000 00001000 11-addr: 25 ? (gear switch info) 
03 40 02 4c - 00000011 01000000 00000010 01001100 11-addr: 26 ? 
03 60 00 0a - 00000011 01100000 00000000 00001010 11-addr: 27 ? 
03 80 10 28 - 00000011 10000000 00010000 00101000 11-addr: 28 ? 
03 a0 00 02 - 00000011 10100000 00000000 00000010 11-addr: 29 DIM?  
03 c0 00 2a - 00000011 11000000 00000000 00101010 11-addr: 30 ?
04 00 00 02 - 00000100 00000000 00000000 00000010 11-addr: 32 ?
04 20 00 02 - 00000100 00100000 00000000 00000010 11-addr: 33 ? 


First 4 bytes are the message header (as shown by ELM327), then binary representation of the same data, followed by the decimal representation of identifier A (first 11 bits of the header). In the last column you can find kind of educated guesses about which module might be transmitting with which id. There seems to be no logical connection to the module ID specified in the electronic diagram, and the header IDs in the list above. 



Much of the content on these messages is status updates and keep-alive messages, broadcast by various modules. For example,  passenger and driver side doors transmit continuously their button status (if some button is pressed) and if the window is open, and if, by how much. 

I will later add detailed analysis of each module and the structure of messages they send. Be tuned!

1 comment:

  1. Hi Olaf,
    First, thank you for this blog; I have found it immensely helpful to get inspired and get started. I know this is old, but I'm just scratching the surface of this project for myself. Did you get around to adding that analysis of each module and the structure of the messages? There seems to be a massive amount of data on the bus, and reverse engineering it is quite a daunting task!
    Thanks,
    Mark

    ReplyDelete