Forum: PC-Programmierung Frame Check Sequence


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Welle 🧐 S. (w3llschmidt)


Angehängte Dateien:

Lesenswert?

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
}

: Bearbeitet durch User
von Εrnst B. (ernst)


Lesenswert?

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.

von Welle 🧐 S. (w3llschmidt)


Lesenswert?

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: 0000003a
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,

: Bearbeitet durch User
von Dergute W. (derguteweka)


Lesenswert?

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

von Welle 🧐 S. (w3llschmidt)


Lesenswert?

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

von Klaus (feelfree)


Lesenswert?

(uint32_t)data[pure_frame_length];

Das holt ein Byte und castet es auf einen uint32_t.

von Welle 🧐 S. (w3llschmidt)


Lesenswert?

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?

von Klaus (feelfree)


Lesenswert?

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.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Vielleicht mit 'nem
1
memcmp(blaptr, bluppptr, 4)
?

Gruss
WK

: Bearbeitet durch User
von Welle 🧐 S. (w3llschmidt)


Lesenswert?

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: 45A7C4AD
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
}

: Bearbeitet durch User
von Klaus (feelfree)


Lesenswert?

Welle 🧐 S. schrieb:
> Ich hab es jetzt mit memcpy gemacht

Ineffezienter ging es nicht?

von Welle 🧐 S. (w3llschmidt)


Lesenswert?

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 ;)

von Dieter S. (ds1)


Lesenswert?

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.

von Dergute W. (derguteweka)


Lesenswert?

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

von Welle 🧐 S. (w3llschmidt)


Angehängte Dateien:

Lesenswert?

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/

: Bearbeitet durch User
von Dieter S. (ds1)


Lesenswert?

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.

von Welle 🧐 S. (w3llschmidt)


Lesenswert?

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!?

von Dieter S. (ds1)


Lesenswert?

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"

von Welle 🧐 S. (w3llschmidt)


Lesenswert?

Ich komme nicht weiter.

Den FCS habe ich mittlerweise Extrahiert
1
packet laenge: 115
2
sizeof(myData): 115
3
Received FCS: 211f0289
4
Calculated CRC32/ISO-HDLC: 0aca0378
5
----------------------------new packet-----------------------------------
6
7
00 00 38 00 2f 40 40 a0 20 08 00 a0 20 08 00 00 
8
57 aa 6a 3d 01 00 00 00 10 02 6c 09 a0 00 f2 00 
9
00 00 00 00 00 00 00 00 97 a9 6a 3d 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 4f 33 0f fe 71 ff ff ff ff ff ff f0 c9 
12
7f 18 fe 34 21 2a 6e d2 dd 15 18 fe 34 04 01 0f 
13
27 00 00 1f 85 45 41 01 00 00 00 a8 c6 b1 41 21 
14
1f 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
211f0289

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!

: Bearbeitet durch User
von Dergute W. (derguteweka)


Lesenswert?

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

von Dieter S. (ds1)


Lesenswert?

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

von Welle 🧐 S. (w3llschmidt)


Angehängte Dateien:

Lesenswert?

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 4f 33 0f fe 71 
3
ff ff ff ff ff ff 30 fa 7f 18 fe 34 22 7d fe 57 
4
dd 15 18 fe 34 04 01 0f 27 00 00 1f 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 2f 40 40 a0 20 08 00 a0 20 08 00 00 
8
51 b7 e6 e1 03 00 00 00 10 02 6c 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 4f 33 0f fe 71 ff ff ff ff ff ff 70 7f 
12
7f 18 fe 34 3d 66 05 f5 dd 15 18 fe 34 04 01 0f 
13
27 00 00 1f 85 45 41 01 00 00 00 a8 c6 b1 41 af 
14
3d 7b ee

: Bearbeitet durch User
von Dergute W. (derguteweka)


Lesenswert?

Moin,

Welle 🧐 S. schrieb:
> Funktioniert, danke!

Yay! hoch die Tassen :-)

Gruss
WK

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
Noch kein Account? Hier anmelden.