Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement] IL2P CRC Extension. #507

Open
maxlock opened this issue Dec 19, 2023 · 4 comments
Open

[Enhancement] IL2P CRC Extension. #507

maxlock opened this issue Dec 19, 2023 · 4 comments

Comments

@maxlock
Copy link

maxlock commented Dec 19, 2023

NinoTNC now has the addition of a CRC check to counter bad frames on noisy links. Could the CRC scheme also be implemented in Direwolf as an option to maintain compatibility, and gain better performance?

Nino's post describing the implementation is here (subscription required). I have quoted it below.

Hi all,

Several users have noticed invalid or corrupt frames coming through links using IL2P, especially in noisy conditions. To counter that, G4KLX and I have developed a CRC scheme that can be added to the end of an IL2P frame to let the decoder perform a final validation of the packet before sending it to the host.

The CRC is calculated exactly the same was as for an AX.25 frame, using the entire AX.25 data frame before any IL2P header conversion/parity/scrambling is done. At the receiver, the CRC is then used to check that the reconstructed AX.25 frame is valid, after IL2P decoding.

The CRC is placed after the IL2P frame, and is not part of the payload data nor the payload count. Since it is therefore outside the FEC-protected part of the frame, it is separately protected with a (7,4) Hamming code. The CRC is broken into four 4-bit nibbles, which are then each padded with 3 Hamming bits and a 0 bit in the MSB to create a single byte. So the 16-bit CRC becomes four bytes added after the IL2P frame. So a packet looks like:

|---preamble---|IL2P Syncword|---IL2P Frame---|---Encoded CRC---|

And the four encoded CRC bytes are arranged:
|CRC3|CRC2|CRC1|CRC0|

CRC3 encoded from high nibble of 16-bit CRC value
CRC0 encoded from low nibble of 16-bit CRC value

Each encoded CRC byte:
msb <------------------------> lsb
|0, 3-bit Hamming, 4-bit CRC nibble|

Here's the Hamming table we're using. Note you can read the underlying 4-bit value directly in bit positions 0-3 of the encoded value. The parity bits are in positions 4,5,6. Position 7 is 0.

// Hamming(7,4) Encoding Table
// Enter this table with the 4-bit value to be encoded.
// Returns 7-bit encoded value, with high bit zero'd.
uint8_t Hamming74EncodeTable[16] = {
0x0,
0x71,
0x62,
0x13,
0x54,
0x25,
0x36,
0x47,
0x38,
0x49,
0x5a,
0x2b,
0x6c,
0x1d,
0xe,
0x7f };

And the decode table:
// Hamming(7,4) Decoding Table
// Enter this table with 7-bit encoded value, high bit masked.
// Returns 4-bit decoded value.
uint8_t Hamming74DecodeTable[128] = {
0x0, 0x0, 0x0, 0x3, 0x0, 0x5, 0xe, 0x7,
0x0, 0x9, 0xe, 0xb, 0xe, 0xd, 0xe, 0xe,
0x0, 0x3, 0x3, 0x3, 0x4, 0xd, 0x6, 0x3,
0x8, 0xd, 0xa, 0x3, 0xd, 0xd, 0xe, 0xd,
0x0, 0x5, 0x2, 0xb, 0x5, 0x5, 0x6, 0x5,
0x8, 0xb, 0xb, 0xb, 0xc, 0x5, 0xe, 0xb,
0x8, 0x1, 0x6, 0x3, 0x6, 0x5, 0x6, 0x6,
0x8, 0x8, 0x8, 0xb, 0x8, 0xd, 0x6, 0xf,
0x0, 0x9, 0x2, 0x7, 0x4, 0x7, 0x7, 0x7,
0x9, 0x9, 0xa, 0x9, 0xc, 0x9, 0xe, 0x7,
0x4, 0x1, 0xa, 0x3, 0x4, 0x4, 0x4, 0x7,
0xa, 0x9, 0xa, 0xa, 0x4, 0xd, 0xa, 0xf,
0x2, 0x1, 0x2, 0x2, 0xc, 0x5, 0x2, 0x7,
0xc, 0x9, 0x2, 0xb, 0xc, 0xc, 0xc, 0xf,
0x1, 0x1, 0x2, 0x1, 0x4, 0x1, 0x6, 0xf,
0x8, 0x1, 0xa, 0xf, 0xc, 0xf, 0xf, 0xf };

My latest beta firmware for the TNC includes a few modes that use it, and some that don't for comparison. That firmware is posted here: https://github.com/ninocarrillo/flashtnc

TNCs with old firmware will still decode packets sent with the trailing CRC. TNCs running CRC modes on this new firmware will reject packets that don't have the CRC.

There is a .png image with how the new modes map to the MODE switches on that page too. Now I need to catch up on documentation! This will be in the IL2P spec doc soon.

73,
Nino

@M0LTE
Copy link

M0LTE commented May 18, 2024

This is also in QtSoundModem courtesy of John G8BPQ

@trunkseize
Copy link

This is supported in other software now too and it would be really great to have the additional interoperability in direwolf

@alexhorner
Copy link

+1 Would like to see Direwolf become compatible with the ever increasing number of stations using CRC

@neil969
Copy link

neil969 commented May 19, 2024

a big +1 from me too! I am using QtSoundModem now to talk to the packet BBS's on HF, and it works well, so direwolf would be good too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants