Ask an “expert.” No seriously, an expert. If you have a CAN Bus Hack related question and you want to share your incompetence to the rest of my readers, please feel free to post your questions. If you don’t want anyone to know that you don’t know what you think you would like to know. Then give shoot me an email by clicking on the “Contact” link on the title bar of canbushack.com.
Most vehicles employ some sort of network management. This is typically for the Low Speed or Body Network. The High Speed or Powertrain network will come alive when the key is in the start position. But if you need to send an unlock command using your key fob and this is done via a CAN Bus, then there will need to be a network management system to wakeup nodes and allow them to go back to sleep.
The problem is that there are sooooo many ways of accomplishing this task. There is GMLAN, OSEK, and many others. In general they may have nothing to do with each other, you will just have to learn them all! So here is a start:
GMLAN Network Management:
GM uses network management on their Single Wire or Low Speed network in order to wake up nodes that are in a low-current or sleep mode. There are essentially two events that must take place to communicate with a sleeping node.
First you must wake it up by sending a High Voltage Wake-Up. On single wire CAN the physical layer is typically an active high, 0-5V line. This means that if you were to watch normal traffic on an oscilloscope, you would see 0 Volts for low values and 5 Volts for high values; but when a node is sending a high voltage wake-up now the high values will be at 12 volts (rather Vbatt which may be as low as 9 Volts or as High as 16 Volts). Although it doesn’t matter what format this message is, it is typically the message with Arbitration ID 0x100 and has NO data. This lets the sleeping nodes know that they need to wake-up. An awake node may or may not be listening to command information just yet. Most nodes require another “Wake-Up” to send data to them.
Second you must send the Virtual Network Management Frame (VNMF). This message is designed to wake-up particular virtual networks or groups of nodes that are associated through common systems such as lighting control or entry systems (i.e. doors). So if I wanted to talk to door module to unlock the doors I would wake up the virtual network for doors. The problem is of course, I have no way of knowing the networks without a proprietary list which I don’t have. So instead of worrying about which virtual network to wake-up I will show you how to wake them ALL up. To wake up ALL virtual network it’s as simple as sending the following message: 0x621 01 FF FF FF FF 00 00 00.
So why does this work? ALL VNMFs have a range of 11 bit IDs (even on 29-bit networks). 0x620-0x63F are reserved IDs for VNMFs. So you can use ANY ID within that range and it will be interpreted as a VNMF by all nodes. The ID is the source node. In this case $621 is from the Body Control Module. The First byte of a VNMF is either 0x00 or 0x01. 0x01 means Initiate the following Virtual Network(s) (VN) and 0x00 means Continue the following VNs. The next three or four data bytes contain a bit encoded list of each VN where 1 means wake-up and 0 means nothing. So if you send 0xFF this is essentially saying wake-up to the eight VNs that are encoded in that byte.
This method is like using a blow horn to wake-up the nodes. Each node will hear it and wake-up. If you want to be more subtle and only wake-up the VN your are interested in, then you can go bit-by-bit and find your VN it should take too much time either as there may only be around 20 VNs at most on any particular vehicle.
A VN will stay awake for up to 3 seconds after the first message was called. So if you want to keep the network awake you must constantly send the Continue frame $621 00 FF FF FF FF 00 00 00.
To summaryize here is the VNMF format:
Format: ArbID, B1, B2, B3, B4, B5, B6, B7, B8
As Seen: $620-$63F, 01 or 00, XX, XX, XX, XX, 00, 00, 00 (Where XX = Some bit-encoded value where each bit represents a single VN).
oh and ALL VNMFs MUST BE 8 BYTES IN LEGTH!
If you do what I do, you like it when the networks you are working with are terminated to a standard connector. The OBDII connector typically contains all of the vehicle’s networks so that engineers working on the vehicle can easily access the data. Of course after it is released, the networks are still there, lonely, waiting for companionship.
However in the case of FiatChrysler Cars, a gateway device blocks us hackers from accessing all the data from one location (the OBDII connector). So if you wanted to access the powertrain or body CAN busses, you had to find them someone in the vehicle and tap into the wires. Annoying!
Well I have good news, this practice is slowly being phased out. Now you can find the body networks located on pins 3 and 11 on the new 2011 Town and Country. All of the data that you’ve come to know and love is now available to you to devour.
As for the new Fiat 500 that will be sold in the US, this also has the body network on the OBDII connector on pins 1 and 9. However to find the connector is a bit difficult (unless they change it for the US edition). Look in the upper left area by the steering wheel. It will be located behind a panel.
Not quite sure what is wrong with me, but I decided to turn on comments as a trial. I’d like to see what your thoughts are of the horrible manure in which I write my blog; how bad my spelling/grammar can be; and how absolutely incompetent I am.
Please keep the language to a minimum and be aware that if you post any good ideas that I will steal them and not give you any credit whatsoever.
Because diagnostic data is built on top of a standard Transport Protocol (ISO 15765-2), you can use this knowledge to see which diagnostic service a particular vehicle supports and which parameters or sub-functions it may support.
Step 1. Finding Nodes’ Diagnostic IDs.
We must first have all of the nodes enumerated with Physical IDs and their respective response IDs (Note: sometimes there may be an ID that is a Functional ID. That means more than one node will respond to request sent on this ID). To do this I usually send the Tester Present Request (Service 0x3E) to each CAN BUS ID. If you are working with a 29bit system this may be daunting simply because of how many possible IDs there are; you may have to find a shortcut instead of request each ID. However on 11bit systems this is quite easy.
Start by sending tester present to ARB ID 0x001. This message would typically look like this:
0x001 01 3E 00 00 00 00 00 00 OR 0x001 02 3E 01 00 00 00 00 00. Try them both and see which works. Next simply increment your arbitration ID by one: 0x001, 0x002, 0x003, … 0x7FF. You will know that a node has diagnostics on it because you will see a response from the node after you send your request. You would typically see this: 0x7E8 01 7E 00 00 00 00 00 00. The 0x7E is the positive response to your 0x3E request (tester present). Write down (or log) the request ID AND the response ID and save them for later. Essentially the request ID is how you query the controller and the response ID is data you will get back from that specific controller. Keep in mind that you may get some CAN BUS errors. This is to be expected, but should not cause concern. You may also have some strange affects on the car such as a windshield wiper move or blinker kick in. This is because you are sending data on the bus that is interpreted by other controllers and you may have inadvertently activated another command. Cool, huh?
Step 2. Finding Supported Services.
This can be a bit tricky only because some services may require a certain message length (i.e. you may have to have 0x04 in the first data byte in order to get a positive response from the controller), but this is usually not the case. In order to do this you must remember that the service ID for a diagnostic command is found in the second byte (ARBID, B1, B2, B3, etc). So your first request might look like this: 0x7E0 01 01 00 00 00 00 00 00, where byte 2 contains the service. In this case we are not sending any protocol data. Diagnostic services are broken into ranges. This is because the request IDs and positive response IDs don’t over-lap, and since we are not interested sending the responses, we can remove the positive response IDs from the services we will request. Service request IDs are as follows: 0x01-0x3E, 0x80-0xBE. (0x3F is reserved, 0x7F is for negative responses and 0x40-0x7E and 0xC0-0xFE are reserved for positive responses coming back from the ECU).
Now that we know what our range is, we can simply send a request and based on its response we will know if this is a service that is supported. We send 0x7E0 01 01 00 00 00 00 00 00 and we get back 0x7E8 03 7F 01 12 00 00 00 00. The response is a negative response because there is a 0x7F in the second data byte. This tells us that there was a problem with our request, but does NOT mean that the service is not supported. We have to look at byte 4 to see why our request failed. In this case we got a 0x12 Negative Response Code (NRC). 0x12 means Sub-Function not supported (please see list below for other NRCs). So it’s telling that the service IS support but the sub-function (which we didn’t send one in this case) is not supported. In fact we can ignore all NRCs except 0x11 and 0x78. NRC 0x11 means that the Service is Not Supported. This gives us a definitive NO that we cannot use this service on this controller. NRC 0x78 doesn’t tell us anything, yet. In fact it means Response Pending. It may response later with another NRC or with a positive response. Other than a NRC 0x11, a simple No-Response will tell you that the controller does not support your service. Simply waiting around 100 milliseconds (ms) will be sufficient proof that the particular service is not supported on your controller.
Step 3. Finding Parameters.
This is the most dynamic of steps. It requires some understanding of the service that you are working with. For example, you may be using a service that has a sub-function or a service that has a parameter and this parameter may be 1 byte, two bytes, three, etc. So you will have to prepare yourself for a lot of negative responses (I hope you don’t fear rejection).
So here is what we do now, send our request but increment the bytes,
0x7E0 02 01 00 00 00 00 00 00,
0x7E0 02 01 01 00 00 00 00 00,
0x7E0 02 01 02 00 00 00 00 00, etc..
If you are getting positive responses back from the controller, then you have won. However if the controller is sending back negative responses then you’ll have to adapt. For instance you may get a NRC 0x22, this means “Conditions Not Correct, Sequence Error”. This NRC is particularly vague. It typically means that you must send a Start Diagnostic command first or that the key must be in the ignition, or that Venus and Mars must be in alignments. So you will just have to work with what you have. But if you get a NRC 0x12, you will know right away that this sub-function or this parameter ID is not supported by this controller and you can move on to the next one.
As you can see the trick is to automate this process. To write each message and handle each repsonse can be difficult.
|$11||Service Not Supported|
|$12||Sub Function Not Supported - Invalid Format|
|$22||Conditions Not Correct Or Request Sequence Error|
|$31||Request Out Of Range|
|$36||Exceed Number Of Attempts|
|$37||Required Time Delay Not Expired|
|$78||Request Correctly Received-Response Pending|
On most late-model cars, there are hundreds of messages with thousands of parameters being transferred between controllers, this leads to the idea that EVERYTHING is being able to be controlled by CAN BUS messages. This simply is not the case. If a controller doesn’t need to send internal data to another controller then it won’t. Simple as that.
So why am I writing this? Because the biggest waste of time in reverse-engineering the CAN BUS is looking for a command or a parameter that simply isn’t there. You need to have the notion that everything is not available and sometimes you won’t find it no matter how much you look.
So how do you determine how long to spend on looking for a parameter or command? Well the answer, I think, depends on the importance of getting the parameter. I take the example of trying to find Engine Speed on a CAN BUS. Engine Speed is nearly universally available on today’s CAN BUS vehicles. It is usually simple to find and scale, so not much time is wasted, but in contrast, Outside Air Temp may not be collected by a module on a car or may not be broadcast by the controller that collects the data. In the first instance where it is not collected there are ways to find this out before hand. You can look at publicly available wiring diagrams that show (or rather do not show) that there is no Outside Air Temp sensor on any controller. This will save you time and frustration.
In the case of commands sent over CAN BUS (i.e. Unlock from a key fob). These can be tested by capturing all of the messages while you pressed the unlock button, then play those messages back to the network one or two times to see if the doors unlock. Why does this work? If the message was sent over the CAN BUS then by playing all of the messages back on the bus you should have the same result as when you pressed the button such as any parking light flashing, horn honking, etc. If you do then you know the message is broadcast over the CAN BUS, if not then you can assume that it is most likely not available. If it is not available, simply move on. You can try the process again one or two more times, but you probably did it right the first time.
So good luck and as always let me know what you’re working on, I’m always interested to help.