Fix AX.25 encoder/decoder
* Force the left over scrambled bits into the LFSR to be transmitted * Refactor the decoding process
This commit is contained in:
parent
d7f8d7dbad
commit
2fb1bfadfc
File diff suppressed because it is too large
Load Diff
|
@ -3,7 +3,7 @@
|
|||
<name>AX.25 Decoder</name>
|
||||
<key>satnogs_ax25_decoder_bm</key>
|
||||
<import>import satnogs</import>
|
||||
<make>satnogs.ax25_decoder_bm($addr, $ssid, $promisc, $descrambling, $max_frame_len, $n_sync_flags)</make>
|
||||
<make>satnogs.ax25_decoder_bm($addr, $ssid, $promisc, $descrambling, $max_frame_len)</make>
|
||||
|
||||
<param>
|
||||
<name>Receiver Callsign</name>
|
||||
|
@ -55,13 +55,6 @@
|
|||
<type>int</type>
|
||||
</param>
|
||||
|
||||
<param>
|
||||
<name>AX.25 Leading SYNC flags Threshold</name>
|
||||
<key>n_sync_flags</key>
|
||||
<value>2</value>
|
||||
<type>int</type>
|
||||
</param>
|
||||
|
||||
<sink>
|
||||
<name>in</name>
|
||||
<type>byte</type>
|
||||
|
|
|
@ -334,7 +334,7 @@ namespace gr
|
|||
/* Check if bit stuffing should be applied */
|
||||
if ((shift_reg & 0x1F) == 0x1F) {
|
||||
out[out_idx++] = 0x0;
|
||||
shift_reg = 0x0;
|
||||
shift_reg <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
|
||||
*
|
||||
* Copyright (C) 2016, 2017
|
||||
* Copyright (C) 2016, 2017, 2018
|
||||
* Libre Space Foundation <http://librespacefoundation.org/>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
|
@ -75,17 +75,11 @@ namespace gr
|
|||
* @param descramble if set to yes, the data will be descrambled prior
|
||||
* decoding using the G3RUH self-synchronizing descrambler.
|
||||
* @param max_frame_len the maximum allowed frame length
|
||||
* @param n_sync_flags the number of the leading AX.25 SYNC flag
|
||||
* repetitions. Normally the SYNC flag is repeated multiple times
|
||||
* prior the payload transmission. Increasing this parameter
|
||||
* reduces significantly the false alarms
|
||||
* @return
|
||||
*/
|
||||
static sptr
|
||||
make (const std::string& addr, uint8_t ssid, bool promisc = false,
|
||||
bool descramble = true,
|
||||
size_t max_frame_len = 512,
|
||||
size_t n_sync_flags = 2);
|
||||
bool descramble = true, size_t max_frame_len = 512);
|
||||
};
|
||||
|
||||
} // namespace satnogs
|
||||
|
|
|
@ -35,12 +35,11 @@ namespace gr
|
|||
|
||||
ax25_decoder_bm::sptr
|
||||
ax25_decoder_bm::make (const std::string& addr, uint8_t ssid, bool promisc,
|
||||
bool descramble, size_t max_frame_len,
|
||||
size_t n_sync_flags)
|
||||
bool descramble, size_t max_frame_len)
|
||||
{
|
||||
return gnuradio::get_initial_sptr (
|
||||
new ax25_decoder_bm_impl (addr, ssid, promisc, descramble,
|
||||
max_frame_len, n_sync_flags));
|
||||
max_frame_len));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -49,21 +48,18 @@ namespace gr
|
|||
ax25_decoder_bm_impl::ax25_decoder_bm_impl (const std::string& addr,
|
||||
uint8_t ssid, bool promisc,
|
||||
bool descramble,
|
||||
size_t max_frame_len,
|
||||
size_t n_sync_flags) :
|
||||
size_t max_frame_len) :
|
||||
gr::sync_block ("ax25_decoder_bm",
|
||||
gr::io_signature::make (1, 1, sizeof(uint8_t)),
|
||||
gr::io_signature::make (0, 0, 0)),
|
||||
d_promisc (promisc),
|
||||
d_descramble (descramble),
|
||||
d_max_frame_len (max_frame_len),
|
||||
d_sync_flags_thr (n_sync_flags - 1),
|
||||
d_state (NO_SYNC),
|
||||
d_shift_reg (0x0),
|
||||
d_dec_b (0x0),
|
||||
d_prev_bit_nrzi (0),
|
||||
d_received_bytes (0),
|
||||
d_sync_received (0),
|
||||
d_decoded_bits (0),
|
||||
d_lfsr (0x21, 0x0, 16),
|
||||
d_frame_buffer (
|
||||
|
@ -79,7 +75,7 @@ namespace gr
|
|||
message_port_register_out (pmt::mp ("failed_pdu"));
|
||||
}
|
||||
|
||||
void
|
||||
size_t
|
||||
ax25_decoder_bm_impl::descramble_and_decode (const uint8_t* in,
|
||||
size_t nitems)
|
||||
{
|
||||
|
@ -87,234 +83,184 @@ namespace gr
|
|||
uint8_t descr_bit;
|
||||
uint8_t dec_bit;
|
||||
|
||||
for (i = 0; i < nitems; i++) {
|
||||
/* Descramble the input bit */
|
||||
descr_bit = d_lfsr.next_bit_descramble (in[i]);
|
||||
|
||||
/* Perform NRZI decoding */
|
||||
dec_bit = (~((descr_bit - d_prev_bit_nrzi) % 2)) & 0x1;
|
||||
d_prev_bit_nrzi = descr_bit;
|
||||
|
||||
/* In AX.25 the LS bit is sent first */
|
||||
d_shift_reg = (d_shift_reg >> 1) | (dec_bit << 7);
|
||||
d_dec_b = (d_dec_b >> 1) | (dec_bit << 7);
|
||||
|
||||
switch (d_state)
|
||||
{
|
||||
case NO_SYNC:
|
||||
for (i = 0; i < nitems; i++) {
|
||||
descramble_and_decode_1b (in[i]);
|
||||
if (d_shift_reg == AX25_SYNC_FLAG) {
|
||||
/*
|
||||
* If the user asked for only one leading AX.25 SYNC flag
|
||||
* start immediately the decoding
|
||||
*/
|
||||
if (d_sync_flags_thr == 0) {
|
||||
enter_decoding_state ();
|
||||
}
|
||||
else {
|
||||
enter_sync_state ();
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
return nitems;
|
||||
case IN_SYNC:
|
||||
/*
|
||||
* Most of the transmitters repeat several times the AX.25 SYNC
|
||||
* In case of G3RUH this is mandatory to allow the self synchronizing
|
||||
* scrambler to settle
|
||||
*/
|
||||
for (i = 0; i < nitems; i++) {
|
||||
descramble_and_decode_1b (in[i]);
|
||||
d_decoded_bits++;
|
||||
if(d_decoded_bits == 8) {
|
||||
d_received_bytes++;
|
||||
d_decoded_bits = 0;
|
||||
if (d_shift_reg == AX25_SYNC_FLAG) {
|
||||
d_sync_received++;
|
||||
if (d_sync_received > d_sync_flags_thr) {
|
||||
/* Perhaps we are in frame! */
|
||||
if(d_shift_reg != AX25_SYNC_FLAG) {
|
||||
enter_decoding_state();
|
||||
return i+1;
|
||||
}
|
||||
d_decoded_bits = 0;
|
||||
}
|
||||
}
|
||||
if (d_received_bytes > 3) {
|
||||
reset_state ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
return nitems;
|
||||
case DECODING:
|
||||
/*
|
||||
* If the received byte was an AX.25 sync flag, there are two
|
||||
* possibilities. Either it was the end of frame or just a repeat of the
|
||||
* preamble.
|
||||
*
|
||||
* Also in case in error at the preamble, the G3RUH polynomial should
|
||||
* re-sync after 3 repetitions of the SYNC flag. For this reason we demand
|
||||
* that the distance between the last SYNC flag is greater than 3 bytes
|
||||
*/
|
||||
for (i = 0; i < nitems; i++) {
|
||||
descramble_and_decode_1b (in[i]);
|
||||
if (d_shift_reg == AX25_SYNC_FLAG) {
|
||||
if (d_received_bytes < 3) {
|
||||
enter_sync_state ();
|
||||
}
|
||||
else {
|
||||
/* Frame end */
|
||||
LOG_DEBUG("Found frame end");
|
||||
enter_frame_end();
|
||||
}
|
||||
return i+1;
|
||||
}
|
||||
else if ((d_shift_reg & 0xfc) == 0x7c) {
|
||||
/*This was a stuffed bit */
|
||||
d_dec_b <<= 1;
|
||||
}
|
||||
else if((d_shift_reg & 0xfe) == 0xfe) {
|
||||
/*This can never happen... Error! */
|
||||
if (d_received_bytes > AX25_MIN_ADDR_LEN) {
|
||||
message_port_pub (
|
||||
pmt::mp ("failed_pdu"),
|
||||
pmt::make_blob (d_frame_buffer, d_received_bytes));
|
||||
}
|
||||
LOG_DEBUG("Invalid shift register value %u", d_received_bytes);
|
||||
reset_state ();
|
||||
return i+1;
|
||||
}
|
||||
else{
|
||||
d_decoded_bits++;
|
||||
if(d_decoded_bits == 8) {
|
||||
d_frame_buffer[d_received_bytes++] = d_dec_b;
|
||||
d_frame_buffer[d_received_bytes] = d_dec_b;
|
||||
d_received_bytes++;
|
||||
d_decoded_bits = 0;
|
||||
|
||||
/*Check if the frame limit was reached */
|
||||
if (d_received_bytes >= d_max_frame_len) {
|
||||
LOG_WARN("Wrong size");
|
||||
LOG_DEBUG("Wrong size");
|
||||
message_port_pub (
|
||||
pmt::mp ("failed_pdu"),
|
||||
pmt::make_blob (d_frame_buffer, d_max_frame_len));
|
||||
reset_state ();
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return nitems;
|
||||
case FRAME_END:
|
||||
if (d_shift_reg == AX25_SYNC_FLAG) {
|
||||
d_dec_b = 0;
|
||||
d_decoded_bits = 0;
|
||||
d_received_bytes = 0;
|
||||
d_state = FRAME_END;
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < nitems; i++) {
|
||||
descramble_and_decode_1b (in[i]);
|
||||
d_decoded_bits++;
|
||||
if (d_decoded_bits / 8 > 3) {
|
||||
if (d_decoded_bits == 8) {
|
||||
/* Repetitions of the trailing SYNC flag finished */
|
||||
if (d_shift_reg != AX25_SYNC_FLAG) {
|
||||
reset_state();
|
||||
return i + 1;
|
||||
}
|
||||
d_decoded_bits = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
return nitems;
|
||||
default:
|
||||
LOG_ERROR("Invalid decoding state");
|
||||
}
|
||||
reset_state();
|
||||
return nitems;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
size_t
|
||||
ax25_decoder_bm_impl::decode (const uint8_t* in, size_t nitems)
|
||||
{
|
||||
size_t i;
|
||||
uint8_t descr_bit;
|
||||
uint8_t dec_bit;
|
||||
|
||||
for (i = 0; i < nitems; i++) {
|
||||
|
||||
/* Perform NRZI decoding */
|
||||
dec_bit = (~(((in[i] & 0x1) - d_prev_bit_nrzi) % 2)) & 0x1;
|
||||
d_prev_bit_nrzi = in[i] & 0x1;
|
||||
|
||||
/* In AX.25 the LS bit is sent first */
|
||||
d_shift_reg = (d_shift_reg >> 1) | (dec_bit << 7);
|
||||
d_dec_b = (d_dec_b >> 1) | (dec_bit << 7);
|
||||
|
||||
switch (d_state)
|
||||
{
|
||||
case NO_SYNC:
|
||||
for (i = 0; i < nitems; i++) {
|
||||
decode_1b (in[i]);
|
||||
if (d_shift_reg == AX25_SYNC_FLAG) {
|
||||
/*
|
||||
* If the user asked for only one leading AX.25 SYNC flag
|
||||
* start immediately the decoding
|
||||
*/
|
||||
if(d_sync_flags_thr == 0) {
|
||||
enter_decoding_state ();
|
||||
}
|
||||
else {
|
||||
enter_sync_state ();
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
return nitems;
|
||||
case IN_SYNC:
|
||||
/*
|
||||
* Most of the transmitters repeat several times the AX.25 SYNC
|
||||
* In case of G3RUH this is mandatory to allow the self synchronizing
|
||||
* scrambler to settle
|
||||
*/
|
||||
for (i = 0; i < nitems; i++) {
|
||||
decode_1b (in[i]);
|
||||
d_decoded_bits++;
|
||||
if (d_decoded_bits == 8) {
|
||||
d_received_bytes++;
|
||||
d_decoded_bits = 0;
|
||||
if (d_shift_reg == AX25_SYNC_FLAG) {
|
||||
d_sync_received++;
|
||||
if (d_sync_received > d_sync_flags_thr) {
|
||||
/* Perhaps we are in frame! */
|
||||
if (d_shift_reg != AX25_SYNC_FLAG) {
|
||||
enter_decoding_state ();
|
||||
return i + 1;
|
||||
}
|
||||
d_decoded_bits = 0;
|
||||
}
|
||||
}
|
||||
if (d_received_bytes > 3) {
|
||||
reset_state ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
return nitems;
|
||||
case DECODING:
|
||||
/*
|
||||
* If the received byte was an AX.25 sync flag, there are two
|
||||
* possibilities. Either it was the end of frame or just a repeat of the
|
||||
* preamble.
|
||||
*
|
||||
* Also in case in error at the preamble, the G3RUH polynomial should
|
||||
* re-sync after 3 repetitions of the SYNC flag. For this reason we demand
|
||||
* that the distance between the last SYNC flag is greater than 3 bytes
|
||||
*/
|
||||
for (i = 0; i < nitems; i++) {
|
||||
decode_1b (in[i]);
|
||||
if (d_shift_reg == AX25_SYNC_FLAG) {
|
||||
if (d_received_bytes < 3) {
|
||||
enter_sync_state ();
|
||||
}
|
||||
else {
|
||||
/* Frame end */
|
||||
enter_frame_end ();
|
||||
}
|
||||
return i + 1;
|
||||
}
|
||||
else if ((d_shift_reg & 0xfc) == 0x7c) {
|
||||
/*This was a stuffed bit */
|
||||
d_dec_b <<= 1;
|
||||
}
|
||||
else if ((d_shift_reg & 0xfe) == 0xfe) {
|
||||
/*This can never happen... Error! */
|
||||
if (d_received_bytes > AX25_MIN_ADDR_LEN) {
|
||||
message_port_pub (
|
||||
pmt::mp ("failed_pdu"),
|
||||
pmt::make_blob (d_frame_buffer, d_received_bytes));
|
||||
}
|
||||
LOG_DEBUG("Invalid shift register value");
|
||||
reset_state ();
|
||||
return i + 1;
|
||||
}
|
||||
else {
|
||||
d_decoded_bits++;
|
||||
if (d_decoded_bits == 8) {
|
||||
d_frame_buffer[d_received_bytes++] = d_dec_b;
|
||||
d_frame_buffer[d_received_bytes] = d_dec_b;
|
||||
d_received_bytes++;
|
||||
d_decoded_bits = 0;
|
||||
|
||||
/*Check if the frame limit was reached */
|
||||
if (d_received_bytes >= d_max_frame_len) {
|
||||
LOG_WARN("Wrong size");
|
||||
LOG_DEBUG("Wrong size");
|
||||
message_port_pub (
|
||||
pmt::mp ("failed_pdu"),
|
||||
pmt::make_blob (d_frame_buffer, d_max_frame_len));
|
||||
reset_state ();
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return nitems;
|
||||
case FRAME_END:
|
||||
if (d_shift_reg == AX25_SYNC_FLAG) {
|
||||
d_dec_b = 0x0;
|
||||
d_shift_reg = 0x0;
|
||||
d_decoded_bits = 0;
|
||||
d_received_bytes = 0;
|
||||
d_state = FRAME_END;
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < nitems; i++) {
|
||||
decode_1b (in[i]);
|
||||
d_decoded_bits++;
|
||||
if (d_decoded_bits / 8 > 3) {
|
||||
if (d_decoded_bits == 8) {
|
||||
/* Repetitions of the trailing SYNC flag finished */
|
||||
if (d_shift_reg != AX25_SYNC_FLAG) {
|
||||
reset_state ();
|
||||
return i + 1;
|
||||
}
|
||||
d_decoded_bits = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
return nitems;
|
||||
default:
|
||||
LOG_ERROR("Invalid decoding state");
|
||||
}
|
||||
reset_state ();
|
||||
return nitems;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -335,7 +281,6 @@ namespace gr
|
|||
d_decoded_bits = 0;
|
||||
d_received_bytes = 0;
|
||||
d_prev_bit_nrzi = 0;
|
||||
d_sync_received = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -346,19 +291,45 @@ namespace gr
|
|||
d_shift_reg = 0x0;
|
||||
d_decoded_bits = 0;
|
||||
d_received_bytes = 0;
|
||||
d_sync_received = 0;
|
||||
}
|
||||
|
||||
void
|
||||
ax25_decoder_bm_impl::enter_decoding_state ()
|
||||
{
|
||||
uint8_t tmp;
|
||||
d_state = DECODING;
|
||||
d_dec_b = 0x0;
|
||||
d_shift_reg = 0x0;
|
||||
d_decoded_bits = 0;
|
||||
d_shift_reg = 0x0;
|
||||
|
||||
/*
|
||||
* Due to the possibility of bit stuffing on the first byte some special
|
||||
* handling is necessary
|
||||
*/
|
||||
tmp = d_dec_b;
|
||||
d_dec_b = 0x0;
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
d_shift_reg = (d_shift_reg >> 1) | (((tmp >> i) & 0x1) << 7);
|
||||
d_dec_b = (d_dec_b >> 1) | (((tmp >> i) & 0x1) << 7);
|
||||
if ((d_shift_reg & 0xfc) == 0x7c) {
|
||||
/*This was a stuffed bit */
|
||||
d_dec_b <<= 1;
|
||||
}
|
||||
else{
|
||||
d_decoded_bits++;
|
||||
}
|
||||
}
|
||||
|
||||
if(d_decoded_bits == 8) {
|
||||
d_frame_buffer[0] = d_dec_b;
|
||||
d_decoded_bits = 0;
|
||||
d_received_bytes = 1;
|
||||
}
|
||||
else {
|
||||
d_received_bytes = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ax25_decoder_bm_impl::enter_frame_end ()
|
||||
{
|
||||
|
@ -373,7 +344,6 @@ namespace gr
|
|||
d_shift_reg = 0x0;
|
||||
d_decoded_bits = 0;
|
||||
d_received_bytes = 0;
|
||||
d_sync_received = 0;
|
||||
d_state = FRAME_END;
|
||||
return;
|
||||
}
|
||||
|
@ -400,25 +370,72 @@ namespace gr
|
|||
d_shift_reg = 0x0;
|
||||
d_decoded_bits = 0;
|
||||
d_received_bytes = 0;
|
||||
d_sync_received = 0;
|
||||
d_state = FRAME_END;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs descrambling and NRZI decoding of an input bit.
|
||||
* The decoded bit is then shifted in front of the d_shift_reg and the d_dec_b
|
||||
* variables. This shift in front is due to the LS bit first transmission
|
||||
* of the Ax.25 protocol.
|
||||
*
|
||||
* @param in input bit
|
||||
*/
|
||||
inline void
|
||||
ax25_decoder_bm_impl::descramble_and_decode_1b (uint8_t in)
|
||||
{
|
||||
uint8_t descr_bit;
|
||||
uint8_t dec_bit;
|
||||
|
||||
in &= 0x1;
|
||||
|
||||
/* Perform NRZI decoding */
|
||||
dec_bit = (~((in - d_prev_bit_nrzi) % 2)) & 0x1;
|
||||
d_prev_bit_nrzi = in;
|
||||
|
||||
|
||||
/* Descramble the input bit */
|
||||
descr_bit = d_lfsr.next_bit_descramble (dec_bit);
|
||||
|
||||
/* In AX.25 the LS bit is sent first */
|
||||
d_shift_reg = (d_shift_reg >> 1) | (descr_bit << 7);
|
||||
d_dec_b = (d_dec_b >> 1) | (descr_bit << 7);
|
||||
}
|
||||
|
||||
inline void
|
||||
ax25_decoder_bm_impl::decode_1b (uint8_t in)
|
||||
{
|
||||
uint8_t dec_bit;
|
||||
in &= 0x1;
|
||||
|
||||
/* Perform NRZI decoding */
|
||||
dec_bit = (~((in - d_prev_bit_nrzi) % 2)) & 0x1;
|
||||
d_prev_bit_nrzi = in;
|
||||
|
||||
/* In AX.25 the LS bit is sent first */
|
||||
d_shift_reg = (d_shift_reg >> 1) | (dec_bit << 7);
|
||||
d_dec_b = (d_dec_b >> 1) | (dec_bit << 7);
|
||||
}
|
||||
|
||||
int
|
||||
ax25_decoder_bm_impl::work (int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *in = (const uint8_t *) input_items[0];
|
||||
|
||||
|
||||
if(noutput_items < 1) {
|
||||
return noutput_items;
|
||||
}
|
||||
if (d_descramble) {
|
||||
descramble_and_decode (in, noutput_items);
|
||||
ret = descramble_and_decode (in, noutput_items);
|
||||
}
|
||||
else {
|
||||
decode (in, noutput_items);
|
||||
ret = decode (in, noutput_items);
|
||||
}
|
||||
return noutput_items;
|
||||
return ret;
|
||||
}
|
||||
|
||||
} /* namespace satnogs */
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
/*
|
||||
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
|
||||
*
|
||||
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
|
||||
* Copyright (C) 2016,2018
|
||||
* 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
|
||||
|
@ -44,13 +45,11 @@ namespace gr
|
|||
const bool d_promisc;
|
||||
const bool d_descramble;
|
||||
const size_t d_max_frame_len;
|
||||
const size_t d_sync_flags_thr;
|
||||
decoding_state_t d_state;
|
||||
uint8_t d_shift_reg;
|
||||
uint8_t d_dec_b;
|
||||
uint8_t d_prev_bit_nrzi;
|
||||
size_t d_received_bytes;
|
||||
size_t d_sync_received;
|
||||
size_t d_decoded_bits;
|
||||
digital::lfsr d_lfsr;
|
||||
uint8_t *d_frame_buffer;
|
||||
|
@ -64,15 +63,20 @@ namespace gr
|
|||
void
|
||||
enter_frame_end ();
|
||||
|
||||
void
|
||||
size_t
|
||||
descramble_and_decode (const uint8_t *in, size_t nitems);
|
||||
void
|
||||
size_t
|
||||
decode (const uint8_t *in, size_t nitems);
|
||||
|
||||
inline void
|
||||
descramble_and_decode_1b (uint8_t in);
|
||||
inline void
|
||||
decode_1b (uint8_t in);
|
||||
|
||||
|
||||
public:
|
||||
ax25_decoder_bm_impl (const std::string& addr, uint8_t ssid, bool promisc,
|
||||
bool descramble, size_t max_frame_len,
|
||||
size_t n_sync_flags);
|
||||
bool descramble, size_t max_frame_len);
|
||||
~ax25_decoder_bm_impl ();
|
||||
|
||||
// Where all the action really happens
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
/*
|
||||
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
|
||||
*
|
||||
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
|
||||
* Copyright (C) 2016,2018
|
||||
* 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
|
||||
|
@ -62,8 +63,8 @@ namespace gr
|
|||
d_produced (0),
|
||||
d_prev_bit (0x0),
|
||||
d_encoded_frame (
|
||||
new uint8_t[preamble_len + postabmle_len
|
||||
+ (AX25_MAX_FRAME_LEN * 2)]),
|
||||
new uint8_t[(preamble_len + postabmle_len
|
||||
+ (AX25_MAX_FRAME_LEN * 2)) * 8]),
|
||||
d_tmp_buf (
|
||||
new uint8_t[preamble_len + postabmle_len
|
||||
+ (AX25_MAX_FRAME_LEN * 2)]),
|
||||
|
@ -103,7 +104,6 @@ namespace gr
|
|||
|
||||
/* If all the frame samples have already be sent, wait for a new frame */
|
||||
if (d_remaining == 0) {
|
||||
boost::mutex::scoped_lock lock (d_mutex);
|
||||
d_produced = 0;
|
||||
d_prev_bit = 0x0;
|
||||
d_lfsr.reset ();
|
||||
|
@ -132,6 +132,15 @@ namespace gr
|
|||
for (i = 0; i < d_remaining; i++) {
|
||||
d_encoded_frame[i] = d_lfsr.next_bit_scramble (d_encoded_frame[i]);
|
||||
}
|
||||
/* Allow the LFSR to pop all its bits */
|
||||
d_remaining += 16;
|
||||
for (; i < d_remaining; i++) {
|
||||
d_encoded_frame[i] = d_lfsr.next_bit_scramble (0x0);
|
||||
}
|
||||
}
|
||||
/* Append a zero byte at the end */
|
||||
memset(&d_encoded_frame[d_remaining], 0, 8);
|
||||
d_remaining += 8;
|
||||
}
|
||||
|
||||
/* If this is the first part of the frame add the start of burst tag*/
|
||||
|
@ -154,10 +163,6 @@ namespace gr
|
|||
return (int) max_avail;
|
||||
}
|
||||
|
||||
// Tell runtime system how many output items we produced.
|
||||
return noutput_items;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ax25_encoder_mb_impl::add_sob (uint64_t item)
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
/*
|
||||
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
|
||||
*
|
||||
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
|
||||
* Copyright (C) 2016,2018
|
||||
* 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
|
||||
|
@ -43,7 +44,6 @@ namespace gr
|
|||
uint8_t *d_addr_field;
|
||||
size_t d_addr_len;
|
||||
digital::lfsr d_lfsr;
|
||||
boost::mutex d_mutex;
|
||||
|
||||
void
|
||||
add_sob (uint64_t item);
|
||||
|
|
|
@ -55,7 +55,8 @@ namespace gr
|
|||
if(d_timestamp) {
|
||||
std::time_t t = std::time(nullptr);
|
||||
std::tm tm = *std::localtime(&t);
|
||||
d_fos << "[" << strftime(buf, sizeof(buf), "%F %T %z", &tm) << "]";
|
||||
strftime(buf, sizeof(buf), "%F %T %z", &tm);
|
||||
d_fos << "[" << buf << "]";
|
||||
}
|
||||
|
||||
switch (d_format)
|
||||
|
|
Loading…
Reference in New Issue