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.
This commit is contained in:
Manolis Surligas 2016-06-30 23:39:16 +03:00
parent bfa2313242
commit 92843c43c9
17 changed files with 403 additions and 602 deletions

View File

@ -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
)

View File

@ -1,38 +0,0 @@
<?xml version="1.0"?>
<block>
<name>afsk_decoder</name>
<key>satnogs_afsk_decoder</key>
<category>satnogs</category>
<import>import satnogs</import>
<make>satnogs.afsk_decoder($sampling_rate, $baudrate, $fft_size)</make>
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
Sub-nodes:
* name
* key (makes the value accessible as $keyname, e.g. in the make node)
* type -->
<param>
<name>...</name>
<key>...</key>
<type>...</type>
</param>
<!-- Make one 'sink' node per input. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<sink>
<name>in</name>
<type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type>
</sink>
<!-- Make one 'source' node per output. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<source>
<name>out</name>
<type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...--></type>
</source>
</block>

View File

@ -1,43 +0,0 @@
<?xml version="1.0"?>
<block>
<name>AX.25 Encoder</name>
<key>satnogs_ax25_encoder_bf</key>
<category>satnogs</category>
<import>import satnogs</import>
<make>satnogs.ax25_encoder_bf($dest_addr, $dest_ssid, $src_addr, $src_ssid)</make>
<callback>set_address_field($dest_addr, $dest_ssid, $src_addr, $src_ssid)</callback>
<param>
<name>Destination Callsign</name>
<key>dest_addr</key>
<type>string</type>
</param>
<param>
<name>Destination SSID</name>
<key>dest_ssid</key>
<type>int</type>
</param>
<param>
<name>Source Callsign</name>
<key>src_addr</key>
<type>string</type>
</param>
<param>
<name>Source SSID</name>
<key>src_ssid</key>
<type>int</type>
</param>
<sink>
<name>info</name>
<type>message</type>
</sink>
<source>
<name>out</name>
<type>float</type>
</source>
</block>

View File

@ -0,0 +1,70 @@
<?xml version="1.0"?>
<block>
<name>AX.25 Encoder</name>
<key>satnogs_ax25_encoder_mb</key>
<category>satnogs</category>
<import>import satnogs</import>
<make>satnogs.ax25_encoder_mb($dest_addr, $dest_ssid, $src_addr, $src_ssid, $preamble_len, $postamble_len, $scramble)</make>
<param>
<name>Destination Callsign</name>
<key>dest_addr</key>
<type>string</type>
</param>
<param>
<name>Destination SSID</name>
<key>dest_ssid</key>
<type>int</type>
</param>
<param>
<name>Source Callsign</name>
<key>src_addr</key>
<type>string</type>
</param>
<param>
<name>Source SSID</name>
<key>src_ssid</key>
<type>int</type>
</param>
<param>
<name>Preamble Length</name>
<key>preamble_len</key>
<value>16</value>
<type>int</type>
</param>
<param>
<name>Postamble Length</name>
<key>postamble_len</key>
<value>16</value>
<type>int</type>
</param>
<param>
<name>G3RUH Scrambling</name>
<key>scramble</key>
<type>enum</type>
<option>
<name>Yes</name>
<key>True</key>
</option>
<option>
<name>No</name>
<key>False</key>
</option>
</param>
<sink>
<name>info</name>
<type>message</type>
</sink>
<source>
<name>out</name>
<type>byte</type>
</source>
</block>

View File

@ -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
)

View File

@ -1,63 +0,0 @@
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_SATNOGS_AFSK_DECODER_H
#define INCLUDED_SATNOGS_AFSK_DECODER_H
#include <satnogs/api.h>
#include <gnuradio/block.h>
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<afsk_decoder> 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 */

View File

@ -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;

View File

@ -1,69 +0,0 @@
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_SATNOGS_AX25_ENCODER_BF_H
#define INCLUDED_SATNOGS_AX25_ENCODER_BF_H
#include <satnogs/api.h>
#include <gnuradio/sync_block.h>
#include <satnogs/ax25.h>
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<ax25_encoder_bf> 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 */

View File

@ -0,0 +1,78 @@
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_SATNOGS_AX25_ENCODER_MB_H
#define INCLUDED_SATNOGS_AX25_ENCODER_MB_H
#include <satnogs/api.h>
#include <gnuradio/sync_block.h>
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<ax25_encoder_mb> 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 */

View File

@ -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)

View File

@ -1,97 +0,0 @@
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/io_signature.h>
#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 */

View File

@ -1,62 +0,0 @@
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_SATNOGS_AFSK_DECODER_IMPL_H
#define INCLUDED_SATNOGS_AFSK_DECODER_IMPL_H
#include <satnogs/afsk_decoder.h>
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 */

View File

@ -1,168 +0,0 @@
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/io_signature.h>
#include "ax25_encoder_bf_impl.h"
#include <satnogs/log.h>
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 */

182
lib/ax25_encoder_mb_impl.cc Normal file
View File

@ -0,0 +1,182 @@
/* -*- c++ -*- */
/*
* gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
*
* Copyright (C) 2016, Libre Space Foundation <http://librespacefoundation.org/>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/io_signature.h>
#include "ax25_encoder_mb_impl.h"
#include <satnogs/log.h>
#include <satnogs/ax25.h>
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 */

View File

@ -18,49 +18,51 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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 <satnogs/ax25_encoder_bf.h>
#include <boost/thread/mutex.hpp>
#include <satnogs/ax25_encoder_mb.h>
#include <gnuradio/digital/lfsr.h>
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 */

View File

@ -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;

View File

@ -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);