Reverse engineering the MQB Electric steering rack
-
- Posts: 700
- Joined: Thu Mar 02, 2023 1:30 pm
- Location: Uk
- Has thanked: 362 times
- Been thanked: 103 times
Reverse engineering the MQB Electric steering rack
I'm looking for a bit of direction in trying to hack this MQB rack from a VW Transporter 6.1.
It works in fail safe but it'd be nicer if it ran with the speed mapping to the level of assist.
I've got some Canlogs from a MK7 Golf (I think) and played them back. I've identified the differences between the two, and there seems to be only one CAN ID required to wake up the rack... 0x0FD ESP_21
When powered up the unit sends out comms on...
086 - 4th and 5th bits change with torque input on the rack, whilt playing the CAN log back at the rack these bits change moreso, 4th bit indicates direction of turn (9F turned CCW and DF/5F when turned CW)
09F - 6th bit changes with torque applied to the rack, I need to map this out but this appears to be the angle of the steering wheel
7th bit changes with direction also (00 for CW and 80 for CCW)
5FC - is a static message when in failsafe mode (no playback, with playback it responds), I need to look into this further but changes occur on the 1st, 2nd, 3rd and 4th bits
32A - need to check this one more but no changes obseved
6C0 - changes at 7th bit from 19 to 11 when having the log played back.
Any pointers on how to narrow things down further?
0FD in the CAN log appears to contain some speed information but I'm sure someone with more experience will be able to shed some some light.
I've cut the CAN log down into sections where it appears there is no driving and parts with driving, as expected, playing back with driving provides more assistance than playing back parts with driving.
It works in fail safe but it'd be nicer if it ran with the speed mapping to the level of assist.
I've got some Canlogs from a MK7 Golf (I think) and played them back. I've identified the differences between the two, and there seems to be only one CAN ID required to wake up the rack... 0x0FD ESP_21
When powered up the unit sends out comms on...
086 - 4th and 5th bits change with torque input on the rack, whilt playing the CAN log back at the rack these bits change moreso, 4th bit indicates direction of turn (9F turned CCW and DF/5F when turned CW)
09F - 6th bit changes with torque applied to the rack, I need to map this out but this appears to be the angle of the steering wheel
7th bit changes with direction also (00 for CW and 80 for CCW)
5FC - is a static message when in failsafe mode (no playback, with playback it responds), I need to look into this further but changes occur on the 1st, 2nd, 3rd and 4th bits
32A - need to check this one more but no changes obseved
6C0 - changes at 7th bit from 19 to 11 when having the log played back.
Any pointers on how to narrow things down further?
0FD in the CAN log appears to contain some speed information but I'm sure someone with more experience will be able to shed some some light.
I've cut the CAN log down into sections where it appears there is no driving and parts with driving, as expected, playing back with driving provides more assistance than playing back parts with driving.
- Attachments
-
- Driving Log1 7-11-23-shortened with drive.csv
- (20.34 MiB) Downloaded 287 times
-
- Driving Log1 7-11-23-shortened no drive from 4286812-262989021.csv
- (22.73 MiB) Downloaded 340 times
-
- 086-with drive.csv
- (228.33 KiB) Downloaded 302 times
-
- 086-no drive.csv
- (246.52 KiB) Downloaded 314 times
-
- 32a-with drive.csv
- (66.75 KiB) Downloaded 312 times
-
- 32a-no drive.csv
- (57.15 KiB) Downloaded 313 times
-
- 11d-with drive.csv
- (91.4 KiB) Downloaded 298 times
-
- 11d-no drive.csv
- (115.72 KiB) Downloaded 299 times
-
- 09f-with drive.csv
- (171.83 KiB) Downloaded 310 times
-
- 09f-no drive.csv
- (158.46 KiB) Downloaded 326 times
-
- 5fc and 6c0-with drive.csv
- (79.06 KiB) Downloaded 326 times
-
- 5fc and 6c0-no drive.csv
- (58.46 KiB) Downloaded 296 times
-
- Posts: 700
- Joined: Thu Mar 02, 2023 1:30 pm
- Location: Uk
- Has thanked: 362 times
- Been thanked: 103 times
Re: Reverse engineering the MQB Electric steering rack
So I've had a little more time to mess with this.
I'm flying by the seat of my pants as I go here so may be making hard work of what you all would find pretty easy but playing the filtered CAN log back at the rack for 0FD EPS_21 I get assist and speed values showing on ODIS.
I played a log whilst taking a bunch of photos and then laid it out in a graph, removing outlier values of assist (likelihood due to extra torque from steering) and the averageing the results I've got an idea of the levels of assist at different speeds... Following on from this, looking at EPS_21 I can see byte 2 starts at 211 and counts up to 223, so I guess that's a counter then that can be seen in green on this flow graph and the DBC ..
The ESP V Signal is noted in "KiloMeterPerHour" so thats likely my speed, starts at byte 5 (bit 32) and is 16 bits long if I am interpreting the DBC correctly...
But I'm uncertain how the data is then cofigured to the speed shown below.. from the raw data flow graph...
I'm flying by the seat of my pants as I go here so may be making hard work of what you all would find pretty easy but playing the filtered CAN log back at the rack for 0FD EPS_21 I get assist and speed values showing on ODIS.
I played a log whilst taking a bunch of photos and then laid it out in a graph, removing outlier values of assist (likelihood due to extra torque from steering) and the averageing the results I've got an idea of the levels of assist at different speeds... Following on from this, looking at EPS_21 I can see byte 2 starts at 211 and counts up to 223, so I guess that's a counter then that can be seen in green on this flow graph and the DBC ..
Code: Select all
BO_ 253 ESP_21: 8 Gateway_MQB
[b]SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" XXX[/b]
SG_ BR_Eingriffsmoment : 12|10@1+ (1,-509) [-509|509] "" XXX
SG_ ESP_PLA_Bremseingriff : 22|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ ESP_Diagnose : 23|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ ESC_Reku_Freigabe : 24|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ ESC_v_Signal_Qualifier_High_Low : 25|3@1+ (1.0,0.0) [0.0|7] "" XXX
SG_ ESP_Vorsteuerung : 28|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ ESP_AWV3_Brems_aktiv : 29|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ OBD_Schlechtweg : 30|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ OBD_QBit_Schlechtweg : 31|1@1+ (1.0,0.0) [0.0|1] "" XXX
[b] SG_ ESP_v_Signal : 32|16@1+ (0.01,0) [0.00|655.32] "Unit_KiloMeterPerHour" XXX[/b]
SG_ ASR_Tastung_passiv : 48|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ ESP_Tastung_passiv : 49|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ ESP_Systemstatus : 50|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ ASR_Schalteingriff : 51|2@1+ (1.0,0.0) [0.0|3] "" XXX
SG_ ESP_Haltebestaetigung : 53|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ ESP_MKB_Abbruch_Geschw : 54|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ ESP_QBit_v_Signal : 55|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ ABS_Bremsung : 56|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ ASR_Anf : 57|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ MSR_Anf : 58|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ EBV_Eingriff : 59|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ EDS_Eingriff : 60|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ ESP_Eingriff : 61|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ ESP_ASP : 62|1@1+ (1.0,0.0) [0.0|1] "" XXX
SG_ ESP_Anhaltevorgang_ACC_aktiv : 63|1@1+ (1.0,0.0) [0.0|1] "" XXX
But I'm uncertain how the data is then cofigured to the speed shown below.. from the raw data flow graph...
-
- Posts: 700
- Joined: Thu Mar 02, 2023 1:30 pm
- Location: Uk
- Has thanked: 362 times
- Been thanked: 103 times
Re: Reverse engineering the MQB Electric steering rack
OK, so the vehicle speed is made up from byte 5 and byte 6 and is calculated by (b5 + b6*253)*0.01.
-
- Posts: 700
- Joined: Thu Mar 02, 2023 1:30 pm
- Location: Uk
- Has thanked: 362 times
- Been thanked: 103 times
Re: Reverse engineering the MQB Electric steering rack
So I made a little progress last night after not having done anything on it in a while...
I asked Gemini (googles AI) to help with the checksum for the CAN ID 0X0FD EPS_21...
It managed pretty quickly to crack it and comparing it to the CAN Log I've got appears to be correct which is good news. I've also got it to generate some code (below), but I need to check it over... whilst learning C++
....
Then I'm hoping to merge it into BigPies Canfilter code so I can get it to translate from my VW transporter CAN data to the newer MQB format to satisfy the rack.
I'll bench test it all first but given the rack goes to failsafe mode if it receives invalid data or looses connection I'm confident it should work OK...
I asked Gemini (googles AI) to help with the checksum for the CAN ID 0X0FD EPS_21...
It managed pretty quickly to crack it and comparing it to the CAN Log I've got appears to be correct which is good news. I've also got it to generate some code (below), but I need to check it over... whilst learning C++
Then I'm hoping to merge it into BigPies Canfilter code so I can get it to translate from my VW transporter CAN data to the newer MQB format to satisfy the rack.
I'll bench test it all first but given the rack goes to failsafe mode if it receives invalid data or looses connection I'm confident it should work OK...
Code: Select all
#include <stdint.h>
uint8_t calculateCRC8(const uint8_t *data, size_t length) {
uint8_t crc = 0x00;
uint8_t polynomial = 0x07;
for (size_t i = 0; i < length; i++) {
uint8_t dataByte = data[i];
for (uint8_t j = 0; j < 8; j++) {
uint8_t msb = (crc & 0x80) ? 1 : 0; // Check if MSB of CRC is 1
crc <<= 1; // Shift CRC left by one bit
if (msb ^ ((dataByte >> (7 - j)) & 0x01)) { // If MSB of CRC XOR current data bit is 1
crc ^= polynomial; // XOR CRC with the polynomial
}
crc &= 0xFF; // Ensure CRC remains an 8-bit value
}
}
return crc;
}
// Example usage:
void setup() {
Serial.begin(115200);
Serial.println("CRC-8 Calculation Example");
// Example CAN data (excluding the checksum byte itself)
uint8_t canData[] = {0xD4, 0x1F, 0x80, 0xB4, 0x29, 0x00, 0x00};
size_t dataLength = sizeof(canData) / sizeof(canData[0]);
uint8_t calculatedChecksum = calculateCRC8(canData, dataLength);
Serial.print("Data: ");
for (size_t i = 0; i < dataLength; i++) {
Serial.print(canData[i], HEX);
Serial.print(" ");
}
Serial.println();
Serial.print("Calculated CRC-8 Checksum: 0x");
Serial.println(calculatedChecksum, HEX);
// For the 5th frame in your log, the expected checksum (D1) was 0xCB
Serial.print("Expected Checksum (from log): 0xCB");
}
void loop() {
// In your real-time application, you would read CAN data here
delay(1000);
}
- uhi22
- Posts: 1085
- Joined: Mon Mar 14, 2022 3:20 pm
- Location: Ingolstadt/Germany
- Has thanked: 187 times
- Been thanked: 604 times
Re: Reverse engineering the MQB Electric steering rack
The shown code does not include the alive counter (which should increment with each message), and also does not contain the table with magic bytes. So it cannot produce valid E2E protected messages.
Github: http://github.com/uhi22 --- Patreon: https://www.patreon.com/uhi22
-
- Posts: 700
- Joined: Thu Mar 02, 2023 1:30 pm
- Location: Uk
- Has thanked: 362 times
- Been thanked: 103 times
Re: Reverse engineering the MQB Electric steering rack
Thanks for looking over it.
If I'm understanding you, the code only calculates the 1st bit. This is the checksum, the counter is a latter bit (I cannot remember which). I gave the AI some data with the first checksum bit removed and asked it calculate the checksum based on the provided data and the checksum bit matched. But I may be misunderstanding how this all works by the sound of it.
If I'm understanding you, the code only calculates the 1st bit. This is the checksum, the counter is a latter bit (I cannot remember which). I gave the AI some data with the first checksum bit removed and asked it calculate the checksum based on the provided data and the checksum bit matched. But I may be misunderstanding how this all works by the sound of it.
- uhi22
- Posts: 1085
- Joined: Mon Mar 14, 2022 3:20 pm
- Location: Ingolstadt/Germany
- Has thanked: 187 times
- Been thanked: 604 times
Re: Reverse engineering the MQB Electric steering rack
The snippet of the DBC above shows that the checksum is at bit 0 and has 8 bits, and the counter starts at bit 8 (means: in the second byte), and has four bits.
The CRC algorithm may be similar to one of the profiles described in the AUTOSAR E2E specification. I described a similar method which Tesla uses, https://github.com/uhi22/tesla-crc
If we have a lot of trace data of an original car, it is possible to find out the missing pieces: the 16-byte table with magic bytes and the CRC polynom.
The CRC algorithm may be similar to one of the profiles described in the AUTOSAR E2E specification. I described a similar method which Tesla uses, https://github.com/uhi22/tesla-crc
If we have a lot of trace data of an original car, it is possible to find out the missing pieces: the 16-byte table with magic bytes and the CRC polynom.
Github: http://github.com/uhi22 --- Patreon: https://www.patreon.com/uhi22
-
- Posts: 700
- Joined: Thu Mar 02, 2023 1:30 pm
- Location: Uk
- Has thanked: 362 times
- Been thanked: 103 times
Re: Reverse engineering the MQB Electric steering rack
I've got 2 can logs from a VW Mk7 Golf, both are quite long so theres plenty of data there of thats what you mean by trace data.
- uhi22
- Posts: 1085
- Joined: Mon Mar 14, 2022 3:20 pm
- Location: Ingolstadt/Germany
- Has thanked: 187 times
- Been thanked: 604 times
Re: Reverse engineering the MQB Electric steering rack
Ahh, I just see the attached logs above, I will have a look into them in the next days.
If you have longer logs you could extract the lines with the esp_21 message (eg using linux grep command) and provide the extract.
If you have longer logs you could extract the lines with the esp_21 message (eg using linux grep command) and provide the extract.
Github: http://github.com/uhi22 --- Patreon: https://www.patreon.com/uhi22
-
- Posts: 700
- Joined: Thu Mar 02, 2023 1:30 pm
- Location: Uk
- Has thanked: 362 times
- Been thanked: 103 times
-
- Posts: 700
- Joined: Thu Mar 02, 2023 1:30 pm
- Location: Uk
- Has thanked: 362 times
- Been thanked: 103 times
Re: Reverse engineering the MQB Electric steering rack
I've filtered the log files for 0x0FD only and attached, thanks again for the help
- Attachments
-
- Driving Log1 7-17-23-0fd.csv
- (2.28 MiB) Downloaded 306 times
-
- Driving Log1 7-11-23-0fd.csv
- (2.69 MiB) Downloaded 297 times
- uhi22
- Posts: 1085
- Joined: Mon Mar 14, 2022 3:20 pm
- Location: Ingolstadt/Germany
- Has thanked: 187 times
- Been thanked: 604 times
Re: Reverse engineering the MQB Electric steering rack
Good news: The CRC algorithm is the same as used in Tesla. Created a program which reads the above two log files, calculates the CRC for each message and compares it with the transmitted CRC. Result: All pass. CRC ok: 91622, CRC fail: 0
Github: https://github.com/uhi22/tesla-crc/tree/main/vag
Github: https://github.com/uhi22/tesla-crc/tree/main/vag
Github: http://github.com/uhi22 --- Patreon: https://www.patreon.com/uhi22
-
- Posts: 700
- Joined: Thu Mar 02, 2023 1:30 pm
- Location: Uk
- Has thanked: 362 times
- Been thanked: 103 times