[Enhancement] IL2P CRC Extension.
maxlock opened this issue · 7 comments
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 valueEach 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
This is also in QtSoundModem courtesy of John G8BPQ
This is supported in other software now too and it would be really great to have the additional interoperability in direwolf
+1 Would like to see Direwolf become compatible with the ever increasing number of stations using CRC
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.
The CRC I assume, is so many stations can be piled-on to the same frequency. The obvious solution for point-point links, is separate frequencies. Since IL2P doesn't use AX25 repeaters, this seems even more desirable. I'm thinking VHF and up, of course HF is a special case, but much better protocols are available for HF. I don't think any FSK burst mode is appropriate there. They can't compete with PSK or QAM modes (single carrier or OFDM).
FYI Here's a Markdown version of the spec: https://github.com/srsampson/IPNode-new/blob/main/docs/il2p-readme.md