Saturday, November 10, 2012

Eye candy

I've been fervently trying to find the message that starts the parking heater, but without success. Manually one starts it by changing menu options (shown on DIM LCD) using left control stalk, selecting correct one (manual start) and then pressing the RESET-button for longer than half second. After numerous attempts, I still haven't found any new, interesting messages immediately after manually starting the heater, so I suspect this is not going to be as easy as I thought.

Back to the roots: The electronic diagram. It seems that CPM (Combustion pre-heater module, the one responsible for controlling the whole heater) is not on CAN bus, but is instead controlled by CEM (central electronic module). So, no direct message is being sent from SWM (steering wheel module) or DIM (driver information module) to CPM, but CEM must be the guy in the middle. So, messages sent by SWM or DIM (stimulated by user pressing buttons on the control stalk) must be interpreted by CEM.

Then I thought, could it be possible to emulate SWM/DIM functionality so that CEM would think that the user is activating the heater manually?

SWM is constantly sending status messages like this:
header: 02 61 30 0a 
data: 80 00 00 27 80 c2 00 cf
1.byte: high nibble: rolling counter (0,4,8,C)
2-3. byte: 0
4. byte: always 27?
5. byte: low nibble: turn indicators (0=off, 4=right, 8=left)
5. byte: high nibble: 8=normal, a=READ-button pressed, c=RESET-button pressed
6.  byte: always c2?
7. byte: windshield wiper: 10=turn wiper once, 01= activate windshield washer, 08=continuous wiper
8. byte: control stalk selection ring position (values 0xC1-0xFF)

Now, the eighth byte seems important. Disappointedly, it's not an indicator of which menu item is selected, but is just an arbitrary position counter from which to discern what is the speed and direction of ring movement.  So I have no way to know which menu item is now selected on DIM, and thus no way of knowing how many positions to move up/down (i.e. how many messages to send and to which direction) to get to "manual start" item on the menu. Damn.

Got bored and started playing around with the GSM module. Then it occured to me that there must be messages on the CAN bus where phone module asks DIM to show certain messages (phone number currently dialed etc) on its LCD display. So, I coded more functionality to the filtering program to show the payload of the message as ASCII characters (if they contain alphanumeric content), and thus I was able to quickly trace the module and the messages responsible for sending distinct characters on the LCD. Rest of the reverse engineering task was pretty easy.

So, here's the example message to control DIM LCD, showing a way to set an arbitrary message on the LCD:
Header: 00 c0 00 08 (phone module)
Data: 
e1 fe 00 00 00 00 00 00  (clears the screen)
a7 00 68 74 74 70 3a 2f  (start message, 7 bytes payload)
21 2f 68 61 63 6b 69 6e  (in-between message, 7 bytes payload)
22 67 76 6f 6c 76 6f 2e  (in-between message, 7 bytes payload)
23 62 6c 6f 67 73 70 6f  (in-between message, 7 bytes payload)
65 74 2e 63 6f 6d 00 00  (ending message, 5 bytes)

So there are 6 messages, of which the first one is separately executed by DIM, and messages 2-6 are the content, displayed only after the last message has been transmitted. It seems that the high nibble of 1st byte of every message here contains a signal: e=command, a=begin, 2=in-between-message, 6=end. Low nibble indicates either payload byte count or the index of the message (in case of in-between message). In the latter case the payload is always 7 bytes. Rest of the bytes are just ASCII-characters. In this case it reads "http://hackingvolvo.blogspot.com" :)

2 comments:

  1. Hey i was experimenting with elm327 on my 2003 s60 AWD found that byte 6 on the SWM corresponds to the dial on the wiper handle to set intermittent wiper speed range C0-C7

    ReplyDelete
  2. Hey Alexandere! Thanks for the info!
    Br,
    Olaf

    ReplyDelete