ssdv_fec/lib.rs
1//! # SSDV systematic erasure FEC
2//!
3//! This crate implements a systematic erasure FEC scheme for
4//! [SSDV](https://github.com/fsphil/ssdv). The FEC scheme is based on a
5//! Reed-Solomon code over GF(2¹⁶) used as a fountain-like code. This idea was
6//! first described in the blog post
7//! [An erasure FEC for SSDV](https://destevez.net/2023/05/an-erasure-fec-for-ssdv/)
8//! by the author of this crate.
9//!
10//! Given an SSDV image formed by k SSDV packets, the FEC encoder can generate
11//! up to 2¹⁶ different SSDV packets identified by a packet ID from 0 to
12//! 2¹⁶-1. The packets with IDs from 0 to k-1 are called "systematic
13//! packets" and are the same as the k packets of the original image. The
14//! remaining packets are called "FEC packets". Each packet can be generated on
15//! demand according to the needs of the transmitter. The large amount of 2¹⁶
16//! distinct packets than can be generated provides a virtually limitless source
17//! of packets. The receiver can recover the original SSDV image from any set of
18//! k distinct packets.
19//!
20//! Several SSDV packet formats are supported:
21//!
22//! - The no-FEC
23//! [standard packet format](https://ukhas.org.uk/doku.php?id=guides:ssdv#packet_format)
24//! implemented by the
25//! [upstream SSDV](https://github.com/fsphil/ssdv). This is a 256-byte packet
26//! format that includes a callsign.
27//!
28//! - The custom packet format used by Longjiang-2, which is implemented in a
29//! [fork of SSVD](https://github.com/daniestevez/ssdv). This is a 218-byte
30//! packet format that omits the sync byte, packet type and callsign fields (but
31//! includes them implicitly in the generation of the CRC-32).
32//!
33//! Other packet formats can be supported by implementing the [`SSDVParameters`]
34//! or the [`SSDVPacket`] trait.
35//!
36//! This implementation of the FEC scheme uses 218-byte SSDV packets following
37//! the format used by Longjiang-2, which omits the sync byte, packet type and
38//! callsign fields (but includes them implicitly in the generation of the
39//! CRC-32).
40//!
41//! The crate supports `no_std` and the implementation is designed with small
42//! microcontrollers in mind. The GF(2¹⁶) arithmetic only uses two tables of 256
43//! bytes each that are included in the `.rodata` section. The FEC encoder and
44//! decoder work with externally provided slices, giving freedom as to how to
45//! perform memory allocation, and do the computations in-place when
46//! possible. The memory required for encoding corresponds to a buffer
47//! containing the k SSDV packets of the original image, and a buffer containing
48//! the packet being encoded. The memory required for decoding corresponds to a
49//! buffer containing at least k distinct received SSDV packets, and another
50//! buffer where the k SSDV packets that compose the original image can be
51//! written. Besides these buffers, the algorithms use only a small amount of
52//! stack space.
53//!
54//! A simple CLI application that can perform encoding and decoding can be built
55//! with the `cli` feature, which is enabled by default.
56
57#![warn(missing_docs)]
58#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
59
60#[cfg(feature = "cli")]
61pub mod cli;
62
63mod crc;
64mod fec;
65pub use fec::{Decoder, DecoderError, Encoder, EncoderError};
66mod gf64k;
67pub use gf64k::{GF64K, GF256};
68mod ssdv;
69pub use ssdv::{SSDVPacket, SSDVPacketArray, SSDVParameters};
70
71pub mod packet_formats;
72
73#[cfg(test)]
74mod test_data;