From 92843c43c95dfa2fa1a9dd206a1145b524deae05 Mon Sep 17 00:00:00 2001 From: Manolis Surligas Date: Thu, 30 Jun 2016 23:39:16 +0300 Subject: [PATCH] Add AX.25 encoder that supports the legacy hardware radios The new encoder now supports NRZI and G3RUH scrambling that makes it compatible with most of the FSK9600 modems. Remove also some unneeded blocks. --- grc/CMakeLists.txt | 5 +- grc/satnogs_afsk_decoder.xml | 38 ---- grc/satnogs_ax25_encoder_bf.xml | 43 ----- grc/satnogs_ax25_encoder_mb.xml | 70 +++++++ include/satnogs/CMakeLists.txt | 5 +- include/satnogs/afsk_decoder.h | 63 ------ include/satnogs/ax25.h | 55 ++++-- include/satnogs/ax25_encoder_bf.h | 69 ------- include/satnogs/ax25_encoder_mb.h | 78 ++++++++ lib/CMakeLists.txt | 5 +- lib/afsk_decoder_impl.cc | 97 ---------- lib/afsk_decoder_impl.h | 62 ------ lib/ax25_encoder_bf_impl.cc | 168 ---------------- lib/ax25_encoder_mb_impl.cc | 182 ++++++++++++++++++ ...coder_bf_impl.h => ax25_encoder_mb_impl.h} | 50 ++--- lib/upsat_fsk_frame_encoder_impl.cc | 4 +- swig/satnogs_swig.i | 11 +- 17 files changed, 403 insertions(+), 602 deletions(-) delete mode 100644 grc/satnogs_afsk_decoder.xml delete mode 100644 grc/satnogs_ax25_encoder_bf.xml create mode 100644 grc/satnogs_ax25_encoder_mb.xml delete mode 100644 include/satnogs/afsk_decoder.h delete mode 100644 include/satnogs/ax25_encoder_bf.h create mode 100644 include/satnogs/ax25_encoder_mb.h delete mode 100644 lib/afsk_decoder_impl.cc delete mode 100644 lib/afsk_decoder_impl.h delete mode 100644 lib/ax25_encoder_bf_impl.cc create mode 100644 lib/ax25_encoder_mb_impl.cc rename lib/{ax25_encoder_bf_impl.h => ax25_encoder_mb_impl.h} (55%) diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index a53db5d..92fc81a 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -22,9 +22,7 @@ install(FILES satnogs_morse_debug_source.xml satnogs_multi_format_msg_sink.xml satnogs_cw_to_symbol.xml - satnogs_afsk_decoder.xml satnogs_sine_matched_filter_ff.xml - satnogs_ax25_encoder_bf.xml satnogs_ax25_decoder_b.xml satnogs_udp_msg_source.xml satnogs_debug_msg_source.xml @@ -38,5 +36,6 @@ install(FILES satnogs_udp_msg_sink.xml satnogs_upsat_transmitter.xml satnogs_coarse_doppler_correction_cc.xml - satnogs_debug_msg_source_raw.xml DESTINATION share/gnuradio/grc/blocks + satnogs_debug_msg_source_raw.xml + satnogs_ax25_encoder_mb.xml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/satnogs_afsk_decoder.xml b/grc/satnogs_afsk_decoder.xml deleted file mode 100644 index 144c674..0000000 --- a/grc/satnogs_afsk_decoder.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - afsk_decoder - satnogs_afsk_decoder - satnogs - import satnogs - satnogs.afsk_decoder($sampling_rate, $baudrate, $fft_size) - - - ... - ... - ... - - - - - in - - - - - - out - - - diff --git a/grc/satnogs_ax25_encoder_bf.xml b/grc/satnogs_ax25_encoder_bf.xml deleted file mode 100644 index a0b5b7b..0000000 --- a/grc/satnogs_ax25_encoder_bf.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - AX.25 Encoder - satnogs_ax25_encoder_bf - satnogs - import satnogs - satnogs.ax25_encoder_bf($dest_addr, $dest_ssid, $src_addr, $src_ssid) - set_address_field($dest_addr, $dest_ssid, $src_addr, $src_ssid) - - - Destination Callsign - dest_addr - string - - - - Destination SSID - dest_ssid - int - - - - Source Callsign - src_addr - string - - - - Source SSID - src_ssid - int - - - - info - message - - - - out - float - - diff --git a/grc/satnogs_ax25_encoder_mb.xml b/grc/satnogs_ax25_encoder_mb.xml new file mode 100644 index 0000000..c49e501 --- /dev/null +++ b/grc/satnogs_ax25_encoder_mb.xml @@ -0,0 +1,70 @@ + + + AX.25 Encoder + satnogs_ax25_encoder_mb + satnogs + import satnogs + satnogs.ax25_encoder_mb($dest_addr, $dest_ssid, $src_addr, $src_ssid, $preamble_len, $postamble_len, $scramble) + + + Destination Callsign + dest_addr + string + + + + Destination SSID + dest_ssid + int + + + + Source Callsign + src_addr + string + + + + Source SSID + src_ssid + int + + + + Preamble Length + preamble_len + 16 + int + + + + Postamble Length + postamble_len + 16 + int + + + + G3RUH Scrambling + scramble + enum + + + + + + info + message + + + + out + byte + + diff --git a/include/satnogs/CMakeLists.txt b/include/satnogs/CMakeLists.txt index 3e0ae41..83554f4 100644 --- a/include/satnogs/CMakeLists.txt +++ b/include/satnogs/CMakeLists.txt @@ -32,10 +32,8 @@ install(FILES morse_debug_source.h multi_format_msg_sink.h cw_to_symbol.h - afsk_decoder.h sine_matched_filter_ff.h utils.h - ax25_encoder_bf.h ax25_decoder_b.h udp_msg_source.h debug_msg_source.h @@ -50,5 +48,6 @@ install(FILES whitening.h udp_msg_sink.h coarse_doppler_correction_cc.h - debug_msg_source_raw.h DESTINATION include/satnogs + debug_msg_source_raw.h + ax25_encoder_mb.h DESTINATION include/satnogs ) diff --git a/include/satnogs/afsk_decoder.h b/include/satnogs/afsk_decoder.h deleted file mode 100644 index ab6850f..0000000 --- a/include/satnogs/afsk_decoder.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- c++ -*- */ -/* - * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module - * - * Copyright (C) 2016, Libre Space Foundation - * - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef INCLUDED_SATNOGS_AFSK_DECODER_H -#define INCLUDED_SATNOGS_AFSK_DECODER_H - -#include -#include - -namespace gr { - namespace satnogs { - - /*! - * \brief AFSK decoder. This particular decoder uses a Frequency Domain - * approach to retrieve the message. - * \ingroup satnogs - * - */ - class SATNOGS_API afsk_decoder : virtual public gr::block - { - public: - typedef boost::shared_ptr sptr; - - - /*! - * An AFSK decoder. - * @param sampling_rate the input sampling rate - * @param baudrate the baudrate (symbols per second) - * @param fft_size the FFT size that the decoder will use. - * @param auto_carrier_tracking if set to yes, the decoder will try - * to automatically find the mark and space frequencies - * @param mark_freq the frequency of the mark (1) - * @param mark_space the frequency of the space (0) - */ - static sptr make(double sampling_rate, size_t baudrate = 1200, - size_t fft_size = 128, - bool auto_carrier_tracking = false, - double mark_freq = 2400.0, - double space_freq = 1200.0); - }; - - } // namespace satnogs -} // namespace gr - -#endif /* INCLUDED_SATNOGS_AFSK_DECODER_H */ - diff --git a/include/satnogs/ax25.h b/include/satnogs/ax25.h index e4c6581..d61ed6c 100644 --- a/include/satnogs/ax25.h +++ b/include/satnogs/ax25.h @@ -136,15 +136,18 @@ namespace gr static inline size_t ax25_prepare_frame (uint8_t *out, const uint8_t *info, size_t info_len, ax25_frame_type_t type, uint8_t *addr, size_t addr_len, - uint16_t ctrl, size_t ctrl_len) + uint16_t ctrl, size_t ctrl_len, size_t preamble_len, + size_t postamble_len) { uint16_t fcs; - size_t i = 1; + size_t i; if(info_len > AX25_MAX_FRAME_LEN) { return 0; } - out[0] = AX25_SYNC_FLAG; + memset(out, AX25_SYNC_FLAG, preamble_len); + i = preamble_len; + /* Insert address and control fields */ if( addr_len == AX25_MIN_ADDR_LEN || addr_len == AX25_MAX_ADDR_LEN){ memcpy(out + i, addr, addr_len); @@ -174,13 +177,13 @@ namespace gr i += info_len; /* Compute the FCS. Ignore the first flag byte */ - fcs = ax25_fcs(out + 1, i - 1); + fcs = ax25_fcs(out + preamble_len, i - preamble_len); /* The MS bits are sent first ONLY at the FCS field */ - out[i++] = (fcs >> 8) & 0xFF; out[i++] = fcs & 0xFF; - out[i++] = AX25_SYNC_FLAG; + out[i++] = (fcs >> 8) & 0xFF; + memset(out + i, AX25_SYNC_FLAG, postamble_len); - return i; + return i + postamble_len; } /** @@ -203,7 +206,8 @@ namespace gr */ static inline ax25_encode_status_t ax25_nrz_bit_stuffing (float *out, size_t *out_len, const uint8_t *buffer, - const size_t buffer_len) + size_t buffer_len, size_t preamble_len, + size_t postamble_len) { uint8_t bit; uint8_t prev_bit = 0; @@ -214,12 +218,14 @@ namespace gr size_t i; /* Leading FLAG field does not need bit stuffing */ - memcpy(out, AX25_SYNC_FLAG_MAP, 8 * sizeof(float)); - out_idx = 8; + for(i = 0; i < preamble_len; i++) { + memcpy(out + out_idx, AX25_SYNC_FLAG_MAP, 8 * sizeof(float)); + out_idx += 8; + } /* Skip the leading and trailing FLAG field */ - buffer++; - for(i = 0; i < 8 * (buffer_len - 2); i++){ + buffer += preamble_len; + for(i = 0; i < 8 * (buffer_len - preamble_len - postamble_len); i++){ bit = (buffer[i / 8] >> ( i % 8)) & 0x1; out[out_idx++] = bit ? 1.0 : -1.0; @@ -247,8 +253,10 @@ namespace gr } /* Trailing FLAG field does not need bit stuffing */ - memcpy(out + out_idx, AX25_SYNC_FLAG_MAP, 8 * sizeof(float)); - out_idx += 8; + for(i = 0; i < postamble_len; i++) { + memcpy(out + out_idx, AX25_SYNC_FLAG_MAP, 8 * sizeof(float)); + out_idx += 8; + } *out_len = out_idx; return AX25_ENC_OK; @@ -274,7 +282,8 @@ namespace gr */ 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) + const size_t buffer_len, size_t preamble_len, + size_t postamble_len) { uint8_t bit; uint8_t prev_bit = 0; @@ -285,12 +294,14 @@ namespace gr 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; + for(i = 0; i < preamble_len; i++) { + memcpy(out + out_idx, 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++){ + buffer += preamble_len; + for(i = 0; i < 8 * (buffer_len - preamble_len - postamble_len); i++){ bit = (buffer[i / 8] >> ( i % 8)) & 0x1; out[out_idx++] = bit; @@ -318,8 +329,10 @@ namespace gr } /* Trailing FLAG field does not need bit stuffing */ - memcpy(out + out_idx, AX25_SYNC_FLAG_MAP_BIN, 8 * sizeof(uint8_t)); - out_idx += 8; + for(i = 0; i < postamble_len; i++) { + memcpy(out + out_idx, AX25_SYNC_FLAG_MAP_BIN, 8 * sizeof(uint8_t)); + out_idx += 8; + } *out_len = out_idx; return AX25_ENC_OK; diff --git a/include/satnogs/ax25_encoder_bf.h b/include/satnogs/ax25_encoder_bf.h deleted file mode 100644 index d794d4f..0000000 --- a/include/satnogs/ax25_encoder_bf.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- c++ -*- */ -/* - * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module - * - * Copyright (C) 2016, Libre Space Foundation - * - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef INCLUDED_SATNOGS_AX25_ENCODER_BF_H -#define INCLUDED_SATNOGS_AX25_ENCODER_BF_H - -#include -#include -#include - -namespace gr { - namespace satnogs { - - /*! - * \brief AX.25 packet encoder - * \ingroup satnogs - * - */ - class SATNOGS_API ax25_encoder_bf : virtual public gr::sync_block - { - public: - typedef boost::shared_ptr sptr; - - - /** - * AX.25 packet encoder. This block receives messages containing - * the packet information, contracts a AX.25 packet end encodes it - * using NRZ. - * - * The block also creates suitable burst tags for proper - * burst transmission in SDR devices that support them. - * - * @param dest_addr the destination callsign address - * @param dest_ssid the destination SSID - * @param src_addr the callsign of the source - * @param src_ssid the source SSID - */ - static sptr make(std::string dest_addr, - uint8_t dest_ssid, - std::string src_addr, - uint8_t src_ssid); - - virtual void - set_address_field (std::string dest_addr, uint8_t dest_ssid, - std::string src_addr, uint8_t src_ssid) = 0; - }; - - } // namespace satnogs -} // namespace gr - -#endif /* INCLUDED_SATNOGS_AX25_ENCODER_BF_H */ - diff --git a/include/satnogs/ax25_encoder_mb.h b/include/satnogs/ax25_encoder_mb.h new file mode 100644 index 0000000..c8f5279 --- /dev/null +++ b/include/satnogs/ax25_encoder_mb.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef INCLUDED_SATNOGS_AX25_ENCODER_MB_H +#define INCLUDED_SATNOGS_AX25_ENCODER_MB_H + +#include +#include + +namespace gr +{ + namespace satnogs + { + + /*! + * \brief AX.25 encoder block that supports the legacy hardware radios. + * + * The block takes as inputs blob PMT messages and generates a byte stream. + * Each output byte contains only one LSB, thus the output can be directly + * used for FM modulation. + * + * \ingroup satnogs + * + */ + class SATNOGS_API ax25_encoder_mb : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr sptr; + + + /** + * AX.25 encoder block that supports the legacy hardware radios. + * + * The block takes as inputs blob PMT messages and generates a byte stream. + * Each output byte contains only one LSB, thus the output can be directly + * used for FM modulation. + * + * @param dest_addr the destination callsign + * @param dest_ssid the destination SSID + * @param src_addr the source callsign + * @param src_ssid the source SSID + * @param preamble_len the number of times that the AX.25 synchronization flags + * should be repeated in front of the frame. + * @param postamble_len the number of times that the AX.25 synchronization flags + * should be repeated at the end of the frame. + * @param scramble if set to true, G3RUH scrambling will be performed + * after bit stuffing + */ + static sptr + make (const std::string& dest_addr, uint8_t dest_ssid, + const std::string& src_addr, + uint8_t src_ssid, size_t preamble_len =16, + size_t postamble_len = 16, + bool scramble = true); + }; + + } // namespace satnogs +} // namespace gr + +#endif /* INCLUDED_SATNOGS_AX25_ENCODER_MB_H */ + diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 176997e..64b81f4 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -31,9 +31,7 @@ list(APPEND satnogs_sources morse_debug_source_impl.cc multi_format_msg_sink_impl.cc cw_to_symbol_impl.cc - afsk_decoder_impl.cc sine_matched_filter_ff_impl.cc - ax25_encoder_bf_impl.cc ax25_decoder_b_impl.cc udp_msg_source_impl.cc debug_msg_source_impl.cc @@ -48,7 +46,8 @@ list(APPEND satnogs_sources whitening.cc udp_msg_sink_impl.cc coarse_doppler_correction_cc_impl.cc - debug_msg_source_raw_impl.cc ) + debug_msg_source_raw_impl.cc + ax25_encoder_mb_impl.cc ) set(satnogs_sources "${satnogs_sources}" PARENT_SCOPE) if(NOT satnogs_sources) diff --git a/lib/afsk_decoder_impl.cc b/lib/afsk_decoder_impl.cc deleted file mode 100644 index 7870891..0000000 --- a/lib/afsk_decoder_impl.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- c++ -*- */ -/* - * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module - * - * Copyright (C) 2016, Libre Space Foundation - * - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "afsk_decoder_impl.h" - -namespace gr -{ - namespace satnogs - { - - afsk_decoder::sptr - afsk_decoder::make (double sampling_rate, size_t samples_per_sym, - size_t fft_size, - bool auto_carrier_tracking, - double mark_freq, - double space_freq) - { - return gnuradio::get_initial_sptr ( - new afsk_decoder_impl (sampling_rate, samples_per_sym, fft_size, - auto_carrier_tracking, - mark_freq, space_freq)); - } - /* - * The private constructor - */ - afsk_decoder_impl::afsk_decoder_impl (double sampling_rate, size_t samples_per_sym, - size_t fft_size, - bool auto_carrier_tracking, - double mark_freq, double space_freq) : - gr::block ("afsk_decoder", - gr::io_signature::make (1, 1, fft_size * sizeof(float)), - gr::io_signature::make (1, 1, sizeof(char))), - d_samp_rate(sampling_rate), - d_samples_per_sym(samples_per_sym), - d_fft_size(fft_size), - d_carriers_found(!auto_carrier_tracking), - d_mark_freq(mark_freq), - d_space_freq(space_freq) - { - if(auto_carrier_tracking){ - d_mark_freq = d_space_freq = 0.0; - } - } - - /* - * Our virtual destructor. - */ - afsk_decoder_impl::~afsk_decoder_impl () - { - } - - void - afsk_decoder_impl::forecast (int noutput_items, - gr_vector_int &ninput_items_required) - { - ninput_items_required[0] = noutput_items; - } - - int - afsk_decoder_impl::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { - const float *in = (const float *) input_items[0]; - - consume_each (noutput_items); - - // Tell runtime system how many output items we produced. - return noutput_items; - } - - } /* namespace satnogs */ -} /* namespace gr */ - diff --git a/lib/afsk_decoder_impl.h b/lib/afsk_decoder_impl.h deleted file mode 100644 index fdb9bf4..0000000 --- a/lib/afsk_decoder_impl.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- c++ -*- */ -/* - * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module - * - * Copyright (C) 2016, Libre Space Foundation - * - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef INCLUDED_SATNOGS_AFSK_DECODER_IMPL_H -#define INCLUDED_SATNOGS_AFSK_DECODER_IMPL_H - -#include - -namespace gr -{ - namespace satnogs - { - - class afsk_decoder_impl : public afsk_decoder - { - private: - const double d_samp_rate; - const size_t d_samples_per_sym; - const size_t d_fft_size; - bool d_carriers_found; - double d_mark_freq; - double d_space_freq; - - - public: - afsk_decoder_impl (double sampling_rate, size_t baudrate, size_t fft_size, - bool auto_carrier_tracking, double mark_freq, - double space_freq); - ~afsk_decoder_impl (); - - // Where all the action really happens - void - forecast (int noutput_items, gr_vector_int &ninput_items_required); - - int - general_work (int noutput_items, gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - }; - - } // namespace satnogs -} // namespace gr - -#endif /* INCLUDED_SATNOGS_AFSK_DECODER_IMPL_H */ - diff --git a/lib/ax25_encoder_bf_impl.cc b/lib/ax25_encoder_bf_impl.cc deleted file mode 100644 index 0bad797..0000000 --- a/lib/ax25_encoder_bf_impl.cc +++ /dev/null @@ -1,168 +0,0 @@ -/* -*- c++ -*- */ -/* - * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module - * - * Copyright (C) 2016, Libre Space Foundation - * - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "ax25_encoder_bf_impl.h" -#include - -namespace gr -{ - namespace satnogs - { - - ax25_encoder_bf::sptr - ax25_encoder_bf::make (std::string dest_addr, - uint8_t dest_ssid, std::string src_addr, - uint8_t src_ssid) - { - return gnuradio::get_initial_sptr (new ax25_encoder_bf_impl (AX25_I_FRAME, - dest_addr, - dest_ssid, - src_addr, - src_ssid)); - } - - /* - * The private constructor - */ - ax25_encoder_bf_impl::ax25_encoder_bf_impl (ax25_frame_type_t type, - std::string dest_addr, - uint8_t dest_ssid, - std::string src_addr, - uint8_t src_ssid) : - gr::sync_block ("ax25_encoder_bf", gr::io_signature::make (0, 0, 0), - gr::io_signature::make (1, 1, sizeof(float))), - d_type (type), - d_remaining (0), - d_produced(0), - d_endoded_frame(new float[(AX25_MAX_FRAME_LEN * 2)]), - d_tmp_buf(new uint8_t[AX25_MAX_FRAME_LEN * 2]), - d_addr_field(new uint8_t[AX25_MAX_ADDR_LEN]) - { - /* Input is a key-value pair containing the info field data */ - message_port_register_in (pmt::mp ("info")); - d_addr_len = ax25_create_addr_field(d_addr_field, dest_addr, dest_ssid, - src_addr, src_ssid); - } - - /* - * Our virtual destructor. - */ - ax25_encoder_bf_impl::~ax25_encoder_bf_impl () - { - delete[] d_endoded_frame; - delete[] d_tmp_buf; - delete[] d_addr_field; - } - - int - ax25_encoder_bf_impl::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { - const uint8_t *info; - size_t info_len; - size_t max_avail; - size_t len; - size_t i; - pmt::pmt_t msg; - ax25_encode_status_t status; - - float *out = (float *) output_items[0]; - - /* 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; - - /* Block waiting from a new message from users */ - msg = delete_head_blocking (pmt::mp ("info")); - info = (const uint8_t *)pmt::blob_data(msg); - info_len = pmt::blob_length(msg); - - /* 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_bit_stuffing(d_endoded_frame, &d_remaining, d_tmp_buf, - len); - if(status != AX25_ENC_OK){ - LOG_ERROR("NRZ Encoding failed"); - d_remaining = 0; - return 0; - } - } - - /* If this is the first part of the frame add the start of burst tag*/ - if(d_produced == 0) { - add_sob(nitems_written(0)); - } - max_avail = std::min(d_remaining, (size_t) noutput_items); - memcpy(out, d_endoded_frame + d_produced, max_avail * sizeof(float)); - d_remaining -= max_avail; - d_produced += max_avail; - if(d_remaining == 0){ - add_eob(nitems_written(0) + max_avail); - } - return (int) max_avail; - } - - /** - * Updates the source and destination callsigns and SSIDs - * @param dest_addr the destination callsign address - * @param dest_ssid the destination SSID - * @param src_addr the callsign of the source - * @param src_ssid the source SSID - */ - void - ax25_encoder_bf_impl::set_address_field (std::string dest_addr, - uint8_t dest_ssid, - std::string src_addr, - uint8_t src_ssid) - { - boost::mutex::scoped_lock lock (d_mutex); - d_addr_len = ax25_create_addr_field(d_addr_field, dest_addr, dest_ssid, - src_addr, src_ssid); - } - - void - ax25_encoder_bf_impl::add_sob (uint64_t item) - { - static const pmt::pmt_t sob_key = pmt::string_to_symbol ("tx_sob"); - static const pmt::pmt_t value = pmt::PMT_T; - static const pmt::pmt_t srcid = pmt::string_to_symbol (alias ()); - add_item_tag (0, item, sob_key, value, srcid); - } - - void - ax25_encoder_bf_impl::add_eob (uint64_t item) - { - static const pmt::pmt_t eob_key = pmt::string_to_symbol ("tx_eob"); - static const pmt::pmt_t value = pmt::PMT_T; - static const pmt::pmt_t srcid = pmt::string_to_symbol (alias ()); - add_item_tag (0, item, eob_key, value, srcid); - } - - } /* namespace satnogs */ -} /* namespace gr */ - diff --git a/lib/ax25_encoder_mb_impl.cc b/lib/ax25_encoder_mb_impl.cc new file mode 100644 index 0000000..7b14784 --- /dev/null +++ b/lib/ax25_encoder_mb_impl.cc @@ -0,0 +1,182 @@ +/* -*- c++ -*- */ +/* + * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module + * + * Copyright (C) 2016, Libre Space Foundation + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "ax25_encoder_mb_impl.h" +#include +#include + +namespace gr +{ + namespace satnogs + { + + ax25_encoder_mb::sptr + ax25_encoder_mb::make (const std::string& dest_addr, uint8_t dest_ssid, + const std::string& src_addr, uint8_t src_ssid, + size_t preamble_len, size_t postamble_len, + bool scramble) + { + return gnuradio::get_initial_sptr ( + new ax25_encoder_mb_impl (dest_addr, dest_ssid, src_addr, src_ssid, + preamble_len, postamble_len, scramble)); + } + + /* + * The private constructor + */ + ax25_encoder_mb_impl::ax25_encoder_mb_impl (const std::string& dest_addr, + uint8_t dest_ssid, + const std::string& src_addr, + uint8_t src_ssid, + size_t preamble_len, + size_t postabmle_len, + bool scramble) : + gr::sync_block ("ax25_encoder_mb", gr::io_signature::make (0, 0, 0), + gr::io_signature::make (1, 1, sizeof(uint8_t))), + d_preamble_len (preamble_len), + d_postamble_len (postabmle_len), + d_scramble(scramble), + d_remaining (0), + d_produced (0), + d_prev_bit(0x0), + d_encoded_frame ( + new uint8_t[preamble_len + postabmle_len + + (AX25_MAX_FRAME_LEN * 2)]), + d_tmp_buf ( + new uint8_t[preamble_len + postabmle_len + + (AX25_MAX_FRAME_LEN * 2)]), + d_addr_field (new uint8_t[AX25_MAX_ADDR_LEN]), + d_lfsr(0x21, 0x0, 16) + { + /* Input is a blob message containing the info field data */ + message_port_register_in (pmt::mp ("info")); + d_addr_len = ax25_create_addr_field(d_addr_field, dest_addr, dest_ssid, + src_addr, src_ssid); + } + + /* + * Our virtual destructor. + */ + ax25_encoder_mb_impl::~ax25_encoder_mb_impl () + { + delete [] d_encoded_frame; + delete [] d_tmp_buf; + delete [] d_addr_field; + } + + int + ax25_encoder_mb_impl::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const uint8_t *info; + size_t info_len; + size_t max_avail; + size_t len; + size_t i; + pmt::pmt_t msg; + ax25_encode_status_t status; + + uint8_t *out = (uint8_t *) output_items[0]; + + /* 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(); + + /* Block waiting from a new message from users */ + msg = delete_head_blocking (pmt::mp ("info")); + info = (const uint8_t *)pmt::blob_data(msg); + info_len = pmt::blob_length(msg); + + /* 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, + d_preamble_len, d_postamble_len); + + /* Perform bit stuffing */ + status = ax25_bit_stuffing (d_encoded_frame, &d_remaining, d_tmp_buf, + len, d_preamble_len, d_postamble_len); + if (status != AX25_ENC_OK) { + LOG_ERROR ("AX.25 encoding failed"); + d_remaining = 0; + return 0; + } + + /*Perform scrambling if the user asked for it */ + if(d_scramble){ + for(i = 0; i < d_remaining; i++){ + d_encoded_frame[i] = d_lfsr.next_bit_scramble(d_encoded_frame[i]); + } + } + + /* If this is the first part of the frame add the start of burst tag*/ + if (d_produced == 0) { + add_sob (nitems_written (0)); + } + max_avail = std::min (d_remaining, (size_t) noutput_items); + + /* Perform NRZI encoding */ + for(i = 0; i < max_avail; i++) { + out[i] = ( (0x1 & ~d_encoded_frame[i + d_produced]) + d_prev_bit) % 2; + d_prev_bit = out[i]; + } + + d_remaining -= max_avail; + d_produced += max_avail; + if (d_remaining == 0) { + add_eob (nitems_written (0) + max_avail); + } + 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) + { + static const pmt::pmt_t sob_key = pmt::string_to_symbol ("tx_sob"); + static const pmt::pmt_t value = pmt::PMT_T; + static const pmt::pmt_t srcid = pmt::string_to_symbol (alias ()); + add_item_tag (0, item, sob_key, value, srcid); + } + + void + ax25_encoder_mb_impl::add_eob (uint64_t item) + { + static const pmt::pmt_t eob_key = pmt::string_to_symbol ("tx_eob"); + static const pmt::pmt_t value = pmt::PMT_T; + static const pmt::pmt_t srcid = pmt::string_to_symbol (alias ()); + add_item_tag (0, item, eob_key, value, srcid); + } + + } /* namespace satnogs */ +} /* namespace gr */ + diff --git a/lib/ax25_encoder_bf_impl.h b/lib/ax25_encoder_mb_impl.h similarity index 55% rename from lib/ax25_encoder_bf_impl.h rename to lib/ax25_encoder_mb_impl.h index d4020b4..5203422 100644 --- a/lib/ax25_encoder_bf_impl.h +++ b/lib/ax25_encoder_mb_impl.h @@ -18,49 +18,51 @@ * along with this program. If not, see . */ -#ifndef INCLUDED_SATNOGS_AX25_ENCODER_BF_IMPL_H -#define INCLUDED_SATNOGS_AX25_ENCODER_BF_IMPL_H +#ifndef INCLUDED_SATNOGS_AX25_ENCODER_MB_IMPL_H +#define INCLUDED_SATNOGS_AX25_ENCODER_MB_IMPL_H -#include -#include +#include +#include -namespace gr { - namespace satnogs { +namespace gr +{ + namespace satnogs + { - class ax25_encoder_bf_impl : public ax25_encoder_bf + class ax25_encoder_mb_impl : public ax25_encoder_mb { - private: - const ax25_frame_type_t d_type; + private: + const size_t d_preamble_len; + const size_t d_postamble_len; + const bool d_scramble; size_t d_remaining; size_t d_produced; - /* Twice the maximum frame length is enough to hold all possible input data*/ - float *d_endoded_frame; + uint8_t d_prev_bit; + uint8_t *d_encoded_frame; uint8_t *d_tmp_buf; uint8_t *d_addr_field; size_t d_addr_len; + digital::lfsr d_lfsr; boost::mutex d_mutex; void add_sob(uint64_t item); void add_eob(uint64_t item); - public: - ax25_encoder_bf_impl (ax25_frame_type_t type, std::string dest_addr, - uint8_t dest_ssid, std::string src_addr, - uint8_t src_ssid); - ~ax25_encoder_bf_impl(); - - void - set_address_field (std::string dest_addr, uint8_t dest_ssid, - std::string src_addr, uint8_t src_ssid); + public: + ax25_encoder_mb_impl (const std::string& dest_addr, uint8_t dest_ssid, + const std::string& src_addr, uint8_t src_ssid, + size_t preamble_len, size_t postamble_len, + bool scramble); + ~ax25_encoder_mb_impl (); // Where all the action really happens - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + int + work (int noutput_items, gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; } // namespace satnogs } // namespace gr -#endif /* INCLUDED_SATNOGS_AX25_ENCODER_BF_IMPL_H */ +#endif /* INCLUDED_SATNOGS_AX25_ENCODER_MB_IMPL_H */ diff --git a/lib/upsat_fsk_frame_encoder_impl.cc b/lib/upsat_fsk_frame_encoder_impl.cc index fa67fea..141fde5 100644 --- a/lib/upsat_fsk_frame_encoder_impl.cc +++ b/lib/upsat_fsk_frame_encoder_impl.cc @@ -313,9 +313,9 @@ namespace gr 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); + d_ax25_addr_len, 0x03, 1, 1, 1); status = ax25_bit_stuffing(d_ax25_pdu, &encoded_len, - d_ax25_tmp_buf, len); + d_ax25_tmp_buf, len, 1, 1); if(status != AX25_ENC_OK) { LOG_WARN("Failed to properly encode into AX.25 frame"); return 0; diff --git a/swig/satnogs_swig.i b/swig/satnogs_swig.i index 43d4e56..ed49385 100644 --- a/swig/satnogs_swig.i +++ b/swig/satnogs_swig.i @@ -15,9 +15,7 @@ #include "satnogs/morse_debug_source.h" #include "satnogs/multi_format_msg_sink.h" #include "satnogs/cw_to_symbol.h" -#include "satnogs/afsk_decoder.h" #include "satnogs/sine_matched_filter_ff.h" -#include "satnogs/ax25_encoder_bf.h" #include "satnogs/ax25_decoder_b.h" #include "satnogs/udp_msg_source.h" #include "satnogs/debug_msg_source.h" @@ -31,6 +29,7 @@ #include "satnogs/udp_msg_sink.h" #include "satnogs/coarse_doppler_correction_cc.h" #include "satnogs/debug_msg_source_raw.h" +#include "satnogs/ax25_encoder_mb.h" %} @@ -45,12 +44,10 @@ GR_SWIG_BLOCK_MAGIC2(satnogs, morse_debug_source); GR_SWIG_BLOCK_MAGIC2(satnogs, multi_format_msg_sink); %include "satnogs/cw_to_symbol.h" GR_SWIG_BLOCK_MAGIC2(satnogs, cw_to_symbol); -%include "satnogs/afsk_decoder.h" -GR_SWIG_BLOCK_MAGIC2(satnogs, afsk_decoder); + %include "satnogs/sine_matched_filter_ff.h" GR_SWIG_BLOCK_MAGIC2(satnogs, sine_matched_filter_ff); -%include "satnogs/ax25_encoder_bf.h" -GR_SWIG_BLOCK_MAGIC2(satnogs, ax25_encoder_bf); + %include "satnogs/ax25_decoder_b.h" GR_SWIG_BLOCK_MAGIC2(satnogs, ax25_decoder_b); %include "satnogs/udp_msg_source.h" @@ -76,3 +73,5 @@ GR_SWIG_BLOCK_MAGIC2(satnogs, udp_msg_sink); GR_SWIG_BLOCK_MAGIC2(satnogs, coarse_doppler_correction_cc); %include "satnogs/debug_msg_source_raw.h" GR_SWIG_BLOCK_MAGIC2(satnogs, debug_msg_source_raw); +%include "satnogs/ax25_encoder_mb.h" +GR_SWIG_BLOCK_MAGIC2(satnogs, ax25_encoder_mb);