wb2osz / direwolf

Dire Wolf is a software "soundcard" AX.25 packet modem/TNC and APRS encoder/decoder. It can be used stand-alone to observe APRS traffic, as a tracker, digipeater, APRStt gateway, or Internet Gateway (IGate). For more information, look at the bottom 1/4 of this page and in https://github.com/wb2osz/direwolf/blob/dev/doc/README.md
GNU General Public License v2.0
1.59k stars 307 forks source link

[Enhancement] IL2P CRC Extension. #507

Open maxlock opened 11 months ago

maxlock commented 11 months ago

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 commented 6 months ago

This is also in QtSoundModem courtesy of John G8BPQ

trunkseize commented 6 months ago

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

alexhorner commented 6 months ago

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

neil969 commented 5 months ago

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.

ghost commented 5 months ago

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

M0LTE commented 5 months ago

No, it’s because corruption slips through the RS FEC in IL2P in practice enough to warrant caring about.

Please review the updated IL2P specification v0.6 at https://tarpn.net/t/il2p/il2p-specification_draft_v0-6.pdf for details.

On Fri, 31 May 2024 at 12:06, Steve Sampson @.***> wrote:

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

— Reply to this email directly, view it on GitHub https://github.com/wb2osz/direwolf/issues/507#issuecomment-2141788849, or unsubscribe https://github.com/notifications/unsubscribe-auth/AJAQNWHPVAQCEDFAOLPWOYTZFBKTVAVCNFSM6AAAAABA3ZYLD6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNBRG44DQOBUHE . You are receiving this because you commented.Message ID: @.***>

ghost commented 5 months ago

FYI Here's a Markdown version of the spec: https://github.com/srsampson/IPNode-new/blob/main/docs/il2p-readme.md