Exemplo n.º 1
0
// decode header
void flexframesync_decode_header(flexframesync _q)
{
#if DEMOD_HEADER_SOFT
    // soft decoding operates on 'header_mod' array directly;
    // no need to pack bits
#else
    // pack 256 1-bit header symbols into 32 8-bit bytes
    unsigned int num_written;
    liquid_pack_bytes(_q->header_mod, FLEXFRAME_H_SYM,
                      _q->header_enc, FLEXFRAME_H_ENC,
                      &num_written);
    assert(num_written==FLEXFRAME_H_ENC);
#endif 

#if DEBUG_FLEXFRAMESYNC_PRINT
    unsigned int i;
    // print header (encoded)
    printf("header rx (enc) : ");
    for (i=0; i<FLEXFRAME_H_ENC; i++)
        printf("%.2X ", _q->header_enc[i]);
    printf("\n");
#endif

    // unscramble header and run packet decoder
#if DEMOD_HEADER_SOFT
    // soft demodulation operates on header_mod directly
    unscramble_data_soft(_q->header_mod, FLEXFRAME_H_ENC);
    _q->header_valid =
    packetizer_decode_soft(_q->p_header, _q->header_mod, _q->header);
#else
    unscramble_data(_q->header_enc, FLEXFRAME_H_ENC);
    _q->header_valid =
    packetizer_decode(_q->p_header, _q->header_enc, _q->header);
#endif

    // return if header is invalid
    if (!_q->header_valid)
        return;

    // first several bytes of header are user-defined
    unsigned int n = FLEXFRAME_H_USER;

    // first byte is for expansion/version validation
    if (_q->header[n+0] != FLEXFRAME_VERSION) {
        fprintf(stderr,"warning: flexframesync_decode_header(), invalid framing version\n");
        _q->header_valid = 0;
        return;
    }

    // strip off payload length
    unsigned int payload_dec_len = (_q->header[n+1] << 8) | (_q->header[n+2]);
    _q->payload_dec_len = payload_dec_len;

    // strip off modulation scheme/depth
    unsigned int mod_scheme = _q->header[n+3];

    // strip off CRC, forward error-correction schemes
    //  CRC     : most-significant 3 bits of [n+4]
    //  fec0    : least-significant 5 bits of [n+4]
    //  fec1    : least-significant 5 bits of [n+5]
    unsigned int check = (_q->header[n+4] >> 5 ) & 0x07;
    unsigned int fec0  = (_q->header[n+4]      ) & 0x1f;
    unsigned int fec1  = (_q->header[n+5]      ) & 0x1f;

    // validate properties
    if (mod_scheme == 0 || mod_scheme >= LIQUID_MODEM_NUM_SCHEMES) {
        fprintf(stderr,"warning: flexframesync_decode_header(), invalid modulation scheme\n");
        _q->header_valid = 0;
        return;
    }
    if (check >= LIQUID_CRC_NUM_SCHEMES) {
        fprintf(stderr,"warning: flexframesync_decode_header(), decoded CRC exceeds available\n");
        _q->header_valid = 0;
        return;
    }
    if (fec0 >= LIQUID_FEC_NUM_SCHEMES) {
        fprintf(stderr,"warning: flexframesync_decode_header(), decoded FEC (inner) exceeds available\n");
        _q->header_valid = 0;
        return;
    }
    if (fec1 >= LIQUID_FEC_NUM_SCHEMES) {
        fprintf(stderr,"warning: flexframesync_decode_header(), decoded FEC (outer) exceeds available\n");
        _q->header_valid = 0;
        return;
    }

    // configure payload receiver
    if (_q->header_valid) {
        // recreate modem
        _q->ms_payload    = mod_scheme;
        _q->bps_payload   = modulation_types[mod_scheme].bps;
        _q->demod_payload = modem_recreate(_q->demod_payload, _q->ms_payload);

        // set new packetizer properties
        _q->check  = check;
        _q->fec0   = fec0;
        _q->fec1   = fec1;

        // recreate packetizer object
        _q->p_payload = packetizer_recreate(_q->p_payload,
                                            _q->payload_dec_len,
                                            _q->check,
                                            _q->fec0,
                                            _q->fec1);

        // re-compute payload encoded message length
        _q->payload_enc_len = packetizer_get_enc_msg_len(_q->p_payload);

        // re-compute number of modulated payload symbols
        div_t d = div(8*_q->payload_enc_len, _q->bps_payload);
        _q->payload_mod_len = d.quot + (d.rem ? 1 : 0);
        
        // re-allocate buffers accordingly
        // (give encoded a few extra bytes to compensate for repacking)
        _q->payload_mod = (unsigned char*) realloc(_q->payload_mod, (_q->payload_mod_len  )*sizeof(unsigned char));
        _q->payload_enc = (unsigned char*) realloc(_q->payload_enc, (_q->payload_enc_len+8)*sizeof(unsigned char));
        _q->payload_dec = (unsigned char*) realloc(_q->payload_dec, (_q->payload_dec_len  )*sizeof(unsigned char));

        if (_q->payload_mod == NULL || _q->payload_enc == NULL || _q->payload_dec == NULL) {
            fprintf(stderr,"error: flexframesync_decode_header(), could not re-allocate payload arrays\n");
            _q->header_valid = 0;
            return;
        }
    }
    
#if DEBUG_FLEXFRAMESYNC_PRINT
    // print results
    printf("flexframesync_decode_header():\n");
    printf("    header crc      : %s\n", _q->header_valid ? "pass" : "FAIL");
    printf("    check           : %s\n", crc_scheme_str[check][1]);
    printf("    fec (inner)     : %s\n", fec_scheme_str[fec0][1]);
    printf("    fec (outer)     : %s\n", fec_scheme_str[fec1][1]);
    printf("    mod scheme      : %s\n", modulation_types[mod_scheme].name);
    printf("    payload dec len : %u\n", _q->payload_dec_len);
    printf("    payload enc len : %u\n", _q->payload_enc_len);
    printf("    payload mod len : %u\n", _q->payload_mod_len);

    printf("    user data       :");
    for (i=0; i<FLEXFRAME_H_USER; i++)
        printf(" %.2x", _q->header[i]);
    printf("\n");
#endif
}
Exemplo n.º 2
0
// decode header
void ofdmflexframesync_decode_header(ofdmflexframesync _q)
{
#if OFDMFLEXFRAME_H_SOFT
#  if 0
    unsigned int i;
    // copy soft bits
    for (i=0; i<8*OFDMFLEXFRAME_H_ENC; i++)
        _q->header_enc[i] = _q->header_mod[i];
#  else
    // TODO: ensure lengths are the same
    memmove(_q->header_enc, _q->header_mod, 8*OFDMFLEXFRAME_H_ENC);
#  endif

    // unscramble header using soft bits
    unscramble_data_soft(_q->header_enc, OFDMFLEXFRAME_H_ENC);

    // run packet decoder
    _q->header_valid = packetizer_decode_soft(_q->p_header, _q->header_enc, _q->header);
#else
    // pack 1-bit header symbols into 8-bit bytes
    unsigned int num_written;
    liquid_repack_bytes(_q->header_mod, OFDMFLEXFRAME_H_BPS, OFDMFLEXFRAME_H_SYM,
                        _q->header_enc, 8,                   OFDMFLEXFRAME_H_ENC,
                        &num_written);
    assert(num_written==OFDMFLEXFRAME_H_ENC);

    // unscramble header
    unscramble_data(_q->header_enc, OFDMFLEXFRAME_H_ENC);

    // run packet decoder
    _q->header_valid = packetizer_decode(_q->p_header, _q->header_enc, _q->header);
#endif

#if 0
    // print header
    printf("header rx (enc) : ");
    for (i=0; i<OFDMFLEXFRAME_H_ENC; i++)
        printf("%.2X ", _q->header_enc[i]);
    printf("\n");

    // print header
    printf("header rx (dec) : ");
    for (i=0; i<OFDMFLEXFRAME_H_DEC; i++)
        printf("%.2X ", _q->header[i]);
    printf("\n");
#endif

#if DEBUG_OFDMFLEXFRAMESYNC
    printf("****** header extracted [%s]\n", _q->header_valid ? "valid" : "INVALID!");
#endif
    if (!_q->header_valid)
        return;

    unsigned int n = OFDMFLEXFRAME_H_USER;

    // first byte is for expansion/version validation
    if (_q->header[n+0] != OFDMFLEXFRAME_PROTOCOL) {
        fprintf(stderr,"warning: ofdmflexframesync_decode_header(), invalid framing version\n");
        _q->header_valid = 0;
    }

    // strip off payload length
    unsigned int payload_len = (_q->header[n+1] << 8) | (_q->header[n+2]);

    // strip off modulation scheme/depth
    unsigned int mod_scheme = _q->header[n+3];
    if (mod_scheme == 0 || mod_scheme >= LIQUID_MODEM_NUM_SCHEMES) {
        fprintf(stderr,"warning: ofdmflexframesync_decode_header(), invalid modulation scheme\n");
        _q->header_valid = 0;
        return;
    }

    // strip off CRC, forward error-correction schemes
    //  CRC     : most-significant 3 bits of [n+4]
    //  fec0    : least-significant 5 bits of [n+4]
    //  fec1    : least-significant 5 bits of [n+5]
    unsigned int check = (_q->header[n+4] >> 5 ) & 0x07;
    unsigned int fec0  = (_q->header[n+4]      ) & 0x1f;
    unsigned int fec1  = (_q->header[n+5]      ) & 0x1f;

    // validate properties
    if (check >= LIQUID_CRC_NUM_SCHEMES) {
        fprintf(stderr,"warning: ofdmflexframesync_decode_header(), decoded CRC exceeds available\n");
        check = LIQUID_CRC_UNKNOWN;
        _q->header_valid = 0;
    }
    if (fec0 >= LIQUID_FEC_NUM_SCHEMES) {
        fprintf(stderr,"warning: ofdmflexframesync_decode_header(), decoded FEC (inner) exceeds available\n");
        fec0 = LIQUID_FEC_UNKNOWN;
        _q->header_valid = 0;
    }
    if (fec1 >= LIQUID_FEC_NUM_SCHEMES) {
        fprintf(stderr,"warning: ofdmflexframesync_decode_header(), decoded FEC (outer) exceeds available\n");
        fec1 = LIQUID_FEC_UNKNOWN;
        _q->header_valid = 0;
    }

    // print results
#if DEBUG_OFDMFLEXFRAMESYNC
    printf("    properties:\n");
    printf("      * mod scheme      :   %s\n", modulation_types[mod_scheme].fullname);
    printf("      * fec (inner)     :   %s\n", fec_scheme_str[fec0][1]);
    printf("      * fec (outer)     :   %s\n", fec_scheme_str[fec1][1]);
    printf("      * CRC scheme      :   %s\n", crc_scheme_str[check][1]);
    printf("      * payload length  :   %u bytes\n", payload_len);
#endif

    // configure payload receiver
    if (_q->header_valid) {
        // configure modem
        if (mod_scheme != _q->ms_payload) {
            // set new properties
            _q->ms_payload  = mod_scheme;
            _q->bps_payload = modulation_types[mod_scheme].bps;

            // recreate modem (destroy/create)
            _q->mod_payload = modem_recreate(_q->mod_payload, _q->ms_payload);
        }

        // set new packetizer properties
        _q->payload_len = payload_len;
        _q->check       = check;
        _q->fec0        = fec0;
        _q->fec1        = fec1;

        // recreate packetizer object
        _q->p_payload = packetizer_recreate(_q->p_payload,
                                            _q->payload_len,
                                            _q->check,
                                            _q->fec0,
                                            _q->fec1);

        // re-compute payload encoded message length
        _q->payload_enc_len = packetizer_get_enc_msg_len(_q->p_payload);
#if DEBUG_OFDMFLEXFRAMESYNC
        printf("      * payload encoded :   %u bytes\n", _q->payload_enc_len);
#endif

        // re-allocate buffers accordingly
        _q->payload_enc = (unsigned char*) realloc(_q->payload_enc, _q->payload_enc_len*sizeof(unsigned char));
        _q->payload_dec = (unsigned char*) realloc(_q->payload_dec, _q->payload_len*sizeof(unsigned char));

        // re-compute number of modulated payload symbols
        div_t d = div(8*_q->payload_enc_len, _q->bps_payload);
        _q->payload_mod_len = d.quot + (d.rem ? 1 : 0);
#if DEBUG_OFDMFLEXFRAMESYNC
        printf("      * payload mod syms:   %u symbols\n", _q->payload_mod_len);
#endif
    }
}
Exemplo n.º 3
0
int main(int argc, char*argv[]) {
    // options
    unsigned int n=8;                       // original data message length
    crc_scheme check = LIQUID_CRC_32;       // data integrity check
    fec_scheme fec0 = LIQUID_FEC_HAMMING74; // inner code
    fec_scheme fec1 = LIQUID_FEC_NONE;      // outer code

    // read command-line options
    int dopt;
    while((dopt = getopt(argc,argv,"uhn:v:c:k:")) != EOF){
        switch (dopt) {
        case 'h':
        case 'u': usage(); return 0;
        case 'n':
            n = atoi(optarg);
            if (n < 1) {
                printf("error: packet length must be positive\n");
                usage();
                exit(-1);
            }
            break;
        case 'v':
            // data integrity check
            check = liquid_getopt_str2crc(optarg);
            if (check == LIQUID_CRC_UNKNOWN) {
                fprintf(stderr,"error: unknown/unsupported CRC scheme \"%s\"\n\n",optarg);
                exit(1);
            }
            break;
        case 'c':
            // inner FEC scheme
            fec0 = liquid_getopt_str2fec(optarg);
            if (fec0 == LIQUID_FEC_UNKNOWN) {
                fprintf(stderr,"error: unknown/unsupported inner FEC scheme \"%s\"\n\n",optarg);
                exit(1);
            }
            break;
        case 'k':
            // outer FEC scheme
            fec1 = liquid_getopt_str2fec(optarg);
            if (fec1 == LIQUID_FEC_UNKNOWN) {
                fprintf(stderr,"error: unknown/unsupported outer FEC scheme \"%s\"\n\n",optarg);
                exit(1);
            }
            break;
        default:
            exit(1);
        }
    }

    unsigned int i;
    unsigned int k = packetizer_compute_enc_msg_len(n,check,fec0,fec1);
    packetizer p = packetizer_create(n,check,fec0,fec1);
    packetizer_print(p);

    // initialize arrays
    unsigned char msg_org[n];   // original message
    unsigned char msg_enc[k];   // encoded message
    unsigned char msg_rec[8*k]; // recieved message (soft bits)
    unsigned char msg_dec[n];   // decoded message
    int crc_pass;

    // initialize original data message
    for (i=0; i<n; i++)
        msg_org[i] = rand() % 256;

    // encode packet
    packetizer_encode(p,msg_org,msg_enc);

    // convert to soft bits and add 'noise'
    for (i=0; i<k; i++) {
        msg_rec[8*i+0] = (msg_enc[i] & 0x80) ? 255 : 0;
        msg_rec[8*i+1] = (msg_enc[i] & 0x40) ? 255 : 0;
        msg_rec[8*i+2] = (msg_enc[i] & 0x20) ? 255 : 0;
        msg_rec[8*i+3] = (msg_enc[i] & 0x10) ? 255 : 0;
        msg_rec[8*i+4] = (msg_enc[i] & 0x08) ? 255 : 0;
        msg_rec[8*i+5] = (msg_enc[i] & 0x04) ? 255 : 0;
        msg_rec[8*i+6] = (msg_enc[i] & 0x02) ? 255 : 0;
        msg_rec[8*i+7] = (msg_enc[i] & 0x01) ? 255 : 0;
    }

    // flip first bit (ensure error)
    msg_rec[0] = 255 - msg_rec[0];

    // add noise (but not so much that it would cause a bit error)
    for (i=0; i<8*k; i++) {
        int soft_bit = msg_rec[i] + (int)(20*randnf());
        if (soft_bit > 255) soft_bit = 255;
        if (soft_bit <   0) soft_bit = 0;
        msg_rec[i] = soft_bit;
    }

    // decode packet
    crc_pass =
    packetizer_decode_soft(p,msg_rec,msg_dec);

    // clean up allocated objects
    packetizer_destroy(p);

    // print results
    printf("original message:  [%3u] ",n);
    for (i=0; i<n; i++)
        printf(" %.2X", (unsigned int) (msg_org[i]));
    printf("\n");

    printf("encoded message:   [%3u] ",k);
    for (i=0; i<k; i++)
        printf(" %.2X", (unsigned int) (msg_enc[i]));
    printf("\n");

#if 0
    printf("received message:  [%3u] ",k);
    for (i=0; i<k; i++)
        printf("%c%.2X", msg_rec[i]==msg_enc[i] ? ' ' : '*', (unsigned int) (msg_rec[i]));
    printf("\n");
#endif

    //if (verbose) {
    if (1) {
        // print expanded result (print each soft bit value)
        for (i=0; i<k; i++) {
            unsigned char msg_cor_hard = 0x00;
            printf("%5u: ", i);
            unsigned int j;
            for (j=0; j<8; j++) {
                msg_cor_hard |= (msg_rec[8*i+j] > 127) ? 1<<(8-j-1) : 0;
                unsigned int bit_enc = (msg_enc[i] >> (8-j-1)) & 0x01;
                unsigned int bit_rec = (msg_rec[8*i+j] > 127) ? 1 : 0;
                //printf("%1u %3u (%1u) %c", bit_enc, msg_rec[i], bit_rec, bit_enc != bit_rec ? '*' : ' ');
                printf("%4u%c", msg_rec[8*i+j], bit_enc != bit_rec ? '*' : ' ');
            }
            printf("  :  %c%.2X\n", msg_cor_hard==msg_enc[i] ? ' ' : '*', (unsigned int) (msg_cor_hard));
        }
    } // verbose


    printf("decoded message:   [%3u] ",n);
    for (i=0; i<n; i++)
        printf("%c%.2X", msg_dec[i] == msg_org[i] ? ' ' : '*', (unsigned int) (msg_dec[i]));
    printf("\n");
    printf("\n");

    // count bit errors
    unsigned int num_sym_errors=0;
    unsigned int num_bit_errors=0;
    for (i=0; i<n; i++) {
        num_sym_errors += (msg_org[i] == msg_dec[i]) ? 0 : 1;

        num_bit_errors += count_bit_errors(msg_org[i], msg_dec[i]);
    }

    //printf("number of symbol errors detected: %d\n", num_errors_detected);
    printf("number of symbol errors received: %4u / %4u\n", num_sym_errors, n);
    printf("number of bit errors received:    %4u / %4u\n", num_bit_errors, n*8);

    if (crc_pass)
        printf("(crc passed)\n");
    else
        printf("(crc failed)\n");

    return 0;
}