testing branch
parent
6ed880ec7f
commit
ec7246136e
|
@ -8,7 +8,7 @@
|
|||
#ifndef INCLUDED_M17_M17_CODER_H
|
||||
#define INCLUDED_M17_M17_CODER_H
|
||||
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/sync_interpolator.h>
|
||||
#include <gnuradio/m17/api.h>
|
||||
|
||||
namespace gr {
|
||||
|
@ -19,7 +19,7 @@ namespace m17 {
|
|||
* \ingroup m17
|
||||
*
|
||||
*/
|
||||
class M17_API m17_coder : virtual public gr::block
|
||||
class M17_API m17_coder : virtual public gr::sync_interpolator
|
||||
{
|
||||
public:
|
||||
typedef std::shared_ptr<m17_coder> sptr;
|
||||
|
|
|
@ -24,8 +24,10 @@ list(APPEND m17_sources
|
|||
../M17_Implementations/libm17/math/rrc.c
|
||||
../M17_Implementations/libm17/payload/call.c
|
||||
../M17_Implementations/libm17/payload/crc.c
|
||||
../M17_Implementations/libm17/payload/lich.c
|
||||
../M17_Implementations/libm17/phy/interleave.c
|
||||
../M17_Implementations/libm17/phy/randomize.c
|
||||
../M17_Implementations/libm17/phy/slice.c
|
||||
../M17_Implementations/libm17/phy/sync.c
|
||||
)
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define GRC_DEBUG
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
@ -35,34 +37,32 @@
|
|||
namespace gr {
|
||||
namespace m17 {
|
||||
|
||||
struct LSF lsf;
|
||||
|
||||
m17_coder::sptr
|
||||
m17_coder::make(std::string src_id,std::string dst_id,short type,std::string meta, bool debug)
|
||||
{
|
||||
return gnuradio::get_initial_sptr
|
||||
(new m17_coder_impl(src_id,dst_id,type,meta,debug));
|
||||
return gnuradio::make_block_sptr<m17_coder_impl>(src_id,dst_id,type,meta,debug);
|
||||
}
|
||||
|
||||
/*
|
||||
* The private constructor
|
||||
*/
|
||||
m17_coder_impl::m17_coder_impl(std::string src_id,std::string dst_id,short type,std::string meta, bool debug)
|
||||
: gr::block("m17_coder",
|
||||
: gr::sync_interpolator("m17_coder",
|
||||
gr::io_signature::make(1, 1, sizeof(char)),
|
||||
gr::io_signature::make(1, 1, sizeof(float)))
|
||||
gr::io_signature::make(1, 1, sizeof(float)),
|
||||
12) // interpolation factor // 192/16
|
||||
, _meta(meta),_type(type), _debug(debug)
|
||||
{ set_meta(meta);
|
||||
{ set_debug(debug);
|
||||
set_meta(meta);
|
||||
set_src_id(src_id);
|
||||
set_dst_id(dst_id);
|
||||
set_type(type);
|
||||
set_debug(debug);
|
||||
set_output_multiple(192);
|
||||
uint16_t ccrc=LSF_CRC(&lsf);
|
||||
lsf.crc[0]=ccrc>>8;
|
||||
lsf.crc[1]=ccrc&0xFF;
|
||||
_got_lsf=0; //have we filled the LSF struct yet?
|
||||
_fn=0; //16-bit Frame Number (for the stream mode)
|
||||
_countin=0;
|
||||
_countout=0;
|
||||
_lich_cnt=0;
|
||||
}
|
||||
|
||||
void m17_coder_impl::set_debug(bool debug)
|
||||
|
@ -75,11 +75,16 @@ void m17_coder_impl::set_src_id(std::string src_id)
|
|||
for (int i=0;i<10;i++) {_src_id[i]=0;}
|
||||
if (src_id.length()>9) length=9; else length=src_id.length();
|
||||
for (int i=0;i<length;i++) {_src_id[i]=toupper(src_id.c_str()[i]);}
|
||||
encode_callsign_bytes(lsf.src, _src_id); // 6 byte ID <- 9 char callsign
|
||||
encode_callsign_bytes(_lsf.src, _src_id); // 6 byte ID <- 9 char callsign
|
||||
|
||||
uint16_t ccrc=LSF_CRC(&lsf);
|
||||
lsf.crc[0]=ccrc>>8;
|
||||
lsf.crc[1]=ccrc&0xFF;
|
||||
uint16_t ccrc=LSF_CRC(&_lsf);
|
||||
_lsf.crc[0]=ccrc>>8;
|
||||
_lsf.crc[1]=ccrc&0xFF;
|
||||
if (_debug==true)
|
||||
{printf("src id:%s ->",src_id.c_str());
|
||||
for (int k=0;k<6;k++) printf(" %hhx",_lsf.src[k]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void m17_coder_impl::set_dst_id(std::string dst_id)
|
||||
|
@ -87,10 +92,15 @@ void m17_coder_impl::set_dst_id(std::string dst_id)
|
|||
for (int i=0;i<10;i++) {_dst_id[i]=0;}
|
||||
if (dst_id.length()>9) length=9; else length=dst_id.length();
|
||||
for (int i=0;i<length;i++) {_dst_id[i]=toupper(dst_id.c_str()[i]);}
|
||||
encode_callsign_bytes(lsf.dst, _dst_id); // 6 byte ID <- 9 char callsign
|
||||
uint16_t ccrc=LSF_CRC(&lsf);
|
||||
lsf.crc[0]=ccrc>>8;
|
||||
lsf.crc[1]=ccrc&0xFF;
|
||||
encode_callsign_bytes(_lsf.dst, _dst_id); // 6 byte ID <- 9 char callsign
|
||||
uint16_t ccrc=LSF_CRC(&_lsf);
|
||||
_lsf.crc[0]=ccrc>>8;
|
||||
_lsf.crc[1]=ccrc&0xFF;
|
||||
if (_debug==true)
|
||||
{printf("dst id:%s ->",dst_id.c_str());
|
||||
for (int k=0;k<6;k++) printf(" %hhx",_lsf.dst[k]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void m17_coder_impl::set_meta(std::string meta)
|
||||
|
@ -98,20 +108,20 @@ void m17_coder_impl::set_meta(std::string meta)
|
|||
printf("new meta: %s\n",meta.c_str());fflush(stdout);
|
||||
_meta.assign(meta);
|
||||
if (meta.length()<14) length=meta.length(); else length=14;
|
||||
for (int i=0;i<length;i++) {lsf.meta[i]=_meta[i];}
|
||||
uint16_t ccrc=LSF_CRC(&lsf);
|
||||
lsf.crc[0]=ccrc>>8;
|
||||
lsf.crc[1]=ccrc&0xFF;
|
||||
for (int i=0;i<length;i++) {_lsf.meta[i]=_meta[i];}
|
||||
uint16_t ccrc=LSF_CRC(&_lsf);
|
||||
_lsf.crc[0]=ccrc>>8;
|
||||
_lsf.crc[1]=ccrc&0xFF;
|
||||
}
|
||||
|
||||
void m17_coder_impl::set_type(short type)
|
||||
{_type=type;
|
||||
lsf.type[0]=_type>>8; // MSB
|
||||
lsf.type[1]=_type&0xff; // LSB
|
||||
uint16_t ccrc=LSF_CRC(&lsf);
|
||||
lsf.crc[0]=ccrc>>8;
|
||||
lsf.crc[1]=ccrc&0xFF;
|
||||
printf("new type: %hhd %hhd\n",lsf.type[1],lsf.type[0]);fflush(stdout);
|
||||
_lsf.type[0]=_type>>8; // MSB
|
||||
_lsf.type[1]=_type&0xff; // LSB
|
||||
uint16_t ccrc=LSF_CRC(&_lsf);
|
||||
_lsf.crc[0]=ccrc>>8;
|
||||
_lsf.crc[1]=ccrc&0xFF;
|
||||
printf("new type: %hhd%hhd\n",_lsf.type[0],_lsf.type[1]);fflush(stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -128,27 +138,144 @@ void m17_coder_impl::set_type(short type)
|
|||
}
|
||||
|
||||
int
|
||||
m17_coder_impl::general_work (int noutput_items,
|
||||
gr_vector_int &ninput_items,
|
||||
m17_coder_impl::work (int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
const char *in = (const char *) input_items[0];
|
||||
float *out = (float *) output_items[0];
|
||||
|
||||
int countin=0;
|
||||
uint32_t countout=0;
|
||||
|
||||
uint8_t enc_bits[SYM_PER_PLD*2]; //type-2 bits, unpacked
|
||||
uint8_t rf_bits[SYM_PER_PLD*2]; //type-4 bits, unpacked
|
||||
uint8_t lich[6]; //48 bits packed raw, unencoded LICH
|
||||
uint8_t lich_encoded[12]; //96 bits packed, encoded LICH
|
||||
|
||||
uint8_t data[16]; //raw payload, packed bits
|
||||
uint8_t lich_cnt=0; //0..5 LICH counter, derived from the Frame Number
|
||||
|
||||
while (countout<(uint32_t)noutput_items) {
|
||||
if (countin+16<=noutput_items)
|
||||
uint8_t data[16]; //raw payload, packed bits
|
||||
//debug
|
||||
//printf("%06X\n", golay24_encode(1)); //golay encoder codeword test
|
||||
//printf("%d -> %d -> %d\n", 1, intrl_seq[1], intrl_seq[intrl_seq[1]]); //interleaver bijective reciprocality test, f(f(x))=x
|
||||
//return 0;
|
||||
_countin=0;
|
||||
_countout=0;
|
||||
#ifdef GRC_DEBUG
|
||||
printf("first item: %x %x %x ",in[0],in[1],in[2]);
|
||||
#endif
|
||||
while (_countout+16<=(uint32_t)noutput_items) {
|
||||
// memcpy(&_next_lsf.dst,&in[_countin],6); _countin+=6;
|
||||
// memcpy(&_next_lsf.src,&in[_countin],6); _countin+=6;
|
||||
// memcpy(&_next_lsf.type,&in[_countin],2); _countin+=2;
|
||||
// memcpy(&_next_lsf.meta,&in[_countin],14); _countin+=14;
|
||||
memcpy(data,&in[_countin],16); _countin+=16;
|
||||
if(_lich_cnt == 0)
|
||||
{
|
||||
// _lsf = _next_lsf; // JMF cannot understand this
|
||||
|
||||
//calculate LSF CRC
|
||||
uint16_t ccrc=LSF_CRC(&_lsf);
|
||||
_lsf.crc[0]=ccrc>>8;
|
||||
_lsf.crc[1]=ccrc&0xFF;
|
||||
}
|
||||
|
||||
if(_got_lsf) //stream frames
|
||||
{
|
||||
//send stream frame syncword
|
||||
send_syncword(&out[_countout], &_countout, SYNC_STR);
|
||||
|
||||
//extract LICH from the whole LSF
|
||||
extract_LICH(lich, _lich_cnt, &_lsf);
|
||||
|
||||
//encode the LICH
|
||||
encode_LICH(lich_encoded, lich);
|
||||
|
||||
//unpack LICH (12 bytes)
|
||||
unpack_LICH(enc_bits, lich_encoded);
|
||||
|
||||
//encode the rest of the frame (starting at bit 96 - 0..95 are filled with LICH)
|
||||
conv_encode_stream_frame(&enc_bits[96], data, (_fn | 0x8000) );
|
||||
|
||||
//reorder bits
|
||||
reorder_bits(rf_bits, enc_bits);
|
||||
|
||||
//randomize
|
||||
randomize_bits(rf_bits);
|
||||
|
||||
//send dummy symbols (debug)
|
||||
/*float s=0.0;
|
||||
for(uint8_t i=0; i<SYM_PER_PLD; i++) //40ms * 4800 - 8 (syncword)
|
||||
fwrite((uint8_t*)&s, sizeof(float), 1, stdout);*/
|
||||
|
||||
//send frame data
|
||||
send_data(&out[_countout], &_countout, rf_bits);
|
||||
// fwrite((uint8_t*)frame_buff, SYM_PER_FRA*sizeof(float), 1, stdout);
|
||||
|
||||
/* if (_debug==true)
|
||||
{printf("\tTX DATA: ");
|
||||
for(uint8_t i=0; i<16; i++)
|
||||
printf("%02X", data[i]);
|
||||
printf("\n");
|
||||
}
|
||||
*/
|
||||
|
||||
//increment the Frame Number
|
||||
_fn = (_fn + 1) % 0x8000;
|
||||
|
||||
//increment the LICH counter
|
||||
_lich_cnt = (_lich_cnt + 1) % 6;
|
||||
|
||||
//debug-only
|
||||
#ifdef FN60_DEBUG
|
||||
if(_fn==6*10)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
else //LSF
|
||||
{
|
||||
_got_lsf=1;
|
||||
|
||||
//send out the preamble
|
||||
send_preamble(&out[_countout], &_countout, 0); //0 - LSF preamble, as opposed to 1 - BERT preamble
|
||||
|
||||
//send LSF syncword
|
||||
send_syncword(&out[_countout], &_countout, SYNC_LSF);
|
||||
|
||||
//encode LSF data
|
||||
conv_encode_LSF(enc_bits, &_lsf);
|
||||
|
||||
//reorder bits
|
||||
reorder_bits(rf_bits, enc_bits);
|
||||
|
||||
//randomize
|
||||
randomize_bits(rf_bits);
|
||||
|
||||
//send LSF data
|
||||
send_data(&out[_countout], &_countout, rf_bits);
|
||||
|
||||
//send dummy symbols (debug)
|
||||
/*float s=0.0;
|
||||
for(uint8_t i=0; i<184; i++) //40ms * 4800 - 8 (syncword)
|
||||
write((uint8_t*)&s, sizeof(float), 1, stdout);*/
|
||||
|
||||
if (_debug==true)
|
||||
{printf("TX DST: ");
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
printf("%02X", _lsf.dst[i]);
|
||||
printf(" SRC: ");
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
printf("%02X", _lsf.src[i]);
|
||||
printf(" TYPE: ");
|
||||
for(uint8_t i=0; i<2; i++)
|
||||
printf("%02X", _lsf.type[i]);
|
||||
printf(" META: ");
|
||||
for(uint8_t i=0; i<14; i++)
|
||||
printf("%02X", _lsf.meta[i]);
|
||||
printf(" CRC: ");
|
||||
for(uint8_t i=0; i<2; i++)
|
||||
printf("%02X", _lsf.crc[i]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
{if(_got_lsf) //stream frames
|
||||
{
|
||||
//we could discard the data we already have
|
||||
|
@ -265,9 +392,9 @@ void m17_coder_impl::set_type(short type)
|
|||
}
|
||||
|
||||
//send dummy symbols (debug)
|
||||
/*float s=0.0;
|
||||
for(uint8_t i=0; i<SYM_PER_PLD; i++) //40ms * 4800 - 8 (syncword)
|
||||
write(STDOUT_FILENO, (uint8_t*)&s, sizeof(float));*/
|
||||
// float s=0.0;
|
||||
// for(uint8_t i=0; i<SYM_PER_PLD; i++) //40ms * 4800 - 8 (syncword)
|
||||
// write(STDOUT_FILENO, (uint8_t*)&s, sizeof(float));
|
||||
|
||||
float s;
|
||||
for(uint16_t i=0; i<SYM_PER_PLD; i++) //40ms * 4800 - 8 (syncword)
|
||||
|
@ -278,10 +405,10 @@ void m17_coder_impl::set_type(short type)
|
|||
countout++;
|
||||
}
|
||||
|
||||
/*printf("\tDATA: ");
|
||||
for(uint8_t i=0; i<16; i++)
|
||||
printf("%02X", data[i]);
|
||||
printf("\n");*/
|
||||
// printf("\tDATA: ");
|
||||
// for(uint8_t i=0; i<16; i++)
|
||||
// printf("%02X", data[i]);
|
||||
// printf("\n");
|
||||
|
||||
//increment the Frame Number
|
||||
_fn = (_fn + 1) % 0x8000;
|
||||
|
@ -336,32 +463,34 @@ void m17_coder_impl::set_type(short type)
|
|||
countout++;
|
||||
}
|
||||
|
||||
/*printf("DST: ");
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
printf("%02X", lsf.dst[i]);
|
||||
printf(" SRC: ");
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
printf("%02X", lsf.src[i]);
|
||||
printf(" TYPE: ");
|
||||
for(uint8_t i=0; i<2; i++)
|
||||
printf("%02X", lsf.type[i]);
|
||||
printf(" META: ");
|
||||
for(uint8_t i=0; i<14; i++)
|
||||
printf("%02X", lsf.meta[i]);
|
||||
printf(" CRC: ");
|
||||
for(uint8_t i=0; i<2; i++)
|
||||
printf("%02X", lsf.crc[i]);
|
||||
printf("\n");*/
|
||||
// printf("DST: ");
|
||||
// for(uint8_t i=0; i<6; i++)
|
||||
// printf("%02X", lsf.dst[i]);
|
||||
// printf(" SRC: ");
|
||||
// for(uint8_t i=0; i<6; i++)
|
||||
// printf("%02X", lsf.src[i]);
|
||||
// printf(" TYPE: ");
|
||||
// for(uint8_t i=0; i<2; i++)
|
||||
// printf("%02X", lsf.type[i]);
|
||||
// printf(" META: ");
|
||||
// for(uint8_t i=0; i<14; i++)
|
||||
// printf("%02X", lsf.meta[i]);
|
||||
// printf(" CRC: ");
|
||||
// for(uint8_t i=0; i<2; i++)
|
||||
// printf("%02X", lsf.crc[i]);
|
||||
// printf("\n");
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
// Tell runtime system how many input items we consumed on
|
||||
// each input stream.
|
||||
consume_each (countin);
|
||||
// printf(" noutput_items=%d countin=%d countout=%d\n",noutput_items,countin,countout);
|
||||
#ifdef GRC_DEBUG
|
||||
printf("last item: %x %x -> coutin %d/noutput_items %d countout %d\n",in[_countin],in[_countin+1],_countin,noutput_items,_countout);
|
||||
#endif
|
||||
consume_each (_countin);
|
||||
// Tell runtime system how many output items we produced.
|
||||
return countout;
|
||||
}
|
||||
|
||||
return _countout;
|
||||
}
|
||||
} /* namespace m17 */
|
||||
} /* namespace gr */
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#define INCLUDED_M17_M17_CODER_IMPL_H
|
||||
|
||||
#include <gnuradio/m17/m17_coder.h>
|
||||
#include "m17.h" // struct lsf declaration
|
||||
|
||||
namespace gr {
|
||||
namespace m17 {
|
||||
|
@ -22,7 +23,11 @@ private:
|
|||
int _got_lsf=0;
|
||||
uint16_t _fn=0; //16-bit Frame Number (for the stream mode)
|
||||
bool _debug=0;
|
||||
|
||||
struct LSF _lsf, _next_lsf;
|
||||
int _countin=0;
|
||||
uint32_t _countout=0;
|
||||
uint8_t _lich_cnt=0; //0..5 LICH counter
|
||||
uint32_t _frame_buff_cnt;
|
||||
|
||||
public:
|
||||
void set_src_id(std::string src_id);
|
||||
|
@ -36,10 +41,9 @@ public:
|
|||
// Where all the action really happens
|
||||
void forecast(int noutput_items, gr_vector_int& ninput_items_required);
|
||||
|
||||
int general_work(int noutput_items,
|
||||
gr_vector_int& ninput_items,
|
||||
gr_vector_const_void_star& input_items,
|
||||
gr_vector_void_star& output_items);
|
||||
int work(int noutput_items,
|
||||
gr_vector_const_void_star& input_items,
|
||||
gr_vector_void_star& output_items);
|
||||
};
|
||||
|
||||
} // namespace m17
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// TODO : replace DIST_THRESHOLD with threshold (argument)
|
||||
|
||||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2023 jmfriedt.
|
||||
|
@ -33,9 +35,8 @@
|
|||
|
||||
#include "m17.h"
|
||||
|
||||
#define DECODE_CALLSIGNS
|
||||
//#define SHOW_VITERBI_ERRS
|
||||
//
|
||||
//#define DECODE_CALLSIGNS
|
||||
#define SHOW_VITERBI_ERRS
|
||||
|
||||
#define CODE_MEAN -0.75 // mean(str_sync_symbols)
|
||||
#define CODE_STD 8.21583836f //std(str_sync_symbols)*sqrt(length(str_sync_symbols)-1)
|
||||
|
@ -111,6 +112,31 @@ namespace gr {
|
|||
//wait for another symbol
|
||||
sample=in[counterin];
|
||||
|
||||
/*
|
||||
float sample; //last raw sample from the stdin
|
||||
float last[8]; //look-back buffer for finding syncwords
|
||||
float dist; //Euclidean distance for finding syncwords in the symbol stream
|
||||
float pld[SYM_PER_PLD]; //raw frame symbols
|
||||
uint16_t soft_bit[2*SYM_PER_PLD]; //raw frame soft bits
|
||||
uint16_t d_soft_bit[2*SYM_PER_PLD]; //deinterleaved soft bits
|
||||
|
||||
uint8_t lsf[30+1]; //complete LSF (one byte extra needed for the Viterbi decoder)
|
||||
uint16_t lich_chunk[96]; //raw, soft LSF chunk extracted from the LICH
|
||||
uint8_t lich_b[6]; //48-bit decoded LICH
|
||||
uint8_t lich_cnt; //LICH_CNT
|
||||
uint8_t lich_chunks_rcvd=0; //flags set for each LSF chunk received
|
||||
uint16_t expected_next_fn=0; //frame number of the next frame expected to arrive
|
||||
|
||||
uint16_t enc_data[272]; //raw frame data soft bits
|
||||
uint8_t frame_data[19]; //decoded frame data, 144 bits (16+128), plus 4 flushing bits
|
||||
|
||||
uint8_t syncd=0; //syncword found?
|
||||
uint8_t fl=0; //Frame=0 of LSF=1
|
||||
uint8_t pushed; //counter for pushed symbols
|
||||
|
||||
//wait for another symbol
|
||||
if(fread((uint8_t*)&sample, 4, 1, stdin)<1) break;
|
||||
*/
|
||||
if(!syncd)
|
||||
{
|
||||
//push new symbol
|
||||
|
@ -124,9 +150,9 @@ namespace gr {
|
|||
//calculate euclidean norm
|
||||
dist = eucl_norm(last, str_sync_symbols, 8);
|
||||
|
||||
if(dist<_threshold) //frame syncword detected
|
||||
if(dist<DIST_THRESH) //frame syncword detected
|
||||
{
|
||||
//fprintf(stderr, "str_sync_symbols dist: %3.5f\n", dist);
|
||||
//fprintf(stderr, "str_sync dist: %3.5f\n", dist);
|
||||
syncd=1;
|
||||
pushed=0;
|
||||
fl=0;
|
||||
|
@ -136,7 +162,7 @@ namespace gr {
|
|||
//calculate euclidean norm again, this time against LSF syncword
|
||||
dist = eucl_norm(last, lsf_sync_symbols, 8);
|
||||
|
||||
if(dist<_threshold) //LSF syncword
|
||||
if(dist<DIST_THRESH) //LSF syncword
|
||||
{
|
||||
//fprintf(stderr, "lsf_sync dist: %3.5f\n", dist);
|
||||
syncd=1;
|
||||
|
@ -152,58 +178,14 @@ namespace gr {
|
|||
if(pushed==SYM_PER_PLD)
|
||||
{
|
||||
//common operations for all frame types
|
||||
//decode symbols to soft dibits
|
||||
for(uint8_t i=0; i<SYM_PER_PLD; i++)
|
||||
{
|
||||
//bit 0
|
||||
if(pld[i]>=symbol_levels[3])
|
||||
{
|
||||
soft_bit[i*2+1]=0xFFFF;
|
||||
}
|
||||
else if(pld[i]>=symbol_levels[2])
|
||||
{
|
||||
soft_bit[i*2+1]=-(float)0xFFFF/(symbol_map[3]-symbol_map[2])*symbol_map[2]+pld[i]*(float)0xFFFF/(symbol_map[3]-symbol_map[2]);
|
||||
}
|
||||
else if(pld[i]>=symbol_levels[1])
|
||||
{
|
||||
soft_bit[i*2+1]=0x0000;
|
||||
}
|
||||
else if(pld[i]>=symbol_levels[0])
|
||||
{
|
||||
soft_bit[i*2+1]=(float)0xFFFF/(symbol_levels[1]-symbol_levels[0])*symbol_levels[1]-pld[i]*(float)0xFFFF/(symbol_levels[1]-symbol_levels[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
soft_bit[i*2+1]=0xFFFF;
|
||||
}
|
||||
|
||||
//bit 1
|
||||
if(pld[i]>=symbol_levels[2])
|
||||
{
|
||||
soft_bit[i*2]=0x0000;
|
||||
}
|
||||
else if(pld[i]>=symbol_levels[1])
|
||||
{
|
||||
soft_bit[i*2]=0x7FFF-pld[i]*(float)0xFFFF/(symbol_levels[2]-symbol_levels[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
soft_bit[i*2]=0xFFFF;
|
||||
}
|
||||
}
|
||||
//slice symbols to soft dibits
|
||||
slice_symbols(soft_bit, pld);
|
||||
|
||||
//derandomize
|
||||
for(uint16_t i=0; i<SYM_PER_PLD*2; i++)
|
||||
{
|
||||
if((rand_seq[i/8]>>(7-(i%8)))&1) //soft XOR. flip soft bit if "1"
|
||||
soft_bit[i]=0xFFFF-soft_bit[i];
|
||||
}
|
||||
randomize_soft_bits(soft_bit);
|
||||
|
||||
//deinterleave
|
||||
for(uint16_t i=0; i<SYM_PER_PLD*2; i++)
|
||||
{
|
||||
d_soft_bit[i]=soft_bit[intrl_seq[i]];
|
||||
}
|
||||
reorder_soft_bits(d_soft_bit, soft_bit);
|
||||
|
||||
//if it is a frame
|
||||
if(!fl)
|
||||
|
@ -215,7 +197,7 @@ namespace gr {
|
|||
}
|
||||
|
||||
//decode
|
||||
viterbi_decode_punctured(frame_data, enc_data, puncture_pattern_2, 272, 12);
|
||||
uint32_t e=viterbi_decode_punctured(frame_data, enc_data, puncture_pattern_2, 272, 12);
|
||||
|
||||
uint16_t fn = (frame_data[1] << 8) | frame_data[2];
|
||||
|
||||
|
@ -260,125 +242,124 @@ namespace gr {
|
|||
//debug - dump LICH
|
||||
if(lich_chunks_rcvd==0x3F) //all 6 chunks received?
|
||||
{
|
||||
if (_debug_ctrl==true) {
|
||||
#ifdef DECODE_CALLSIGNS
|
||||
uint8_t d_dst[12], d_src[12]; //decoded strings
|
||||
|
||||
decode_callsign_bytes(d_dst, &lsf[0]);
|
||||
decode_callsign_bytes(d_src, &lsf[6]);
|
||||
|
||||
if (_debug_ctrl==true) {
|
||||
//DST
|
||||
printf("DST: %-9s ", d_dst);
|
||||
//DST
|
||||
printf("RX DST: %-9s ", d_dst);
|
||||
|
||||
//SRC
|
||||
printf("SRC: %-9s ", d_src);
|
||||
#else
|
||||
//DST
|
||||
printf("DST: ");
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
printf("%02X", lsf[i]);
|
||||
printf(" ");
|
||||
//SRC
|
||||
printf("SRC: %-9s ", d_src);
|
||||
#else
|
||||
//DST
|
||||
printf("RX DST: ");
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
printf("%02X", lsf[i]);
|
||||
printf(" ");
|
||||
|
||||
//SRC
|
||||
printf("SRC: ");
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
printf("%02X", lsf[6+i]);
|
||||
printf(" ");
|
||||
#endif
|
||||
//SRC
|
||||
printf("SRC: ");
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
printf("%02X", lsf[6+i]);
|
||||
printf(" ");
|
||||
#endif
|
||||
|
||||
//TYPE
|
||||
printf("TYPE: ");
|
||||
for(uint8_t i=0; i<2; i++)
|
||||
printf("%02X", lsf[12+i]);
|
||||
printf(" ");
|
||||
//TYPE
|
||||
printf("TYPE: ");
|
||||
for(uint8_t i=0; i<2; i++)
|
||||
printf("%02X", lsf[12+i]);
|
||||
printf(" ");
|
||||
|
||||
//META
|
||||
printf("META: ");
|
||||
for(uint8_t i=0; i<14; i++)
|
||||
printf("%02X", lsf[14+i]);
|
||||
//printf(" ");
|
||||
//META
|
||||
printf("META: ");
|
||||
for(uint8_t i=0; i<14; i++)
|
||||
printf("%02X", lsf[14+i]);
|
||||
//printf(" ");
|
||||
|
||||
//CRC
|
||||
//printf("CRC: ");
|
||||
//for(uint8_t i=0; i<2; i++)
|
||||
//printf("%02X", lsf[28+i]);
|
||||
if(CRC_M17(lsf, 30))
|
||||
printf(" LSF_CRC_ERR");
|
||||
else
|
||||
printf(" LSF_CRC_OK ");
|
||||
printf("\n");
|
||||
}
|
||||
lich_chunks_rcvd=0; //reset all flags
|
||||
//CRC
|
||||
//printf("CRC: ");
|
||||
//for(uint8_t i=0; i<2; i++)
|
||||
//printf("%02X", lsf[28+i]);
|
||||
if(CRC_M17(lsf, 30))
|
||||
printf(" LSF_CRC_ERR");
|
||||
else
|
||||
printf(" LSF_CRC_OK ");
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
_expected_next_fn = (fn + 1) % 0x8000;
|
||||
}
|
||||
else //lsf
|
||||
{
|
||||
if (_debug_ctrl==true) {
|
||||
printf("LSF\n");
|
||||
}
|
||||
printf("RX LSF\n");
|
||||
|
||||
//decode
|
||||
viterbi_decode_punctured(lsf, d_soft_bit, puncture_pattern_1, 2*SYM_PER_PLD, 61);
|
||||
uint32_t e=viterbi_decode_punctured(lsf, d_soft_bit, puncture_pattern_1, 2*SYM_PER_PLD, 61);
|
||||
|
||||
//shift the buffer 1 position left - get rid of the encoded flushing bits
|
||||
for(uint8_t i=0; i<30; i++)
|
||||
lsf[i]=lsf[i+1];
|
||||
|
||||
if (_debug_ctrl==true) {
|
||||
//dump data
|
||||
#ifdef DECODE_CALLSIGNS
|
||||
#ifdef DECODE_CALLSIGNS
|
||||
uint8_t d_dst[12], d_src[12]; //decoded strings
|
||||
|
||||
decode_callsign_bytes(d_dst, &lsf[0]);
|
||||
decode_callsign_bytes(d_src, &lsf[6]);
|
||||
|
||||
if (_debug_ctrl==true) {
|
||||
//DST
|
||||
printf("DST: %-9s ", d_dst);
|
||||
|
||||
//SRC
|
||||
printf("SRC: %-9s ", d_src);
|
||||
#else
|
||||
//DST
|
||||
printf("DST: ");
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
printf("%02X", lsf[i]);
|
||||
printf(" ");
|
||||
|
||||
//SRC
|
||||
printf("SRC: ");
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
printf("%02X", lsf[6+i]);
|
||||
printf(" ");
|
||||
#endif
|
||||
|
||||
//TYPE
|
||||
printf("TYPE: ");
|
||||
for(uint8_t i=0; i<2; i++)
|
||||
printf("%02X", lsf[12+i]);
|
||||
printf(" ");
|
||||
|
||||
//META
|
||||
printf("META: ");
|
||||
for(uint8_t i=0; i<14; i++)
|
||||
printf("%02X", lsf[14+i]);
|
||||
printf(" ");
|
||||
|
||||
//CRC
|
||||
//printf("CRC: ");
|
||||
//for(uint8_t i=0; i<2; i++)
|
||||
//printf("%02X", lsf[28+i]);
|
||||
if(CRC_M17(lsf, 30))
|
||||
printf("LSF_CRC_ERR");
|
||||
else
|
||||
printf("LSF_CRC_OK ");
|
||||
//Viterbi decoder errors
|
||||
#ifdef SHOW_VITERBI_ERRS
|
||||
printf(" e=%1.1f\n", (float)e/0xFFFF);
|
||||
#else
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
//DST
|
||||
printf("RX DST: %-9s ", d_dst);
|
||||
|
||||
//SRC
|
||||
printf("SRC: %-9s ", d_src);
|
||||
#else
|
||||
//DST
|
||||
printf("RX DST: ");
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
printf("%02X", lsf[i]);
|
||||
printf(" ");
|
||||
|
||||
//SRC
|
||||
printf("SRC: ");
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
printf("%02X", lsf[6+i]);
|
||||
printf(" ");
|
||||
#endif
|
||||
|
||||
//TYPE
|
||||
printf("TYPE: ");
|
||||
for(uint8_t i=0; i<2; i++)
|
||||
printf("%02X", lsf[12+i]);
|
||||
printf(" ");
|
||||
|
||||
//META
|
||||
printf("META: ");
|
||||
for(uint8_t i=0; i<14; i++)
|
||||
printf("%02X", lsf[14+i]);
|
||||
printf(" ");
|
||||
|
||||
//CRC
|
||||
//printf("CRC: ");
|
||||
//for(uint8_t i=0; i<2; i++)
|
||||
//printf("%02X", lsf[28+i]);
|
||||
if(CRC_M17(lsf, 30))
|
||||
printf("LSF_CRC_ERR");
|
||||
else
|
||||
printf("LSF_CRC_OK ");
|
||||
|
||||
//Viterbi decoder errors
|
||||
#ifdef SHOW_VITERBI_ERRS
|
||||
printf(" e=%1.1f\n", (float)e/0xFFFF);
|
||||
#else
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//job done
|
||||
|
@ -389,7 +370,9 @@ namespace gr {
|
|||
last[i]=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Tell runtime system how many input items we consumed on
|
||||
// each input stream.
|
||||
consume_each (ninput_items[0]);
|
||||
|
|
|
@ -33,7 +33,7 @@ void bind_m17_coder(py::module &m) {
|
|||
|
||||
using m17_coder = ::gr::m17::m17_coder;
|
||||
|
||||
py::class_<m17_coder, gr::block, gr::basic_block, std::shared_ptr<m17_coder>>(
|
||||
py::class_<m17_coder, gr::sync_interpolator, gr::basic_block, std::shared_ptr<m17_coder>>(
|
||||
m, "m17_coder", D(m17_coder))
|
||||
|
||||
.def(py::init(&m17_coder::make), py::arg("src_id"), py::arg("dst_id"),
|
||||
|
|
Loading…
Reference in New Issue