Can the propeller be used as a CAN sniffer? (bit collection project idea)
turbosupra
Posts: 1,088
I'd like to build a Prop Sniffer. Toyota has a CAN like network called Bo dy Electronic Area Net work and it is not encrypted. It uses 2 multiplex lines, MPX1 and MPX2. For those of you that have done something like this, or are more experienced than I, is this feasible?
The specification for the network is
1 SOF (1 bit) (start of frame)
2-5 PRI (4 bits) (priority of bits)
6-9 ML (4 bits) (message length, length of message and number of bytes, [ID + DATA] (3-13)
10-17 DST-ID (8 bits) (the id showing the communication destination)
18-25 MES-ID (8 bits) (is an area showing message contents)
26-113 DATA (8 to 88 bits) (1 to 11 bytes of data, variable length, could be as small as bits 26-33, reskewing the bit number slots for the remaining bit groups)
114-121 CRC (8 bits) (error check code remainder from polynomial)
122-129 EOM (8 bits) (end of message and controls time to prepare response for sending)
130-132 RSP (2 bits) (represents the response area)
133-138 EOF (6 bits) (shows the end of the frame)
More specs
CSMA/CD
Bit encoding: NRZ
Media Access: Contention
Error Detection: 8-bit CRC
Header Length: 25bits
Data length: 1-11bytes
Overhead: 28%
In-message response: NO
Bit rate: 10Kb/s
Maximum Bus Length: Not Specified
Maximum Nodes: 20
u Needed?: YES
Sleep / Wakeup: NO
H/W Avail?: YES (?)
Cost: Low
Communication speed: Max 10kbps
Communication wire: av single wire
Drive type: single wire voltage drive
Data length: 1-11 byte (variable)
It also employs bit stuffing where an inverted bit is inserted when 5 consecutive bits have the same value from the SOF to CRC bit groups
With that being said, could the prop monitor the lines for binary and convert it to hex? I'd like to reverse engineer the CRC poly as well once I get this information so that I could send my own messages. On the net I found partial examples of data captured by them, that data is in quotes below.
The specification for the network is
1 SOF (1 bit) (start of frame)
2-5 PRI (4 bits) (priority of bits)
6-9 ML (4 bits) (message length, length of message and number of bytes, [ID + DATA] (3-13)
10-17 DST-ID (8 bits) (the id showing the communication destination)
18-25 MES-ID (8 bits) (is an area showing message contents)
26-113 DATA (8 to 88 bits) (1 to 11 bytes of data, variable length, could be as small as bits 26-33, reskewing the bit number slots for the remaining bit groups)
114-121 CRC (8 bits) (error check code remainder from polynomial)
122-129 EOM (8 bits) (end of message and controls time to prepare response for sending)
130-132 RSP (2 bits) (represents the response area)
133-138 EOF (6 bits) (shows the end of the frame)
More specs
CSMA/CD
Bit encoding: NRZ
Media Access: Contention
Error Detection: 8-bit CRC
Header Length: 25bits
Data length: 1-11bytes
Overhead: 28%
In-message response: NO
Bit rate: 10Kb/s
Maximum Bus Length: Not Specified
Maximum Nodes: 20
u Needed?: YES
Sleep / Wakeup: NO
H/W Avail?: YES (?)
Cost: Low
Communication speed: Max 10kbps
Communication wire: av single wire
Drive type: single wire voltage drive
Data length: 1-11 byte (variable)
It also employs bit stuffing where an inverted bit is inserted when 5 consecutive bits have the same value from the SOF to CRC bit groups
With that being said, could the prop monitor the lines for binary and convert it to hex? I'd like to reverse engineer the CRC poly as well once I get this information so that I could send my own messages. On the net I found partial examples of data captured by them, that data is in quotes below.
DID 62
MID BF
DATA1 00
CRC 78
EOM 7E
DID 62
MID D2
DATA1 00
DATA2 A0
DATA3 08
CRC 0A
EOM 7E
DID 98
MID CC
DATA1 02
DATA2 A8
CRC 35
EOM 7E
DID EF
MID 6A
DATA1 04
CRC 44
EOM 3F
Comments
so how much time is there to process the bits - and then the message ...
I tested everything with a USB-CAN interface called PCAN (provided by client). In the end, the object I wrote was used for node-to-node comms in an HVAC system.
There is a software CAN object somewhere, that only requires the interface chip (MCP2551, 8-pin DIP in photo). I've not used it, but it might be worth looking at. I went the full hardware route because I had been asked to code a client project with that circuit and it worked very well.
I've written a few Prop-based objects that should work with some modifications to the parse_bit routine in the reader section.
What are the signal levels?
Does it idle high or low?
Are the bits inverted?
You may not even need the 2551 line driver. I'm currently working on a modification to the above CANbus routines that'll work with a GMLAN class-2 databus, which uses the same CAN protocol, but the messages are inverted, uses 5V for dominant '0' bits and gnd for recessive '1' bits, so all I need for that is a transistor driver for tx, and a current limiter for rx.
I was able to ask for more complete data sets that the person used matlab to get.
Did you use a scope to gather your information, or can I use a scope to answer the questions you've asked me?
Using the first code set
You show a Standard Frame and say it's the only frame kind that the MCP2515 decodes. Did you omit the Extended Frame kind or have you encountered problems with the MCP2515 and Extended Frames?
Thanks
Do you know if it is CAN?
If yes, then the MCP2551 or similar would do for the interface chip.
But your mention here seems to not be CAN COuld it be LIN?
At 10kbs the prop should handle it fine.
Initially it might be better to snoop the bus/line(s) using an optoisolator - a 6N137 or similar should do the job.
For the CRC, often the address/header is not included in the CRC. Check the CAN bus spec as this might be the CRC used.
There are online calculators that include setting the CRC algorithm and using that, hopefully you can determine which CRC is used. There are only a few common ones.
Since it is only a single byte CRC it may just be a simple XOR function.
I managed to find a CRC that works with two of your messages, but fails all of the others, not sure what to make of that. Every search for more info about this BEAN protocol sends me to the SAE paywalled paper. The above code stops searching once the CRC reaches 10 bits. I'm currently (for the past half-hour) letting it run up to the full 32 bits just to see.
@ksltd
Extended and remote frames work fine; I didn't see a reason to show them as they closely resemble the standard frame, and are nothing like what turbosupra is describing:
Chris
That does not sound like CAN, looks like a Custom Automotive Network, using LIN bus hardware drivers
(which are 10KHz region, single pin, 12V signaling)
You might like to change the heading from CAN
I'd also suggest you look into LIN bus a little, even if this is not a LIN clone, LIN has things like an Autobaud preamble this might use.
10KHz is quite low speed, so I'd suggest doing a Bridge device in a Prop - that can Read/Write on this bus, and converts to a Generic UART PC serial stream.
eg One simple way is to nibble encode, where lower 4 bits are a half byte payload, and the upper 4 bits give 16 choices of what to do with it. 2 of those can tag DataH,DataL, which leaves 14 spare for control and commands
That allows the complex reverse engineering stuff to be managed on a PC, which is MUCH easier than a microcontroller.
You need to run the PC link at > 2x the Toyota bus, with some buffering, but 10KHz is very slow.
I'm struggling trying to understand the code and decode process from start to finish, which bits are computed for message length, which are computed for the CRC, why you need the RSP field, how you know what the SOF bit is and similar questions. I'm going to try and read your code and see what you've done, why do you have ,00 at the end of the string in SPIN, is that to terminate the byte? How does bit stuffing work? How would the receiver know if you had 1111111 but bit stuffing translated it to 1111011 or 11111011 (depending if it inserts or replaces)? And that it wasn't originally 1111011 or 11111011 (depending on if it inserts or replaces) in the first place?
About the B.E.A.N protocol, it was said to
Here are the SAE papers for you
https://drive.google.com/folderview?id=0B7FYCjMZX9RtejhDbGRvRGo5RVE&usp=sharing
For the 00 at the end of the strings, I've written all of the messages as text strings to allow me to parse one bit at a time, and the 00 is a null-terminator so Spin knows where the end of the string is.
For bit stuffing, the bus is non-return-to-zero, and there is no clock line, so it relies on transitions in order to maintain synchronization. If there are no transitions for five bits, a stuffed, opposite, bit is inserted in order to force a transition. A sequence of 1111100000 will be stuffed as 111110000010, where the underlined bits are stuffed. To unstuff, if you count five similar bits in a row, discard the bit that follows. 111110111110000 unstuffs to 1111111111000. The exception to that where you might see six or more identical bits in a row is in error-frames (at least with CAN) and also for end-of-frame.
I'll hopefully know more after I get a chance to study the papers.
Chris
I'm going to wrap my head around the bit stuffing a little more, thank you for the explanation though. I need to see it in practice and working to really feel confident in how it works. I'll keep studying, thank you.
*In the set below, italicized means I'm guessing at this field
Maybe bit stuffing plays into it?
How could the DID + MID be an initialization pattern for the CRC polynomial? Below are the combos I have tried, I cannot find a pattern.
I also didn't realize that messages 4 through 7 were posted without a priority and message length, and I mis-copied some of those as well. Message 6 matches when prefaced with a priority 6 and message length 4 %01100100.
Frustratingly, I still can't get matches to messages 4, 5, or 7 even trying every priority from $0 to $F. A couple messages matching to the same polynomial might be a coincidence, but 4 out of 7?
I've tried inverting, I've tried without headers, I've tried subtractions instead of xor's, I've tried comparing to => crc instead of => $100; nothing gives as consistent a result as with header, non-inverted, xor'ing when => $100.
Stuffed bits cannot be part of the CRC, as the CRC field may also be stuffed. I dunno why priority and message-length wouldn't be part of the calculation, but omitting them doesn't seem to help.
I had guessed at the message length and verified it in the paper you posted. The paper also shows a typical bitstream with levels for SOF, EOM, and EOF, so I should be able to get a reader coded from that.
My CRC calculator wasn't very well thought out, stopping at the first positive match. This should be easier to use. Chris
The other hint I was given (and didn't realize until today) was that it had something to do with encryption. The person that said they've cracked it said to check out this site
http://cryptopals.com/
Have you ever seen a CRC that could been encrypted by the MID and DID? Could that be what this means? Maybe repeating key XOR? Or an XOR of the MID and DID used in the repeating key, or a single byte XOR cipher? The single byte xor cipher makes the most sense based on what was written below I think?
I'm modifying my GMLAN reader to work with BEAN, but I really need to see an actual signal from an o'scope as the tech paper doesn't really say much about it.
The papers show the frame format in figure 9 with high and low levels for each bit field. According to that figure, the bus idles low.
However figure 3 shows a bus interface circuit with what looks like a pull-up resistor and a transistor driver to assert a low. It also labels the connections to the microcontroller as Rx-not and Tx-not.
Kinda hard to tell what's going on in the interface circuit in figure 7 but that one appears to be biased low, with Tx asserting a high.
Then I can try and insert the poly and see what happens?
I have an ECU that uses bean, I'll have to fabricate something up for it and try and get you an Oscope, the only problem is that I have a propscope and I don't think it will record/archive data, it just displays it onscreen.
Shift the bitstream left into a working register
If bit 8 of the working register is set, then xor it with the polynomial
Repeat until all bits are shifted
That's for decoding. To encode it, repeat the loop until the entire bitstream has been shifted plus eight "0" bits for the crc field. I've included an example in the latest code, which I've yet again modified to deal with strings of hexadecimal characters rather than binary.
A screen capture of the propscope should be fine. Just hit 'printscreen', create a new bitmap image, edit in ms-paint, paste the captured image, save as jpg. Simple.
CRC calculator 2.spin
I usually do screen caps with my prop scope, so if that is sufficient, I will do that in this case as well.
So is the basic premise to
1.) count the number of hex digits
2.) go into a loop based on that count
3.) get first hex digit, get first character, get 4 digit binary value of that character
4.) bit shift the nibble lsb to the nibble msb 4 times in a loop
5.) bit shift the crc_result bits 4 to 0 shifted to 8-4
6.) append the bits from the nibble to the crc_result bits 3-0
7.) Xor them with the crc you are testing
8.) If the Xor value is 0, the crc is valid
What is the crc_result value before it is appended and where does it come from?
Why does the CRC8 have 9 values?
Why does it need that leading 1?
Is that to give it significant digits in case the value behind it is a 0?
Is the CRC field in the stream of bits a value that is calculated and inserted to allow the poly to work?
What is the crc_result value before it is appended and where does it come from?
The crc_result is initially zero, it's a working register that the bitstream is shifted into and xor'd with the polynomial.
Why does the CRC8 have 9 values?
Wikipedia has some good info on the Cyclic redundancy check. Regarding the naming convention for why CRC8 has nine bits: I suppose I should've been saying the polynomial is $13 rather than $113, but that's just an extra layer of confusion I didn't wanna deal with.
Is the CRC field in the stream of bits a value that is calculated and inserted to allow the poly to work?
The CRC field is calculated in the exact same manner as verifying the message. Suppose the bitstream from priority/message-length through the final data byte is $64, $98, $CC, $02, $A7. In order to get the crc field, append an empty byte to the end of the string to hold the crc, run it through the same process in the flowchart, and value remaining in the crc_result register will be $D4.
In other words:
Running the string $64, $98, $CC, $02, $A7, $00 through the flowchart process leaves $D4 in the crc_result register.
Running the string $64, $98, $CC, $02, $A7, $D4 through the flowchart process leaves $00 in the crc_result register.
Clear as mud?
using 113 or 100010011
5 = 01011111
3 = 00110101
D = 11000111
2 = 00100110
C = 11010100
8 = 10011000
0 = 00000000
0 = 00000000
E = 11110010
9 = 10001011
53 = 10011010
D2 = 10000010
C8 = 00011111
00 = 00000000
E9 = 01001010
53D2 = 00010100
C800E9 = 11101011
but
53D2C800E9 = 00000000
I'm going to keep reading and hope it clicks.
After I read this, I was able to read through and understand the code block you put in your object as well. I'm going to start fresh and write code tomorrow and try to implement what you've taught me.
In the second code block, why do you take the extra step to xor the poly with the resulting xored value at the bottom? Is this to check your answer?
I cannot for the life of me figure out how this problem works though, your answer was $14, the online calculator's
answer was $14 but I keep getting 100100 $24 or 1001000 $48 when I do it by hand and when I input those numbers into my calculator. Even when I try the wikipedia way, I still get 1001000, what am I doing wrong?
Wikipedia way
For the second code block, you somehow inserted an extra line: