pascallanger / DIY-Multiprotocol-TX-Module

Multiprotocol TX Module (or MULTI-Module) is a 2.4GHz transmitter module which controls many different receivers and models.
https://www.rcgroups.com/forums/showthread.php?t=2165676&goto=newpost
GNU General Public License v3.0
1.66k stars 441 forks source link

RC Car toy hacking for Multiprotocol #558

Closed VasilyRakche closed 3 years ago

VasilyRakche commented 3 years ago

Background

Familiarity with your code structure:

I have familiarized myself with general structure, I have been checking Symax_nrf and Multiprotocol arduino files mostly to understand how everything works.

With respect to the RC car:

Hacking

I am using HackRF with the approach presented here GRCon16 - Whole Packet Clock Recovery, Michael Ossmann to decode the messages being transmitted.

Decoded data

Check here
Note: _One run corresponds to one binding instance (since after new binding the message is changing) Sometimes you will see several Batches for one command - these are just some artifacts from decoding, one of them should be the right one._

I was trying to make some common sense regarding the pattern:

image

Question

Regardless of collected data, I can not find any common pattern how they communicate, to be able to recreate it with Multiprotocol. Can you help me how should I continue from this point?

pascallanger commented 3 years ago

The link to the car doesn't point to the right thing. The decoded stream bytes in the file are sometime shifted by 1 or 2 bits which is why it's kind of hard to get what the messages are but you can shift them to obtain the right output. I've done it below for the "run 3":

Run 3 Preamble Preamble Preamble ID ID ID ID SID SID SID SID -- -- -- -- -- -- -- -- -- -- --
Pairing-TX   AA AA F6 AC A8 62 A6 04 8C 95 F1 58 20 0D 01 16 0F 6C A7 D3 FF
Pairing-RX   AA AA F6 AC A8 62 A6 04 8C 95 F0 DF DA 7B 01 16 08 B3 15 87 FF
Forward` 55 55 55 2C 59 2B 46 A6 04 8C 95 F2 F3 E0 17 11 0A 88 87 E7 1D 40
Back 55 55 55 2C 59 2B 46 A6 04 8C 95 F2 F3 E0 17 21 2F 09 73 16 D1 50
Right 55 55 55 2C 59 2B 46 A6 04 8C 95 F2 F3 E0 9C 05 24 08 B3 B6 09 54
Left 55 55 55 2C 59 2B 46 A6 04 8C 95 F2 F3 E4 10 21 2E 0C 3F BF 11 40
Double forward   55 55 2C 59 2B 46 A6 04 8C 95 F2 F3 E0 22 00 00 08 66 B7 D5 00

F6 AC A8 62 is the bind ID which is a contant and enables the RX to find the TX A6 04 8C 95 is a session ID 2C 59 2B 46 is the normal packet ID but I don't know yet where it's coming from I have the impression that the bytes after SID are not in clear text which prevents us to decode the message. I'm wondering if there is something additional like a frame counter (F0, F1, F2) which could be the pid of the packet usually on 3 bits which also usually means that the message after is bit shifted which is obfuscating the content as well. Also I'm not sure of the real length of the message...

To go further, I would recommend to use the NRF to listen to the messages so we can have live data which would help to find some of the missing pieces. For this purpose the XN297dump protocol as a NRF sub protocol which you can use in debug mode but you need to modify the code first to give the bitrate, channel and ID: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/34f16b0b66519dd39f261db4824c94b76af7bba6/Multiprotocol/XN297Dump_nrf24l01.ino#L598 Pascal

VasilyRakche commented 3 years ago

Thanks a lot! I didnt know how to shift it so the message would make sense, thats why I was analyzing it by bits. Not sure why the link to the car points to the wrong place (it should point to the amazon website, is the amazon problem?). I added description of the model and image, hopefully it would be more clear now.
Thanks for creating a table, yeah, makes much more sense to analyze that way. I am really not familiar with common communication message structure, so not sure what to look for, are there some articles explaining this part? I didnt know that it is possible to dump the messages with NRF, that would be much better for sure (feel that HackRF is more like a workaround, I needed to do many things manually still). I will try to set it up. Unfortunatelly I would be quite busy following days, but I will try to do it sometime throughout the week - really curios to understand how they are communicating :) Thanks again, cheers!

VasilyRakche commented 3 years ago

Hey, here is the new data from nRF that I combined in the table. Not sure how to find relationship, would really appreciate some help. Let me know if you need more data or something else

Run 1 Preamble Preamble ID ID ID ID SID SID SID SID -- -- -- -- -- -- -- -- -- -- --
Pairing-TX 55 55 F6 AC A8 62 09 19 2B E2 B0 40 1A 02 2C 1E D9 4F A7 FF FF
Pairing-RX 55 55 F6 AC A8 62 09 19 2B E1 BE B4 F6 02 2C 11 66 2B 0F FF FF
Forward 55 55 C5 92 B4 6A 60 48 C9 5F 3B AC 01 A1 10 A8 88 70 4E 3F FF
Double-forward 55 55 C5 92 B4 6A 60 48 C9 5F 3B AC 02 F0 00 00 86 65 43 5F FF
Stop 55 55 C5 92 B4 6A 60 48 C9 5F 3B AC 01 A0 11 60 86 75 45 FF FF
Backward 55 55 C5 92 B4 6A 60 48 C9 5F 3B AC 01 A2 12 F0 97 3F 52 FF FF
Right 55 55 C5 92 B4 6A 60 48 C9 5F 3B AC 09 10 52 40 8B 35 5F 7F FF
Left 55 55 C5 92 B4 6A 60 48 C9 5F 3B AC 41 D2 12 E0 C3 F5 CE FF FF
Run 2 Preamble Preamble ID ID ID ID SID SID SID SID -- -- -- -- -- -- -- -- -- -- --
Pairing-TX 55 55 F6 AC A8 62 A6 04 8C 95 F1 58 20 0D 21 2F 0E 78 06 A3 FF
Pairing-RX 55 55 F6 AC A8 62 A6 04 8C 95 F0 DF DA 7B 21 2F 09 A7 B4 F7 FF
Forward 55 55 C5 92 B4 6A 60 48 C9 5F 2F 3A 00 D1 10 A8 F8 CB D5 5F FF
Double-forward 55 55 C5 92 B4 6A 60 48 C9 5F 2F 3A 03 80 00 00 F6 DE D8 3F FF
Stop 55 55 C5 92 B4 6A 60 48 C9 5F 2F 3A 00 D0 11 60 F6 CE DE 9F FF
Backward 55 55 C5 92 B4 6A 60 48 C9 5F 2F 3A 00 D2 12 F0 E7 84 C9 9F FF
Right 55 55 C5 92 B4 6A 60 48 C9 5F 2F 3A 08 60 52 40 FB 8E C4 1F FF
Left 55 55 C5 92 B4 6A 60 48 C9 5F 2F 3A 40 A2 12 E0 B3 4E 55 9F FF
pascallanger commented 3 years ago

I'm surprised by these dumps since:

  • They are bitshifted by 4 bits from the previous with a "2" missing in the address of the NRF (verify your address):
Run 3 Preamble Preamble ID ID ID ID SID SID SID SID -- -- -- -- -- -- -- -- -- -- --
Pairing-TX 55 55 F6 AC A8 62 A6 04 8C 95 F1 58 22 14 11 0A 0D 40 A3 8B FF
Pairing-RX 55 55 F6 AC A8 62 A6 04 8C 95 F0 DF DA 7B 11 0A 08 B3 C9 31 FF
Forward 55 55 C5 92 B4 6A 60 48 C9 5F 0A F6 02 20 00 00 86 5A C5 FF FF
Double-forward 55 55 C5 92 B4 6A 60 48 C9 5F 0A F6 02 20 00 00 86 5A C5 FF FF
Stop 55 55 C5 92 B4 6A 60 48 C9 5F 0A F6 01 70 11 60 86 4A C3 5F FF
Backward 55 55 C5 92 B4 6A 60 48 C9 5F 0A F6 01 72 12 F0 97 00 D4 5F FF
Right 55 55 C5 92 B4 6A 60 48 C9 5F 0A F6 09 C0 52 40 8B 0A D9 DF FF
Left 55 55 C5 92 B4 6A 60 48 C9 5F 0A F6 41 02 12 E0 C3 CA 48 5F FF
hackrf dump 2C 59 2B 46 A6 04 8C 95 F
nrf24 dump C5 92 B4 6A 60 48 C9 5F

Also what about posting live data like I suggested? Can you post a serial monitor dump of all the packets you are getting without any transformation? Are all packets transmitted always the same if you don't press a button or some values change on their own?

pascallanger commented 3 years ago

More questions:

VasilyRakche commented 3 years ago

Thanks for your responses. I will try to answer all the questions further.

Decoded data

All the data is recorded within one connection (communication) instance (on the bottom of this post you can find the serial monitor dump)

Arduino decoded

Here is the decoded table of the new data recorded (you were right about the shift by "4 bits" my address was wrong, so it was truncating the input). I also provided right decoding of the preamble based on the nRF24L01 datasheet page 27

Run 1 Preamble Preamble ID ID ID ID SID SID SID SID -- -- -- -- -- -- -- -- -- -- --
Pairing-TX AA AA F6 AC A8 62 A6 04 8C 95 F1 58 20 0D 11 0A 8F 8C F7 6F FF
Pairing-RX AA AA F6 AC A8 62 A6 04 8C 95 F0 DF DA 7B 11 0A 88 53 45 3B FF
Forward 55 55 2C 59 2B 46 A6 04 8C 95 F0 3E A0 0D 11 0A 88 50 C9 8F FF
Backward 55 55 2C 59 2B 46 A6 04 8C 95 F0 3E A0 0D 21 2F 09 A4 38 43 FF
Right 55 55 2C 59 2B 46 A6 04 8C 95 F0 3E A0 86 05 24 08 64 98 9B FF
Left 55 55 2C 59 2B 46 A6 04 8C 95 F0 3E A4 0A 21 2E 0C E8 91 83 FF
Stop 55 55 2C 59 2B 46 A6 04 8C 95 F0 3E A0 0D 01 16 08 B0 99 33 FF

HackRF decoded

The data is from the same connection instance as Arduino decoded data previously provided (it should match the dumped data from serial monitor aswell). This should solve the mystery about FF at the end.

Pairing

pairing

0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1

0xaa, 0xaa, 0xf6, 0xac, 0xa8, 0x62, 0xa6, 0x04, 0x8c, 0x95, 0xf1, 0x58, 0x20, 0x0d, 0x11, 0x0a, 0x8f, 0x8c, 0xf7, 0x6f

Forward

forward

0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1

0x55, 0x55, 0x55, 0x2c, 0x59, 0x2b, 0x46, 0xa6, 0x04, 0x8c, 0x95, 0xf0, 0x3e, 0xa0, 0x0d, 0x11, 0x0a, 0x88, 0x50, 0xc9, 0x8f, 0xf

Explanation on communication

RF frequences used

The pictures are provided from the HackRF spectrum sweep analyser.

Pairing

2.46 Ghz
2460

Commands

2.421 GHz 2.441 GHz 2.454 GHz 2.469 GHz 2.474 GHz
2421 2441 2454 2469 2474

Serial monitor dump from nRF24l01

Provided as a file Dump_data_Arduino.md

VasilyRakche commented 3 years ago

So I was playing around, in 90% of cases SID is consistent with your initial observation. In other occasion, when it differs, it might occur due to some error state - I am not sure exactly why, but in order to restart the RC I am just plugging out and plugging in the battery again so that might cause some issues. As well it has predetermined time of how long it tries to connect, so I might take the battery at some wrong moment, but here will be the dump of exactly the scenario when SID is not consistent (at first there will be some dumped data from other pairing instance, I think the difference can be easily spotted). Also I will first provide the table with decoded data.

Table with decoded data

Run 1 Preamble Preamble ID ID ID ID SID SID SID SID -- -- -- -- -- -- -- -- -- -- --
Pairing-TX AA AA F6 AC A8 62 A6 04 88 46 C1 53 A0 0D 41 0C 08 65 BF C1 FF
Pairing-RX AA AA F6 AC A8 62 A6 04 8C 95 F0 DF DA 7B 41 0C 08 B0 66 EF FF
Forward 55 55 2C 59 2B 46 A6 04 8C 95 F3 BA A0 0D 11 0A 8C 09 F3 5B FE
Backward 55 55 2C 59 2B 46 A6 04 8C 95 F3 BA A0 0D 21 2F 0D FD 02 97 FF
Right 55 55 2C 59 2B 46 A6 04 8C 95 F3 BA A0 86 05 24 0C 3D A2 4F FF
Left 55 55 2C 59 2B 46 A6 04 8C 95 F3 BA A4 0A 21 2E 08 B1 AB 57 FF
Stop 55 55 2C 59 2B 46 A6 04 8C 95 F3 BA A0 0D 01 16 0C E9 A3 E7 FF

Serial monitor dump from nRF24l01

Dump_data_Arduino2.md

VasilyRakche commented 2 years ago

Hey @pascallanger . I came back to decoding the car messages. I am now able to properly record all the messages exchanged between the car and the controller. So what I have so far:

One controller can control all the cars of the same model provided that they have done pairing procedure before. I am not understanding how the messages are being formed based on the pairing procedure.

The pairing procedure is basically done as follows:

1. Controller is transmitting certain message on pairing channel 2. The car is responding on the same channel 3. When controller gets the message from the car, it transmits certain message (different from previous messages) on channels used for communication, also this message is further used as a stop message for the car. Note: communication channels are different for each car model.

This finishes the pairing procedure

After that they have a certain instance of messages that work with this car.
So the idea is to understand how to generalize it. Properly structured data can be found in Recorded data for Cruz Ramirez.pdf, and also presented bellow:

Recorded data for Cruz Ramirez_page-0001

Recorded data for Cruz Ramirez_page-0002

Recorded data for Cruz Ramirez_page-0003

EDIT: Found a tool for structuring the data, here is nicely formatted part with the first car communication.