Improve the performance of AX.25 decoder

* Decrease false frame detection alarms that can reduce the number of
succesfully decoded frames
* Fix and improve the AX.25 bit stuffing mechanism
This commit is contained in:
Manolis Surligas 2016-08-07 02:11:59 +03:00
parent 265f526b69
commit 5056189d5e
5 changed files with 83 additions and 29 deletions

View File

@ -4,7 +4,7 @@
<key>satnogs_ax25_decoder_bm</key>
<category>satnogs</category>
<import>import satnogs</import>
<make>satnogs.ax25_decoder_bm($addr, $ssid, $promisc, $descrambling, $max_frame_len)</make>
<make>satnogs.ax25_decoder_bm($addr, $ssid, $promisc, $descrambling, $max_frame_len, $n_sync_flags)</make>
<param>
<name>Receiver Callsign</name>
@ -55,6 +55,13 @@
<value>256</value>
<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>

View File

@ -299,11 +299,9 @@ namespace gr
size_t postamble_len)
{
uint8_t bit;
uint8_t prev_bit = 0;
uint8_t shift_reg = 0x0;
size_t out_idx = 0;
size_t bit_idx;
size_t cont_1 = 0;
size_t total_cont_1 = 0;
size_t i;
/* Leading FLAG field does not need bit stuffing */
@ -316,28 +314,13 @@ namespace gr
buffer += preamble_len;
for(i = 0; i < 8 * (buffer_len - preamble_len - postamble_len); i++){
bit = (buffer[i / 8] >> ( i % 8)) & 0x1;
shift_reg = (shift_reg << 1) | bit;
out[out_idx++] = bit;
/* Check if bit stuffing should be applied */
if(bit & prev_bit){
cont_1++;
total_cont_1++;
if(cont_1 == 4){
out[out_idx++] = 0;
cont_1 = 0;
}
}
else{
cont_1 = total_cont_1 = 0;
}
prev_bit = bit;
/*
* If the total number of continuous 1's is 15 the the frame should be
* dropped
*/
if(total_cont_1 >= 14) {
return AX25_ENC_FAIL;
if( (shift_reg & 0x1F) == 0x1F){
out[out_idx++] = 0x0;
shift_reg = 0x0;
}
}

View File

@ -74,12 +74,17 @@ 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 max_frame_len = 512,
size_t n_sync_flags = 2);
};
} // namespace satnogs

View File

@ -34,11 +34,13 @@ 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)
bool descramble, size_t max_frame_len,
size_t n_sync_flags)
{
return gnuradio::get_initial_sptr (
new ax25_decoder_bm_impl (addr, ssid, promisc,
descramble, max_frame_len));
descramble, max_frame_len,
n_sync_flags));
}
/*
@ -47,18 +49,21 @@ 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 max_frame_len,
size_t n_sync_flags) :
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 (
@ -101,6 +106,22 @@ namespace gr
}
break;
case IN_SYNC:
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) {
enter_decoding_state();
}
}
if(d_received_bytes > 3){
reset_state();
}
}
break;
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
@ -140,6 +161,7 @@ namespace gr
/*Check if the frame limit was reached */
if(d_received_bytes >= d_max_frame_len) {
LOG_WARN("Wrong size");
message_port_pub (
pmt::mp ("failed_pdu"),
pmt::make_blob (d_frame_buffer, d_max_frame_len));
@ -192,6 +214,22 @@ namespace gr
}
break;
case IN_SYNC:
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) {
enter_decoding_state ();
}
}
if (d_received_bytes > 3) {
reset_state ();
}
}
break;
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
@ -231,6 +269,7 @@ namespace gr
/*Check if the frame limit was reached */
if (d_received_bytes >= d_max_frame_len) {
LOG_WARN("Wrong size");
message_port_pub (
pmt::mp ("failed_pdu"),
pmt::make_blob (d_frame_buffer, d_max_frame_len));
@ -277,6 +316,7 @@ namespace gr
d_decoded_bits = 0;
d_received_bytes = 0;
d_prev_bit_nrzi = 0;
d_sync_received = 0;
}
void
@ -287,6 +327,17 @@ 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 ()
{
d_state = DECODING;
d_dec_b = 0x0;
d_shift_reg = 0x0;
d_decoded_bits = 0;
d_received_bytes = 0;
}
void
@ -303,6 +354,7 @@ namespace gr
d_shift_reg = 0x0;
d_decoded_bits = 0;
d_received_bytes = 0;
d_sync_received = 0;
d_state = FRAME_END;
return;
}
@ -323,11 +375,13 @@ namespace gr
pmt::mp ("failed_pdu"),
pmt::make_blob (d_frame_buffer,
d_received_bytes - sizeof(uint16_t)));
LOG_WARN("Wrong crc");
}
d_dec_b = 0x0;
d_shift_reg = 0x0;
d_decoded_bits = 0;
d_received_bytes = 0;
d_sync_received = 0;
d_state = FRAME_END;
}

View File

@ -34,7 +34,7 @@ namespace gr
private:
typedef enum
{
NO_SYNC, IN_SYNC, FRAME_END
NO_SYNC, IN_SYNC, DECODING, FRAME_END
} decoding_state_t;
/**
@ -44,11 +44,13 @@ 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;
@ -58,6 +60,8 @@ namespace gr
void
enter_sync_state ();
void
enter_decoding_state ();
void
enter_frame_end ();
void
@ -67,7 +71,8 @@ namespace gr
public:
ax25_decoder_bm_impl (const std::string& addr, uint8_t ssid, bool promisc,
bool descramble, size_t max_frame_len);
bool descramble, size_t max_frame_len,
size_t n_sync_flags);
~ax25_decoder_bm_impl ();
// Where all the action really happens