// execute synchronizer, receiving header // _q : frame synchronizer object // _x : input sample // _sym : demodulated symbol void flexframesync_execute_rxheader(flexframesync _q, float complex _x) { // step synchronizer float complex mf_out = 0.0f; int sample_available = flexframesync_step(_q, _x, &mf_out); // compute output if timeout if (sample_available) { // save payload symbols (modem input/output) _q->header_sym[_q->symbol_counter] = mf_out; // increment counter _q->symbol_counter++; if (_q->symbol_counter == _q->header_sym_len) { // decode header flexframesync_decode_header(_q); if (_q->header_valid) { // continue on to decoding payload _q->symbol_counter = 0; _q->state = FLEXFRAMESYNC_STATE_RXPAYLOAD; return; } // update statistics _q->framedatastats.num_frames_detected++; // header invalid: invoke callback if (_q->callback != NULL) { // set framestats internals _q->framesyncstats.evm = 0.0f; //20*log10f(sqrtf(_q->framesyncstats.evm / 600)); _q->framesyncstats.rssi = 20*log10f(_q->gamma_hat); _q->framesyncstats.cfo = nco_crcf_get_frequency(_q->mixer); _q->framesyncstats.framesyms = NULL; _q->framesyncstats.num_framesyms = 0; _q->framesyncstats.mod_scheme = LIQUID_MODEM_UNKNOWN; _q->framesyncstats.mod_bps = 0; _q->framesyncstats.check = LIQUID_CRC_UNKNOWN; _q->framesyncstats.fec0 = LIQUID_FEC_UNKNOWN; _q->framesyncstats.fec1 = LIQUID_FEC_UNKNOWN; // invoke callback method _q->callback(_q->header_dec, _q->header_valid, NULL, // payload 0, // payload length 0, // payload valid, _q->framesyncstats, _q->userdata); } // reset frame synchronizer flexframesync_reset(_q); return; } } }
// execute synchronizer, receiving header // _q : frame synchronizer object // _x : input sample void flexframesync_execute_rxheader(flexframesync _q, float complex _x) { // mix signal down float complex y; nco_crcf_mix_down(_q->nco_coarse, _x*0.5f/_q->gamma_hat, &y); nco_crcf_step(_q->nco_coarse); // update symbol synchronizer float complex mf_out = 0.0f; int sample_available = flexframesync_update_symsync(_q, y, &mf_out); // compute output if timeout if (sample_available) { // push through fine-tuned nco nco_crcf_mix_down(_q->nco_fine, mf_out, &mf_out); #if DEBUG_FLEXFRAMESYNC if (_q->debug_enabled) _q->header_sym[_q->header_counter] = mf_out; #endif // demodulate unsigned int sym_out = 0; #if DEMOD_HEADER_SOFT unsigned char bpsk_soft_bit = 0; modem_demodulate_soft(_q->demod_header, mf_out, &sym_out, &bpsk_soft_bit); _q->header_mod[_q->header_counter] = bpsk_soft_bit; #else modem_demodulate(_q->demod_header, mf_out, &sym_out); _q->header_mod[_q->header_counter] = (unsigned char)sym_out; #endif // update phase-locked loop and fine-tuned NCO float phase_error = modem_get_demodulator_phase_error(_q->demod_header); nco_crcf_pll_step(_q->nco_fine, phase_error); nco_crcf_step(_q->nco_fine); // update error vector magnitude float evm = modem_get_demodulator_evm(_q->demod_header); _q->framestats.evm += evm*evm; // increment counter _q->header_counter++; if (_q->header_counter == FLEXFRAME_H_SYM) { // decode header and invoke callback flexframesync_decode_header(_q); // invoke callback if header is invalid if (!_q->header_valid && _q->callback != NULL) { // set framestats internals _q->framestats.evm = 20*log10f(sqrtf(_q->framestats.evm / FLEXFRAME_H_SYM)); _q->framestats.rssi = 20*log10f(_q->gamma_hat); _q->framestats.cfo = nco_crcf_get_frequency(_q->nco_coarse) + nco_crcf_get_frequency(_q->nco_fine) / 2.0f; //(float)(_q->k); _q->framestats.framesyms = NULL; _q->framestats.num_framesyms = 0; _q->framestats.mod_scheme = LIQUID_MODEM_UNKNOWN; _q->framestats.mod_bps = 0; _q->framestats.check = LIQUID_CRC_UNKNOWN; _q->framestats.fec0 = LIQUID_FEC_UNKNOWN; _q->framestats.fec1 = LIQUID_FEC_UNKNOWN; // invoke callback method _q->callback(_q->header, _q->header_valid, NULL, 0, 0, _q->framestats, _q->userdata); } if (!_q->header_valid) { flexframesync_reset(_q); return; } // update state _q->state = STATE_RXPAYLOAD; } } }