Add LRPT decoding flowgraph
This commit is contained in:
parent
854becb15d
commit
63218b157b
|
@ -17,11 +17,15 @@
|
|||
<name>AMSAT FOX</name>
|
||||
<block>satnogs_fox_telem_mm</block>
|
||||
</cat>
|
||||
<cat>
|
||||
<name>METOP</name>
|
||||
<block>satnogs_lrpt_sync</block>
|
||||
<block>satnogs_lrpt_decoder</block>
|
||||
</cat>
|
||||
</cat>
|
||||
<block>satnogs_cw_matched_filter_ff</block>
|
||||
<block>satnogs_morse_decoder</block>
|
||||
<block>satnogs_multi_format_msg_sink</block>
|
||||
<block>satnogs_lrpt_sync</block>
|
||||
<block>satnogs_iq_sink</block>
|
||||
<block>satnogs_ogg_encoder</block>
|
||||
<block>satnogs_ogg_source</block>
|
||||
|
|
|
@ -23,12 +23,16 @@
|
|||
|
||||
#include <cstdint>
|
||||
#include <cmath>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
|
||||
namespace satnogs
|
||||
{
|
||||
|
||||
#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
|
||||
#define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
|
||||
/**
|
||||
* Computes the Mean Absolute Percentage Error
|
||||
* @param ref the reference value
|
||||
|
|
|
@ -41,8 +41,10 @@ namespace gr
|
|||
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);
|
||||
void scramble(uint8_t *out, const uint8_t *in, size_t len,
|
||||
bool msb = false);
|
||||
void descramble(uint8_t *out, const uint8_t *in, size_t len,
|
||||
bool msb = false);
|
||||
|
||||
void
|
||||
scramble_one_bit_per_byte (uint8_t *out, const uint8_t *in,
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#include <gnuradio/io_signature.h>
|
||||
#include "lrpt_decoder_impl.h"
|
||||
#include <satnogs/log.h>
|
||||
#include <satnogs/utils.h>
|
||||
|
||||
|
||||
extern "C" {
|
||||
#include <fec.h>
|
||||
}
|
||||
|
@ -47,11 +50,18 @@ lrpt_decoder_impl::lrpt_decoder_impl()
|
|||
: gr::block("lrpt_decoder",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_cadu_len(1020 + 4),
|
||||
d_coded_cadu_len(1020 * 2 + 4*2),
|
||||
d_conv_deinterl(36, 2048)
|
||||
/*
|
||||
* Metop violates the standard as many times as possible...
|
||||
* The frame should contain 128 RS check symbols at the end.
|
||||
* For some unknown reasons, it seems that the RS encoding is not performed.
|
||||
* Thus, they dropped the check symbols at the end of the frame.
|
||||
*/
|
||||
d_cadu_len(1020 + 4 - 128),
|
||||
d_coded_cadu_len(1020 * 2 + 4*2 - 128 * 2),
|
||||
d_mpdu_max_len(59400),
|
||||
d_scrambler(0x2A9, 0xFF, 7),
|
||||
d_have_mpdu(false)
|
||||
{
|
||||
|
||||
message_port_register_in(pmt::mp("cadu"));
|
||||
message_port_register_out(pmt::mp("frame"));
|
||||
|
||||
|
@ -63,11 +73,13 @@ lrpt_decoder_impl::lrpt_decoder_impl()
|
|||
if(!d_vt) {
|
||||
throw std::runtime_error("lrpt_decoder: Failed to init Viterbi decoder");
|
||||
}
|
||||
int polys[2] = {0x79, 0x5b};
|
||||
|
||||
int polys[2] = {0x4f, 0x6d};
|
||||
set_viterbi27_polynomial(polys);
|
||||
|
||||
d_cadu = new uint8_t[d_cadu_len];
|
||||
d_coded_cadu_syms = new uint8_t[d_coded_cadu_len * 8];
|
||||
d_mpdu = new uint8_t[d_mpdu_max_len];
|
||||
|
||||
}
|
||||
|
||||
|
@ -79,6 +91,7 @@ lrpt_decoder_impl::~lrpt_decoder_impl ()
|
|||
|
||||
delete [] d_cadu;
|
||||
delete [] d_coded_cadu_syms;
|
||||
delete [] d_mpdu;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -93,21 +106,68 @@ lrpt_decoder_impl::decode (pmt::pmt_t m)
|
|||
init_viterbi27(d_vt, 0);
|
||||
|
||||
for(size_t i = 0; i < d_coded_cadu_len; i++) {
|
||||
d_coded_cadu_syms[i * 8] = ~(255 + (coded_cadu[i] >> 7));
|
||||
d_coded_cadu_syms[i * 8 + 1] = ~(255 + (coded_cadu[i] >> 6) & 0x1);
|
||||
d_coded_cadu_syms[i * 8 + 2] = ~(255 + (coded_cadu[i] >> 5) & 0x1);
|
||||
d_coded_cadu_syms[i * 8 + 3] = ~(255 + (coded_cadu[i] >> 4) & 0x1);
|
||||
d_coded_cadu_syms[i * 8 + 4] = ~(255 + (coded_cadu[i] >> 3) & 0x1);
|
||||
d_coded_cadu_syms[i * 8 + 5] = ~(255 + (coded_cadu[i] >> 2) & 0x1);
|
||||
d_coded_cadu_syms[i * 8 + 6] = ~(255 + (coded_cadu[i] >> 1) & 0x1);
|
||||
d_coded_cadu_syms[i * 8 + 7] = ~(255 + (coded_cadu[i] & 0x1));
|
||||
d_coded_cadu_syms[i * 8] = 0xFF * (coded_cadu[i] >> 7);
|
||||
d_coded_cadu_syms[i * 8 + 1] = 0xFF * ((coded_cadu[i] >> 6) & 0x1);
|
||||
d_coded_cadu_syms[i * 8 + 2] = 0xFF * ((coded_cadu[i] >> 5) & 0x1);
|
||||
d_coded_cadu_syms[i * 8 + 3] = 0xFF * ((coded_cadu[i] >> 4) & 0x1);
|
||||
d_coded_cadu_syms[i * 8 + 4] = 0xFF * ((coded_cadu[i] >> 3) & 0x1);
|
||||
d_coded_cadu_syms[i * 8 + 5] = 0xFF * ((coded_cadu[i] >> 2) & 0x1);
|
||||
d_coded_cadu_syms[i * 8 + 6] = 0xFF * ((coded_cadu[i] >> 1) & 0x1);
|
||||
d_coded_cadu_syms[i * 8 + 7] = 0xFF * ((coded_cadu[i] & 0x1));
|
||||
}
|
||||
|
||||
/* Convolutional decoding */
|
||||
update_viterbi27_blk(d_vt, d_coded_cadu_syms, d_cadu_len * 8);
|
||||
chainback_viterbi27(d_vt, d_cadu, d_cadu_len * 8, 0);
|
||||
message_port_pub(pmt::mp("frame"), pmt::make_blob(d_cadu, d_cadu_len));
|
||||
|
||||
/* Descrambling */
|
||||
d_scrambler.reset();
|
||||
d_scrambler.descramble(d_cadu + 4, d_cadu + 4, d_cadu_len - 4, true);
|
||||
decode_ccsds_packet(d_cadu + 4);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lrpt_decoder_impl::decode_ccsds_packet(const uint8_t *cvcdu)
|
||||
{
|
||||
/* Check first the VCDU version and if encryption is off */
|
||||
if( (cvcdu[0] >> 6) != 0x1) {
|
||||
return;
|
||||
}
|
||||
if(cvcdu[6] != 0x0 || cvcdu[7] != 0x0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if the VCDU contans data */
|
||||
//if((cvcdu[8] >> 3) != 0x0 && (cvcdu[8] >> 3) != 0x1f) {
|
||||
// return;
|
||||
//}
|
||||
|
||||
const uint8_t *mpdu = cvcdu + 10;
|
||||
/* Check CCSDS packet version and type */
|
||||
//if( (mpdu[0] >> 5) != 0x0) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
uint32_t vcdu_seq = 0;
|
||||
vcdu_seq = cvcdu[2];
|
||||
vcdu_seq = (vcdu_seq << 8) | cvcdu[3];
|
||||
vcdu_seq = (vcdu_seq << 8) | cvcdu[4];
|
||||
|
||||
uint16_t hdr_ptr = 0;
|
||||
hdr_ptr = cvcdu[8] & 0x7;
|
||||
hdr_ptr = (hdr_ptr << 8) | cvcdu[9];
|
||||
|
||||
/* Try to find the start of a MPDU */
|
||||
if(!d_have_mpdu) {
|
||||
if(hdr_ptr != 0) {
|
||||
return;
|
||||
}
|
||||
d_have_mpdu = true;
|
||||
}
|
||||
message_port_pub(pmt::mp("frame"), pmt::make_blob(cvcdu, d_cadu_len - 4));
|
||||
}
|
||||
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <satnogs/lrpt_decoder.h>
|
||||
#include <satnogs/convolutional_deinterleaver.h>
|
||||
#include <satnogs/whitening.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
|
@ -39,13 +40,20 @@ public:
|
|||
private:
|
||||
const size_t d_cadu_len;
|
||||
const size_t d_coded_cadu_len;
|
||||
convolutional_deinterleaver d_conv_deinterl;
|
||||
const size_t d_mpdu_max_len;
|
||||
whitening d_scrambler;
|
||||
bool d_have_mpdu;
|
||||
|
||||
uint8_t *d_coded_cadu_syms;
|
||||
uint8_t *d_cadu;
|
||||
uint8_t *d_mpdu;
|
||||
void *d_vt;
|
||||
|
||||
void
|
||||
decode(pmt::pmt_t m);
|
||||
|
||||
void
|
||||
decode_ccsds_packet(const uint8_t *cvcdu);
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
|
|
|
@ -58,12 +58,18 @@ lrpt_sync_impl::lrpt_sync_impl (size_t threshold) :
|
|||
*/
|
||||
d_window((72 + 8)/2),
|
||||
/* Each CADU has the 4 byte ASM and a VCDU of 1020 bytes*/
|
||||
d_coded_cadu_len(1020 * 2 + 4*2),
|
||||
/*
|
||||
* NOTE:
|
||||
* Metop violates the standard as many times as possible...
|
||||
* The frame should contain 128 RS check symbols at the end.
|
||||
* For some unknown reasons, it seems that the RS encoding is not performed.
|
||||
* Thus, they dropped the check symbols at the end of the frame.
|
||||
*/
|
||||
d_coded_cadu_len(1020 * 2 + 4*2 - 128 * 2),
|
||||
d_frame_sync(false),
|
||||
d_received(0),
|
||||
d_rotate(1, 0),
|
||||
d_rotate(1.0, 0.0),
|
||||
d_qpsk(digital::constellation_qpsk::make()),
|
||||
d_conv_deinter(36, 2048),
|
||||
d_shift_reg0(0x0),
|
||||
d_shift_reg1(0x0),
|
||||
d_shift_reg2(0x0),
|
||||
|
@ -72,25 +78,29 @@ lrpt_sync_impl::lrpt_sync_impl (size_t threshold) :
|
|||
set_output_multiple(d_window);
|
||||
const int alignment_multiple = volk_get_alignment () / sizeof(gr_complex);
|
||||
set_alignment (std::max (1, alignment_multiple));
|
||||
d_rotate_pi2 = (gr_complex *)volk_malloc(d_window, volk_get_alignment ());
|
||||
d_rotate_pi2 = (gr_complex *) volk_malloc (d_window * sizeof(gr_complex),
|
||||
volk_get_alignment ());
|
||||
if(!d_rotate_pi2) {
|
||||
throw std::runtime_error("lrpt_sync: Could not allocate memory");
|
||||
}
|
||||
|
||||
d_rotate_2pi2 = (gr_complex *)volk_malloc(d_window, volk_get_alignment ());
|
||||
d_rotate_2pi2 = (gr_complex *) volk_malloc (d_window * sizeof(gr_complex),
|
||||
volk_get_alignment ());
|
||||
if(!d_rotate_2pi2) {
|
||||
volk_free(d_rotate_pi2);
|
||||
throw std::runtime_error("lrpt_sync: Could not allocate memory");
|
||||
}
|
||||
|
||||
d_rotate_3pi2 = (gr_complex *)volk_malloc(d_window, volk_get_alignment ());
|
||||
d_rotate_3pi2 = (gr_complex *) volk_malloc (d_window * sizeof(gr_complex),
|
||||
volk_get_alignment ());
|
||||
if(!d_rotate_3pi2) {
|
||||
volk_free(d_rotate_pi2);
|
||||
volk_free(d_rotate_2pi2);
|
||||
throw std::runtime_error("lrpt_sync: Could not allocate memory");
|
||||
}
|
||||
|
||||
d_corrected = (gr_complex *)volk_malloc(d_window, volk_get_alignment ());
|
||||
d_corrected = (gr_complex *)volk_malloc(d_window * sizeof(gr_complex),
|
||||
volk_get_alignment ());
|
||||
if(!d_corrected) {
|
||||
volk_free(d_rotate_pi2);
|
||||
volk_free(d_rotate_2pi2);
|
||||
|
@ -98,7 +108,7 @@ lrpt_sync_impl::lrpt_sync_impl (size_t threshold) :
|
|||
throw std::runtime_error("lrpt_sync: Could not allocate memory");
|
||||
}
|
||||
|
||||
uint64_t asm_coded = reverse_uint64_bytes(d_asm_coded);
|
||||
uint64_t asm_coded = htonll(d_asm_coded);
|
||||
d_coded_cadu = new uint8_t[d_coded_cadu_len];
|
||||
memcpy(d_coded_cadu, &asm_coded, sizeof(uint64_t));
|
||||
d_received = sizeof(uint64_t);
|
||||
|
@ -133,11 +143,11 @@ lrpt_sync_impl::work_no_sync(const gr_complex *in, int noutput_items)
|
|||
int multiple = noutput_items / d_window;
|
||||
for(int i = 0; i < multiple; i++) {
|
||||
volk_32fc_s32fc_multiply_32fc(d_rotate_pi2, in + i * d_window,
|
||||
gr_complex(0, 1), d_window);
|
||||
gr_complex(0.0, 1.0), d_window);
|
||||
volk_32fc_s32fc_multiply_32fc(d_rotate_2pi2, in + i * d_window,
|
||||
gr_complex(-1, 0), d_window);
|
||||
gr_complex(-1.0, 0.0), d_window);
|
||||
volk_32fc_s32fc_multiply_32fc(d_rotate_3pi2, in + i * d_window,
|
||||
gr_complex(0, -1), d_window);
|
||||
gr_complex(0.0, -1.0), d_window);
|
||||
/*
|
||||
* Search for the sync pattern, rotating the QPSK constellation on
|
||||
* all possible positions
|
||||
|
@ -147,9 +157,11 @@ lrpt_sync_impl::work_no_sync(const gr_complex *in, int noutput_items)
|
|||
//bits = (d_conv_deinter.decode_bit(bits >> 1) << 1) | d_conv_deinter.decode_bit(bits & 0x1);
|
||||
d_shift_reg0 = (d_shift_reg0 << 2) | bits;
|
||||
if(found_sync(d_shift_reg0)) {
|
||||
d_rotate = gr_complex(1.0, 0);
|
||||
d_rotate = gr_complex(1.0, 0.0);
|
||||
d_frame_sync = true;
|
||||
return i * d_window + j;
|
||||
uint64_t asm_coded = htonll(d_shift_reg0);
|
||||
memcpy(d_coded_cadu, &asm_coded, sizeof(uint64_t));
|
||||
return i * d_window + j + 1;
|
||||
}
|
||||
|
||||
bits = d_qpsk->decision_maker(d_rotate_pi2 + j);
|
||||
|
@ -158,16 +170,20 @@ lrpt_sync_impl::work_no_sync(const gr_complex *in, int noutput_items)
|
|||
if(found_sync(d_shift_reg1)) {
|
||||
d_rotate = gr_complex(0.0, 1.0);
|
||||
d_frame_sync = true;
|
||||
return i * d_window + j;
|
||||
uint64_t asm_coded = htonll(d_shift_reg1);
|
||||
memcpy(d_coded_cadu, &asm_coded, sizeof(uint64_t));
|
||||
return i * d_window + j + 1;
|
||||
}
|
||||
|
||||
bits = d_qpsk->decision_maker(d_rotate_2pi2 + j);
|
||||
//bits = (d_conv_deinter.decode_bit(bits >> 1) << 1) | d_conv_deinter.decode_bit(bits & 0x1);
|
||||
d_shift_reg2 = (d_shift_reg2 << 2) | bits;
|
||||
if(found_sync(d_shift_reg2)) {
|
||||
d_rotate = gr_complex(-1.0, 0);
|
||||
d_rotate = gr_complex(-1.0, 0.0);
|
||||
d_frame_sync = true;
|
||||
return i * d_window + j;
|
||||
uint64_t asm_coded = htonll(d_shift_reg2);
|
||||
memcpy(d_coded_cadu, &asm_coded, sizeof(uint64_t));
|
||||
return i * d_window + j + 1;
|
||||
}
|
||||
|
||||
bits = d_qpsk->decision_maker(d_rotate_3pi2 + j);
|
||||
|
@ -176,7 +192,9 @@ lrpt_sync_impl::work_no_sync(const gr_complex *in, int noutput_items)
|
|||
if(found_sync(d_shift_reg3)) {
|
||||
d_rotate = gr_complex(0.0, -1.0);
|
||||
d_frame_sync = true;
|
||||
return i * d_window + j;
|
||||
uint64_t asm_coded = htonll(d_shift_reg3);
|
||||
memcpy(d_coded_cadu, &asm_coded, sizeof(uint64_t));
|
||||
return i * d_window + j + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +218,6 @@ lrpt_sync_impl::work_sync(const gr_complex *in, int noutput_items)
|
|||
|
||||
d_coded_cadu[d_received++] = b;
|
||||
if(d_received == d_coded_cadu_len) {
|
||||
LOG_ERROR("frame");
|
||||
d_received = sizeof(uint64_t);
|
||||
d_frame_sync = false;
|
||||
message_port_pub (pmt::mp ("cadu"),
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
private:
|
||||
const size_t d_thresh;
|
||||
const uint64_t d_asm_coded;
|
||||
const uint64_t d_asm_coded_len;
|
||||
const size_t d_asm_coded_len;
|
||||
const uint64_t d_asm_coded_mask;
|
||||
const int d_window;
|
||||
const size_t d_coded_cadu_len;
|
||||
|
@ -52,7 +52,6 @@ private:
|
|||
size_t d_received;
|
||||
gr_complex d_rotate;
|
||||
digital::constellation_qpsk::sptr d_qpsk;
|
||||
convolutional_deinterleaver d_conv_deinter;
|
||||
uint64_t d_shift_reg0;
|
||||
uint64_t d_shift_reg1;
|
||||
uint64_t d_shift_reg2;
|
||||
|
|
192
lib/whitening.cc
192
lib/whitening.cc
|
@ -26,97 +26,117 @@
|
|||
#include <satnogs/whitening.h>
|
||||
#include <satnogs/utils.h>
|
||||
|
||||
namespace gr {
|
||||
namespace satnogs {
|
||||
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_lfsr(mask, seed, order)
|
||||
{
|
||||
/**
|
||||
* 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_lfsr (mask, seed, order)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the scrambler (or the descrambler) to the initial stage and
|
||||
* the initial seed.
|
||||
*/
|
||||
void
|
||||
whitening::reset ()
|
||||
{
|
||||
d_lfsr.reset ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs data scrambling
|
||||
* @param out the output buffer
|
||||
* @param in the input buffer
|
||||
* @param len the number of the bytes to be scrambled
|
||||
* @param msb if set to true, the descrambler starts from the msb
|
||||
*/
|
||||
void
|
||||
whitening::scramble (uint8_t* out, const uint8_t* in, size_t len, bool msb)
|
||||
{
|
||||
size_t i;
|
||||
uint8_t b;
|
||||
if(msb) {
|
||||
for (i = 0; i < len; i++) {
|
||||
b = d_lfsr.next_bit () << 7;
|
||||
b |= d_lfsr.next_bit () << 6;
|
||||
b |= d_lfsr.next_bit () << 5;
|
||||
b |= d_lfsr.next_bit () << 4;
|
||||
b |= d_lfsr.next_bit () << 3;
|
||||
b |= d_lfsr.next_bit () << 2;
|
||||
b |= d_lfsr.next_bit () << 1;
|
||||
b |= d_lfsr.next_bit ();
|
||||
out[i] = in[i] ^ b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the scrambler (or the descrambler) to the initial stage and
|
||||
* the initial seed.
|
||||
*/
|
||||
void
|
||||
whitening::reset ()
|
||||
{
|
||||
d_lfsr.reset();
|
||||
}
|
||||
else{
|
||||
for (i = 0; i < len; i++) {
|
||||
b = d_lfsr.next_bit ();
|
||||
b |= d_lfsr.next_bit () << 1;
|
||||
b |= d_lfsr.next_bit () << 2;
|
||||
b |= d_lfsr.next_bit () << 3;
|
||||
b |= d_lfsr.next_bit () << 4;
|
||||
b |= d_lfsr.next_bit () << 5;
|
||||
b |= d_lfsr.next_bit () << 6;
|
||||
b |= d_lfsr.next_bit () << 7;
|
||||
out[i] = in[i] ^ b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
uint8_t b;
|
||||
for(i = 0; i < len; i++){
|
||||
b = d_lfsr.next_bit();
|
||||
b |= d_lfsr.next_bit() << 1;
|
||||
b |= d_lfsr.next_bit() << 2;
|
||||
b |= d_lfsr.next_bit() << 3;
|
||||
b |= d_lfsr.next_bit() << 4;
|
||||
b |= d_lfsr.next_bit() << 5;
|
||||
b |= d_lfsr.next_bit() << 6;
|
||||
b |= d_lfsr.next_bit() << 7;
|
||||
out[i] = in[i] ^ b;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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
|
||||
* @param msb if set to true, the descrambler starts from the msb
|
||||
*/
|
||||
void
|
||||
whitening::descramble (uint8_t* out, const uint8_t* in, size_t len,
|
||||
bool msb)
|
||||
{
|
||||
scramble (out, in, len, msb);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
/**
|
||||
* Performs data scrambling. The input and output buffer
|
||||
* contain one bit per byte
|
||||
* @param out the output buffer
|
||||
* @param in the input buffer
|
||||
* @param bits_num the number of bits to be scrambled
|
||||
*/
|
||||
void
|
||||
whitening::scramble_one_bit_per_byte (uint8_t* out, const uint8_t* in,
|
||||
size_t bits_num)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < bits_num; i++) {
|
||||
out[i] = in[i] ^ d_lfsr.next_bit ();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs data scrambling. The input and output buffer
|
||||
* contain one bit per byte
|
||||
* @param out the output buffer
|
||||
* @param in the input buffer
|
||||
* @param bits_num the number of bits to be scrambled
|
||||
*/
|
||||
void
|
||||
whitening::scramble_one_bit_per_byte (uint8_t* out, const uint8_t* in,
|
||||
size_t bits_num)
|
||||
{
|
||||
size_t i;
|
||||
for(i = 0; i < bits_num; i++){
|
||||
out[i] = in[i] ^ d_lfsr.next_bit();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Performs data descrambling. The input and output buffer
|
||||
* contain one bit per byte
|
||||
* @param out the output buffer
|
||||
* @param in the input buffer
|
||||
* @param bits_num the number of bits to be descrambled
|
||||
*/
|
||||
void
|
||||
whitening::descramble_one_bit_per_byte (uint8_t* out, const uint8_t* in,
|
||||
size_t bits_num)
|
||||
{
|
||||
scramble_one_bit_per_byte (out, in, bits_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs data descrambling. The input and output buffer
|
||||
* contain one bit per byte
|
||||
* @param out the output buffer
|
||||
* @param in the input buffer
|
||||
* @param bits_num the number of bits to be descrambled
|
||||
*/
|
||||
void
|
||||
whitening::descramble_one_bit_per_byte (uint8_t* out, const uint8_t* in,
|
||||
size_t bits_num)
|
||||
{
|
||||
scramble_one_bit_per_byte(out, in, bits_num);
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
} /* namespace satnogs */
|
||||
} /* namespace gr */
|
||||
|
|
Loading…
Reference in New Issue