Improve and make more generic the whitening mechanism
* The AX.25 framing now supports whitening. * Change again the AFSK flowgraph.
This commit is contained in:
parent
bfa2313242
commit
a22d37e961
File diff suppressed because it is too large
Load Diff
|
@ -22,6 +22,7 @@
|
|||
#define INCLUDED_SATNOGS_WHITENING_H
|
||||
|
||||
#include <satnogs/api.h>
|
||||
#include <gnuradio/digital/lfsr.h>
|
||||
|
||||
namespace gr
|
||||
{
|
||||
|
@ -36,7 +37,6 @@ namespace gr
|
|||
{
|
||||
public:
|
||||
whitening (uint32_t mask, uint32_t seed, uint32_t order);
|
||||
~whitening ();
|
||||
|
||||
void
|
||||
reset();
|
||||
|
@ -44,10 +44,15 @@ namespace gr
|
|||
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_one_bit_per_byte (uint8_t *out, const uint8_t *in,
|
||||
size_t bits_num);
|
||||
void
|
||||
descramble_one_bit_per_byte (uint8_t *out, const uint8_t *in,
|
||||
size_t bits_num);
|
||||
|
||||
private:
|
||||
const size_t d_lut_len;
|
||||
size_t d_lut_idx;
|
||||
uint8_t *d_lut;
|
||||
digital::lfsr d_lfsr;
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace gr
|
|||
d_decoded_bytes (0),
|
||||
d_decoded_bits (0),
|
||||
d_frame_len (0),
|
||||
d_descrambler(0x21, 0x1FF, 9)
|
||||
d_descrambler(0x1001, 0x1FF, 17)
|
||||
{
|
||||
size_t i;
|
||||
message_port_register_out (pmt::mp ("pdu"));
|
||||
|
@ -183,6 +183,7 @@ namespace gr
|
|||
{
|
||||
size_t i;
|
||||
uint8_t *in = d_pdu + 1;
|
||||
|
||||
for(i = 0; i < len_bytes; i++){
|
||||
d_ax25_tmp_buf[8*i] = (in[i] >> 7) & 0x1;
|
||||
d_ax25_tmp_buf[8*i + 1] = (in[i] >> 6) & 0x1;
|
||||
|
@ -193,6 +194,13 @@ namespace gr
|
|||
d_ax25_tmp_buf[8*i + 6] = (in[i] >> 1) & 0x1;
|
||||
d_ax25_tmp_buf[8*i + 7] = in[i] & 0x1;
|
||||
}
|
||||
|
||||
/* De-white the data if necessary */
|
||||
if (d_whitening) {
|
||||
d_descrambler.descramble_one_bit_per_byte (d_ax25_tmp_buf,
|
||||
d_ax25_tmp_buf,
|
||||
len_bytes * 8);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -298,6 +306,7 @@ namespace gr
|
|||
|
||||
if (d_decoded_bytes == d_frame_len) {
|
||||
if(d_is_ax25) {
|
||||
|
||||
unpack_ax25_bytes(d_frame_len - 1);
|
||||
status = ax25_decode(d_ax25_buf, &ax25_frame_len,
|
||||
d_ax25_tmp_buf, (d_frame_len - 1)*8);
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace gr
|
|||
d_settling_samples(settling_samples),
|
||||
d_encoded(0),
|
||||
d_pdu_len(0),
|
||||
d_scrambler(0x21, 0x1FF, 9)
|
||||
d_scrambler(0x1001, 0x1FF, 17)
|
||||
{
|
||||
/* Simplify the logic of the output samples handling */
|
||||
set_output_multiple(8);
|
||||
|
@ -294,6 +294,7 @@ namespace gr
|
|||
ax25_encode_status_t status;
|
||||
size_t extra_bits;
|
||||
size_t i;
|
||||
uint8_t len_field;
|
||||
|
||||
/*
|
||||
* If the whole previous frame has been successfully sent, block waiting
|
||||
|
@ -314,6 +315,7 @@ namespace gr
|
|||
len = ax25_prepare_frame(d_ax25_tmp_buf, (uint8_t *) pmt::blob_data (pdu),
|
||||
d_pdu_len, AX25_UI_FRAME, d_ax25_addr,
|
||||
d_ax25_addr_len, 0x03, 1);
|
||||
|
||||
status = ax25_bit_stuffing(d_ax25_pdu, &encoded_len,
|
||||
d_ax25_tmp_buf, len);
|
||||
if(status != AX25_ENC_OK) {
|
||||
|
@ -335,22 +337,23 @@ namespace gr
|
|||
* the address field (if exists) and the payload. Length and CRC fields
|
||||
* are NOT included.
|
||||
*/
|
||||
d_pdu[d_preamble_len + d_sync_word_len] = (uint8_t) (encoded_len/8);
|
||||
len_field = (uint8_t) (encoded_len/8);
|
||||
|
||||
/* Apply whitening */
|
||||
if (d_whitening) {
|
||||
d_scrambler.reset ();
|
||||
d_scrambler.scramble(&len_field, &len_field, 1);
|
||||
d_scrambler.scramble_one_bit_per_byte (d_ax25_pdu, d_ax25_pdu,
|
||||
encoded_len);
|
||||
}
|
||||
|
||||
d_pdu[d_preamble_len + d_sync_word_len] = len_field;
|
||||
|
||||
/* If it is necessary calculate and append the CRC */
|
||||
if (d_append_crc) {
|
||||
LOG_WARN("AX.25 has its own CRC-16 field. Skipping...");
|
||||
}
|
||||
|
||||
/*
|
||||
* Whitening can not be applied in the AX.25 because it will alter
|
||||
* the SYNC flag of the stack
|
||||
*/
|
||||
if (d_whitening) {
|
||||
LOG_WARN("AX.25 and whitening are not compatible."
|
||||
" No whitening will be performed");
|
||||
}
|
||||
|
||||
d_pdu_len = d_preamble_len + d_sync_word_len + 1 + encoded_len/8;
|
||||
|
||||
/* NRZ encoding the FSK preamble with the standard method */
|
||||
|
|
|
@ -37,33 +37,11 @@ namespace gr {
|
|||
* 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)
|
||||
d_lfsr(mask, seed, order)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,7 +51,7 @@ namespace gr {
|
|||
void
|
||||
whitening::reset ()
|
||||
{
|
||||
d_lut_idx = 0;
|
||||
d_lfsr.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,10 +64,18 @@ namespace gr {
|
|||
whitening::scramble (uint8_t* out, const uint8_t* in, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
uint8_t b;
|
||||
for(i = 0; i < len; i++){
|
||||
out[i] = in[i] ^ d_lut[ (d_lut_idx + i ) % d_lut_len];
|
||||
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;
|
||||
}
|
||||
d_lut_idx = (d_lut_idx + len ) % d_lut_len;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,6 +90,36 @@ namespace gr {
|
|||
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 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 gr */
|
||||
|
||||
|
|
Loading…
Reference in New Issue