In a previous post, I found and reverse engineered the door status message on the HS-CAN bus on my vehicle. For reference, the HS-CAN bus on my vehicle is on Pins 6 & 14 of the OBD Port (J1962 Connector) and it is a High Speed CAN network operating at 500Kbit/s which is true for every vehicle sold in the USA since 2008. In this post, I will I try to influence the display of my Instrument Panel Cluster (IPC). I determined, with the help of the internet, that the IPC is on a network known as MS-CAN. MS-CAN is accessible on Pins 3 & 11 of the OBD Port and it is a High Speed CAN network operating at 125Kbit/s. My gut said that there was a separate CAN message on the MS-CAN network which also indicates the door status so that the IPC can react accordingly and update the display.
Quick disclaimer before we continue on: All code in this article is licensed under the MIT License, and I want to stress that I am not liable for any claims, damages or other liability from executing the software in this article – I have purposefully left all the channels on vcan0 so someone would need to modify the code first before it could do anything on a real network. Please use common sense and don’t inject CAN messages on a vehicle that is driving or a vehicle that is not compatible as messages containing Engine RPM information on one manufacturers vehicle might be a blow airbags event in another.
In order to access the MS-CAN bus using my USB2CAN tool, I had to make use of the special MS-CAN harness adapter I made in another post. I then configured my tool to operate at 125Kbit/s using the following commands:
sudo ip link set can0 type can bitrate 125000 sudo ip link set up can0
The next thing I did was plug in the connector with the adapter attached into the J1962 vehicle connector and fired up cansniffer. I looked at each individual CAN message for changes as I opened the driver side font door and closed it. I quickly noticed that a message with CAN ID 0x80 changed everytime I opened and closed my driver side front door. After that, I reached over and opened the passenger side front door and it changed again. The way the data was encoded into the message was very similar to the sister message on the HS-CAN bus which made spotting the signature I was looking for in the data all the more easy.
// All Doors Closed can0 080 [8] 77 83 06 3F D9 06 03 82 // Open Front Left Door can0 080 [8] 77 83 06 3E D9 06 03 82 // Open Hood can0 080 [8] 77 83 06 1E D9 06 03 82 // Open Front Right Door can0 080 [8] 77 83 06 1C D9 06 03 82 // Open Rear Right Door can0 080 [8] 77 83 06 14 D9 06 03 82 // Open Trunk can0 080 [8] 77 83 06 04 D9 06 03 82 // Open Rear Left Door can0 080 [8] 77 83 06 00 D9 06 03 82
This message with CAN ID 0x80 was transmitted onto the MS-CAN bus every 60 ms. After studying this CAN message in various vehicle operating states I was able to deduce the following:
Offset Byte[Bit] | Length Byte[Bit] | Value | Comments |
---|---|---|---|
0[0] | 1[0] | $77 | Uknown (Static) |
1[0] | 0[7] | $3 | Uknown (Static) |
1[7] | 0[1] | 1 – Key In RUN 0 – Key Not In RUN |
Key In RUN Status |
2[0] | 0[4] | No Key – $1 Key OFF – $2 Key OFF transition from ACC – $3 Key ACC – $4 Key ACC transition from RUN – $5 Key RUN, Engine Off – $6 Key RUN, Engine On – $7 Key START – $9 |
Ignition Status |
2[4] | 0[4] | $0 | Unknown (Suspect Reserved) |
3[0] | 0[1] | Closed – 1 Opened – 0 |
Driver Side Front Door (Front Left) Closed |
3[1] | 0[1] | Closed – 1 Opened – 0 |
Passenger Side Front Door (Front Right) Closed |
3[2] | 0[1] | Closed – 1 Opened – 0 |
Driver Side Rear Door (Rear Left) Closed |
3[3] | 0[1] | Closed – 1 Opened – 0 |
Passenger Side Rear Door (Rear Right) Closed |
3[4] | 0[1] | Closed – 1 Opened – 0 |
Hatchback (Luggage Compartment) Closed |
3[5] | 0[1] | Closed – 1 Opened – 0 |
Hood/Bonnet (Engine Compartment) Closed |
3[6] | 0[1] | $0 | Suspect Either Reserved or for Sunroof/Moonroof |
3[7] | 0[1] | $0 | Unknown (Suspect Reserved) |
4[0] | 1[0] | Usually $D9, although did see $C9 briefly | Unknown |
5[0] | 0[4] | No Key – $1 Key OFF – $2 Key OFF transition from ACC – $3 Key ACC – $4 Key ACC transition from RUN – $5 Key RUN, Engine Off – $6 Key RUN, Engine On – $7 Key START – $A |
Ignition Status (Secondary) |
5[4] | 0[4] | $0 | Unknown (Suspect Reserved) |
6[0] | 2[0] | Usually initially $0000, but after the engine runs a while this value gets set. Maybe average idle RPMs? | Appears to be some 16-bit value |
I then wrote the following python script to override the native door signal.
import can import time bustype = 'socketcan' channel = 'vcan0' # can0 on non-virtual physical bus bus = can.interface.Bus(channel=channel, bustype=bustype, bitrate=125000) for i in range(6000): #driver door open, key in run, engine off msg = can.Message( is_extended_id=False, arbitration_id=0x80, data=[0x77, 0x83, 0x06, 0x00, 0xD9, 0x06, 0x00, 0x00]) print(msg) bus.send(msg) time.sleep(0.01) # send every 10 ms
The script sends the CAN ID 0x80 message representing the key in run position with engine off and all doors opened. The vehicle natively sends this CAN ID 0x80 message every 60 ms and in order to successfully override the native message the script sends its message every 10 ms.
Next, I placed the key of the vehicle in run position with the engine off and all the doors closed so that IPC display looked like the following:
I executed the script and monitored the bus during the execution of the script. Below is the annotated output:
(1618619305.844831) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619305.855390) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619305.865933) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619305.876488) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619305.887065) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619305.890145) can0 080 [8] 77 83 06 3F D9 06 00 00 <-- vehicle message (1618619305.897486) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619305.907962) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619305.918437) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619305.928922) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619305.939475) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619305.946819) can0 080 [8] 77 83 06 3F D9 06 00 00 <-- vehicle message (1618619305.949926) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619305.960383) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619305.970850) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619305.981342) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619305.991781) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619306.002259) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619306.007437) can0 080 [8] 77 83 06 3F D9 06 00 00 <-- vehicle message (1618619306.012693) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619306.023212) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619306.033660) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619306.044103) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619306.054610) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619306.065080) can0 080 [8] 77 83 06 00 D9 06 00 00 <-- script message (1618619306.067178) can0 080 [8] 77 83 06 3F D9 06 00 00 <-- vehicle message
Please note that the script transmits it’s version of the message 5-6 times for every time the vehicle transmits it’s native version of the message. Immediately after starting the script, despite all my doors being closed, the IPC showed all the doors including the engine compartment and luggage compartment, as being opened. Success!
Thank you as always for reading. This was a fun exercise in CAN bus hacking with an easily verifiable result. If you have questions or comments, please let me know.
hey Derek, Happy New Year.
I’m building a Focus ST swapped RX8 and as a side project, I am working on a HS can convertor (with the hopes of just using the ST PCM in the car instead of it AND the 8s). There are still a couple message/message Ids I haven’t seen logged and have not been able to track down (because I don’t have a running focus to sniff).
1 – check engine light
2 – “A/C On” message/ID that the BCM (I assume) sends the PCM.
the A/C is something I’m most concerned with. I COULD bypass the PCM for A/C control but i’d rather not.
you wouldnt happen to have decoded either of these or have a log of them would you?