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:
parent
265f526b69
commit
5056189d5e
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue