frame64 Generator/Synchronizer

liquid comes packaged with two basic framing structures: frame64 and flexframe which can be used with little modification to transmit data over a wireless link. The interface for both of these objects is intended to be as simple as possible while allowing control over some of the parameters of the system. On the transmitter side, the appropriate frame generator object is created, configured, and executed. The receiver side uses an appropriate frame synchronizer object which simply picks packets of a stream of samples, invoking a callback function for each packet it finds. The simplicity of the receiver is that the frame synchronizer object automatically reconfigures itself for packets of different size, modulation scheme, and other parameters.

frame64 description

The framegen64 and framesync64 objects implement a basic framing structure for communicating packetized data over the air. The framegen64 object accepts a 12-byte header and 64-byte payload and assemble a 1280sample frame. Internally, the frame generator encodes the header and payload each with a Hamming(12,8) block code, 16-bit cyclic redundancy check, and modulates the result with a QPSK modem. The header and payload are encapsulated with special phasing sequences, and finally the resulting symbols are interpolated using a half-rate root-raised cosine filter (see [section-filter-firdes-rnyquist] ).

The true spectral efficiency of the frame is exactly \(4/5\) ; 64 bytes of data (512 bits) encoded into 640 symbols. The frame64 structure has the advantage of simplicity but lacks the ability for true flexibility.

#include <liquid/liquid.h>

// static callback function
static int callback(unsigned char *  _header,
                    int              _header_valid,
                    unsigned char *  _payload,
                    unsigned int     _payload_len,
                    int              _payload_valid,
                    framesyncstats_s _stats,
                    void *           _userdata)
    printf("*** callback invoked ***\n");
    return 0;

int main() {
    // create frame generator
    framegen64 fg = framegen64_create();

    // create frame synchronizer using default properties
    framesync64 fs = framesync64_create(callback,NULL);

    // data payload
    unsigned char header[8];
    unsigned char payload[64];

    // .. initialize header and payload data ..

    // generate the frame
    float complex frame[LIQUID_FRAME64_LEN];
    framegen64_execute(fg, header, payload, frame);

    // synchronize/receive the frame
    framesync64_execute(fs, frame, LIQUID_FRAME64_LEN);

    // clean up allocated objects