Ich versuche, eine einfache Arduino-basierte IR-Fernbedienung für einen billigen IR-gesteuerten Spielzeughubschrauber zu bauen (wie dieser - er heißt "Diamond Gyro" oder "Diamond Force"). Ich habe das IR-Protokoll bis auf die letzten Bits entschlüsselt. Diese letzten Bits scheinen ein Check oder CRC zu sein, aber ich konnte es nicht "knacken".
Es ist einfach genug, ein aufgezeichnetes Paket einfach zu wiederholen, aber ich möchte den Hubschrauber vollständig steuern. Das bedeutet Reverse-Engineering der Prüfbits.
(Ich sollte hinzufügen, dass ich tagsüber Software mache, aber Elektronik ist manchmal ein Hobby, also vermisse ich vielleicht nur etwas sehr Grundlegendes.)
Die Details des Protokolls sind in der Frage und Antwort enthalten, aber hier sind die Grundlagen:
Hier ist ein Diagramm
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
--+---------------------------+-----------+---+---+-+-+-----------
P| Yaw | Throttle | Pitch | T | C |X|X| CRC?
P: Preamble (always 1), T: Trim, C: Channel,
X: Either part of the channel data or the checksum.
Zunächst einmal bin ich mir nicht sicher, ob die X
Bits Teil des Kanalwerts, Teil der Prüfung oder etwas anderes sind. Sie folgen jedoch immer dem Kanalwert, daher ist es wahrscheinlich, dass der Kanalwert 3-4 Bit breit ist, obwohl 2 Bit für die 3 möglichen Kanalwerte ausreichen würden.
Zweitens gibt es die letzten 6 Bits ( CRC?
oben markiert), die eindeutig eine Art Überprüfung darstellen (und tatsächlich reagiert der Hubschrauber nicht, wenn ich eines dieser Bits ändere).
Im Grunde gibt es also ein Paket mit 24–26 Datenbits, gefolgt von 6–8 Prüfbits. Und ich würde wirklich gerne diese Prüfbits herausfinden, damit ich selbst Pakete zusammenstellen kann.
Unten sind einige Beispiele der binären Daten, die ich bekomme. Die Präambel "1" ist immer vorhanden, und ich glaube nicht, dass sie zu den Daten zählt, aber ich habe sie trotzdem eingefügt, nur für den Fall, dass sie der Schlüssel zu allem ist.
Auch hier weiß ich nicht, ob die X
Bits Teil der Daten oder der Prüfung sind. Je nach Berechnungsweise des Checks kann es sein, dass die ersten 1-2 Bits des Checks zufällig auf den Kanalwert folgen. Es ist aber auch durchaus möglich, dass der Kanalwert 4 Bit lang ist, inklusive der X
Bits. Oder es liegt dazwischen, wobei ein X
Bit Teil des Kanals und das andere Teil der Prüfung ist. Ich weiß nicht.
Wenn jemand weiß, was das ist, oder wie ich das herausfinden könnte, würde ich es gerne wissen. Ich kann mir vorstellen, dass ich es brutal erzwingen kann, aber selbst wenn dies die einzige Option ist, würde ich gerne einige Hinweise hören, wie man das am besten macht.
Der Helikopter ist spottbillig, also bezweifle ich, dass irgendetwas wirklich Besonderes los ist.
Channel A
P Yaw Throttle Pitch Tr Ch XX Check Description
--------------------------------------------------------------
1 000100 10000100 000000 00 01 01 000101 Left Mid + throttle
1 000000 10000110 010001 00 01 01 010010 Left Max + throttle
1 100001 10000110 000000 00 01 01 100010 Right Mid + throttle
1 100100 10000100 010001 00 01 01 110100 Right Max + throttle
1 010001 00000000 001011 00 01 01 011111 Forward Min
1 010001 00000000 000000 00 01 01 010100 Forward Max
1 010001 00000000 011000 00 01 01 001100 Back Min
1 010001 00000000 100101 00 01 01 110001 Back Max
1 010001 00000000 010001 01 01 01 010101 Left Trim
1 010001 00000000 010001 10 01 01 100101 Right Trim
1 010001 00000011 010001 00 01 01 000110 Throttle 01 (min)
1 010001 00010110 010001 00 01 01 010011 Throttle 02
1 010001 00011111 010001 00 01 01 011010 Throttle 03
1 010001 00101111 010001 00 01 01 101010 Throttle 04
1 010001 00111110 010001 00 01 01 111011 Throttle 05
1 010001 01010101 010001 00 01 01 010000 Throttle 06
1 010001 01011111 010001 00 01 01 011010 Throttle 07
1 010001 01101100 010001 00 01 01 101001 Throttle 08
1 010001 01111010 010001 00 01 01 111111 Throttle 09
1 010001 10000101 010001 00 01 01 000000 Throttle 10 (max)
Channel B
P Yaw Throttle Pitch Tr Ch XX Check Description
--------------------------------------------------------------
1 000000 10000110 010001 00 00 10 010101 Left Max + throttle
1 100100 10000110 010001 00 00 10 110001 Right Max + throttle
1 010001 00000000 001001 00 00 10 011010 Forward Min
1 010001 00000000 000000 00 00 10 010011 Forward Max
1 010001 00000000 010111 00 00 10 000100 Back Min
1 010001 00000000 100110 00 00 10 110101 Back Max
1 010001 00000000 010001 01 00 10 010010 Left Trim
1 010001 00000000 010001 10 00 10 100010 Right Trim
1 010001 00000001 010001 00 00 10 000011 Throttle Min
1 010001 00110100 010001 00 00 10 110110 Throttle Mid
1 010001 01100111 010001 00 00 10 100101 Throttle High
1 010001 10001111 010001 00 00 10 001101 Throttle Max
Channel C
P Yaw Throttle Pitch Tr Ch XX Check Description
--------------------------------------------------------------
1 000000 10000101 010001 00 10 00 011100 Left Max + throttle
1 100100 10000101 010001 00 10 00 111000 Right Max + throttle
1 010001 00000000 001010 00 10 00 010011 Forward Min
1 010001 00000000 000000 00 10 00 011001 Forward Max
1 010001 00000000 010111 00 10 00 001110 Back Min
1 010001 00000000 100110 00 10 00 111111 Back Max
1 010001 00000000 010001 01 10 00 011000 Left Trim
1 010001 00000000 010001 10 10 00 101000 Right Trim
1 010001 00000001 010001 00 10 00 001001 Throttle Min
1 010001 00110100 010001 00 10 00 111100 Throttle Mid
1 010001 01100110 010001 00 10 00 101110 Throttle High
1 010001 10000101 010001 00 10 00 001101 Throttle Max
Zunächst einmal ist es ziemlich klar, dass die „XX“-Bits Teil der Kanalbezeichnung sind , da sie nur davon abhängen. Die "XX"-Bits können einfach eine Überprüfung der "Ch"-Bits sein.
Die Prüfbits sind ein einfaches bitweises XOR von 24 der 26 Datenbits: Wenn Sie die 6 Yaw-Bits, die 6 LSBs des Throttle, die 6 Pitch-Bits und die nächsten 6 Bits nehmen und diese Mengen XOR zusammenfügen, erhalten Sie die 6 Prüfbits. Es scheint, dass die oberen 2 Bits des Throttle die Prüfbits überhaupt nicht beeinflussen.
Das folgende Perl-Skript überprüft dies.
#!/usr/bin/perl
# crc.pl - verify decoding of check bits
# On the lines starting with '1', just keep the '0's and '1's in an array.
while (<>) {
my @letters = split '', $_;
next unless $letters[0] eq '1';
@letters = grep /[01]/, @letters;
@letters = @letters[1..32];
$a = string2bin (@letters[0..5]);
$b = string2bin (@letters[8..13]);
$c = string2bin (@letters[14..19]);
$d = string2bin (@letters[20..25]);
$e = string2bin (@letters[26..31]);
$f = $a ^ $b ^ $c ^ $d;
printf "%02X %02X %02X %02X %02X %02X %s\n", $a, $b, $c, $d, $e, $f,
$e == $f ? '-' : '###';
}
sub string2bin {
my $temp = 0;
for (@_) {
$temp = ($temp << 1) + ($_ eq '1' ? 1 : 0);
}
$temp;
}
Ich sehe kein sofort offensichtliches Muster, also würde ich dies eher algorithmisch angreifen. Sie haben anscheinend die Fähigkeit, eine große Anzahl von Paketen zu erfassen und sie dann auf automatisierte Weise in einen Computer zu bringen. Ich würde eine große Anzahl erfassen, während ich die Steuerung langsam variiere.
Nachdem Sie einen Haufen Pakete in einer Datei haben, schreiben Sie etwas Code, um den Code zu knacken. Betrachten Sie es als ein Kryptografieproblem. Eines der ersten Dinge, die ich tun würde, ist, nach Paketpaaren zu suchen, die sich nur in einem Bit unterscheiden. Das sollte Ihnen sofort sagen, ob Sie eine einfache Prüfsumme oder etwas Komplizierteres wie einen CRC haben. Wenn es sich um eine einfache Prüfsumme handelt, dann sollte die Prüfsumme solcher Paketpaare nur variieren, indem ihr eine Potenz von 2 hinzugefügt wird. Wenn eine ganze Reihe von Bits auf unvorhersehbare Weise variieren, haben Sie wahrscheinlich einen CRC.
Wenn es sich um eine Grundsumme handelt, sollten Sie nach einigen Einzelbitänderungen herausfinden können, wie jedes Feld zur Prüfsumme hinzugefügt wird. Wenn es wie ein CRC aussieht, würde ich wahrscheinlich als nächstes eine umfassende Suche durchführen. Es ist nur eine 6-Bit-Prüfsumme, also gibt es nur 64 mögliche Polynome. Es kann bis zu 64 verschiedene Startwerte geben, aber normalerweise beginnt man einen CRC mit dem hohen Bit gesetzt und den anderen Bits auf 0. Neue Bits können von beiden Enden verschoben werden. Wahrscheinlich, zumindest wenn derjenige, der den CRC entworfen hat, wüsste, was er tut, dann sollte das Ergebnis 0 sein, wenn Sie das gesamte Paket durch den CRC laufen lassen. Die Anzahl der Kombinationen ist klein genug, dass eine erschöpfende maschinelle Suche die Antwort sofort finden sollte Menschenzeit, ob es sich wirklich um einen gewöhnlichen CRC handelt.
Ich habe gerade Dave Tweeds Antwort gesehen, wo er gezeigt hat, dass dies sogar noch einfacher ist als eine Summe, nur XOR der Felder. Es gibt viele faule Ingenieure da draußen. Ich hätte dies mit einem CRC gemacht, der wirklich sehr einfach zu berechnen ist.
Ich hinterlasse meine Antwort hier als Beschreibung, wie man so etwas angreift, wenn man bei der Inspektion kein Muster sieht. Wenn Sie diese Methode verwendet hätten, hätten Sie gesehen, dass einzelne Bitänderungen in den Daten zu einzelnen Bitänderungen in der Prüfsumme geführt hätten, was sofort auf ein XOR-Schema hingewiesen hätte.
X
. Was das Ändern eines einzelnen Bits und das Betrachten des Schecks betrifft, hätte ich das gerne versucht, aber es hätte einige Arbeit mit diesem billigen Controller erfordert. Hätte es ein wenig modifizieren müssen, um diese Art von Auflösung zu erhalten.Über die XX: Wie Dave betont, scheinen sie Teil der Kanalinformationen zu sein, da sie für einen bestimmten Kanal immer gleich sind. Sie sind nicht wirklich erforderlich; wie Sie sagten, Sie können 3 Kanäle mit nur 2 Bit codieren, aber die gegebenen 4 Bit erlauben eine Hamming-Distanz von 2. Dies bedeutet, dass die Codes für die Kanäle immer mindestens 2 Bit-Änderungen voneinander entfernt sind. Das Ändern eines einzelnen Bits führt nicht zu einem gültigen Kanalcode. Zusammen mit der Prüfsumme erhöht dies die Zuverlässigkeit.
Flambino
David Tweed
Flambino