Tuesday, November 27, 2012

Introducing J2534..

So, I've been down with the flu for the past week and half, and frankly quite tired of it already. But what else can you do than hack when you're confined to the sick bay, even when there's the constant head ache and runny nose making things harder. I think I got the double jack pot: both rhino and adenoviruses at the same time.  Anyway, I took this as an opportunity to go extreme and maximize my suffering by starting to learn Win32 APIs, DLL programming, multi-threading, semaphores, COM port handling and of course Hungarian notation. That, combined with unicode type naming etc was the straw that almost broke the back of this camel.

Ok, why all this Win32 nonsense. I'm totally happy coding on Linux as it is, so why learn all aforementioned stuff? First, I'm gonna tell you a riddle: What's the difference between sardine can and Sardine CAN?

¨
On the right you can see John West sardine can. The sardines are submersed in a delicious tomato sauce and deliver 164kcal per 100g of energy. Good for recuperating from the flu.

And then on the left there's Sardine CAN by Olaf's Hacking Volvo labs. Included currently is a firmware version 01.00, offering part of SAE J2534-1 functionality and a bit of J2534-2.

So, what are these useful for? The SAE J2534 is an industry standard that defines how third-party software can be used to communicate with automobile ECUs in a hardware independent way. Buy any (expensive) J2534 flash/diagnostic tools and what you get is their proprietary software for diagnostics, supplemented with a standard J2534 API (Win32 DLL) that uses the hardware supplied to communicate with the car via its OBD port. The API offers various protocols (ISO9141, CAN, ISO 15765, J1850 and so on) and thus lets third party applications to send and receive messages without having to know anything about what happens between the API and the communication stack of ECU - it's all transparent.

Now, what is interesting is that some car manufacturers (including Volvo) have in their diagnostic software a possibility to use communication tools other than the one supplied. First they parse the Windows registry for entries related to J2534 devices. Usually they offer the user a list of available devices, then load the DLL associated with the device and start using its services. VIDA (Vehicle Information and Diagnostics application) from Volvo is one of these applications, and its J2534 support enables us to use it without the related hardware, the DiCE (Diagnostic Communication Equipment). With VIDA, you can browse all the ECUs in the car (including CPM, the module responsible for the parking heater!) and send diagnostic commands to test their functionality. And the logical conclusion would be, of course, that if these commands could be intercepted, then the command for turning on the parking heater might be found :)

There are plethora of J2534 devices, most of them quite expensive (1000+ euros). There are also some cheap chinese copies selling for 100-200 euros, but there's no guarantee of them working out of the box, and I wouldn't like the idea of spending my free weekend diagnosing the diagnostic tool.  There are absolutely no open source or freeware solutions available, so my last option would be to tackle this beast on my own.  I got ahold of J2534-1 and J2534-2 standards documents and started hacking. And after few days full of dizzy coding sessions with viral headache enhanced with nausea from Hungarian notation, this is the result:

VIDA can now recognize the Sardine CAN tool and send VIN (Vehicle information number) query via CAN bus :)  Actually the command seen in the first picture is one of the messages sent by Vida. However I haven't yet been able to access the diagnostics part of Vida, since it seems to require proper response from ECU in order to function correctly. I've implemented most of the CAN bus related stuff on J2534 (including sending periodic messages), as well as some of the ISO 15765 flow control in order for VIDA to receive long CAN messages, where payload length>8 (such as the VIN), but lower level pass/block filtering is yet to be done. So connecting Sardine CAN to car in its current form would flood the VIDA with unrelated messages. There's still quite a lot to do, but sending and receiving messages using Drewtech's free J2534 tool already works though, so I'm confident that after few days of tinkering I might able to give this monster a shot at the car itself.

BTW. I'm releasing the software as open source after I get this reasonably stable and functioning. This still needs quite a bit of work to be useful to anybody and frankly, I'm little bit embarrassed at the Win32 specific portions of the software (related to my few days worth of programming experience on the platform), so I'm not yet ready to open this to the world. But anyway, if you're interested in alpha testing and have reasonable debugging skills, I might make an exception and let you test this tool before it hits SourceForge.

Sardine power!

Sunday, November 18, 2012

Wireless fun

As my attempts at starting the heater have failed again and again, I needed to get my mind off for a while and decided to concentrate on prototyping the wireless connection and CAN controller. ELM327 is too cumbersome to be used as a permanent installation and frankly, I'm not too fond of the AT command interface that it uses. I ordered few things online and now it's time to put them into use:
  • 2 XBee modules (XB24-ASI-001 & XB24-AWI-001)
  • Wireless SD shield for easy XBee prototyping
  • XBee USB Explorer for transparent testing with terminal emulator
  • Arduino CAN shield
  • 2 MCP2515 CAN controller chips and 2 MCP2551 CAN transceiver
The CAN controller and transceiver chips are identical to those in Arduino CAN shield, so after prototyping with Arduino and aforementioned shields, it's easy to design and build a PCB from those same components.

After some weekend hacking, I managed to build a CAN network consisting of ELM327 and Arduino CAN modules with XBee modules routing the CAN traffic and commands quite transparently.


Here's some early XBee module testing. 


Here's the CAN network: On the left, Arduino with CAN shield and on the right, ELM327. The network is terminated with two 56 ohm resistors to minimize signal reflection. It might work without them, but I added them just in case.
Here we are sending one message with Xbee module to the Arduino. The XBee USB Explorer allows hassle-free connection with any terminal emulation software. Here we use Minicom.
Message is received via XBee module and sent through CAN bus using the CAN shield (topmost shield). The antenna used here from old wireless ADSL router. Seems to work quite fine anyway.

Finally the message is received with ELM327 in a "monitor all" mode. The communication works also backwards: A message sent with ELM327 is received on the CAN controller on Arduino, and sent via XBee to the other laptop.





Here we can see beautiful symmetrical CAN signaling on the oscilloscope :)

I also tested the power consumption of various shields and modules with 12V input power (using HP 6632B lab power supply).
  • Arduino: 52 mA
  • Wireless SD shield + XBee module: 55 mA
  • CAN shield: 6 mA
  • LCD: 27 mA (with backlight), 10 mA (without backlight)
  • Total: 140 mA
As you can see, there's quite a lot of optimization to be done. The 7805 power regulator has some overhead that can be minimized with smarter power supply. Arduino can be put to sleep mode, to be awoken with a signal from either XBee or CAN module, but at minimum, we are talking about 60-70 mA consumption at idle. With my 95 Ah car battery, it would take around (95 Ah/2) / 0.07 A = 678 hours =  28 days for the battery to be depleted to half charge. Not bad, but still potentially harmful, since this device is not the only machine in the car using battery.


Friday, November 16, 2012

Another try..

After more researching, I got unexpected help from a Swedish Volvo forum. Now I know why it's so hard to find any hits from Google when searching with keywords relating to Volvo proprietary CAN protocol: All the hackers in that field of expertise are swedish :) So, I spent quite many hours reading the thread via help of Google Translator, but still couldn't find any references to parking heater. Nice guys on the forum did mention few tricks on how the heater could be ignited, but nevertheless they didn't work. When sending commands to CEM to start the heater directly, such as this:

Id: 00 0F FF FE
Data: CF 40 B1 5F 3B 01 01 04


The result is
Id: 00 80 00 03
Data: CC 40 7F B1 22 00 00 00

which indicates "Error: Conditions not correct or request sequence error"

It seems that starting the heater directly is a process more complicated than expected, involving the need to start perhaps also the water pump and other components via a direct command.

Here's a a command for querying the heater status:


000FFFFE CD 40 A6 5F 32 01 00 00 
          |  |  |  '--|  | 
          |  |  |     |  '-------- 01=Send the record once 
          |  |  |     '----------- 5F 32=Heater work status 
          |  |  '----------------- A6=Read Current Data By Identifier 
          |  '-------------------- CEM id 
          '----------------------- message length 

Heater work status 0x5F32
0x10 Heater is not started
0x20 Heater is starting
0x30 Heater & fuel pump active
0x40 Heater is running
0x50 Heater is stopping
0x60 Heater is cycling
0x70 Heater is stopped
0x80 Blow out occurred
0x90 Rest heat is running
0xA0 Operate fuel pump function
0xB0 One activation on fuel pump



I did start the heater manually using control stalk and queried the status few times:

00 0F FF FE cd 40 a6 5f 32 01 00 00
00 80 00 03 CD 40 E6 5F 32 01 00 00 // before starting (01=not powered?)
00 0F FF FE cd 40 a6 5f 32 01 00 00
00 80 00 03 CD 40 E6 5F 32 11 00 00 // turned it on manually: not yet started, but powered?
00 0F FF FE cd 40 a6 5f 32 01 00 00
00 80 00 03 CD 40 E6 5F 32 20 00 00 / /after few secs: heater is starting
00 0F FF FE cd 40 a6 5f 32 01 00 00
00 80 00 03 CD 40 E6 5F 32 30 00 00 // after 1 min: heater & fuel pump active

So at least querying works.. This needs more investigation.

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" :)

Wednesday, November 7, 2012

Poking bits

Ok, today was the first time I tried to duplicate the messages I had previously analyzed. What is there more to science than proving your hypotheses right or wrong: scientific principle!

I was pretty confident I had managed to unravel the format in the messages SWM (steering wheel module) sends while pressing audio control buttons and playing with cruise control (ignition off, mind you).

Typical message is:

Header: 00 40 00 66 
Data:   c0 00 00 01 1f 40 40 7f

1st data byte: High nibble: Rolling counter (either 0/4/8/c). This changes every message.

   Low nibble: 0 always
2-3: 0x00
4: rolling counter (0-7), advances only when there's a change in the message content
5-6: cruise control button commands: 
   1f 40  (nothing pressed)
   1e 41 (cruise main button)
   0f 50 (0/zero)
   17 48  (reload/return to previously set speed)
   1d 42 (+ speed)
   1b 44 (- speed)

7: 0x40
8:  audio 
   7f=nothing pressed
  77 volume up
  7b volume down
  7d forward
  7e backward     

With this information, I was ready to construct my first message: Fast-forward to next song in audio-cd. And it worked! God damn that felt good after passive logging for so many days :) Then I tried other audio related commands with success. Only thing that needs to be taken care of is advancing those two counters. Second one is easier, since it changes only after each key press, but first counter advances every new message (dozens of times/sec). Thus sometimes the receiving end dismisses the message (thinking that it was old one, if current latest msg index is 'c' and we tried sending ours with index '4').

Now, I wasn't going to fiddle with cruise control while driving (after childhood one starts accumulating these boring self-preservative tendencies), but I couldn't resist forging remote fob central locking messages. And with a little bit anxiety, I sent the message. Cold chills went up my spine when I heard the central locking mechanism engage! Then tried the unlocking message, and off the locks went..  I'm not going to describe the messages in detail here (I'm little bit paranoid should they contain specific details of my car security), even if I know one must be physically connected to the CAN bus to send the aforementioned commands. Most likely they are just messages where CEM (central electronic module) is commanding doors to unlock (unencrypted messages) after the more secure encrypted wireless messaging between the remote fob and CEM.




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!

Saturday, November 3, 2012

Our mysterious friend, CAN bus

First things first:  Researching.


Volvo S80 offers diagnostic interface via the official OBD port, accessible under the dash board.
I bought myself a ELM327 based reader in order to get a first glimpse of messages trafficking in the CAN bus. ELM327 does offer plethora of protocols, including 11 & 29 bit CAN protocols at various speeds. So I plugged it to a laptop running linux, and succesfully connected to the reader via terminal program (minicom in this case). I was able to connect to a car via ISO 9141-2, which is a standard protocol for OBD scanners. I was able to access few parameters the car's CEM (central electronic module) offered (such as error codes), but all attempts to access the CAN bus failed.

According to this OBD connector printout, Volvo cars offer CAN bus on pins 6 & 14. The pinout varies from manufacturer to another, so maybe ELM327 doesn't use correct pins? Said goodbye to the warranty and pried out the cover off the adapter. Pins 6&14 were connected. Damn.

Alright, more research: Found maybe the most important document when thinking about embarking on a quest like this: 2002 S60/S80 electric wiring diagram. According to the diagrams, Volvo has 2 separate CAN buses: Hi-speed (connecting modules responsible for engine, breaks, transmission etc) is on pins 6&14, and low-speed (climate control, audio, window & sunroof control etc) on pins 3 & 11.  Pried ELM327 open again to see that neither of the latter pins were connected. Alright, doesn't still explain why I cannot access hi-speed bus, even if low speed is naturally out of reach.

This time I was starting to get annoyed, so it was time to use the low-level tools.

Interestingly, all of the pins supposedly offering CAN bus access did have digital signal, but it was only on 20-50 millivolt range, instead of somewhere between 5-12 volts that I would expect from a normal CAN signal. More interestingly, they contained exactly the same varying binary signal and at the same speed.  WTF, I might ask.

More googling. Facing the reality: There are a lot of people accessing their cars via Bluetooth OBD dongle and cell phone app (such as Torque), but the amount of serious hackers involved in snooping around proprietary Volvo protocols is incredibly low. However, there are few guys out there who are doing something similar.  I managed to find this conversation, containing advises to send a certain "keep-alive" message every 5 seconds to K-line (pin 7 on OBD-connector) to keep CAN bus interface open. Content is "84 40 13 b2 f0 03 7c", serial settings: 10800 baud, 8N1 and voltage range 0-12V (0V=0b, 12V=1b).

More obstacles.. This wasn't going to work with normal ELM327. However, another member advised to use RTI or AEM connectors, of which the latter at least is accessible in the trunk, rear right corner. According to the electronic diagram, AEM connector pinout is: 1=GND (BLACK), 2=12V (RED), 3=CAN lo-signal (GREEN), 4=CAN hi-signal (WHITE).

Connected the oscilloscope...

and success! 29bit communication @ 125kbit/second. Remind you, this is the low-speed network, but for now, I don't need to access the high-speed can bus connected to engine room modules. Hooked up ELM again to laptop and voila! CAN bus interface is open and messages are firing away at 200-300/sec.

Next step: Intercepting and message analyzing!




Friday, November 2, 2012

What's going on here?

Combine the following attributes:
  • Newly acquired Volvo S80 2002 with a diesel heater (Ardic)
  • Cold and hostile environment.
  • Moderate amount of free time (but never enough!)
  • Reasonable coding skills and electronics know-how
  • Hatred of cold and snow
Mix them in a blender (figuratively) and what you get? Desire to construct a remote control for the diesel heater! Laziness is indeed a major motivator for comfort zone aficionados.

My Volvo does have a timer for starting the heater, but I my schedules are almost never fixed, and what I would rather do in my mornings is to press a button, sip coffee and watch behind a window how my Volvo gets warmer, instead of going there to set it on manually. Hence the project in question.

Now, the quest started with basic Googling: what is already available, have other people done something like this before and how much do they cost? Volvo does offer OEM remote heaters, but they cost shitload of money. Not going pay a hefty amount of 600-1000+ euros for a simple remote control and a box that hits a switch. My hacker soul laughs - challenge accepted.

I've decided to document this project, not only gather my thoughts, but also to share any bits of information that I might find. I hate re-inventing the wheel as much as any other coder, so if this ends up helping even one person trying to figure out their Volvo innards and hack their Swedish tanks, writing this might not been in vain.

My plan was to build a prototype using Arduino (open-source microcontroller) and XBee (low-cost radio module). I've been messing around with Arduino for quite a while, but wireless experience I do not have. However XBee is supposedly quite easy to program and is well documented, so I won't anticipate huge problems in that area. Besides, it's fun to expand your field of expertise. In this case to two new fields: car automation and wireless communication.

Other DIY guys have been thinking alike: 
However to control the actual heater, all of the above mentioned devices rely on AEM (Accessory Electronical Module) to do the dirty work. AEM is a 150-200+ euro Volvo accessory that  offers simple voltage-based on/off interface for non-official, non-Volvo external accessories, such as alarm systems, parking assistance, handsfree systems etc, and of course remote heater starters. AEM then connects to the car's internal electronic system (CAN bus) and controls other devices in the car by sending them CAN bus messages. Thus, external devices don't have to know how to talk to the aforementioned devices directly but can use the simple interface offered by AEM.

Again, I was definitely not going to go out and spend money on a device that just turns the heater on when being told so. I'm both cheapskate and stubborn. So, my only choice was to find out how CAN bus works by a humongous task of googling, researching and reverse engineering the message traffic, and ultimately perhaps finding out how to control the heater. Then design and construct a prototype for sending the ignition command. Then add wireless modules and build a remote. Then press button, sip coffee and watch my Volvo get warm.

Sounds like a lot of work? Sure. But even risking having frostbites after hours of hacking outside in cold temperatures, I'd rather do that than empty my bank account and pay a horseload of money to a guy behind the counter in order to fast-forward to the coffee sipping. Did I mention stubborn?