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:
Manolis Surligas 2016-04-11 21:26:57 +03:00
parent defb1378b8
commit 10d4519bcb
11 changed files with 248 additions and 9 deletions

View File

@ -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
)

38
grc/satnogs_whitening.xml Normal file
View File

@ -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>

View File

@ -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
)

View File

@ -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 */

View File

@ -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)

View File

@ -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"),

View File

@ -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

View File

@ -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;
}

View File

@ -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

109
lib/whitening.cc Normal file
View File

@ -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 */

View File

@ -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"