Softwareentwicklung
›
Thread
Frame Check Sequence
Hallo Leute,
ich möchte gerne den FCS auswerten komme aber nicht weiter.
Ist mein Ansatz erstmal richtig?
data ist der Empfangspuffer, len die Packetlenge (hier 115 Bytes).
1
uint32_t crc32 ( const uint8_t * data , size_t length )
2
{
3
4
uint32_t crc = 0xFFFFFFFF ;
5
for ( size_t i = 0 ; i < length ; i ++ ) {
6
uint8_t byte = data [ i ];
7
crc = ( crc >> 8 ) ^ crc32_table [( crc ^ byte ) & 0xFF ];
8
}
9
10
printf ( "CRC32: %08X \n " , crc );
11
return 0 ;
12
}
13
14
uint32_t calculate_fcs ( const uint8_t * data , size_t length )
15
{
16
uint32_t crc = crc32 (( const uint8_t * ) data , length );
17
return 0 ;
18
}
19
20
int checkfcs ( uint8_t * data , int len )
21
{
22
23
size_t frame_length = len - 4 ; // Länge ohne FCS
24
printf ( "frame_length: %ld \n " , frame_length );
25
26
uint32_t received_fcs = ( uint32_t ) data [ frame_length ]; // FCS extrahieren
27
printf ( "received_fcs:%08X \n " , received_fcs );
28
29
// Berechne die FCS für die empfangenen Daten
30
uint32_t calculated_fcs = calculate_fcs ( data , frame_length );
31
32
// Vergleiche die empfangene FCS mit der berechneten FCS
33
34
if ( received_fcs == calculated_fcs ) {
35
printf ( "FCS ist korrekt. \n " );
36
} else {
37
printf ( "FCS ist fehlerhaft. \n " );
38
}
39
40
return 0 ;
41
}
Welle 🧐 S. schrieb:
printf("CRC32: %08X\n", crc);
return 0; <<--- Sollte da nicht "return crc" stehen?
Genau wie hier?
uint32_t crc = crc32((const uint8_t *)data, length);
return 0;
Sonst erkennt der Compiler eine unused variable "crc" und optimiert dir den "crc32"-Aufruf weg.
Hall Ernst, danke.
Aber Irgenetwas stimmt hier nicht:
size_t pure_frame_length = len-4; // Länge ohne FCS
uint32_t received_fcs = (uint32_t)data[pure_frame_length];
Ich bekomme in received_fcs nur das erste Byte - 03a.
Es sollte aber 0x3a, 0x86, 0x4c, 0x62 sein ...
1
pure_frame_length: 111
2
received_fcs : 0000003 a
3
CRC32 : EF3E605E
4
FCS ist fehlerhaft .
5
---------------------------- new packet -----------------------------------
6
7
0x00 , 0x00 , 0x38 , 0x00 , 0x2f , 0x40 , 0x40 , 0xa0 , 0x20 , 0x08 , 0x00 , 0xa0 , 0x20 , 0x08 , 0x00 , 0x00 ,
8
0x11 , 0xab , 0x17 , 0xc8 , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 , 0x02 , 0x6c , 0x09 , 0xa0 , 0x00 , 0xe0 , 0x00 ,
9
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x51 , 0xaa , 0x17 , 0xc8 , 0x00 , 0x00 , 0x00 , 0x00 ,
10
0x16 , 0x00 , 0x11 , 0x03 , 0xe0 , 0x00 , 0xb4 , 0x01 , 0xd0 , 0x00 , 0x00 , 0x00 , 0xff , 0xff , 0xff , 0xff ,
11
0xff , 0xff , 0xc4 , 0x4f , 0x33 , 0x0f , 0xfe , 0x71 , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xf0 , 0x59 ,
12
0x7f , 0x18 , 0xfe , 0x34 , 0xa1 , 0x9b , 0x1c , 0x4d , 0xdd , 0x15 , 0x18 , 0xfe , 0x34 , 0x04 , 0x01 , 0x0f ,
13
0x27 , 0x00 , 0x00 , 0x1f , 0x85 , 0x45 , 0x41 , 0x01 , 0x00 , 0x00 , 0x00 , 0xa8 , 0xc6 , 0xb1 , 0x41 , 0x3a ,
14
0x86 , 0x4c , 0x62 ,
Moin,
Welle 🧐 S. schrieb:
Ich bekomme in received_fcs nur das erste Byte - 03a.
Was auch - oh wunder - genau das ist, was du geschrieben hast.
Du holst dir einen 8-Bit Wert, den castest du dann auf 32 bit...
Gruss
WK
Dergute W. schrieb:
Du holst dir einen 8-Bit Wert, den castest du dann auf 32 bit...
Ich komme nicht drauf ... !
size_t?
1
size_t pure_frame_length = len - 4 ; // Länge ohne FCS
(uint32_t)data[pure_frame_length];
Das holt ein Byte und castet es auf einen uint32_t.
Klaus schrieb:
(uint32_t)data[pure_frame_length];
Das holt ein Byte und castet es auf einen uint32_t.
Ahh, klar data[111] ein Byte ...
Muss ich eine Schleife laufen lassen um die 4Bytes einzulesen?
Welle 🧐 S. schrieb:
Muss ich eine Schleife laufen lassen um die 4Bytes einzulesen?
für 4 Bytes lohnt sich keine Schleife.
Data[x]+ Data[x+1]<<8 + Data[x+2]<<16 + Data[x+3]<<24
Oder so ähnlich, je nach Endianess.
Moin,
Vielleicht mit 'nem
1
memcmp ( blaptr , bluppptr , 4 )
?
Gruss
WK
Dergute W. schrieb:
Vielleicht mit 'nem memcmp
:)
Ich hab es jetzt mit memcpy gemacht, was schonmal die 4 Bytes extrahiert;
Ich werde aber Klaus seinen Vorschlag eingehen, weil die Werte Endianess'd
sind ...
Der calculated_fcs (CRC-32/JAMCRC) passt, hab ich geprüft!
1
received_fcs: 45 A7C4AD
2
calculated_fcs : A1047041
3
FCS ist fehlerhaft .
4
---------------------------- new packet -----------------------------------
5
6
0x00 , 0x00 , 0x38 , 0x00 , 0x2f , 0x40 , 0x40 , 0xa0 , 0x20 , 0x08 , 0x00 , 0xa0 , 0x20 , 0x08 , 0x00 , 0x00 ,
7
0x14 , 0x07 , 0x01 , 0x2c , 0x07 , 0x00 , 0x00 , 0x00 , 0x10 , 0x02 , 0x6c , 0x09 , 0xa0 , 0x00 , 0xe1 , 0x00 ,
8
0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x54 , 0x06 , 0x01 , 0x2c , 0x00 , 0x00 , 0x00 , 0x00 ,
9
0x16 , 0x00 , 0x11 , 0x03 , 0xe1 , 0x00 , 0xb7 , 0x01 , 0xd0 , 0x00 , 0x00 , 0x00 , 0xff , 0xff , 0xff , 0xff ,
10
0xff , 0xff , 0xc4 , 0x4f , 0x33 , 0x0f , 0xfe , 0x71 , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xb0 , 0x90 ,
11
0x7f , 0x18 , 0xfe , 0x34 , 0x1d , 0x34 , 0xb5 , 0x87 , 0xdd , 0x15 , 0x18 , 0xfe , 0x34 , 0x04 , 0x01 , 0x0f ,
12
0x27 , 0x00 , 0x00 , 0x1f , 0x85 , 0x45 , 0x41 , 0x01 , 0x00 , 0x00 , 0x00 , 0xa8 , 0xc6 , 0xb1 , 0x41 , 0xad ,
13
0xc4 , 0xa7 , 0x45 ,
1
typedef struct struct_message
2
{
3
uint8_t radio_tap_header [ 95 ];
4
int b ;
5
float c ;
6
bool d ;
7
uint8_t pad_for_bool [ 3 ];
8
float e ;
9
uint32_t fcs ;
10
} __attribute__ (( packed , aligned ( 1 ))) struct_message ;
11
struct_message myData ;
12
13
uint32_t crc32 ( const uint8_t * data , size_t length ) // CRC-32/JAMCRC
14
{
15
16
uint32_t crc = 0xFFFFFFFF ;
17
for ( size_t i = 0 ; i < length ; i ++ ) {
18
uint8_t byte = data [ i ];
19
crc = ( crc >> 8 ) ^ crc32_table [( crc ^ byte ) & 0xFF ];
20
}
21
22
return crc ;
23
}
24
25
int checkfcs ( uint8_t * data , int len )
26
{
27
memcpy ( & myData , data , len );
28
29
uint32_t received_fcs = ( uint32_t ) myData . fcs ; // FCS extrahieren
30
printf ( "received_fcs: %08X \n " , received_fcs );
31
32
// Berechne die CRC32 für die empfangenen Daten
33
uint32_t calculated_fcs = crc32 ( data , len - 4 ); // Exclude FCS
34
printf ( "calculated_fcs: %08X \n " , calculated_fcs );
35
36
// Vergleiche die empfangene FCS mit der berechneten FCS
37
38
if ( received_fcs == calculated_fcs ) {
39
printf ( "FCS ist korrekt. \n " );
40
} else {
41
printf ( "FCS ist fehlerhaft. \n " );
42
}
43
44
return 0 ;
45
}
Welle 🧐 S. schrieb:
Ich hab es jetzt mit memcpy gemacht
Ineffezienter ging es nicht?
Klaus schrieb:
Welle 🧐 S. schrieb:
Ich hab es jetzt mit memcpy gemacht
Ineffezienter ging es nicht?
Bestimmt nicht, aber wie du siehst bin ich noch Anfänger ;)
DS
Dieter S.
(ds1)
28.01.2025 11:35
#7819206
Dir ist bewusst dass der Radiotap Header nicht bei der CRC Berechnung berüchksichtigt wird sondern nur die Daten? Also in dem Beispiel ab "0xd0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, ...".
Außerdem ist der CRC Algorithmus "CRC-32" und nicht "JAMCRC", es reicht allerdings auch wenn man das Ergebnis invertiert (XOR mit 0xFFFFFFFF) um aus "JAMCRC" "CRC-32" zu machen.
Wenn man das alles so macht kommt auch die richtige CRC/FCS heraus.
Moin,
Dieter S. schrieb:
Wenn man das alles so macht kommt auch die richtige CRC/FCS heraus.
Kaum macht man's richtig, geht's auch schon:
1
wk [ ~ ]$ reveng -m"CRC-32/ISO-HDLC" -c d0000000ffffffffffffc44f330ffe71fffffffffffff0597f18fe34a19b1c4ddd1518fe3404010f2700001f85454101000000a8c6b141
2
3a864c62
Gruss
WK
Ich habe meinen Code nochmal überarbeitet ... CRC32, natürlich ohne die
4 Byte FCS stimmt jetzt ...
1
#include <stddef.h>
2
#include <stdint.h>
3
4
uint32_t crc32_table [ 256 ];
5
6
void build_crc32_table ( void ) {
7
for ( uint32_t i = 0 ; i < 256 ; i ++ ) {
8
uint32_t ch = i ;
9
uint32_t crc = 0 ;
10
for ( size_t j = 0 ; j < 8 ; j ++ ) {
11
uint32_t b = ( ch ^ crc ) & 1 ;
12
crc >>= 1 ;
13
if ( b ) crc = crc ^ 0xEDB88320 ;
14
ch >>= 1 ;
15
}
16
crc32_table [ i ] = crc ;
17
}
18
}
19
20
uint32_t crc32_fast ( const uint8_t * data , size_t length ) {
21
uint32_t crc = 0xFFFFFFFF ;
22
23
for ( size_t i = 0 ; i < length ; i ++ ) {
24
char ch = data [ i ];
25
uint32_t t = ( ch ^ crc ) & 0xFF ;
26
crc = ( crc >> 8 ) ^ crc32_table [ t ];
27
}
28
29
return ~ crc ;
30
}
https://lxp32.github.io/docs/a-simple-example-crc32-calculation/
DS
Dieter S.
(ds1)
28.01.2025 12:28
#7819248
Im Screenshot sieht man dass immer noch der Radiotap Header bei der CRC Berechnung berücksichtigt wird, daher ist der Wert von "FCS:" und "CRC32:" im Screenshot auch nicht identisch.
Dieter S. schrieb:
Im Screenshot sieht man dass immer noch der Radiotap Header bei der CRC
Berechnung berücksichtigt wird, daher ist der Wert von "FCS:" und
"CRC32:" im Screenshot auch nicht identisch.
Ahh! Der FCS wird nur auf den Payload berrechent!?
DS
Dieter S.
(ds1)
28.01.2025 13:19
#7819287
Welle 🧐 S. schrieb:
Ahh! Der FCS wird nur auf den Payload berrechent!?
Wurde doch hier schon geschrieben:
Beitrag "Re: Frame Check Sequence"
Beitrag "Re: Frame Check Sequence"
Ich komme nicht weiter.
Den FCS habe ich mittlerweise Extrahiert
1
packet laenge : 115
2
sizeof ( myData ) : 115
3
Received FCS : 211 f0289
4
Calculated CRC32 / ISO - HDLC : 0 aca0378
5
---------------------------- new packet -----------------------------------
6
7
00 00 38 00 2 f 40 40 a0 20 08 00 a0 20 08 00 00
8
57 aa 6 a 3 d 01 00 00 00 10 02 6 c 09 a0 00 f2 00
9
00 00 00 00 00 00 00 00 97 a9 6 a 3 d 00 00 00 00
10
16 00 11 03 f2 00 c5 01 d0 00 00 00 ff ff ff ff
11
ff ff c4 4 f 33 0 f fe 71 ff ff ff ff ff ff f0 c9
12
7 f 18 fe 34 21 2 a 6 e d2 dd 15 18 fe 34 04 01 0 f
13
27 00 00 1 f 85 45 41 01 00 00 00 a8 c6 b1 41 21
14
1 f 02 89
15
16
reveng - m "CRC-32/ISO-HDLC" - c "d0 00 00 00 ff ff ff ff
17
ff ff c4 4f 33 0f fe 71 ff ff ff ff ff ff f0 c9
18
7f 18 fe 34 21 2a 6e d2 dd 15 18 fe 34 04 01 0f
19
27 00 00 1f 85 45 41 01 00 00 00 a8 c6 b1 41"
20
211 f0289
Ich habe aber keine Idee wie ich den entsprechend Teil das Packetes
an die CRC32 funktion übergeben kann
1
memcpy ( & myData , data , len );
2
uint32_t calculated_crc32 = crc32_fast ( data , len - 4 );
Den FCS hinten abschneiden (-4 Bytes) ist einfach, aber Radiotapheader, der davor ist bekomme ich nicht hin ...
Bitte um Hilfe!
Moin,
1
calculated_crc32 = crc32_fast ( & data [ offset ], len - offset - 4 );
So?
Irgendwie musst du halt auf den konkreten Wert von offset kommen, das wird dann wohl in der Spec stehen, wo der Aufbau des Packerl beschrieben ist.
Gruss
WK
DS
Dieter S.
(ds1)
04.02.2025 16:30
#7823465
Dergute W. schrieb:
Irgendwie musst du halt auf den konkreten Wert von offset kommen, das
wird dann wohl in der Spec stehen, wo der Aufbau des Packerl beschrieben
ist.
Der TO müsste nur vorher mal die Doku lesen, dann wäre es ziemlich einfach. Der Aufbau der Radiotap Header steht dort schon ganz am Anfang:
https://www.radiotap.org
Funktioniert, danke!
1
calculated_crc32 = crc32_fast ( & data [ offset ], len - offset - 4 );
1
---------------------------- paylaod -----------------------------------
2
d0 00 00 00 ff ff ff ff ff ff c4 4 f 33 0 f fe 71
3
ff ff ff ff ff ff 30 fa 7 f 18 fe 34 22 7 d fe 57
4
dd 15 18 fe 34 04 01 0 f 27 00 00 1 f 85 45 41 01
5
00 00 00 a8 c6 b1 41
1
packet laenge : 115
2
sizeof ( myData ) : 115
3
Received FCS : ee7b3daf
4
CRC32 / ISO - HDLC : ee7b3daf
5
---------------------------- new packet -----------------------------------
6
7
00 00 38 00 2 f 40 40 a0 20 08 00 a0 20 08 00 00
8
51 b7 e6 e1 03 00 00 00 10 02 6 c 09 a0 00 f2 00
9
00 00 00 00 00 00 00 00 91 b6 e6 e1 00 00 00 00
10
16 00 11 03 f2 00 c8 01 d0 00 00 00 ff ff ff ff
11
ff ff c4 4 f 33 0 f fe 71 ff ff ff ff ff ff 70 7 f
12
7 f 18 fe 34 3 d 66 05 f5 dd 15 18 fe 34 04 01 0 f
13
27 00 00 1 f 85 45 41 01 00 00 00 a8 c6 b1 41 af
14
3 d 7 b ee
Moin,
Welle 🧐 S. schrieb:
Funktioniert, danke!
Yay! hoch die Tassen :-)
Gruss
WK
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
Noch kein Account?
Die Registrierung ist kostenlos und dauert nur eine Minute.
Jetzt registrieren