Implement the whitening and de-whitening process for the UPSAT
The data whitening and de-whitening mechanism is implemented using lookup tables for fast processing times. The implementation is quite generic and modular supporting user defined polynomial masks and seeds. The lookup table is created during the initialization without any runtime overhead.
This commit is contained in:
parent
defb1378b8
commit
10d4519bcb
|
@ -33,5 +33,6 @@ install(FILES
|
|||
satnogs_frame_encoder.xml
|
||||
satnogs_doppler_correction_cc.xml
|
||||
satnogs_upsat_fsk_frame_acquisition.xml
|
||||
satnogs_upsat_fsk_frame_encoder.xml DESTINATION share/gnuradio/grc/blocks
|
||||
satnogs_upsat_fsk_frame_encoder.xml
|
||||
satnogs_whitening.xml DESTINATION share/gnuradio/grc/blocks
|
||||
)
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0"?>
|
||||
<block>
|
||||
<name>whitening</name>
|
||||
<key>satnogs_whitening</key>
|
||||
<category>satnogs</category>
|
||||
<import>import satnogs</import>
|
||||
<make>satnogs.whitening($mask, $seed, $order)</make>
|
||||
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
|
||||
Sub-nodes:
|
||||
* name
|
||||
* key (makes the value accessible as $keyname, e.g. in the make node)
|
||||
* type -->
|
||||
<param>
|
||||
<name>...</name>
|
||||
<key>...</key>
|
||||
<type>...</type>
|
||||
</param>
|
||||
|
||||
<!-- Make one 'sink' node per input. Sub-nodes:
|
||||
* name (an identifier for the GUI)
|
||||
* type
|
||||
* vlen
|
||||
* optional (set to 1 for optional inputs) -->
|
||||
<sink>
|
||||
<name>in</name>
|
||||
<type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type>
|
||||
</sink>
|
||||
|
||||
<!-- Make one 'source' node per output. Sub-nodes:
|
||||
* name (an identifier for the GUI)
|
||||
* type
|
||||
* vlen
|
||||
* optional (set to 1 for optional inputs) -->
|
||||
<source>
|
||||
<name>out</name>
|
||||
<type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type>
|
||||
</source>
|
||||
</block>
|
|
@ -46,5 +46,6 @@ install(FILES
|
|||
doppler_fit.h
|
||||
freq_drift.h
|
||||
upsat_fsk_frame_acquisition.h
|
||||
upsat_fsk_frame_encoder.h DESTINATION include/satnogs
|
||||
upsat_fsk_frame_encoder.h
|
||||
whitening.h DESTINATION include/satnogs
|
||||
)
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
|
||||
*
|
||||
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_SATNOGS_WHITENING_H
|
||||
#define INCLUDED_SATNOGS_WHITENING_H
|
||||
|
||||
#include <satnogs/api.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
namespace satnogs
|
||||
{
|
||||
|
||||
/*!
|
||||
* \brief Performs data whitening and de-whitening
|
||||
*
|
||||
*/
|
||||
class SATNOGS_API whitening
|
||||
{
|
||||
public:
|
||||
whitening (uint32_t mask, uint32_t seed, uint32_t order);
|
||||
~whitening ();
|
||||
|
||||
void
|
||||
reset();
|
||||
|
||||
void scramble(uint8_t *out, const uint8_t *in, size_t len);
|
||||
void descramble(uint8_t *out, const uint8_t *in, size_t len);
|
||||
|
||||
private:
|
||||
const size_t d_lut_len;
|
||||
size_t d_lut_idx;
|
||||
uint8_t *d_lut;
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
} // namespace gr
|
||||
|
||||
#endif /* INCLUDED_SATNOGS_WHITENING_H */
|
||||
|
|
@ -44,7 +44,8 @@ list(APPEND satnogs_sources
|
|||
doppler_fit.cc
|
||||
freq_drift.cc
|
||||
upsat_fsk_frame_acquisition_impl.cc
|
||||
upsat_fsk_frame_encoder_impl.cc )
|
||||
upsat_fsk_frame_encoder_impl.cc
|
||||
whitening.cc )
|
||||
|
||||
set(satnogs_sources "${satnogs_sources}" PARENT_SCOPE)
|
||||
if(NOT satnogs_sources)
|
||||
|
|
|
@ -72,7 +72,8 @@ namespace gr
|
|||
d_shifting_byte (0x0),
|
||||
d_decoded_bytes (0),
|
||||
d_decoded_bits (0),
|
||||
d_frame_len (0)
|
||||
d_frame_len (0),
|
||||
d_descrambler(0x21, 0x1FF, 9)
|
||||
{
|
||||
size_t i;
|
||||
message_port_register_out (pmt::mp ("pdu"));
|
||||
|
@ -154,6 +155,7 @@ namespace gr
|
|||
upsat_fsk_frame_acquisition_impl::have_frame_len ()
|
||||
{
|
||||
LOG_DEBUG("Enter frame len");
|
||||
d_descrambler.reset();
|
||||
d_state = HAVE_FRAME_LEN;
|
||||
d_decoded_bytes = 0;
|
||||
d_decoded_bits = 0;
|
||||
|
@ -243,10 +245,20 @@ namespace gr
|
|||
case HAVE_FRAME_LEN:
|
||||
d_decoded_bits++;
|
||||
if(d_decoded_bits == 8) {
|
||||
/* Frame length field is needed for the CRC calculation */
|
||||
d_pdu[0] = d_shifting_byte;
|
||||
/* CRC is not included in the frame length field, but we want it */
|
||||
d_frame_len = 1 + d_shifting_byte + sizeof(uint16_t);
|
||||
|
||||
/* Length field has been whitened if the option is enabled */
|
||||
if(d_whitening){
|
||||
/* Frame length field is needed for the CRC calculation */
|
||||
d_descrambler.descramble(d_pdu, &d_shifting_byte, 1);
|
||||
/* CRC is not included in the frame length field, but we want it */
|
||||
d_frame_len = 1 + d_pdu[0] + sizeof(uint16_t);
|
||||
}
|
||||
else{
|
||||
/* Frame length field is needed for the CRC calculation */
|
||||
d_pdu[0] = d_shifting_byte;
|
||||
/* CRC is not included in the frame length field, but we want it */
|
||||
d_frame_len = 1 + d_shifting_byte + sizeof(uint16_t);
|
||||
}
|
||||
have_payload();
|
||||
}
|
||||
break;
|
||||
|
@ -258,6 +270,9 @@ namespace gr
|
|||
d_decoded_bytes++;
|
||||
|
||||
if (d_decoded_bytes == d_frame_len) {
|
||||
if(d_whitening){
|
||||
d_descrambler.descramble(d_pdu+1, d_pdu+1, d_frame_len - 1);
|
||||
}
|
||||
if(!d_check_crc){
|
||||
message_port_pub (
|
||||
pmt::mp ("pdu"),
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <satnogs/config.h>
|
||||
#include <satnogs/upsat_fsk_frame_acquisition.h>
|
||||
#include <satnogs/whitening.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
|
@ -59,6 +60,7 @@ namespace gr
|
|||
size_t d_decoded_bytes;
|
||||
size_t d_decoded_bits;
|
||||
size_t d_frame_len;
|
||||
whitening d_descrambler;
|
||||
uint8_t *d_pdu;
|
||||
|
||||
inline void
|
||||
|
|
|
@ -66,7 +66,8 @@ namespace gr
|
|||
d_max_pdu_len(d_preamble_len + d_sync_word_len + sizeof(uint8_t)
|
||||
+ UPSAT_MAX_FRAME_LEN + sizeof(uint16_t)),
|
||||
d_encoded(0),
|
||||
d_pdu_len(0)
|
||||
d_pdu_len(0),
|
||||
d_scrambler(0x21, 0x1FF, 9)
|
||||
{
|
||||
/* Simplify the logic of the output samples handling */
|
||||
set_output_multiple(8);
|
||||
|
@ -181,6 +182,16 @@ namespace gr
|
|||
d_pdu_len += sizeof(uint16_t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Whitening is performed on all byes except preamble and SYNC fields
|
||||
*/
|
||||
if(d_whitening){
|
||||
d_scrambler.reset();
|
||||
d_scrambler.scramble (d_pdu + d_preamble_len + d_sync_word_len,
|
||||
d_pdu + d_preamble_len + d_sync_word_len,
|
||||
d_pdu_len + 1);
|
||||
}
|
||||
|
||||
d_pdu_len += d_preamble_len + d_sync_word_len + 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define INCLUDED_SATNOGS_UPSAT_FSK_FRAME_ENCODER_IMPL_H
|
||||
|
||||
#include <satnogs/upsat_fsk_frame_encoder.h>
|
||||
#include <satnogs/whitening.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
|
@ -42,6 +43,7 @@ namespace gr
|
|||
const size_t d_max_pdu_len;
|
||||
size_t d_encoded;
|
||||
size_t d_pdu_len;
|
||||
whitening d_scrambler;
|
||||
uint8_t *d_pdu;
|
||||
|
||||
inline void
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
|
||||
*
|
||||
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <satnogs/whitening.h>
|
||||
#include <satnogs/utils.h>
|
||||
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
|
||||
/**
|
||||
* Data whitening and de-whitening class
|
||||
* @param mask the polynomial mask
|
||||
* @param seed the initial seed
|
||||
* @param order the order of the shift register. This is equal to the
|
||||
* number of memory stages.
|
||||
*/
|
||||
whitening::whitening (uint32_t mask, uint32_t seed, uint32_t order) :
|
||||
d_lut_len (std::pow (2, order)),
|
||||
d_lut_idx (0)
|
||||
{
|
||||
size_t i;
|
||||
size_t j;
|
||||
uint32_t cnt;
|
||||
uint32_t shift_reg = seed;
|
||||
|
||||
if (order > 32) {
|
||||
throw std::invalid_argument ("The maximum allowed order is 32");
|
||||
}
|
||||
|
||||
d_lut = new uint8_t[d_lut_len];
|
||||
|
||||
for (i = 0; i < d_lut_len; i++) {
|
||||
d_lut[i] = shift_reg & 0xFF;
|
||||
for (j = 0; j < 8; j++) {
|
||||
cnt = bit_count (shift_reg & mask) % 2;
|
||||
shift_reg = shift_reg >> 1;
|
||||
shift_reg |= cnt << (order - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
whitening::~whitening()
|
||||
{
|
||||
delete [] d_lut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the scrambler (or the descrambler) to the initial stage and
|
||||
* the initial seed.
|
||||
*/
|
||||
void
|
||||
whitening::reset ()
|
||||
{
|
||||
d_lut_idx = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs data scrambling
|
||||
* @param out the output buffer
|
||||
* @param in the input buffer
|
||||
* @param len the number of the bytes to be scrambled
|
||||
*/
|
||||
void
|
||||
whitening::scramble (uint8_t* out, const uint8_t* in, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
for(i = 0; i < len; i++){
|
||||
out[i] = in[i] ^ d_lut[ (d_lut_idx + i ) % d_lut_len];
|
||||
}
|
||||
d_lut_idx = (d_lut_idx + len ) % d_lut_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs data de-scrambling
|
||||
* @param out the output buffer
|
||||
* @param in the input buffer
|
||||
* @param len the number of the bytes to be de-scrambled
|
||||
*/
|
||||
void
|
||||
whitening::descramble (uint8_t* out, const uint8_t* in, size_t len)
|
||||
{
|
||||
scramble(out, in, len);
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
#include "satnogs/frame_encoder.h"
|
||||
#include "satnogs/upsat_fsk_frame_acquisition.h"
|
||||
#include "satnogs/upsat_fsk_frame_encoder.h"
|
||||
#include "satnogs/whitening.h"
|
||||
%}
|
||||
|
||||
|
||||
|
@ -65,3 +66,4 @@ GR_SWIG_BLOCK_MAGIC2(satnogs, doppler_correction_cc);
|
|||
GR_SWIG_BLOCK_MAGIC2(satnogs, upsat_fsk_frame_acquisition);
|
||||
%include "satnogs/upsat_fsk_frame_encoder.h"
|
||||
GR_SWIG_BLOCK_MAGIC2(satnogs, upsat_fsk_frame_encoder);
|
||||
%include "satnogs/whitening.h"
|
||||
|
|
Loading…
Reference in New Issue