diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index c260c62..e76e60c 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -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 ) diff --git a/grc/satnogs_whitening.xml b/grc/satnogs_whitening.xml new file mode 100644 index 0000000..66815b7 --- /dev/null +++ b/grc/satnogs_whitening.xml @@ -0,0 +1,38 @@ + + + whitening + satnogs_whitening + satnogs + import satnogs + satnogs.whitening($mask, $seed, $order) + + + ... + ... + ... + + + + + in + + + + + + out + + + diff --git a/include/satnogs/CMakeLists.txt b/include/satnogs/CMakeLists.txt index 32e4a5d..802df56 100644 --- a/include/satnogs/CMakeLists.txt +++ b/include/satnogs/CMakeLists.txt @@ -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 ) diff --git a/include/satnogs/whitening.h b/include/satnogs/whitening.h new file mode 100644 index 0000000..e68117f --- /dev/null +++ b/include/satnogs/whitening.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * 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 . + */ + +#ifndef INCLUDED_SATNOGS_WHITENING_H +#define INCLUDED_SATNOGS_WHITENING_H + +#include + +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 */ + diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index d7e88bb..870bf06 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -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) diff --git a/lib/upsat_fsk_frame_acquisition_impl.cc b/lib/upsat_fsk_frame_acquisition_impl.cc index bea3176..c150e1e 100644 --- a/lib/upsat_fsk_frame_acquisition_impl.cc +++ b/lib/upsat_fsk_frame_acquisition_impl.cc @@ -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"), diff --git a/lib/upsat_fsk_frame_acquisition_impl.h b/lib/upsat_fsk_frame_acquisition_impl.h index ad8a1cb..750224e 100644 --- a/lib/upsat_fsk_frame_acquisition_impl.h +++ b/lib/upsat_fsk_frame_acquisition_impl.h @@ -23,6 +23,7 @@ #include #include +#include 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 diff --git a/lib/upsat_fsk_frame_encoder_impl.cc b/lib/upsat_fsk_frame_encoder_impl.cc index 8fae92a..7b2e0f6 100644 --- a/lib/upsat_fsk_frame_encoder_impl.cc +++ b/lib/upsat_fsk_frame_encoder_impl.cc @@ -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; } diff --git a/lib/upsat_fsk_frame_encoder_impl.h b/lib/upsat_fsk_frame_encoder_impl.h index cffd0c6..0952e0d 100644 --- a/lib/upsat_fsk_frame_encoder_impl.h +++ b/lib/upsat_fsk_frame_encoder_impl.h @@ -22,6 +22,7 @@ #define INCLUDED_SATNOGS_UPSAT_FSK_FRAME_ENCODER_IMPL_H #include +#include 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 diff --git a/lib/whitening.cc b/lib/whitening.cc new file mode 100644 index 0000000..3c54afa --- /dev/null +++ b/lib/whitening.cc @@ -0,0 +1,109 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * 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 . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +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 */ + diff --git a/swig/satnogs_swig.i b/swig/satnogs_swig.i index ebec1e7..9e1f567 100644 --- a/swig/satnogs_swig.i +++ b/swig/satnogs_swig.i @@ -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"