Hallo, Ich habe einen seriellen Stream, wo am Ende eines Blocks eine Prüfsumme mitgesendet wird. Ich komme einfach nicht auf die Berechnungsgrundlage dieser Prüfsumme und wäre für jeden Tip dankbar. 3 verschiedene Blöcke dieses Streams habe ich unten aufgeführt. Es ist weder XOR noch Quersummenberechnung. Ich habe keine Idee mehr. Grüße Klaus Dezimal, Startbyte und Endbyte (beides 192) habe ich weggelassen. 4 126 1 2 16 5 0 0 0 0 25 12 1 2 3 4 5 6 7 8 9 10 11 12 0 0 Prüfsumme: 28 4 119 0 1 2 7 0 0 Prüfsumme: 6 4 120 0 1 2 7 0 0 Prüfsumme: 12
Moin, Wenns CRC sein koennte, wuerd' ich mal diesen Thread empfehlen: Beitrag "Tip: Reverse-Engineering von CRCs" Gruss WK
Hallo Joe, es geht um die Kommunikation zwischen einem Prozessor und einem Digitaltuner. Ich möchte den Tuner extern steuern, bzw in ein Projekt einbinden. Dazu muss ich wissen, wie er angesteuert wird. Er ist von Frontier Silicon und es gibt absolut keine Datenblätter im Netz. Initialisierung, Band scannen konnte ich so übernehmen. Aber ich benötige für eigene Programmmethoden den Befehlssatz, den ich zZt. entkrypte. Gruß Klaus
Woher stammt die Information über Start- und Stoppbyte und wo die Checksum zu finden ist?
Aus jeder Menge Recherche: Start/Stopbyte war eine Annahme, bis ich einen kompletten Befehlssatz zusammen hatte und diesen erfolgreich an den Tuner gesendet habe. Auch die Checksum war erst Annahme, bis ich durch Zufall in einer Diy-Zeitung über ein Projekt mit diesem Tuner gelesen habe. Das wars dann aber auch, alles andere habe ich durch viel Ausprobieren, Try/Error
Klaus schrieb: > Aus jeder Menge Recherche: > > Start/Stopbyte war eine Annahme, bis ich einen kompletten Befehlssatz > zusammen hatte und diesen erfolgreich an den Tuner gesendet habe. Auch > die Checksum war erst Annahme, bis ich durch Zufall in einer Diy-Zeitung > über ein Projekt mit diesem Tuner gelesen habe. Das wars dann aber auch, > alles andere habe ich durch viel Ausprobieren, Try/Error Tja, klingt mühsam. Evtl. wäre ja der Autor des DIY Artikels ein Ansprechpartner...
Oh ja, mühsam: Tuner aus Radio extrahiert, eigene Schaltung mit Stromversorgung (3,3V/1,2V), Pegelwandler und Atmega gebaut, das Radio an den Atmega, Atmega an Tuner und jede Menge seriell "geschnüffelt"..mehrmals in den letzten 3 Monaten eingelagert und bei Lust wieder aufgebaut. Zeitung anschreiben bringt nix, jeder, der mit dem Tuner arbeiten will, muss bei Frontier Silicon ein Agreement unterschreiben und ist bei Strafe zur geheimhaltung verpflichtet. Ausser Andeutungen oder abgeschwächte Beschreibungen des Protokolls findet man nix...Ich habe z.B. eine Stationstaste gespeichert, dann beim Streaming mitgeschnitten und analysiert. Dann konnte ich den aufbereiteten Befehl erfolgreich an den Tuner schicken und so habe ich fast alles rausbekommen: Blocknr, Befehlstyp, Platzhalter usw...nur, um ein Programm zu schreiben, wo ich mein Speichermanagement, Senderliste usw handle, muss ich wissen, wie für den eigenen Befehlsblock die Checksumme lautet...
Verständlich. Die zwei kürzeren Datensätze sind ganz interessant, da sich nur ein Byte in den Nutzdaten geändert hat. Ich denke es wäre hilfreich möglichst viele solche Beispiele zu haben. Differenz der Summe der Daten ist eins, Unterschied der Prüfsummen ist Faktor 2, könnte ein Bitshift um 1 nach links bedeuten. Ist aber mangels Datenmenge erstmal reine Spekulation... Ansonsten trifft man auf viele Beispiele für das "SLIP" Protokoll, wenn man im Netz nach Protokollen mit delimiter 0xC0 (dec 192) sucht. Evtl. ist dein Protokoll eine Abwandlung davon... Was passiert eigentlich wenn die Checksumme falsch ist? Wird das Kommando dann ignoriert?
:
Bearbeitet durch User
Super, danke für den Tip. Mitschnitte in Textform habe ich genug.Hier ein kurzer Mitschnitt ab Einschalten.: ---------192--------- 0 1 4 1 2 1 0 0 0 1 1 70 ---------192--------- ---------192--------- 0 2 4 1 2 1 0 0 0 1 1 91 ---------192--------- ---------192--------- 0 3 4 1 5 9 0 0 0 1 0 178 ---------192--------- ---------192--------- 0 4 4 1 2 4 0 0 0 1 2 108 ---------192--------- ---------192--------- 0 5 6 1 2 10 1 0 1 148 ---------192--------- ---------192--------- 0 6 6 1 2 10 2 0 1 133 ---------192--------- ---------192--------- 0 7 6 1 2 6 0 0 1 156 ---------192--------- ---------192--------- 0 8 6 1 2 15 0 0 1 150 ---------192--------- ---------192--------- 0 9 0 1 1 3 0 0 95 ---------192--------- ---------192--------- 0 10 4 1 2 16 2 0 0 1 1 46 ---------192--------- ---------192--------- 0 11 4 1 2 10 1 0 0 1 1 243 ---------192---------
Ich habe einen Befehlsblock, der einen Sendernamen anzeigt, trage ich nun ein anderen Speicherplatz ein, wird der Block nicht akzeptiert, der Tuner reagiert dann nicht(unterstrichen ist der Sender im Speicher): zb: 4 126 1 2 16 5 0 0 0 0 25 12 1 2 3 4 5 6 7 8 9 10 11 12 0 0 28 -- funtioniert....(Radio Relax)... 4 126 1 2 16 5 0 0 0 0 17 12 1 2 3 4 5 6 7 8 9 10 11 12 0 0 28 -- funktioniert nicht...(NDR)..hier muss ich die orginalen Daten austauschen, wie lfd. Nummer(ersten beiden Bytes) und Checksum: 0 28 1 2 16 5 0 0 0 0 17 12 1 2 3 4 5 6 7 8 9 10 11 12 0 0 8 - -- -- - ..dann klappt das Senderwechseln.
Ok. Deine Daten anbei nochmal als (etwas übersichtlichere) HEX Pakete. Muss mal eben weg, vielleicht guckt ja jemand anderes zwischenzeitlich drauf.
1 | 00 01 04 01 02 01 00 00 00 01 01 46 |
2 | 00 02 04 01 02 01 00 00 00 01 01 5B |
3 | 00 03 04 01 05 09 00 00 00 01 00 B2 |
4 | 00 04 04 01 02 04 00 00 00 01 02 6C |
5 | 00 05 06 01 02 0A 01 00 01 94 |
6 | 00 06 06 01 02 0A 02 00 01 85 |
7 | 00 07 06 01 02 06 00 00 01 9C |
8 | 00 08 06 01 02 0F 00 00 01 96 |
9 | 00 09 00 01 01 03 00 00 5F |
10 | 00 0A 04 01 02 10 02 00 00 01 01 2E |
11 | 00 0B 04 01 02 0A 01 00 00 01 01 F3 |
Ich muss auch erstmal raus, vielen Dank für Deine Tips... Gruß, schönen Abend noch.. Klaus
Manchmal wird die Prüfsumme mit in das Paket eingerechnet. Sollte nicht sein, ist aber so, wenn sie am Anfang kommt, als FEC oder so.
Hi, Tobias. Kann ich auch ausschließen, weil bei fehlerhafter Prüfsumme der Tuner nicht reagiert und einfach stumm bleibt und bei der Vorwärtsfehlerkorrektur wenigstens irgendwas vom Tuner zurückkommen würde. Habe heute nochmals mit kompletten Block und danach Addition der einzelnen Bytes nochmals crc durchprobiert...256 Möglichkeiten für das Generatorpolynom...puh..nichts. Und wenn ich bei der Berechnung die Checksumme als Ergebnis hatte und einen anderen Block mit dem Generatorpolynom berechnet habe, passte wieder nix. Jetzt fängt`s an zu nerven, werde das Projekt wohl erstmal einmotten... Diese Firmwareentwickler von Frontier sind aber auch ein gehässiger Haufen...:) Gruß Klaus
Klaus schrieb: > Habe heute nochmals mit kompletten Block und danach Addition der > einzelnen Bytes nochmals crc durchprobiert...256 Möglichkeiten für das > Generatorpolynom...puh..nichts. Neben den 256 Polynomen musst du noch 256 Startwerte und 256 XOR-Werte (also insgesamt 16777216 Möglichkeiten) durchprobieren. Mit RevEng geht das auch ohne "puh" :)
Du könntest ja auch jedes Kommando einfach 256 mal (mit unterschiedlicher "Prüfsumme") schicken. Eine Kombination muss ja dann richtig sein, und die wird der Tuner dann fressen... Nicht besonders elegant, aber "works for me"...
Das zweite Byte sieht aus wie ein Frame Zähler. Es könnte sein, dass damit aus einer Lookup Tabelle noch ein weiteres unbekanntes Byte in den CRC gepackt wird. Ebenso könnte der Frame Zähler nur bei korrektem Zählen zu einem erfolgreichem Frame führen.
Joe F. schrieb: > Du könntest ja auch jedes Kommando einfach 256 mal (mit > unterschiedlicher "Prüfsumme") schicken. > Eine Kombination muss ja dann richtig sein, und die wird der Tuner dann > fressen... > Nicht besonders elegant, aber "works for me"... Das würde bei einem Frame Zähler nicht funktionieren, da ich für jeden Zählerwert den genauen CRC Wert (bei ansonstem gleichem Inhalt) kennen müsste. Wären als 2^16 Möglichkeiten ;)
Erik B. schrieb: > Das würde bei einem Frame Zähler nicht funktionieren Das stimmt zwar, wenn ich mir die Kommandos von Klaus zur Senderauswahl angucke, glaube ich allerdings nicht, dass das ein Zähler ist. Beim Starten des Gerätes werden hier vermutlich Register gesetzt, die in dem Fall eben alle in aufeinanderfolgender Reihe angesprochen werden.
:
Bearbeitet durch User
Unwahrscheinlich, dafür verwendet man kein Format mit wechselnder Länge. Wobei... alle "04" Frames und alle "06" Frames haben die gleiche Länge.
:
Bearbeitet durch User
Moin, Wird wohl die Frage sein, warum der Tunerhersteller den Affenzirkus mit extra Byte veranstaltet: a.) Um sicherzugehen, dass die Nachricht richtig empfangen wurde oder b.) Um sicherzugehen, dass nur Unterschreiber des NDAs "richtige" Nachrichten erzeugen koennen. Also ob das Extrabyte eher eine Fehlererkennung/korrektur oder eher eine Signatur darstellt. Fuer eine Fehlererkennung waere wohl CRC oder irgendwelche Pruefsummen das Mittel der Wahl. Fuer Signatur koennte man sich so beliebigen, fiesen Kram ausdenken, dass es da ziemlich chancenlos ist draufzukommen; sogar wenn man die Algorithmen wuesste. Gruss WK
Das mit dem extra Byte ist ja nur eine Idee. Ich würde mal versuchen ein paar Frames mit evtl Zusatz-Byte in das oben verlinkte CRC Reverse Tool zu packen.
Moin, Leute. Joe seine Idee funktioniert, hatte das am Anfang ausprobiert. Bei 115200Baud wäre es auch nicht soo viel Zeit, bis der Tuner antwortet, aber eben -wie Joe schrieb - nicht gerade elegant. Wäre aber meine letzte Idee. Die ersten beiden Byte sind tatsächlich nur Zähler, wenn das 2te Byte "voll" ist, gibt es einen Übertrag ins erste Byte und Byte 2 fängt wieder mit 0 an. Ist Byte 1 auch voll, geht alles bei 0 wieder los. Der Tuner hat einen Befehlsbuffer und der Zähler dient dazu, den ausgeführten Befehl vom Proz zu identifizieren, der Tuner quittiert den Befehl mit dem Zählerwert: Beispiel: Prozessor sendet: c0 0 2 4 1 2 1 0 0 0 1 1 5b c0 Tuner antwortet: c0 0 2 84 1 0 11 c0 Da ich diese Kontrolle nicht brauche/nutze, ist es relativ egal, was für ein Zählerstand vorn steht. Tatsächlich sind die Werte der ersten 2 Byte egal für den Befehl, wenn die Checksum passt. Ich habe irgendwo mal gelesen, dass die 2 ersten Byte auch Serial oder Serials genannt werden, kenne aber diese Begrifflichkeit nicht in diesem Zusammenhang. Gruß
Ich werfe einfach mal das hier in den Raum: "fsapi - Frontier Silicon API for PHP" https://github.com/flammy/fsapi und "fsapi-remote" https://github.com/flammy/fsapi-remote Ohne allerdings genauer gelesen zu haben, ob es dort Informationen gibt, die die CRC-Berechnung beschreiben, aber vielleicht hilft Dir das ja weiter...
Ich habe folgenden Text mal aus der DIY-Zeitung (Silicon Chip Online, 11/2010)rausgekramt: The serial port runs at 115,200 bps and uses an 8-bit word with one stop bit and no parity. The microcontroller sends commands to the Venice 7 module and receives data back from it. Error detection is accomplished using a checksum appended to each packet sent. Das was dann auch mit der Info im Netz. Aus einer Examensarbeit, Integrating FM/RDS/DAB in off-highway vehicles: 4.1.3 Communication protocol The communication with the radio module is done by sending a series of bytes. Depending on the structure different commands will be carried out. Since these commands are confidential and only for the consumers of these radio modules I will not describe in detail the exact bytes being used and only the structure. Bissl Offtopic: So ein Alarm gabs bei den analogen Tunern nicht. Der sehr gute Sony-Tuner damals, I2C Protokoll, Datenblatt gezogen und losgelegt. Ich kapier das nicht, was der Hersteller davon hat. Keystone zum Beispiel verkauft ihren DAD-Tuner ab 5 Stück. Nach Vorlage des Kaufbeleges bekommt man auch Datenblätter. Frontier Silicon wälzt bei Anfrage auf den Radiohersteller ab. Naja...und der muss die Klappe halten. Leider ist der Frontier-Tuner nunmal von den Werten, Abschirmumg, Empfindlichkeit usw. der ideale Tuner für meine Basteleien..und ich hab einige davon.
Hallo Wolfgang, danke für Deine Mühe. Dabei geht es um Internetradio und Frontends usw. Frontier ist auch irgendwie Anbieter für Internetradio-Tuner und betreibt einen "Senderpool", kenne mich in dem Metier nicht so aus. Gruß
Klaus schrieb: > der Tuner quittiert den Befehl mit dem > Zählerwert: (...) > Da ich diese Kontrolle nicht brauche/nutze, ist es relativ egal, was für > ein Zählerstand vorn steht. Das ist ja noch besser. Dann verwende doch immer den gleichen Zähler, wenn das den Prozessor nicht stört. Für "neue" Kommandos probierst du alle 256 mögliche Prüfsummen durch, bis der Prozessor das Kommando quittiert. Diese Prüfsumme merkst du dir dann für zukünftige Aufrufe des gleichen Kommandos.
Das ist lustig, Joe: Hatte nach Deinem letzten Post den selben Gedanken. Ich suche grad nach einer Möglichkeit, irgendeine wiederkehrende Reaktion auf einen Fehler zu bekommen. Sei es Datentechnisch, oder Elektronisch. Wenn schon unelegant, dann aber elegant unelegant :) Dann werde ich ein kleines Prog basteln, was mir Sendeplätze (Befehle) generiert..von Speicherplatz 1 bis nn. Da ich ja soweit bin, dass der Tuner beim Anschalten automatisch alle Bereiche durchscannt, kann ich nach dem Scan die Sender abfragen. Die Antwort für einen aktiven Sender vom Tuner kenne ich. Diese schreibe ich ins EEPROM und habe so meine Senderliste. Auf alle Fälle wieder was zum "Anfassen", gehe ich eben diesen Weg...
OK, ich habs geknackt :-) Es ist eine Flechter Sum, und die beiden Resultate werden mit XOR verknüpft. Du brauchst zwei unsigned 8-Bit Zähler (A und B). In A summierst du jedes Eingangsbyte auf (modulo 256) in B den jeweiligen Wert von A. Am Ende noch A XOR B, das ist die Checksum.
1 | #include <stdio.h> |
2 | #include <stdlib.h> |
3 | #include <stdint.h> |
4 | |
5 | uint8_t calc_checksum(uint8_t *data, uint8_t len) |
6 | {
|
7 | uint8_t a=0; |
8 | uint8_t b=0; |
9 | uint8_t i; |
10 | |
11 | for (i=0; i<len; i++) |
12 | {
|
13 | a += data[i]; |
14 | b += a; |
15 | }
|
16 | return (a^b); |
17 | }
|
18 | |
19 | |
20 | |
21 | int main(int argc, char **argv) |
22 | {
|
23 | uint8_t data[9] = { 0, 6, 6, 1, 2, 10, 2, 0, 1 }; |
24 | |
25 | printf("checksum: %d\n", calc_checksum(data, 9)); |
26 | return 0; |
27 | }
|
checksum: 133 Aus deinem Datensatz: ---------192--------- 0 6 6 1 2 10 2 0 1 133 ---------192---------
:
Bearbeitet durch User
Das ist der Hammer.... Wär ich niee drauf gekommen, ist für mich immer nur eine TCP-lastige rechnerei gewesen. Boah, vollsten Respekt. Kannst Dir nicht vorstellen, wie ich mich freue, nach dieser Hürde wieder voll weitermachen zu können. Werde das nachher umsetzen...freufreu Vielen Dank Klaus
Scyte R. schrieb: > Ich finde es auch cool, wie bist du darauf gekommen? Mit ziemlich viel Glück... ;-) https://de.wikipedia.org/wiki/Prüfsumme Darin von Flecher's Checksum gelesen, von der ich noch nie was gehört habe. https://de.wikipedia.org/wiki/Fletcher’s_Checksum Das dann in Excel mal mit den vorhandenen Daten ausprobiert, und geguckt, ob es für die beiden Summen irgendeine Operation gibt, um es auf das 1 Checkbyte zu reduzieren (aufsummieren, subtrahieren, XOR). XOR war dann ein Treffer. 2, 3 andere Datensätze ausprobiert, Resultat stimmte jeweils, done. ;-)
WOW, mal schnell Wikki und umgesetzt...Ich hatte Manchestercodierung, Flechter usw mal in der Technikerschule...Gekonnt wechgehört. Hatte das irgendwie in der TCP-Schublade....is ja auch schon ne Weile her. Nie gebraucht. Weiß noch, dass das irgendwie in 3(?) oder vierte ISO-Schicht gehört.. Achso, ich habe ich mal eins meiner Basteleien in "Zeigt her eure Kunstwerke " in Projekte gepostet. Nur fair, nach soviel Hilfe.
@Joe So, habs mal umgesetzt. Obwohl Umsetzen das falsche Wort ist. Du hast mir ja die Lösung schon mundgerecht geliefert: ---------192--------- 0 1 4 1 2 1 0 0 0 1 1 70 ---------192--------- void loop() { int main(int argc, char **argv); uint8_t data[11] = { 0, 1, 4, 1, 2, 1, 0, 0, 0, 1, 1 }; Serial.print("Checksum: "); Serial.println(calc_checksum(data, 11)); return 0; } uint8_t calc_checksum(uint8_t *data, uint8_t len) { uint8_t a=0; uint8_t b=0; uint8_t i; for (i=0; i<len; i++) { a += data[i]; b += a; } return (a^b); } Antwort: Checksum: 70 Jetzt noch das Array dynamisch machen, length-variablen und zack... ne nette kleine Methode... Nochmals vielen Dank Klaus
Gerne, war eine nette kleine Übung. Das "int main(int argc, char **argv);" brauchst du in der loop() Funktion natürlich nicht (wirft vermutlich auch eine Compiler Warnung). Das kennt ihr Arduino-Nutzer nicht mehr, aber main() ist die Hauptfunktion eines jeden C-Programms. Ist in der Arduino-Umgebung schon vordefiniert und vor euch versteckt...
Naja, in der ersten Hibbeligkeit erstmal ausprobiert und später aufgeräumt. Ist schon in meinem Prog eingebunden, läuft super. In einem Array ist der Grund-Datensatz, der durch eine Zählschleife die Bytes an das data Array übergibt. So kann ich an jeder beliebigen Stelle meinen Wert übergeben, am Ende wird die Prüfsumme berechnet. Dann alles in 192 verpackt und an den Tuner gesendet. War nen Kick, das Erste mal umschalten und einen anderen Sender hören. Die Arduino IDE bietet sich für mich an, für meine Elektronik-Projekte. Die Programmerhardware natürlich selbst gebaut, Ehrensache :) Jetzt, wo ich als Rentner aus Lust an der Sache progge, meistens Phyton(ist so schön zickig :) oder für Microsoftrechner C#. Gruß
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.