diff --git a/grc/satnogs_upsat_fsk_frame_acquisition.xml b/grc/satnogs_upsat_fsk_frame_acquisition.xml
index f06b07e..9e4e83b 100644
--- a/grc/satnogs_upsat_fsk_frame_acquisition.xml
+++ b/grc/satnogs_upsat_fsk_frame_acquisition.xml
@@ -4,7 +4,7 @@
satnogs_upsat_fsk_frame_acquisitionsatnogsimport satnogs
- satnogs.upsat_fsk_frame_acquisition($preamble, $sync_word, $whitening, $manchester, $check_crc)
+ satnogs.upsat_fsk_frame_acquisition($preamble, $sync_word, $whitening, $manchester, $check_crc, $ax_25)Frame Preamble
@@ -60,6 +60,20 @@
+
+ Use AX.25 encapsulation
+ ax_25
+ enum
+
+
+
+
infloat
diff --git a/grc/satnogs_upsat_fsk_frame_encoder.xml b/grc/satnogs_upsat_fsk_frame_encoder.xml
index 95bef59..9d5369c 100644
--- a/grc/satnogs_upsat_fsk_frame_encoder.xml
+++ b/grc/satnogs_upsat_fsk_frame_encoder.xml
@@ -4,7 +4,7 @@
satnogs_upsat_fsk_frame_encodersatnogsimport satnogs
- satnogs.upsat_fsk_frame_encoder($preamble, $sync_word, $append_crc, $whitening, $manchester, $msb_first, $settling_samples)
+ satnogs.upsat_fsk_frame_encoder($preamble, $sync_word, $append_crc, $whitening, $manchester, $msb_first, $ax_25, $settling_samples)Frame Preamble
@@ -74,6 +74,20 @@
+
+ Use AX.25 encapsulation
+ ax_25
+ enum
+
+
+
+
Number of zero settling samplessettling_samples
diff --git a/include/satnogs/ax25.h b/include/satnogs/ax25.h
index 5d46fc2..e0c3f3a 100644
--- a/include/satnogs/ax25.h
+++ b/include/satnogs/ax25.h
@@ -36,6 +36,7 @@ namespace gr
const uint8_t AX25_SYNC_FLAG = 0x7E;
const uint8_t AX25_CALLSIGN_MAX_LEN = 6;
const float AX25_SYNC_FLAG_MAP[8] = {-1, 1, 1, 1, 1, 1, 1, -1};
+ const uint8_t AX25_SYNC_FLAG_MAP_BIN[8] = {0, 1, 1, 1, 1, 1, 1, 0};
/**
* AX.25 Frame types
*/
@@ -80,7 +81,7 @@ namespace gr
}
/**
- * Createst the header field of the AX.25 frame
+ * Creates the header field of the AX.25 frame
* @param out the output buffer with enough memory to hold the address field
* @param dest_addr the destination callsign address
* @param dest_ssid the destination SSID
@@ -172,9 +173,27 @@ namespace gr
return i;
}
+ /**
+ * Constructs an AX.25 by performing NRZ encoding and bit stuffing
+ * @param out the output buffer to hold the frame. Note that due to
+ * the NRZ encoding the output would be [-1, 1]. Also the size of the
+ * buffer should be enough, such that the extra stuffed bits are fitting
+ * on the allocated space.
+ *
+ * @param out_len due to bit stuffing the output size can vary. This
+ * pointer will hold the resulting frame size after bit stuffing.
+ *
+ * @param buffer buffer holding the data that should be encoded.
+ * Note that this buffer SHOULD contain the leading and trailing
+ * synchronization flag, all necessary headers and the CRC.
+ *
+ * @param buffer_len the length of the input buffer.
+ *
+ * @return the resulting status of the encoding
+ */
static inline ax25_encode_status_t
- ax25_nrz_encode(float *out, size_t *out_len,
- const uint8_t *buffer, const size_t buffer_len)
+ ax25_nrz_bit_stuffing (float *out, size_t *out_len, const uint8_t *buffer,
+ const size_t buffer_len)
{
uint8_t bit;
uint8_t prev_bit = 0;
@@ -225,6 +244,77 @@ namespace gr
return AX25_ENC_OK;
}
+ /**
+ * Constructs an AX.25 by performing bit stuffing.
+ * @param out the output buffer to hold the frame. To keep it simple,
+ * each byte of the buffer holds only one bit. Also the size of the
+ * buffer should be enough, such that the extra stuffed bits are fitting
+ * on the allocated space.
+ *
+ * @param out_len due to bit stuffing the output size can vary. This
+ * pointer will hold the resulting frame size after bit stuffing.
+ *
+ * @param buffer buffer holding the data that should be encoded.
+ * Note that this buffer SHOULD contain the leading and trailing
+ * synchronization flag, all necessary headers and the CRC.
+ *
+ * @param buffer_len the length of the input buffer.
+ *
+ * @return the resulting status of the encoding
+ */
+ static inline ax25_encode_status_t
+ ax25_bit_stuffing (uint8_t *out, size_t *out_len, const uint8_t *buffer,
+ const size_t buffer_len)
+ {
+ uint8_t bit;
+ uint8_t prev_bit = 0;
+ 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 */
+ memcpy(out, AX25_SYNC_FLAG_MAP_BIN, 8 * sizeof(uint8_t));
+ out_idx = 8;
+
+ /* Skip the leading and trailing FLAG field */
+ buffer++;
+ for(i = 0; i < 8 * (buffer_len - 2); i++){
+ bit = (buffer[i / 8] >> ( i % 8)) & 0x1;
+ 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;
+ }
+ }
+
+ /* Trailing FLAG field does not need bit stuffing */
+ memcpy(out + out_idx, AX25_SYNC_FLAG_MAP_BIN, 8 * sizeof(uint8_t));
+ out_idx += 8;
+
+ *out_len = out_idx;
+ return AX25_ENC_OK;
+ }
+
} // namespace satnogs
} // namespace gr
diff --git a/include/satnogs/upsat_fsk_frame_acquisition.h b/include/satnogs/upsat_fsk_frame_acquisition.h
index a9f23fb..d8c748b 100644
--- a/include/satnogs/upsat_fsk_frame_acquisition.h
+++ b/include/satnogs/upsat_fsk_frame_acquisition.h
@@ -47,18 +47,28 @@ namespace gr
/*!
* Creates the FSK frame acquisition block for the UPSAT satellite.
* @param preamble the bytes that consist the preamble of the frame
+ *
* @param sync_word the byte synchronization word
+ *
* @param whitening true if the transmitted data have been processed by
* the whitening algorithm of the CC1120 chip. False otherwise.
+ *
* @param manchester true if the transmitted data have been processed by
* the Manchester algorithm of the CC1120 chip. False otherwise.
+ *
* @param check_crc if set to true the decoder will push frames only if
* their CRC field in correct.
+ *
+ * @param ax25_format if set to true the frame contains an AX.25
+ * encoded payload. Prior producing the payload, AX.25 decoding
+ * will be performed. If set to false, the payload will be pushed
+ * as it is.
*/
static sptr
make (const std::vector &preamble,
const std::vector &sync_word, bool whitening = false,
- bool manchester = false, bool check_crc = true);
+ bool manchester = false, bool check_crc = true,
+ bool ax25_format = false);
};
} // namespace satnogs
diff --git a/include/satnogs/upsat_fsk_frame_encoder.h b/include/satnogs/upsat_fsk_frame_encoder.h
index ca8bfc5..560359c 100644
--- a/include/satnogs/upsat_fsk_frame_encoder.h
+++ b/include/satnogs/upsat_fsk_frame_encoder.h
@@ -64,6 +64,8 @@ namespace gr
*
* @param msb_first if set to true, the the treansmission starts from the
* MSB of each byte.
+ * @param ax25_format if set to true the frame payload will be encoded
+ * using AX.25 encapsulation.
*
* @param settling_samples the number of zero samples that the encoder
* should append after the end of the FSK frame. This is especially
@@ -71,6 +73,7 @@ namespace gr
* arbitrary in-out ratio of samples will cause the stream tags to be
* delivered at the sink block out-of-sync causing the frame transmission
* to terminate sooner.
+ *
*/
static sptr
make (const std::vector& preamble,
@@ -78,6 +81,7 @@ namespace gr
bool append_crc = true,
bool whitening = false, bool manchester = false,
bool msb_first = true,
+ bool ax25_format = false,
size_t settling_samples = 64);
};
diff --git a/lib/ax25_encoder_bf_impl.cc b/lib/ax25_encoder_bf_impl.cc
index c2d967f..4eaddbb 100644
--- a/lib/ax25_encoder_bf_impl.cc
+++ b/lib/ax25_encoder_bf_impl.cc
@@ -104,7 +104,7 @@ namespace gr
/* Prepare and encode the AX.25 frame */
len = ax25_prepare_frame (d_tmp_buf, info, info_len, AX25_I_FRAME,
d_addr_field, d_addr_len, 0, 1);
- status = ax25_nrz_encode(d_endoded_frame, &d_remaining, d_tmp_buf,
+ status = ax25_nrz_bit_stuffing(d_endoded_frame, &d_remaining, d_tmp_buf,
len);
if(status != AX25_ENC_OK){
LOG_ERROR("NRZ Encoding failed");
diff --git a/lib/upsat_fsk_frame_acquisition_impl.cc b/lib/upsat_fsk_frame_acquisition_impl.cc
index c150e1e..229dc3a 100644
--- a/lib/upsat_fsk_frame_acquisition_impl.cc
+++ b/lib/upsat_fsk_frame_acquisition_impl.cc
@@ -37,11 +37,13 @@ namespace gr
upsat_fsk_frame_acquisition::make (const std::vector &preamble,
const std::vector &sync_word,
bool whitening, bool manchester,
- bool check_crc)
+ bool check_crc,
+ bool ax25_format)
{
return gnuradio::get_initial_sptr (
new upsat_fsk_frame_acquisition_impl (preamble, sync_word, whitening,
- manchester, check_crc));
+ manchester, check_crc,
+ ax25_format));
}
/*
@@ -50,7 +52,7 @@ namespace gr
upsat_fsk_frame_acquisition_impl::upsat_fsk_frame_acquisition_impl (
const std::vector &preamble,
const std::vector &sync_word, bool whitening, bool manchester,
- bool check_crc) :
+ bool check_crc, bool ax25_format) :
gr::sync_block ("upsat_fsk_frame_acquisition",
gr::io_signature::make (1, 1, sizeof(float)),
gr::io_signature::make (0, 0, 0)),
@@ -68,6 +70,7 @@ namespace gr
d_whitening(whitening),
d_manchester(manchester),
d_check_crc(check_crc),
+ d_is_ax25(ax25_format),
d_state (SEARCHING),
d_shifting_byte (0x0),
d_decoded_bytes (0),
diff --git a/lib/upsat_fsk_frame_acquisition_impl.h b/lib/upsat_fsk_frame_acquisition_impl.h
index 750224e..def126c 100644
--- a/lib/upsat_fsk_frame_acquisition_impl.h
+++ b/lib/upsat_fsk_frame_acquisition_impl.h
@@ -55,6 +55,7 @@ namespace gr
const bool d_whitening;
const bool d_manchester;
const bool d_check_crc;
+ const bool d_is_ax25;
decoding_state_t d_state;
uint8_t d_shifting_byte;
size_t d_decoded_bytes;
@@ -83,7 +84,8 @@ namespace gr
upsat_fsk_frame_acquisition_impl (const std::vector &preamble,
const std::vector &sync_word,
bool whitening, bool manchester,
- bool check_crc);
+ bool check_crc,
+ bool ax25_format);
~upsat_fsk_frame_acquisition_impl ();
// Where all the action really happens
diff --git a/lib/upsat_fsk_frame_encoder_impl.cc b/lib/upsat_fsk_frame_encoder_impl.cc
index 970d9c8..d03a748 100644
--- a/lib/upsat_fsk_frame_encoder_impl.cc
+++ b/lib/upsat_fsk_frame_encoder_impl.cc
@@ -39,12 +39,14 @@ namespace gr
bool append_crc, bool whitening,
bool manchester,
bool msb_first,
+ bool ax25_format,
size_t settling_samples)
{
return gnuradio::get_initial_sptr (
new upsat_fsk_frame_encoder_impl (preamble, sync_word,
append_crc,
- whitening, manchester, msb_first,
+ whitening, manchester,
+ msb_first, ax25_format,
settling_samples));
}
@@ -56,6 +58,7 @@ namespace gr
const std::vector& sync_word,
bool append_crc, bool whitening,
bool manchester, bool msb_first,
+ bool ax25_format,
size_t settling_samples) :
gr::sync_block ("upsat_fsk_frame_encoder",
gr::io_signature::make (0, 0, 0),
@@ -68,6 +71,7 @@ namespace gr
d_whitening(whitening),
d_manchester(manchester),
d_msb_first(msb_first),
+ d_is_ax25(ax25_format),
d_max_pdu_len(d_preamble_len + d_sync_word_len + sizeof(uint8_t)
+ UPSAT_MAX_FRAME_LEN + sizeof(uint16_t)),
d_settling_samples(settling_samples),
diff --git a/lib/upsat_fsk_frame_encoder_impl.h b/lib/upsat_fsk_frame_encoder_impl.h
index fe3abd2..34f3edb 100644
--- a/lib/upsat_fsk_frame_encoder_impl.h
+++ b/lib/upsat_fsk_frame_encoder_impl.h
@@ -40,6 +40,7 @@ namespace gr
const bool d_whitening;
const bool d_manchester;
const bool d_msb_first;
+ const bool d_is_ax25;
const size_t d_max_pdu_len;
const size_t d_settling_samples;
size_t d_encoded;
@@ -63,6 +64,7 @@ namespace gr
bool append_crc, bool whitening,
bool manchester,
bool msb_first,
+ bool ax25_format,
size_t settling_samples);
~upsat_fsk_frame_encoder_impl ();