diff --git a/grc/satnogs_upsat_fsk_frame_encoder.xml b/grc/satnogs_upsat_fsk_frame_encoder.xml
index 9d5369c..1fb7b5d 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_encoder
satnogs
import satnogs
- satnogs.upsat_fsk_frame_encoder($preamble, $sync_word, $append_crc, $whitening, $manchester, $msb_first, $ax_25, $settling_samples)
+ satnogs.upsat_fsk_frame_encoder($preamble, $sync_word, $append_crc, $whitening, $manchester, $msb_first, $ax_25, $src_addr, $src_ssid, $dest_addr, $dest_ssid, $settling_samples)
Frame Preamble
@@ -88,6 +88,30 @@
+
+ Destination Callsign
+ dest_addr
+ string
+
+
+
+ Destination SSID
+ dest_ssid
+ int
+
+
+
+ Source Callsign
+ src_addr
+ string
+
+
+
+ Source SSID
+ src_ssid
+ int
+
+
Number of zero settling samples
settling_samples
diff --git a/include/satnogs/ax25.h b/include/satnogs/ax25.h
index e0c3f3a..19f3b1e 100644
--- a/include/satnogs/ax25.h
+++ b/include/satnogs/ax25.h
@@ -22,6 +22,8 @@
#define INCLUDE_SATNOGS_AX25_H_
#include
+#include
+#include
namespace gr
{
@@ -44,7 +46,8 @@ namespace gr
{
AX25_I_FRAME, //!< AX25_I_FRAME Information frame
AX25_S_FRAME, //!< AX25_S_FRAME Supervisory frame
- AX25_U_FRAME //!< AX25_U_FRAME Unnumbered frame
+ AX25_U_FRAME, //!< AX25_U_FRAME Unnumbered frame
+ AX25_UI_FRAME /**!< AX25_UI_FRAME Unnumbered information frame */
} ax25_frame_type_t;
typedef enum
@@ -53,6 +56,12 @@ namespace gr
AX25_ENC_OK
} ax25_encode_status_t;
+ typedef enum
+ {
+ AX25_DEC_FAIL,
+ AX25_DEC_OK
+ } ax25_decode_status_t;
+
typedef struct
{
uint8_t address[AX25_MAX_ADDR_LEN];
@@ -60,7 +69,8 @@ namespace gr
uint16_t ctrl;
size_t ctrl_len;
uint8_t pid;
- uint8_t info[AX25_MAX_FRAME_LEN];
+ uint8_t *info;
+ size_t info_len;
ax25_frame_type_t type;
} ax25_frame_t;
@@ -75,7 +85,7 @@ namespace gr
{
uint16_t fcs = 0xFFFF;
while (len--) {
- fcs = (fcs >> 8) ^ crc16_ccitt_table_reverse[(fcs ^ *buffer++) & 0XFF];
+ fcs = (fcs >> 8) ^ crc16_ccitt_table_reverse[(fcs ^ *buffer++) & 0xFF];
}
return fcs ^ 0xFFFF;
}
@@ -146,7 +156,7 @@ namespace gr
if( ctrl_len == AX25_MIN_CTRL_LEN || ctrl_len == AX25_MAX_CTRL_LEN){
memcpy(out + i, &ctrl, ctrl_len);
- i += addr_len;
+ i += ctrl_len;
}
else{
return 0;
@@ -157,7 +167,7 @@ namespace gr
* FIXME: For now, only the "No layer 3 is implemented" information is
* inserted
*/
- if(type == AX25_I_FRAME){
+ if (type == AX25_I_FRAME || type == AX25_UI_FRAME) {
out[i++] = 0xF0;
}
memcpy(out + i, info, info_len);
@@ -315,6 +325,104 @@ namespace gr
return AX25_ENC_OK;
}
+ static inline ax25_decode_status_t
+ ax25_decode (uint8_t *out, size_t *out_len,
+ const uint8_t *ax25_frame, size_t len)
+ {
+ size_t i;
+ size_t frame_start = UINT_MAX;
+ size_t frame_stop = UINT_MAX;
+ uint8_t res;
+ size_t cont_1 = 0;
+ size_t received_bytes = 0;
+ size_t bit_cnt = 0;
+ uint8_t decoded_byte = 0x0;
+ uint16_t fcs;
+ uint16_t recv_fcs;
+
+
+ /* Start searching for the SYNC flag */
+ for(i = 0; i < len - sizeof(AX25_SYNC_FLAG_MAP_BIN); i++) {
+ res = (AX25_SYNC_FLAG_MAP_BIN[0] ^ ax25_frame[i]) |
+ (AX25_SYNC_FLAG_MAP_BIN[1] ^ ax25_frame[i + 1]) |
+ (AX25_SYNC_FLAG_MAP_BIN[2] ^ ax25_frame[i + 2]) |
+ (AX25_SYNC_FLAG_MAP_BIN[3] ^ ax25_frame[i + 3]) |
+ (AX25_SYNC_FLAG_MAP_BIN[4] ^ ax25_frame[i + 4]) |
+ (AX25_SYNC_FLAG_MAP_BIN[5] ^ ax25_frame[i + 5]) |
+ (AX25_SYNC_FLAG_MAP_BIN[6] ^ ax25_frame[i + 6]) |
+ (AX25_SYNC_FLAG_MAP_BIN[7] ^ ax25_frame[i + 7]);
+ /* Found it! */
+ if(res == 0){
+ frame_start = i;
+ break;
+ }
+ }
+
+ /* We failed to find the SYNC flag */
+ if(frame_start == UINT_MAX){
+ return AX25_DEC_FAIL;
+ }
+
+ for(i = frame_start + sizeof(AX25_SYNC_FLAG_MAP_BIN);
+ i < len - sizeof(AX25_SYNC_FLAG_MAP_BIN); i++) {
+ /* Check if we reached the frame end */
+ res = (AX25_SYNC_FLAG_MAP_BIN[0] ^ ax25_frame[i]) |
+ (AX25_SYNC_FLAG_MAP_BIN[1] ^ ax25_frame[i + 1]) |
+ (AX25_SYNC_FLAG_MAP_BIN[2] ^ ax25_frame[i + 2]) |
+ (AX25_SYNC_FLAG_MAP_BIN[3] ^ ax25_frame[i + 3]) |
+ (AX25_SYNC_FLAG_MAP_BIN[4] ^ ax25_frame[i + 4]) |
+ (AX25_SYNC_FLAG_MAP_BIN[5] ^ ax25_frame[i + 5]) |
+ (AX25_SYNC_FLAG_MAP_BIN[6] ^ ax25_frame[i + 6]) |
+ (AX25_SYNC_FLAG_MAP_BIN[7] ^ ax25_frame[i + 7]);
+ /* Found it! */
+ if(res == 0){
+ frame_stop = i;
+ break;
+ }
+
+ if (ax25_frame[i]) {
+ cont_1++;
+ decoded_byte |= 1 << bit_cnt;
+ bit_cnt++;
+ }
+ else {
+ /* If 5 consecutive 1's drop the extra zero*/
+ if (cont_1 >= 5) {
+ cont_1 = 0;
+ }
+ else{
+ bit_cnt++;
+ cont_1 = 0;
+ }
+ }
+
+ /* Fill the fully constructed byte */
+ if(bit_cnt == 8){
+ out[received_bytes++] = decoded_byte;
+ bit_cnt = 0;
+ decoded_byte = 0x0;
+ }
+ }
+
+ if(frame_stop == UINT_MAX || received_bytes < AX25_MIN_ADDR_LEN){
+ return AX25_DEC_FAIL;
+ }
+
+ /* Now check the CRC */
+ fcs = ax25_fcs (out, received_bytes - sizeof(uint16_t));
+ recv_fcs = (((uint16_t) out[received_bytes - 2]) << 8)
+ | out[received_bytes - 1];
+
+ if(fcs != recv_fcs) {
+ LOG_WARN("AX.25 CRC-16 failed");
+ return AX25_DEC_FAIL;
+ }
+
+ *out_len = received_bytes - sizeof(uint16_t);
+ return AX25_DEC_OK;
+
+ }
+
} // namespace satnogs
} // namespace gr
diff --git a/include/satnogs/upsat_fsk_frame_encoder.h b/include/satnogs/upsat_fsk_frame_encoder.h
index 560359c..83327c4 100644
--- a/include/satnogs/upsat_fsk_frame_encoder.h
+++ b/include/satnogs/upsat_fsk_frame_encoder.h
@@ -63,7 +63,10 @@ namespace gr
* the Manchester algorithm of the CC1120 chip. False otherwise.
*
* @param msb_first if set to true, the the treansmission starts from the
- * MSB of each byte.
+ * MSB of each byte. In case the AX.25 encapuslation is selected, this
+ * parameter is NOT taken into consideration for the AX.25 part,
+ * as the AX.25 dictates that the LS bit should be sent first.
+ *
* @param ax25_format if set to true the frame payload will be encoded
* using AX.25 encapsulation.
*
@@ -78,11 +81,16 @@ namespace gr
static sptr
make (const std::vector& preamble,
const std::vector& sync_word,
- bool append_crc = true,
- bool whitening = false, bool manchester = false,
- bool msb_first = true,
- bool ax25_format = false,
- size_t settling_samples = 64);
+ bool append_crc,
+ bool whitening,
+ bool manchester,
+ bool msb_first,
+ bool ax25_format,
+ const std::string& ax25_dest_addr,
+ uint8_t ax25_dest_ssid,
+ const std::string& ax25_src_addr,
+ uint8_t ax25_src_ssid,
+ size_t settling_samples);
};
} // namespace satnogs
diff --git a/lib/upsat_fsk_frame_acquisition_impl.cc b/lib/upsat_fsk_frame_acquisition_impl.cc
index 229dc3a..29f84a1 100644
--- a/lib/upsat_fsk_frame_acquisition_impl.cc
+++ b/lib/upsat_fsk_frame_acquisition_impl.cc
@@ -25,6 +25,7 @@
#include
#include "upsat_fsk_frame_acquisition_impl.h"
#include
+#include
#include
#include
@@ -97,6 +98,8 @@ namespace gr
}
d_pdu = new uint8_t[UPSAT_MAX_FRAME_LEN];
+ d_ax25_tmp_buf = new uint8_t[2 * UPSAT_MAX_FRAME_LEN * 8];
+ d_ax25_buf = new uint8_t[2 * UPSAT_MAX_FRAME_LEN];
}
/*
@@ -105,6 +108,8 @@ namespace gr
upsat_fsk_frame_acquisition_impl::~upsat_fsk_frame_acquisition_impl ()
{
delete[] d_pdu;
+ delete[] d_ax25_tmp_buf;
+ delete[] d_ax25_buf;
}
inline void
@@ -173,6 +178,23 @@ namespace gr
d_decoded_bits = 0;
}
+ inline void
+ upsat_fsk_frame_acquisition_impl::unpack_ax25_bytes (size_t len_bytes)
+ {
+ 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;
+ d_ax25_tmp_buf[8*i + 2] = (in[i] >> 5) & 0x1;
+ d_ax25_tmp_buf[8*i + 3] = (in[i] >> 4) & 0x1;
+ d_ax25_tmp_buf[8*i + 4] = (in[i] >> 3) & 0x1;
+ d_ax25_tmp_buf[8*i + 5] = (in[i] >> 2) & 0x1;
+ d_ax25_tmp_buf[8*i + 6] = (in[i] >> 1) & 0x1;
+ d_ax25_tmp_buf[8*i + 7] = in[i] & 0x1;
+ }
+ }
+
int
upsat_fsk_frame_acquisition_impl::work (
int noutput_items, gr_vector_const_void_star &input_items,
@@ -181,6 +203,8 @@ namespace gr
int i;
uint16_t crc_received;
uint16_t crc_calc;
+ size_t ax25_frame_len = 0;
+ ax25_decode_status_t status;
const float *in = (const float *) input_items[0];
for (i = 0; i < noutput_items; i++) {
slice_and_shift (in[i]);
@@ -273,9 +297,30 @@ namespace gr
d_decoded_bytes++;
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);
+ if(status == AX25_DEC_OK){
+ message_port_pub (pmt::mp ("pdu"),
+ pmt::make_blob(d_ax25_buf, ax25_frame_len));
+ }
+ else{
+ LOG_WARN("AX.25 decoding failed.");
+ }
+
+ /*
+ * We are done here. Whitening and FSK CRC is not supported
+ * when transmitting/receiving AX.25 frames
+ */
+ reset_state ();
+ break;
+ }
+
if(d_whitening){
d_descrambler.descramble(d_pdu+1, d_pdu+1, d_frame_len - 1);
}
+
if(!d_check_crc){
message_port_pub (
pmt::mp ("pdu"),
diff --git a/lib/upsat_fsk_frame_acquisition_impl.h b/lib/upsat_fsk_frame_acquisition_impl.h
index def126c..58da2fe 100644
--- a/lib/upsat_fsk_frame_acquisition_impl.h
+++ b/lib/upsat_fsk_frame_acquisition_impl.h
@@ -63,6 +63,8 @@ namespace gr
size_t d_frame_len;
whitening d_descrambler;
uint8_t *d_pdu;
+ uint8_t *d_ax25_tmp_buf;
+ uint8_t *d_ax25_buf;
inline void
slice_and_shift (float in);
@@ -79,6 +81,8 @@ namespace gr
have_frame_len ();
inline void
have_payload ();
+ inline void
+ unpack_ax25_bytes(size_t len_bytes);
public:
upsat_fsk_frame_acquisition_impl (const std::vector &preamble,
diff --git a/lib/upsat_fsk_frame_encoder_impl.cc b/lib/upsat_fsk_frame_encoder_impl.cc
index d03a748..d9608b2 100644
--- a/lib/upsat_fsk_frame_encoder_impl.cc
+++ b/lib/upsat_fsk_frame_encoder_impl.cc
@@ -37,9 +37,12 @@ namespace gr
upsat_fsk_frame_encoder::make (const std::vector& preamble,
const std::vector& sync_word,
bool append_crc, bool whitening,
- bool manchester,
- bool msb_first,
+ bool manchester, bool msb_first,
bool ax25_format,
+ const std::string& ax25_dest_addr,
+ uint8_t ax25_dest_ssid,
+ const std::string& ax25_src_addr,
+ uint8_t ax25_src_ssid,
size_t settling_samples)
{
return gnuradio::get_initial_sptr (
@@ -47,6 +50,8 @@ namespace gr
append_crc,
whitening, manchester,
msb_first, ax25_format,
+ ax25_src_addr, ax25_src_ssid,
+ ax25_dest_addr, ax25_dest_ssid,
settling_samples));
}
@@ -59,6 +64,10 @@ namespace gr
bool append_crc, bool whitening,
bool manchester, bool msb_first,
bool ax25_format,
+ const std::string& ax25_dest_addr,
+ uint8_t ax25_dest_ssid,
+ const std::string& ax25_src_addr,
+ uint8_t ax25_src_ssid,
size_t settling_samples) :
gr::sync_block ("upsat_fsk_frame_encoder",
gr::io_signature::make (0, 0, 0),
@@ -91,6 +100,18 @@ namespace gr
* User def. User def. 1B 1-255 B 2 B
*/
d_pdu = new uint8_t[d_max_pdu_len];
+
+
+ if(d_is_ax25){
+ d_ax25_addr = new uint8_t[AX25_MAX_ADDR_LEN];
+ /* One useful bit per byte for the AX.25 buffer */
+ d_ax25_pdu = new uint8_t[2 * d_max_pdu_len * 8];
+ d_ax25_tmp_buf = new uint8_t[d_max_pdu_len * 2];
+ d_ax25_addr_len = ax25_create_addr_field (d_ax25_addr, ax25_dest_addr,
+ ax25_dest_ssid, ax25_src_addr,
+ ax25_src_ssid);
+ }
+
d_pdu_encoded = new float[d_max_pdu_len*8 + d_settling_samples];
/* Copy the preamble at the start of the pdu */
@@ -105,6 +126,11 @@ namespace gr
{
delete [] d_pdu;
delete [] d_pdu_encoded;
+ if(d_is_ax25) {
+ delete [] d_ax25_addr;
+ delete [] d_ax25_pdu;
+ delete [] d_ax25_tmp_buf;
+ }
}
inline void
@@ -163,25 +189,23 @@ namespace gr
add_item_tag (0, item, eob_key, value, srcid);
}
- int
- upsat_fsk_frame_encoder_impl::work (int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
+ inline int
+ upsat_fsk_frame_encoder_impl::raw_frame_handling (float* out,
+ int noutput_items)
{
uint16_t crc;
size_t min_available;
pmt::pmt_t pdu;
- float *out = (float *) output_items[0];
/*
* If the whole previous frame has been successfully sent, block waiting
* for a new one
*/
- if(d_encoded == 0){
- pdu = delete_head_blocking(pmt::mp("pdu"));
+ if (d_encoded == 0) {
+ pdu = delete_head_blocking (pmt::mp ("pdu"));
d_pdu_len = pmt::blob_length (pdu);
- if(d_pdu_len > UPSAT_MAX_FRAME_LEN){
+ if (d_pdu_len > UPSAT_MAX_FRAME_LEN) {
LOG_ERROR("PDU is greater than the supported. Dropping the PDU");
return 0;
}
@@ -198,21 +222,21 @@ namespace gr
pmt::blob_data (pdu), d_pdu_len);
/* If it is necessary calculate and append the CRC */
- if(d_append_crc) {
- crc = crc16_ccitt(d_pdu + d_preamble_len + d_sync_word_len,
- d_pdu_len + 1);
+ if (d_append_crc) {
+ crc = crc16_ccitt (d_pdu + d_preamble_len + d_sync_word_len,
+ d_pdu_len + 1);
/* CRC must be transmitted MSB first */
- crc = htons(crc);
- memcpy(d_pdu + d_preamble_len + d_sync_word_len + 1 + d_pdu_len,
- &crc, sizeof(uint16_t));
+ crc = htons (crc);
+ memcpy (d_pdu + d_preamble_len + d_sync_word_len + 1 + d_pdu_len,
+ &crc, sizeof(uint16_t));
d_pdu_len += sizeof(uint16_t);
}
/*
* Whitening is performed on all bytes except preamble and SYNC fields
*/
- if(d_whitening){
- d_scrambler.reset();
+ if (d_whitening) {
+ d_scrambler.reset ();
d_scrambler.scramble (d_pdu + d_preamble_len + d_sync_word_len,
d_pdu + d_preamble_len + d_sync_word_len,
d_pdu_len + 1);
@@ -235,28 +259,151 @@ namespace gr
d_settling_samples * sizeof(float));
/* The new frame now has a bigger size of course*/
- d_pdu_len += d_settling_samples/8;
+ d_pdu_len += d_settling_samples / 8;
/* Start of burst */
- add_sob(nitems_written(0));
+ add_sob (nitems_written (0));
}
noutput_items = std::max (0, noutput_items);
min_available = std::min ((size_t) noutput_items,
(d_pdu_len - d_encoded) * 8);
- memcpy(out, d_pdu_encoded + d_encoded*8, min_available * sizeof(float));
- d_encoded += min_available/8;
+ memcpy (out, d_pdu_encoded + d_encoded * 8,
+ min_available * sizeof(float));
+ d_encoded += min_available / 8;
/* End of the frame reached */
- if(d_encoded == d_pdu_len){
- add_eob(nitems_written(0) + min_available - 1);
+ if (d_encoded == d_pdu_len) {
+ add_eob (nitems_written (0) + min_available - 1);
d_encoded = 0;
}
return min_available;
}
+ inline int
+ upsat_fsk_frame_encoder_impl::ax25_frame_handling (float* out,
+ int noutput_items)
+ {
+ uint16_t crc;
+ size_t min_available;
+ pmt::pmt_t pdu;
+ size_t len;
+ size_t encoded_len;
+ ax25_encode_status_t status;
+ size_t extra_bits;
+ size_t i;
+
+ /*
+ * If the whole previous frame has been successfully sent, block waiting
+ * for a new one
+ */
+ if (d_encoded == 0) {
+ /* Reset the buffer */
+ memset(d_ax25_pdu, 0, 2 * d_max_pdu_len * 8);
+ pdu = delete_head_blocking (pmt::mp ("pdu"));
+ d_pdu_len = pmt::blob_length (pdu);
+
+ if (d_pdu_len > UPSAT_MAX_FRAME_LEN) {
+ LOG_ERROR("PDU is greater than the supported. Dropping the PDU");
+ return 0;
+ }
+
+ 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) {
+ LOG_WARN("Failed to properly encode into AX.25 frame");
+ return 0;
+ }
+
+ /* Due to bit stuffing the resulting bit number may not be
+ * a multiple of 8. Thus we append proper number of zeros
+ * after the SYNC flag. So neither the AX.25 or the FSK
+ * framing are affected
+ */
+ extra_bits = 8 - (encoded_len % 8);
+ encoded_len += extra_bits;
+
+ /*
+ * Set the frame length at the corresponding field.
+ * NOTE: The frame length is calculated taking consideration only
+ * 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;
+
+ /* 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 */
+ map_msb_first (d_pdu_encoded, (d_preamble_len + d_sync_word_len + 1) * 8);
+
+ /* NRZ encode the AX.25 part of the FSK frame */
+ for(i = 0; i < encoded_len; i++){
+ d_pdu_encoded[i + (d_preamble_len + d_sync_word_len + 1)*8]
+ = (d_ax25_pdu[i] * 2.0f) - 1.0f;
+ }
+
+ /* Reset the settling trailing samples */
+ memset (d_pdu_encoded + d_pdu_len * 8, 0,
+ d_settling_samples * sizeof(float));
+
+ /* The new frame now has a bigger size of course*/
+ d_pdu_len += d_settling_samples / 8;
+
+ /* Start of burst */
+ add_sob (nitems_written (0));
+ }
+
+ noutput_items = std::max (0, noutput_items);
+ min_available = std::min ((size_t) noutput_items,
+ (d_pdu_len - d_encoded) * 8);
+
+ memcpy (out, d_pdu_encoded + d_encoded * 8,
+ min_available * sizeof(float));
+ d_encoded += min_available / 8;
+
+ /* End of the frame reached */
+ if (d_encoded == d_pdu_len) {
+ add_eob (nitems_written (0) + min_available - 1);
+ d_encoded = 0;
+ }
+
+ return min_available;
+ }
+
+ int
+ upsat_fsk_frame_encoder_impl::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ float *out = (float *) output_items[0];
+
+ if(d_is_ax25) {
+ return ax25_frame_handling(out, noutput_items);
+ }
+ else{
+ return raw_frame_handling(out, noutput_items);
+ }
+ }
+
} /* namespace satnogs */
} /* namespace gr */
diff --git a/lib/upsat_fsk_frame_encoder_impl.h b/lib/upsat_fsk_frame_encoder_impl.h
index 34f3edb..25cb8fa 100644
--- a/lib/upsat_fsk_frame_encoder_impl.h
+++ b/lib/upsat_fsk_frame_encoder_impl.h
@@ -23,6 +23,7 @@
#include
#include
+#include
namespace gr
{
@@ -47,6 +48,10 @@ namespace gr
size_t d_pdu_len;
whitening d_scrambler;
uint8_t *d_pdu;
+ uint8_t *d_ax25_pdu;
+ uint8_t *d_ax25_tmp_buf;
+ uint8_t *d_ax25_addr;
+ size_t d_ax25_addr_len;
float *d_pdu_encoded;
inline void
@@ -58,6 +63,11 @@ namespace gr
inline void
add_eob (uint64_t item);
+ inline int
+ raw_frame_handling(float *out, int noutput_items);
+ inline int
+ ax25_frame_handling(float *out, int noutput_items);
+
public:
upsat_fsk_frame_encoder_impl (const std::vector& preamble,
const std::vector& sync_word,
@@ -65,6 +75,10 @@ namespace gr
bool manchester,
bool msb_first,
bool ax25_format,
+ const std::string& ax25_dest_addr,
+ uint8_t ax25_dest_ssid,
+ const std::string& ax25_src_addr,
+ uint8_t ax25_src_ssid,
size_t settling_samples);
~upsat_fsk_frame_encoder_impl ();