mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-13 03:30:33 +00:00
Adding UDP GNSS signal source block
This commit is contained in:
parent
43103068fd
commit
7865387df9
86
conf/gnss-sdr_GPS_L1_2ch_udp.conf
Normal file
86
conf/gnss-sdr_GPS_L1_2ch_udp.conf
Normal file
@ -0,0 +1,86 @@
|
||||
; You can define your own receiver and invoke it by doing
|
||||
; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf
|
||||
;
|
||||
|
||||
[GNSS-SDR]
|
||||
|
||||
;######### GLOBAL OPTIONS ##################
|
||||
;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [Sps].
|
||||
GNSS-SDR.internal_fs_sps=2600000
|
||||
|
||||
;######### SIGNAL_SOURCE CONFIG ############
|
||||
SignalSource.implementation=UDP_Signal_Source
|
||||
;SignalSource.implementation=File_Signal_Source
|
||||
SignalSource.filename=/home/javier/gnss/gnss-simulator/build/signal_out.bin ; <- PUT YOUR FILE HERE
|
||||
SignalSource.item_type=gr_complex
|
||||
SignalSource.address=0.0.0.0
|
||||
SignalSource.port=1234
|
||||
SignalSource.payload_bytes=1024
|
||||
SignalSource.sample_type=cbyte
|
||||
SignalSource.RF_channels=2
|
||||
SignalSource.dump=true
|
||||
SignalSource.dump_filename=./signal_source.dat
|
||||
|
||||
|
||||
;######### SIGNAL_CONDITIONER CONFIG ############
|
||||
SignalConditioner0.implementation=Pass_Through
|
||||
SignalConditioner1.implementation=Pass_Through
|
||||
|
||||
;######### CHANNELS GLOBAL CONFIG ############
|
||||
Channels_1C.count=2
|
||||
Channels.in_acquisition=1
|
||||
|
||||
;# CHANNEL CONNECTION
|
||||
Channel0.RF_channel_ID=0
|
||||
Channel0.signal=1C
|
||||
Channel1.RF_channel_ID=1
|
||||
Channel1.signal=1C
|
||||
|
||||
;######### ACQUISITION GLOBAL CONFIG ############
|
||||
Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition
|
||||
Acquisition_1C.item_type=gr_complex
|
||||
Acquisition_1C.threshold=20
|
||||
Acquisition_1C.use_CFAR_algorithm=false
|
||||
Acquisition_1C.blocking=true
|
||||
Acquisition_1C.doppler_max=10000
|
||||
Acquisition_1C.doppler_step=250
|
||||
Acquisition_1C.dump=false
|
||||
Acquisition_1C.dump_filename=./acq_dump.dat
|
||||
|
||||
|
||||
;######### TRACKING GLOBAL CONFIG ############
|
||||
Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking
|
||||
Tracking_1C.item_type=gr_complex
|
||||
Tracking_1C.dump=false
|
||||
Tracking_1C.dump_filename=./tracking_ch_
|
||||
Tracking_1C.pll_bw_hz=35.0;
|
||||
Tracking_1C.dll_bw_hz=2.0;
|
||||
Tracking_1C.early_late_space_chips=0.5;
|
||||
|
||||
|
||||
;######### TELEMETRY DECODER GPS CONFIG ############
|
||||
TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder
|
||||
TelemetryDecoder_1C.dump=false
|
||||
|
||||
|
||||
;######### OBSERVABLES CONFIG ############
|
||||
Observables.implementation=Hybrid_Observables
|
||||
Observables.dump=false
|
||||
Observables.dump_filename=./observables.dat
|
||||
|
||||
|
||||
;######### PVT CONFIG ############
|
||||
PVT.implementation=RTKLIB_PVT
|
||||
PVT.positioning_mode=Single ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic
|
||||
PVT.iono_model=Broadcast ; options: OFF, Broadcast, SBAS, Iono-Free-LC, Estimate_STEC, IONEX
|
||||
PVT.trop_model=Saastamoinen ; options: OFF, Saastamoinen, SBAS, Estimate_ZTD, Estimate_ZTD_Grad
|
||||
PVT.output_rate_ms=100
|
||||
PVT.display_rate_ms=500
|
||||
PVT.dump_filename=./PVT
|
||||
PVT.nmea_dump_filename=./gnss_sdr_pvt.nmea;
|
||||
PVT.flag_nmea_tty_port=false;
|
||||
PVT.nmea_dump_devname=/dev/pts/4
|
||||
PVT.flag_rtcm_server=false
|
||||
PVT.flag_rtcm_tty_port=false
|
||||
PVT.rtcm_dump_devname=/dev/pts/1
|
||||
PVT.dump=false
|
@ -166,6 +166,7 @@ set(SIGNAL_SOURCE_ADAPTER_SOURCES file_signal_source.cc
|
||||
spir_gss6450_file_signal_source.cc
|
||||
rtl_tcp_signal_source.cc
|
||||
labsat_signal_source.cc
|
||||
udp_signal_source.cc
|
||||
${OPT_DRIVER_SOURCES}
|
||||
)
|
||||
|
||||
|
186
src/algorithms/signal_source/adapters/udp_signal_source.cc
Normal file
186
src/algorithms/signal_source/adapters/udp_signal_source.cc
Normal file
@ -0,0 +1,186 @@
|
||||
/*!
|
||||
* \file rtl_tcp_signal_source.cc
|
||||
* \brief Signal source for the Realtek RTL2832U USB dongle DVB-T receiver
|
||||
* over TCP.
|
||||
* (see http://sdr.osmocom.org/trac/wiki/rtl-sdr for more information)
|
||||
* \author Anthony Arnold, 2015. anthony.arnold(at)uqconnect.edu.au
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
|
||||
*
|
||||
* GNSS-SDR is a software defined Global Navigation
|
||||
* Satellite Systems receiver
|
||||
*
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* GNSS-SDR 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.
|
||||
*
|
||||
* GNSS-SDR 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 GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "udp_signal_source.h"
|
||||
#include "configuration_interface.h"
|
||||
#include "GPS_L1_CA.h"
|
||||
#include <boost/format.hpp>
|
||||
#include <glog/logging.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using google::LogMessage;
|
||||
|
||||
|
||||
UDPSignalSource::UDPSignalSource(ConfigurationInterface* configuration,
|
||||
std::string role, unsigned int in_stream, unsigned int out_stream,
|
||||
boost::shared_ptr<gr::msg_queue> queue) : role_(role), in_stream_(in_stream), out_stream_(out_stream), queue_(queue)
|
||||
{
|
||||
// DUMP PARAMETERS
|
||||
std::string empty = "";
|
||||
std::string default_dump_file = "./data/signal_source.dat";
|
||||
std::string default_item_type = "gr_complex";
|
||||
dump_ = configuration->property(role + ".dump", false);
|
||||
dump_filename_ = configuration->property(role + ".dump_filename",
|
||||
default_dump_file);
|
||||
|
||||
// rtl_tcp PARAMETERS
|
||||
std::string default_address = "127.0.0.1";
|
||||
int default_port = 1234;
|
||||
|
||||
RF_channels_ = configuration->property(role + ".RF_channels", 2);
|
||||
std::string default_sample_type = "cbyte";
|
||||
std::string sample_type = configuration->property(role + ".sample_type", default_sample_type);
|
||||
|
||||
item_type_ = configuration->property(role + ".item_type", default_item_type);
|
||||
address_ = configuration->property(role + ".address", default_address);
|
||||
port_ = configuration->property(role + ".port", default_port);
|
||||
int payload_bytes = configuration->property(role + ".payload_bytes", 1024);
|
||||
|
||||
if (sample_type.compare("cbyte")==0)
|
||||
{
|
||||
std::cout<<"address_ "<<address_<<" port_ "<<port_<<" payload_bytes"<<payload_bytes<<std::endl;
|
||||
udp_gnss_rx_source_ = make_udp_gnss_rx_source(sizeof(char), address_, port_, payload_bytes, true);
|
||||
demux_=gr::blocks::deinterleave::make(sizeof(char),1);
|
||||
}else{
|
||||
std::cout<<"WARNING: Requested UDP sample type unsuported, setting sample type to cbyte\n";
|
||||
udp_gnss_rx_source_ = make_udp_gnss_rx_source(sizeof(char), address_, port_, payload_bytes, true);
|
||||
demux_=gr::blocks::deinterleave::make(sizeof(char),1);
|
||||
}
|
||||
|
||||
|
||||
//create I, Q -> gr_complex type conversion blocks
|
||||
for (int n = 0; n < (RF_channels_ * 2); n++)
|
||||
{
|
||||
char_to_float.push_back(gr::blocks::char_to_float::make());
|
||||
}
|
||||
|
||||
for (int n = 0; n < RF_channels_; n++)
|
||||
{
|
||||
float_to_complex_.push_back(gr::blocks::float_to_complex::make());
|
||||
}
|
||||
|
||||
item_size_ = sizeof(gr_complex);
|
||||
|
||||
if (dump_)
|
||||
{
|
||||
file_sink_dbg_=gr::blocks::file_sink::make(sizeof(char), "debug.dat");
|
||||
|
||||
for (int n = 0; n < RF_channels_; n++)
|
||||
{
|
||||
DLOG(INFO) << "Dumping output into file " << (dump_filename_+"ch"+std::to_string(n));
|
||||
file_sink_.push_back(gr::blocks::file_sink::make(item_size_, (dump_filename_+"ch"+std::to_string(n)).c_str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UDPSignalSource::~UDPSignalSource()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void UDPSignalSource::connect(gr::top_block_sptr top_block)
|
||||
{
|
||||
top_block->connect(udp_gnss_rx_source_,0, demux_,0);
|
||||
DLOG(INFO)<<"connected udp_source to demux"<<std::endl;
|
||||
for (int n = 0; n < (RF_channels_ * 2); n++)
|
||||
{
|
||||
|
||||
top_block->connect(demux_, n, char_to_float.at(n), 0);
|
||||
DLOG(INFO) << "connected demux to char_to_float CH" << n;
|
||||
}
|
||||
for (int n = 0; n < RF_channels_; n++)
|
||||
{
|
||||
top_block->connect(char_to_float.at(n * 2), 0, float_to_complex_.at(n), 0);
|
||||
top_block->connect(char_to_float.at(n * 2 + 1), 0, float_to_complex_.at(n), 1);
|
||||
DLOG(INFO) << "connected char_to_float to float_to_complex_ CH" << n;
|
||||
}
|
||||
|
||||
if (dump_)
|
||||
{
|
||||
top_block->connect(udp_gnss_rx_source_,0, file_sink_dbg_,0);
|
||||
for (int n = 0; n < RF_channels_; n++)
|
||||
{
|
||||
top_block->connect(float_to_complex_.at(n), 0, file_sink_.at(n), 0);
|
||||
DLOG(INFO) << "connected source to file sink";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void UDPSignalSource::disconnect(gr::top_block_sptr top_block)
|
||||
{
|
||||
|
||||
for (int n = 0; n < (RF_channels_ * 2); n++)
|
||||
{
|
||||
top_block->disconnect(demux_, n, char_to_float.at(n), 0);
|
||||
DLOG(INFO) << "disconnect demux to char_to_float CH" << n;
|
||||
}
|
||||
for (int n = 0; n < RF_channels_; n++)
|
||||
{
|
||||
top_block->disconnect(char_to_float.at(n * 2), 0, float_to_complex_.at(n), 0);
|
||||
top_block->disconnect(char_to_float.at(n * 2 + 1), 0, float_to_complex_.at(n), 1);
|
||||
DLOG(INFO) << "disconnect char_to_float to float_to_complex_ CH" << n;
|
||||
}
|
||||
|
||||
if (dump_)
|
||||
{
|
||||
top_block->disconnect(udp_gnss_rx_source_,0, file_sink_dbg_,0);
|
||||
for (int n = 0; n < RF_channels_; n++)
|
||||
{
|
||||
top_block->disconnect(float_to_complex_.at(n), 0, file_sink_.at(n), 0);
|
||||
DLOG(INFO) << "disconnected source to file sink";
|
||||
}
|
||||
}
|
||||
top_block->disconnect(udp_gnss_rx_source_,0, demux_,0);
|
||||
DLOG(INFO)<<"disconnected udp_source to demux"<<std::endl;
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr UDPSignalSource::get_left_block()
|
||||
{
|
||||
LOG(WARNING) << "Left block of a signal source should not be retrieved";
|
||||
return gr::block_sptr();
|
||||
}
|
||||
|
||||
|
||||
gr::basic_block_sptr UDPSignalSource::get_right_block()
|
||||
{
|
||||
return get_right_block(0);
|
||||
}
|
||||
|
||||
gr::basic_block_sptr UDPSignalSource::get_right_block(int RF_channel)
|
||||
{
|
||||
return float_to_complex_.at(RF_channel);
|
||||
}
|
||||
|
114
src/algorithms/signal_source/adapters/udp_signal_source.h
Normal file
114
src/algorithms/signal_source/adapters/udp_signal_source.h
Normal file
@ -0,0 +1,114 @@
|
||||
/*!
|
||||
* \file rtl_tcp_signal_source.h
|
||||
* \brief Signal source which reads from rtl_tcp.
|
||||
* (see http://sdr.osmocom.org/trac/wiki/rtl-sdr for more information)
|
||||
* \author Anthony Arnold, 2015. anthony.arnold(at)uqconnect.edu.au
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors)
|
||||
*
|
||||
* GNSS-SDR is a software defined Global Navigation
|
||||
* Satellite Systems receiver
|
||||
*
|
||||
* This file is part of GNSS-SDR.
|
||||
*
|
||||
* GNSS-SDR 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.
|
||||
*
|
||||
* GNSS-SDR 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 GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GNSS_SDR_UDP_SIGNAL_SOURCE_H
|
||||
#define GNSS_SDR_UDP_SIGNAL_SOURCE_H
|
||||
|
||||
#include "gnss_block_interface.h"
|
||||
#include "udp_gnss_rx_source.h"
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <gnuradio/msg_queue.h>
|
||||
#include <gnuradio/blocks/char_to_float.h>
|
||||
//#include <gnuradio/blocks/udp_source.h>
|
||||
#include <gnuradio/blocks/file_sink.h>
|
||||
#include <gnuradio/blocks/deinterleave.h>
|
||||
#include <gnuradio/blocks/float_to_complex.h>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class ConfigurationInterface;
|
||||
|
||||
/*!
|
||||
* \brief This class reads from UDP packets, which streams interleaved
|
||||
* I/Q samples over a network.
|
||||
*/
|
||||
class UDPSignalSource : public GNSSBlockInterface
|
||||
{
|
||||
public:
|
||||
UDPSignalSource(ConfigurationInterface* configuration,
|
||||
std::string role, unsigned int in_stream,
|
||||
unsigned int out_stream, boost::shared_ptr<gr::msg_queue> queue);
|
||||
|
||||
virtual ~UDPSignalSource();
|
||||
|
||||
inline std::string role() override
|
||||
{
|
||||
return role_;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns "UDP_Signal_Source"
|
||||
*/
|
||||
inline std::string implementation() override
|
||||
{
|
||||
return "UDP_Signal_Source";
|
||||
}
|
||||
|
||||
inline size_t item_size() override
|
||||
{
|
||||
return item_size_;
|
||||
}
|
||||
|
||||
void connect(gr::top_block_sptr top_block) override;
|
||||
void disconnect(gr::top_block_sptr top_block) override;
|
||||
gr::basic_block_sptr get_left_block() override;
|
||||
gr::basic_block_sptr get_right_block() override;
|
||||
gr::basic_block_sptr get_right_block(int RF_channel) override;
|
||||
|
||||
private:
|
||||
std::string role_;
|
||||
|
||||
// UDP settings
|
||||
std::string address_;
|
||||
int port_;
|
||||
int RF_channels_;
|
||||
|
||||
unsigned int in_stream_;
|
||||
unsigned int out_stream_;
|
||||
|
||||
|
||||
std::string item_type_;
|
||||
size_t item_size_;
|
||||
bool dump_;
|
||||
std::string dump_filename_;
|
||||
std::vector<boost::shared_ptr<gr::block>> char_to_float;
|
||||
std::vector<boost::shared_ptr<gr::block>> float_to_complex_;
|
||||
|
||||
udp_gnss_rx_source_sptr udp_gnss_rx_source_;
|
||||
gr::blocks::deinterleave::sptr demux_;
|
||||
gr::blocks::file_sink::sptr file_sink_dbg_;
|
||||
std::vector<boost::shared_ptr<gr::block>> file_sink_;
|
||||
boost::shared_ptr<gr::msg_queue> queue_;
|
||||
};
|
||||
|
||||
#endif /*GNSS_SDR_UDP_SIGNAL_SOURCE_H */
|
@ -25,6 +25,7 @@ set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES
|
||||
unpack_2bit_samples.cc
|
||||
unpack_spir_gss6450_samples.cc
|
||||
labsat23_source.cc
|
||||
udp_gnss_rx_source.cc
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
@ -0,0 +1,215 @@
|
||||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2007-2010,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
* GNU Radio 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "udp_gnss_rx_source.h"
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <gnuradio/math.h>
|
||||
#include <gnuradio/prefs.h>
|
||||
#include <stdexcept>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
const int udp_gnss_rx_source::BUF_SIZE_PAYLOADS =
|
||||
gr::prefs::singleton()->get_long("udp_blocks", "buf_size_payloads", 50);
|
||||
|
||||
udp_gnss_rx_source_sptr
|
||||
make_udp_gnss_rx_source(size_t itemsize,
|
||||
const std::string &ipaddr, int port,
|
||||
int payload_size, bool eof)
|
||||
{
|
||||
return gnuradio::get_initial_sptr
|
||||
(new udp_gnss_rx_source(itemsize, ipaddr, port,
|
||||
payload_size, eof));
|
||||
}
|
||||
|
||||
udp_gnss_rx_source::udp_gnss_rx_source(size_t itemsize,
|
||||
const std::string &host, int port,
|
||||
int payload_size, bool eof)
|
||||
: sync_block("udp_gnss_rx_source",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(1, 1, itemsize)),
|
||||
d_itemsize(itemsize), d_payload_size(payload_size),
|
||||
d_eof(eof), d_connected(false), d_residual(0), d_sent(0), d_offset(0)
|
||||
{
|
||||
// Give us some more room to play.
|
||||
d_rxbuf = new char[4*d_payload_size];
|
||||
d_residbuf = new char[BUF_SIZE_PAYLOADS*d_payload_size];
|
||||
|
||||
connect(host, port);
|
||||
}
|
||||
|
||||
udp_gnss_rx_source::~udp_gnss_rx_source()
|
||||
{
|
||||
if(d_connected)
|
||||
disconnect();
|
||||
|
||||
delete [] d_rxbuf;
|
||||
delete [] d_residbuf;
|
||||
}
|
||||
|
||||
void
|
||||
udp_gnss_rx_source::connect(const std::string &host, int port)
|
||||
{
|
||||
if(d_connected)
|
||||
disconnect();
|
||||
|
||||
d_host = host;
|
||||
d_port = static_cast<unsigned short>(port);
|
||||
|
||||
std::string s_port;
|
||||
s_port = (boost::format("%d")%d_port).str();
|
||||
|
||||
if(host.size() > 0) {
|
||||
boost::asio::ip::udp::resolver resolver(d_io_service);
|
||||
boost::asio::ip::udp::resolver::query query(d_host, s_port,
|
||||
boost::asio::ip::resolver_query_base::passive);
|
||||
d_endpoint = *resolver.resolve(query);
|
||||
|
||||
d_socket = new boost::asio::ip::udp::socket(d_io_service);
|
||||
d_socket->open(d_endpoint.protocol());
|
||||
|
||||
boost::asio::socket_base::reuse_address roption(true);
|
||||
d_socket->set_option(roption);
|
||||
|
||||
d_socket->bind(d_endpoint);
|
||||
|
||||
start_receive();
|
||||
d_udp_thread = gr::thread::thread(boost::bind(&udp_gnss_rx_source::run_io_service, this));
|
||||
d_connected = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
udp_gnss_rx_source::disconnect()
|
||||
{
|
||||
gr::thread::scoped_lock lock(d_setlock);
|
||||
|
||||
if(!d_connected)
|
||||
return;
|
||||
|
||||
d_io_service.reset();
|
||||
d_io_service.stop();
|
||||
d_udp_thread.join();
|
||||
|
||||
d_socket->close();
|
||||
delete d_socket;
|
||||
|
||||
d_connected = false;
|
||||
}
|
||||
|
||||
// Return port number of d_socket
|
||||
int
|
||||
udp_gnss_rx_source::get_port(void)
|
||||
{
|
||||
//return d_endpoint.port();
|
||||
return d_socket->local_endpoint().port();
|
||||
}
|
||||
|
||||
void
|
||||
udp_gnss_rx_source::start_receive()
|
||||
{
|
||||
d_socket->async_receive_from(boost::asio::buffer((void*)d_rxbuf, d_payload_size), d_endpoint_rcvd,
|
||||
boost::bind(&udp_gnss_rx_source::handle_read, this,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
|
||||
void
|
||||
udp_gnss_rx_source::handle_read(const boost::system::error_code& error,
|
||||
size_t bytes_transferred)
|
||||
{
|
||||
if(!error) {
|
||||
{
|
||||
boost::lock_guard<gr::thread::mutex> lock(d_udp_mutex);
|
||||
if(d_eof && (bytes_transferred == 0)) {
|
||||
// If we are using EOF notification, test for it and don't
|
||||
// add anything to the output.
|
||||
d_residual = WORK_DONE;
|
||||
d_cond_wait.notify_one();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// Make sure we never go beyond the boundary of the
|
||||
// residual buffer. This will just drop the last bit of
|
||||
// data in the buffer if we've run out of room.
|
||||
if((int)(d_residual + bytes_transferred) >= (BUF_SIZE_PAYLOADS*d_payload_size)) {
|
||||
GR_LOG_WARN(d_logger, "Too much data; dropping packet.");
|
||||
}
|
||||
else {
|
||||
// otherwise, copy received data into local buffer for
|
||||
// copying later.
|
||||
memcpy(d_residbuf+d_residual, d_rxbuf, bytes_transferred);
|
||||
d_residual += bytes_transferred;
|
||||
}
|
||||
}
|
||||
d_cond_wait.notify_one();
|
||||
}
|
||||
}
|
||||
start_receive();
|
||||
}
|
||||
|
||||
int
|
||||
udp_gnss_rx_source::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
gr::thread::scoped_lock l(d_setlock);
|
||||
|
||||
char *out = (char*)output_items[0];
|
||||
|
||||
// Use async receive_from to get data from UDP buffer and wait
|
||||
// on a conditional signal before proceeding. We use this
|
||||
// because the conditional wait is interruptable while a
|
||||
// synchronous receive_from is not.
|
||||
boost::unique_lock<boost::mutex> lock(d_udp_mutex);
|
||||
|
||||
//use timed_wait to avoid permanent blocking in the work function
|
||||
d_cond_wait.timed_wait(lock, boost::posix_time::milliseconds(10));
|
||||
|
||||
if (d_residual < 0) {
|
||||
return d_residual;
|
||||
}
|
||||
|
||||
int bytes_left_in_buffer = (int)(d_residual - d_sent);
|
||||
int bytes_to_send = std::min<int>(d_itemsize * noutput_items, bytes_left_in_buffer);
|
||||
|
||||
// Copy the received data in the residual buffer to the output stream
|
||||
memcpy(out, d_residbuf+d_sent, bytes_to_send);
|
||||
int nitems = bytes_to_send/d_itemsize;
|
||||
|
||||
// Keep track of where we are if we don't have enough output
|
||||
// space to send all the data in the residbuf.
|
||||
if (bytes_to_send == bytes_left_in_buffer) {
|
||||
d_residual = 0;
|
||||
d_sent = 0;
|
||||
}
|
||||
else {
|
||||
d_sent += bytes_to_send;
|
||||
}
|
||||
|
||||
return nitems;
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2007-2010,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
* GNU Radio 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, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio 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 GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_UDP_GNSS_RX_SOURCE_IMPL_H
|
||||
#define INCLUDED_GR_UDP_GNSS_RX_SOURCE_IMPL_H
|
||||
|
||||
#include <gnuradio/blocks/udp_source.h>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <gnuradio/thread/thread.h>
|
||||
|
||||
class udp_gnss_rx_source;
|
||||
|
||||
typedef boost::shared_ptr<udp_gnss_rx_source> udp_gnss_rx_source_sptr;
|
||||
|
||||
udp_gnss_rx_source_sptr make_udp_gnss_rx_source(size_t itemsize,
|
||||
const std::string &ipaddr, int port,
|
||||
int payload_size, bool eof);
|
||||
|
||||
|
||||
|
||||
class udp_gnss_rx_source : public gr::blocks::udp_source
|
||||
{
|
||||
private:
|
||||
size_t d_itemsize;
|
||||
int d_payload_size; // maximum transmission unit (packet length)
|
||||
bool d_eof; // look for an EOF signal
|
||||
bool d_connected; // are we connected?
|
||||
char *d_rxbuf; // get UDP buffer items
|
||||
char *d_residbuf; // hold buffer between calls
|
||||
ssize_t d_residual; // hold information about number of bytes stored in residbuf
|
||||
ssize_t d_sent; // track how much of d_residbuf we've outputted
|
||||
size_t d_offset; // point to residbuf location offset
|
||||
|
||||
static const int BUF_SIZE_PAYLOADS; //!< The d_residbuf size in multiples of d_payload_size
|
||||
|
||||
std::string d_host;
|
||||
unsigned short d_port;
|
||||
|
||||
boost::asio::ip::udp::socket *d_socket;
|
||||
boost::asio::ip::udp::endpoint d_endpoint;
|
||||
boost::asio::ip::udp::endpoint d_endpoint_rcvd;
|
||||
boost::asio::io_service d_io_service;
|
||||
|
||||
gr::thread::condition_variable d_cond_wait;
|
||||
gr::thread::mutex d_udp_mutex;
|
||||
gr::thread::thread d_udp_thread;
|
||||
|
||||
void start_receive();
|
||||
void handle_read(const boost::system::error_code& error,
|
||||
size_t bytes_transferred);
|
||||
void run_io_service() { d_io_service.run(); }
|
||||
|
||||
public:
|
||||
udp_gnss_rx_source(size_t itemsize,
|
||||
const std::string &host, int port,
|
||||
int payload_size, bool eof);
|
||||
~udp_gnss_rx_source();
|
||||
|
||||
void connect(const std::string &host, int port);
|
||||
void disconnect();
|
||||
|
||||
int payload_size() { return d_payload_size; }
|
||||
int get_port();
|
||||
|
||||
int work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
};
|
||||
|
||||
|
||||
#endif /* INCLUDED_GR_UDP_GNSS_RX_SOURCE_H */
|
@ -45,6 +45,7 @@
|
||||
#include "spir_file_signal_source.h"
|
||||
#include "spir_gss6450_file_signal_source.h"
|
||||
#include "rtl_tcp_signal_source.h"
|
||||
#include "udp_signal_source.h"
|
||||
#include "two_bit_packed_file_signal_source.h"
|
||||
#include "labsat_signal_source.h"
|
||||
#include "channel.h"
|
||||
@ -1029,6 +1030,21 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock(
|
||||
block = std::move(block_);
|
||||
}
|
||||
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
std::cout << "GNSS-SDR program ended." << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else if (implementation.compare("UDP_Signal_Source") == 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::unique_ptr<GNSSBlockInterface> block_(new UDPSignalSource(configuration.get(), role, in_streams,
|
||||
out_streams, queue));
|
||||
block = std::move(block_);
|
||||
}
|
||||
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
std::cout << "GNSS-SDR program ended." << std::endl;
|
||||
|
Loading…
Reference in New Issue
Block a user