Packetizer (multi-level error correction)

Keywords: packetizer forward error correction FEC encode decode cyclic redundancy check CRD

The liquid packetizer is a structure for abstracting multi-level forward error-correction from the user. The packetizer accepts a buffer of uncoded data bytes and adds a cyclic redundancy check (CRC) before applying two levels of forward error-correction and bit-level interleaving. The user may choose any two supported FEC schemes (including none) and the packetizer object will handle buffering and data management internally, providing a truly abstract interface. The same is true for the packet decoder which accepts an array of possibly corrupt data and attempts to recover the original message using the FEC schemes provided. The packet decoder returns the validity of the resulting CRC as well as its best effort of decoding the message.

The packetizer also allows for re-structuring if the user wishes to change error-correction schemes or data lengths. This is accomplished with the packetizer_recreate() method. Listed below is the full interface to the packetizer object.

  • packetizer_create(n,crc,fec0,fec1) creates and returns a packetizer object which accepts \(n\) uncoded input bytes and uses the specified CRC and bi-level FEC schemes.
  • packetizer_recreate(q,n,crc,fec0,fec1) re-creates an existing packetizer object with new parameters.
  • packetizer_destroy(q) destroys an packetizer object, freeing all internally-allocated memory.
  • packetizer_print(q) prints the internal state of the packetizer object to the standard output.
  • packetizer_get_dec_msg_len(q) returns the specified decoded message length \(n\) in bytes.
  • packetizer_get_enc_msg_len(q) returns the fully-encoded message length \(k\) in bytes.
  • packetizer_encode(q,*msg,*pkt) encodes the \(n\) -byte input message storing the result in the\(k\) -byte encoded output message.
  • packetizer_decode(q,*pkt,*msg) decodes the \(k\) -byte encoded input message storing the result in the\(n\) -byte output. The function returns a 1 if the internal CRC passed and a 0 if it failed. If no CRC was specified (e.g. LIQUID_CRC_NONE ) then a 1 is always returned.
  • packetizer_decode_soft(q,*pkt,*msg) decodes the encoded input message just like packetizer_decode() but with soft bits instead of hard bytes. The input is an array of type unsigned char with \(8 \times k\) elements representing soft bits. As before, the function returns a 1 if the internal CRC passed and a 0 if it failed. See [ref:section-fec-soft] for more information on soft-decision decoding.

Here is a minimal example demonstrating the packetizer's most basic functionality:

#include <liquid/liquid.h>

int main() {
    // set up the options
    unsigned int n=16;                      // uncoded data length
    crc_scheme crc  = LIQUID_CRC_32;        // validity check
    fec_scheme fec0 = LIQUID_FEC_HAMMING74; // inner code
    fec_scheme fec1 = LIQUID_FEC_REP3;      // outer code

    // compute resulting packet length
    unsigned int k = packetizer_compute_enc_msg_len(n,crc,fec0,fec1);

    // set up the arrays
    unsigned char msg[n];       // original message
    unsigned char packet[k];    // encoded message
    unsigned char msg_dec[n];   // decoded message
    int crc_pass;               // decoder validity check

    // create the packetizer object
    packetizer p = packetizer_create(n,crc,fec0,fec1);

    // initialize msg here
    unsigned int i;
    for (i=0; i<n; i++) msg[i] = i & 0xff;

    // encode the packet
    packetizer_encode(p,msg,packet);

    // decode the packet, returning validity
    crc_pass = packetizer_decode(p,packet,msg_dec);

    // destroy the packetizer object
    packetizer_destroy(p);
}

See also: fec module, examples/packetizer_example.c