From 7865387df961047729dcf474c09ee6ca72089320 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Tue, 1 May 2018 21:25:15 +0200 Subject: [PATCH 01/12] Adding UDP GNSS signal source block --- conf/gnss-sdr_GPS_L1_2ch_udp.conf | 86 +++++++ .../signal_source/adapters/CMakeLists.txt | 1 + .../adapters/udp_signal_source.cc | 186 +++++++++++++++ .../adapters/udp_signal_source.h | 114 ++++++++++ .../gnuradio_blocks/CMakeLists.txt | 1 + .../gnuradio_blocks/udp_gnss_rx_source.cc | 215 ++++++++++++++++++ .../gnuradio_blocks/udp_gnss_rx_source.h | 91 ++++++++ src/core/receiver/gnss_block_factory.cc | 16 ++ 8 files changed, 710 insertions(+) create mode 100644 conf/gnss-sdr_GPS_L1_2ch_udp.conf create mode 100644 src/algorithms/signal_source/adapters/udp_signal_source.cc create mode 100644 src/algorithms/signal_source/adapters/udp_signal_source.h create mode 100644 src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.cc create mode 100644 src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.h diff --git a/conf/gnss-sdr_GPS_L1_2ch_udp.conf b/conf/gnss-sdr_GPS_L1_2ch_udp.conf new file mode 100644 index 000000000..6fa7684c6 --- /dev/null +++ b/conf/gnss-sdr_GPS_L1_2ch_udp.conf @@ -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 diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index ededc5dc7..d135412e0 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -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} ) diff --git a/src/algorithms/signal_source/adapters/udp_signal_source.cc b/src/algorithms/signal_source/adapters/udp_signal_source.cc new file mode 100644 index 000000000..af0a63378 --- /dev/null +++ b/src/algorithms/signal_source/adapters/udp_signal_source.cc @@ -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 . + * + * ------------------------------------------------------------------------- + */ + +#include "udp_signal_source.h" +#include "configuration_interface.h" +#include "GPS_L1_CA.h" +#include +#include +#include + + +using google::LogMessage; + + +UDPSignalSource::UDPSignalSource(ConfigurationInterface* configuration, + std::string role, unsigned int in_stream, unsigned int out_stream, + boost::shared_ptr 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_ "< 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"<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"<. + * + * ------------------------------------------------------------------------- + */ + +#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 +#include +#include +//#include +#include +#include +#include +#include +#include +#include + + +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 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> char_to_float; + std::vector> 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> file_sink_; + boost::shared_ptr queue_; +}; + +#endif /*GNSS_SDR_UDP_SIGNAL_SOURCE_H */ diff --git a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt index a9252edb0..863a90390 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt @@ -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( diff --git a/src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.cc b/src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.cc new file mode 100644 index 000000000..ef24c829b --- /dev/null +++ b/src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.cc @@ -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 +#include +#include +#include +#include +#include +#include + +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(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 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 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(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; +} diff --git a/src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.h b/src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.h new file mode 100644 index 000000000..5bab10b4a --- /dev/null +++ b/src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.h @@ -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 +#include +#include +#include + +class udp_gnss_rx_source; + +typedef boost::shared_ptr 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 */ diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 09d396b36..7aa1bab99 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -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 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 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; From 189cded82a856eeebda92eecaf79ae69a6813092 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Wed, 2 May 2018 19:48:15 +0200 Subject: [PATCH 02/12] Adding IQ Swap options to UDP source --- .../adapters/udp_signal_source.cc | 105 +++++++++++++----- .../adapters/udp_signal_source.h | 13 +-- 2 files changed, 80 insertions(+), 38 deletions(-) diff --git a/src/algorithms/signal_source/adapters/udp_signal_source.cc b/src/algorithms/signal_source/adapters/udp_signal_source.cc index af0a63378..85d353a96 100644 --- a/src/algorithms/signal_source/adapters/udp_signal_source.cc +++ b/src/algorithms/signal_source/adapters/udp_signal_source.cc @@ -57,50 +57,62 @@ UDPSignalSource::UDPSignalSource(ConfigurationInterface* configuration, std::string default_address = "127.0.0.1"; int default_port = 1234; - RF_channels_ = configuration->property(role + ".RF_channels", 2); + RF_channels_ = configuration->property(role + ".RF_channels", 1); + channels_in_udp_= configuration->property(role + ".channels_in_udp", 1); + IQ_swap_= configuration->property(role + ".IQ_swap", false); + 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); + std::string address = configuration->property(role + ".address", default_address); + int 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_ "< gr_complex type conversion blocks - for (int n = 0; n < (RF_channels_ * 2); n++) + for (int n = 0; n < (channels_in_udp_ * 2); n++) { - char_to_float.push_back(gr::blocks::char_to_float::make()); + char_to_float_.push_back(gr::blocks::char_to_float::make()); } - for (int n = 0; n < RF_channels_; n++) + for (int n = 0; n < channels_in_udp_; n++) { float_to_complex_.push_back(gr::blocks::float_to_complex::make()); } - item_size_ = sizeof(gr_complex); + if (channels_in_udp_>=RF_channels_) + { + for (int n = 0; n < (channels_in_udp_-RF_channels_); n++) + { + null_sinks_.push_back(gr::blocks::null_sink::make(sizeof(gr_complex))); + } + }else + { + std::cout<<"Configuration error: RF_channelsconnect(udp_gnss_rx_source_,0, demux_,0); DLOG(INFO)<<"connected udp_source to demux"<connect(demux_, n, char_to_float.at(n), 0); + 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++) + for (int n = 0; n < channels_in_udp_; 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); + if (!IQ_swap_) + { + 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); + } + else + { + top_block->connect(char_to_float_.at(n * 2), 0, float_to_complex_.at(n), 1); + top_block->connect(char_to_float_.at(n * 2 + 1), 0, float_to_complex_.at(n), 0); + } DLOG(INFO) << "connected char_to_float to float_to_complex_ CH" << n; } + //connect null sinks to unused streams + if (channels_in_udp_>RF_channels_) + { + for (int n = 0; n < (channels_in_udp_-RF_channels_); n++) + { + top_block->connect(float_to_complex_.at(RF_channels_+n),0,null_sinks_.at(n),0); + } + } + if (dump_) { - top_block->connect(udp_gnss_rx_source_,0, file_sink_dbg_,0); - for (int n = 0; n < RF_channels_; n++) + for (int n = 0; n < channels_in_udp_; n++) { top_block->connect(float_to_complex_.at(n), 0, file_sink_.at(n), 0); DLOG(INFO) << "connected source to file sink"; @@ -141,22 +169,39 @@ void UDPSignalSource::connect(gr::top_block_sptr top_block) void UDPSignalSource::disconnect(gr::top_block_sptr top_block) { - for (int n = 0; n < (RF_channels_ * 2); n++) + for (int n = 0; n < (channels_in_udp_ * 2); n++) { - top_block->disconnect(demux_, n, char_to_float.at(n), 0); + 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++) + for (int n = 0; n < channels_in_udp_; 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); + if (!IQ_swap_) + { + 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); + } + else + { + top_block->disconnect(char_to_float_.at(n * 2), 0, float_to_complex_.at(n), 1); + top_block->disconnect(char_to_float_.at(n * 2 + 1), 0, float_to_complex_.at(n), 0); + } DLOG(INFO) << "disconnect char_to_float to float_to_complex_ CH" << n; } + //disconnect null sinks to unused streams + if (channels_in_udp_>RF_channels_) + { + for (int n = 0; n < (channels_in_udp_-RF_channels_); n++) + { + top_block->disconnect(float_to_complex_.at(RF_channels_+n),0,null_sinks_.at(n),0); + } + } + + if (dump_) { - top_block->disconnect(udp_gnss_rx_source_,0, file_sink_dbg_,0); - for (int n = 0; n < RF_channels_; n++) + for (int n = 0; n < channels_in_udp_; n++) { top_block->disconnect(float_to_complex_.at(n), 0, file_sink_.at(n), 0); DLOG(INFO) << "disconnected source to file sink"; diff --git a/src/algorithms/signal_source/adapters/udp_signal_source.h b/src/algorithms/signal_source/adapters/udp_signal_source.h index 8b81d528c..cd60b8e34 100644 --- a/src/algorithms/signal_source/adapters/udp_signal_source.h +++ b/src/algorithms/signal_source/adapters/udp_signal_source.h @@ -37,8 +37,8 @@ #include #include #include -//#include #include +#include #include #include #include @@ -88,25 +88,22 @@ public: private: std::string role_; - // UDP settings - std::string address_; - int port_; + bool IQ_swap_; int RF_channels_; - + int channels_in_udp_; unsigned int in_stream_; unsigned int out_stream_; - std::string item_type_; size_t item_size_; bool dump_; std::string dump_filename_; - std::vector> char_to_float; + std::vector> char_to_float_; std::vector> float_to_complex_; + std::vector> null_sinks_; udp_gnss_rx_source_sptr udp_gnss_rx_source_; gr::blocks::deinterleave::sptr demux_; - gr::blocks::file_sink::sptr file_sink_dbg_; std::vector> file_sink_; boost::shared_ptr queue_; }; From 9912acc4f8ec74677ed8461f659ba2bbba36557f Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Thu, 3 May 2018 18:44:04 +0200 Subject: [PATCH 03/12] Adding channel selector option in config if a single RF channel is used in UDP source --- conf/gnss-sdr_GPS_L1_2ch_udp.conf | 34 +++++++++++-------- .../adapters/udp_signal_source.cc | 17 +++++----- .../adapters/udp_signal_source.h | 1 + 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/conf/gnss-sdr_GPS_L1_2ch_udp.conf b/conf/gnss-sdr_GPS_L1_2ch_udp.conf index 6fa7684c6..65773b04c 100644 --- a/conf/gnss-sdr_GPS_L1_2ch_udp.conf +++ b/conf/gnss-sdr_GPS_L1_2ch_udp.conf @@ -6,7 +6,8 @@ ;######### GLOBAL OPTIONS ################## ;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [Sps]. -GNSS-SDR.internal_fs_sps=2600000 +;GNSS-SDR.internal_fs_sps=3312500 +GNSS-SDR.internal_fs_sps=2650000 ;######### SIGNAL_SOURCE CONFIG ############ SignalSource.implementation=UDP_Signal_Source @@ -17,32 +18,37 @@ 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.RF_channels=1 +SignalSource.select_single_channel=1 +SignalSource.channels_in_udp=2 +SignalSource.IQ_swap=true +SignalSource.dump=false SignalSource.dump_filename=./signal_source.dat ;######### SIGNAL_CONDITIONER CONFIG ############ -SignalConditioner0.implementation=Pass_Through -SignalConditioner1.implementation=Pass_Through +SignalConditioner.implementation=Pass_Through +;SignalConditioner0.implementation=Pass_Through +;SignalConditioner1.implementation=Pass_Through ;######### CHANNELS GLOBAL CONFIG ############ -Channels_1C.count=2 +Channels_1C.count=8 Channels.in_acquisition=1 ;# CHANNEL CONNECTION -Channel0.RF_channel_ID=0 -Channel0.signal=1C -Channel1.RF_channel_ID=1 -Channel1.signal=1C +Channel.signal=1C +;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.threshold=60 Acquisition_1C.use_CFAR_algorithm=false -Acquisition_1C.blocking=true -Acquisition_1C.doppler_max=10000 +Acquisition_1C.blocking=false +Acquisition_1C.doppler_max=5000 Acquisition_1C.doppler_step=250 Acquisition_1C.dump=false Acquisition_1C.dump_filename=./acq_dump.dat @@ -51,7 +57,7 @@ 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=true Tracking_1C.dump_filename=./tracking_ch_ Tracking_1C.pll_bw_hz=35.0; Tracking_1C.dll_bw_hz=2.0; diff --git a/src/algorithms/signal_source/adapters/udp_signal_source.cc b/src/algorithms/signal_source/adapters/udp_signal_source.cc index 85d353a96..f24345293 100644 --- a/src/algorithms/signal_source/adapters/udp_signal_source.cc +++ b/src/algorithms/signal_source/adapters/udp_signal_source.cc @@ -53,11 +53,12 @@ UDPSignalSource::UDPSignalSource(ConfigurationInterface* configuration, dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); - // rtl_tcp PARAMETERS + // network PARAMETERS std::string default_address = "127.0.0.1"; int default_port = 1234; RF_channels_ = configuration->property(role + ".RF_channels", 1); + select_single_channel_ = configuration->property(role + ".select_single_channel", 0); channels_in_udp_= configuration->property(role + ".channels_in_udp", 1); IQ_swap_= configuration->property(role + ".IQ_swap", false); @@ -90,9 +91,9 @@ UDPSignalSource::UDPSignalSource(ConfigurationInterface* configuration, float_to_complex_.push_back(gr::blocks::float_to_complex::make()); } - if (channels_in_udp_>=RF_channels_) + if (channels_in_udp_>RF_channels_) { - for (int n = 0; n < (channels_in_udp_-RF_channels_); n++) + for (int n = 0; n < channels_in_udp_; n++) { null_sinks_.push_back(gr::blocks::null_sink::make(sizeof(gr_complex))); } @@ -149,9 +150,9 @@ void UDPSignalSource::connect(gr::top_block_sptr top_block) //connect null sinks to unused streams if (channels_in_udp_>RF_channels_) { - for (int n = 0; n < (channels_in_udp_-RF_channels_); n++) + for (int n = 0; n < channels_in_udp_; n++) { - top_block->connect(float_to_complex_.at(RF_channels_+n),0,null_sinks_.at(n),0); + top_block->connect(float_to_complex_.at(n),0,null_sinks_.at(n),0); } } @@ -192,9 +193,9 @@ void UDPSignalSource::disconnect(gr::top_block_sptr top_block) //disconnect null sinks to unused streams if (channels_in_udp_>RF_channels_) { - for (int n = 0; n < (channels_in_udp_-RF_channels_); n++) + for (int n = 0; n < channels_in_udp_; n++) { - top_block->disconnect(float_to_complex_.at(RF_channels_+n),0,null_sinks_.at(n),0); + top_block->disconnect(float_to_complex_.at(n),0,null_sinks_.at(n),0); } } @@ -221,7 +222,7 @@ gr::basic_block_sptr UDPSignalSource::get_left_block() gr::basic_block_sptr UDPSignalSource::get_right_block() { - return get_right_block(0); + return get_right_block(select_single_channel_); } gr::basic_block_sptr UDPSignalSource::get_right_block(int RF_channel) diff --git a/src/algorithms/signal_source/adapters/udp_signal_source.h b/src/algorithms/signal_source/adapters/udp_signal_source.h index cd60b8e34..ebb8636af 100644 --- a/src/algorithms/signal_source/adapters/udp_signal_source.h +++ b/src/algorithms/signal_source/adapters/udp_signal_source.h @@ -90,6 +90,7 @@ private: bool IQ_swap_; int RF_channels_; + int select_single_channel_; int channels_in_udp_; unsigned int in_stream_; unsigned int out_stream_; From 2a64473aad94d327cdcf625da64c810fa1ef081f Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Mon, 7 May 2018 11:45:41 +0200 Subject: [PATCH 04/12] Update UDP source config example --- conf/gnss-sdr_GPS_L1_2ch_udp.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/gnss-sdr_GPS_L1_2ch_udp.conf b/conf/gnss-sdr_GPS_L1_2ch_udp.conf index 65773b04c..25334e569 100644 --- a/conf/gnss-sdr_GPS_L1_2ch_udp.conf +++ b/conf/gnss-sdr_GPS_L1_2ch_udp.conf @@ -19,7 +19,7 @@ SignalSource.port=1234 SignalSource.payload_bytes=1024 SignalSource.sample_type=cbyte SignalSource.RF_channels=1 -SignalSource.select_single_channel=1 +SignalSource.select_single_channel=0 SignalSource.channels_in_udp=2 SignalSource.IQ_swap=true SignalSource.dump=false From bde6bd6cee7ae3d97724247c74fdfb110f35f9f1 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Fri, 11 May 2018 13:21:53 +0200 Subject: [PATCH 05/12] Replacing GNURadio udp packet source with custom libpcap-based ethernet packet source --- CMakeLists.txt | 28 ++ cmake/Modules/FindPCAP.cmake | 122 ++++++++ conf/gnss-sdr_GPS_L1_2ch_udp.conf | 11 +- .../adapters/udp_signal_source.cc | 14 +- .../adapters/udp_signal_source.h | 4 +- .../gnuradio_blocks/CMakeLists.txt | 9 +- .../gnuradio_blocks/raw_ip_packet_source.cc | 289 ++++++++++++++++++ .../gnuradio_blocks/raw_ip_packet_source.h | 99 ++++++ .../gnuradio_blocks/udp_gnss_rx_source.cc | 215 ------------- .../gnuradio_blocks/udp_gnss_rx_source.h | 91 ------ 10 files changed, 561 insertions(+), 321 deletions(-) create mode 100644 cmake/Modules/FindPCAP.cmake create mode 100644 src/algorithms/signal_source/gnuradio_blocks/raw_ip_packet_source.cc create mode 100644 src/algorithms/signal_source/gnuradio_blocks/raw_ip_packet_source.h delete mode 100644 src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.cc delete mode 100644 src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 22ad70e01..5bd42db6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1455,6 +1455,34 @@ if(ENABLE_GPROF) endif(ENABLE_GPROF) +# - Try to find libpcap include dirs and libraries +# +# Usage of this module as follows: +# +# find_package(PCAP) +# +# Variables used by this module, they can change the default behaviour and need +# to be set before calling find_package: +# +# PCAP_ROOT_DIR Set this variable to the root installation of +# libpcap if the module has problems finding the +# proper installation path. +# +# Variables defined by this module: +# +# PCAP_FOUND System has libpcap, include and library dirs found +# PCAP_INCLUDE_DIR The libpcap include directories. +# PCAP_LIBRARY The libpcap library (possibly includes a thread +# library e.g. required by pf_ring's libpcap) +# HAVE_PF_RING If a found version of libpcap supports PF_RING +find_package(PCAP) +if(NOT PCAP_FOUND) + message(FATAL_ERROR "PCAP required to compile dbfcttc") +endif() +get_filename_component(PCAP_LIBRARY_DIRS ${PCAP_LIBRARY} DIRECTORY CACHE) + + + ######################################################################## # Set compiler flags diff --git a/cmake/Modules/FindPCAP.cmake b/cmake/Modules/FindPCAP.cmake new file mode 100644 index 000000000..7e0ea6995 --- /dev/null +++ b/cmake/Modules/FindPCAP.cmake @@ -0,0 +1,122 @@ + +################################################################### +# +# Copyright (c) 2006 Frederic Heem, +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of the Telsey nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +################################################################### +# - Find pcap +# Find the PCAP includes and library +# http://www.tcpdump.org/ +# +# The environment variable PCAPDIR allows to specficy where to find +# libpcap in non standard location. +# +# PCAP_INCLUDE_DIRS - where to find pcap.h, etc. +# PCAP_LIBRARIES - List of libraries when using pcap. +# PCAP_FOUND - True if pcap found. + + +IF(EXISTS $ENV{PCAPDIR}) + FIND_PATH(PCAP_INCLUDE_DIR + NAMES + pcap/pcap.h + pcap.h + PATHS + $ENV{PCAPDIR} + NO_DEFAULT_PATH + ) + + FIND_LIBRARY(PCAP_LIBRARY + NAMES + pcap + PATHS + $ENV{PCAPDIR} + NO_DEFAULT_PATH + ) + + +ELSE(EXISTS $ENV{PCAPDIR}) + FIND_PATH(PCAP_INCLUDE_DIR + NAMES + pcap/pcap.h + pcap.h + ) + + FIND_LIBRARY(PCAP_LIBRARY + NAMES + pcap + ) + +ENDIF(EXISTS $ENV{PCAPDIR}) + +SET(PCAP_INCLUDE_DIRS ${PCAP_INCLUDE_DIR}) +SET(PCAP_LIBRARIES ${PCAP_LIBRARY}) + +IF(PCAP_INCLUDE_DIRS) + MESSAGE(STATUS "Pcap include dirs set to ${PCAP_INCLUDE_DIRS}") +ELSE(PCAP_INCLUDE_DIRS) + MESSAGE(FATAL " Pcap include dirs cannot be found") +ENDIF(PCAP_INCLUDE_DIRS) + +IF(PCAP_LIBRARIES) + MESSAGE(STATUS "Pcap library set to ${PCAP_LIBRARIES}") +ELSE(PCAP_LIBRARIES) + MESSAGE(FATAL "Pcap library cannot be found") +ENDIF(PCAP_LIBRARIES) + +#Functions +INCLUDE(CheckFunctionExists) +SET(CMAKE_REQUIRED_INCLUDES ${PCAP_INCLUDE_DIRS}) +SET(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARIES}) +CHECK_FUNCTION_EXISTS("pcap_breakloop" HAVE_PCAP_BREAKLOOP) +CHECK_FUNCTION_EXISTS("pcap_datalink_name_to_val" HAVE_PCAP_DATALINK_NAME_TO_VAL) +CHECK_FUNCTION_EXISTS("pcap_datalink_val_to_name" HAVE_PCAP_DATALINK_VAL_TO_NAME) +CHECK_FUNCTION_EXISTS("pcap_findalldevs" HAVE_PCAP_FINDALLDEVS) +CHECK_FUNCTION_EXISTS("pcap_freecode" HAVE_PCAP_FREECODE) +CHECK_FUNCTION_EXISTS("pcap_get_selectable_fd" HAVE_PCAP_GET_SELECTABLE_FD) +CHECK_FUNCTION_EXISTS("pcap_lib_version" HAVE_PCAP_LIB_VERSION) +CHECK_FUNCTION_EXISTS("pcap_list_datalinks" HAVE_PCAP_LIST_DATALINKS) +CHECK_FUNCTION_EXISTS("pcap_open_dead" HAVE_PCAP_OPEN_DEAD) +CHECK_FUNCTION_EXISTS("pcap_set_datalink" HAVE_PCAP_SET_DATALINK) + + +#Is pcap found ? +IF(PCAP_INCLUDE_DIRS AND PCAP_LIBRARIES) + SET( PCAP_FOUND "YES" ) +ENDIF(PCAP_INCLUDE_DIRS AND PCAP_LIBRARIES) + + +MARK_AS_ADVANCED( + PCAP_LIBRARIES + PCAP_INCLUDE_DIRS +) \ No newline at end of file diff --git a/conf/gnss-sdr_GPS_L1_2ch_udp.conf b/conf/gnss-sdr_GPS_L1_2ch_udp.conf index 25334e569..d80ffda68 100644 --- a/conf/gnss-sdr_GPS_L1_2ch_udp.conf +++ b/conf/gnss-sdr_GPS_L1_2ch_udp.conf @@ -14,9 +14,10 @@ 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.origin_address=0.0.0.0 +SignalSource.capture_device=eth0 SignalSource.port=1234 -SignalSource.payload_bytes=1024 +SignalSource.payload_bytes=1472 SignalSource.sample_type=cbyte SignalSource.RF_channels=1 SignalSource.select_single_channel=0 @@ -32,7 +33,7 @@ SignalConditioner.implementation=Pass_Through ;SignalConditioner1.implementation=Pass_Through ;######### CHANNELS GLOBAL CONFIG ############ -Channels_1C.count=8 +Channels_1C.count=1 Channels.in_acquisition=1 ;# CHANNEL CONNECTION @@ -49,7 +50,7 @@ Acquisition_1C.threshold=60 Acquisition_1C.use_CFAR_algorithm=false Acquisition_1C.blocking=false Acquisition_1C.doppler_max=5000 -Acquisition_1C.doppler_step=250 +Acquisition_1C.doppler_step=500 Acquisition_1C.dump=false Acquisition_1C.dump_filename=./acq_dump.dat @@ -57,7 +58,7 @@ 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=true +Tracking_1C.dump=false Tracking_1C.dump_filename=./tracking_ch_ Tracking_1C.pll_bw_hz=35.0; Tracking_1C.dll_bw_hz=2.0; diff --git a/src/algorithms/signal_source/adapters/udp_signal_source.cc b/src/algorithms/signal_source/adapters/udp_signal_source.cc index f24345293..ed79ff97f 100644 --- a/src/algorithms/signal_source/adapters/udp_signal_source.cc +++ b/src/algorithms/signal_source/adapters/udp_signal_source.cc @@ -54,8 +54,14 @@ UDPSignalSource::UDPSignalSource(ConfigurationInterface* configuration, default_dump_file); // network PARAMETERS + std::string default_capture_device = "eth0"; std::string default_address = "127.0.0.1"; int default_port = 1234; + std::string address = configuration->property(role + ".origin_address", default_address); + std::string capture_device = configuration->property(role + ".capture_device", default_capture_device); + int port = configuration->property(role + ".port", default_port); + int payload_bytes = configuration->property(role + ".payload_bytes", 1024); + RF_channels_ = configuration->property(role + ".RF_channels", 1); select_single_channel_ = configuration->property(role + ".select_single_channel", 0); @@ -64,19 +70,15 @@ UDPSignalSource::UDPSignalSource(ConfigurationInterface* configuration, 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); - std::string address = configuration->property(role + ".address", default_address); - int port = configuration->property(role + ".port", default_port); - int payload_bytes = configuration->property(role + ".payload_bytes", 1024); if (sample_type.compare("cbyte")==0) { - udp_gnss_rx_source_ = make_udp_gnss_rx_source(sizeof(char), address, port, payload_bytes, true); + udp_gnss_rx_source_ = raw_ip_packet_source::make(capture_device, address, port, payload_bytes); 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); + udp_gnss_rx_source_ = raw_ip_packet_source::make(capture_device, address, port, payload_bytes); demux_=gr::blocks::deinterleave::make(sizeof(char),1); } diff --git a/src/algorithms/signal_source/adapters/udp_signal_source.h b/src/algorithms/signal_source/adapters/udp_signal_source.h index ebb8636af..b3b43289b 100644 --- a/src/algorithms/signal_source/adapters/udp_signal_source.h +++ b/src/algorithms/signal_source/adapters/udp_signal_source.h @@ -33,7 +33,7 @@ #define GNSS_SDR_UDP_SIGNAL_SOURCE_H #include "gnss_block_interface.h" -#include "udp_gnss_rx_source.h" +#include "raw_ip_packet_source.h" #include #include #include @@ -103,7 +103,7 @@ private: std::vector> float_to_complex_; std::vector> null_sinks_; - udp_gnss_rx_source_sptr udp_gnss_rx_source_; + raw_ip_packet_source::sptr udp_gnss_rx_source_; gr::blocks::deinterleave::sptr demux_; std::vector> file_sink_; boost::shared_ptr queue_; diff --git a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt index 863a90390..83a7ee7b2 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt @@ -25,7 +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 + raw_ip_packet_source.cc ) include_directories( @@ -41,5 +41,10 @@ file(GLOB SIGNAL_SOURCE_GR_BLOCKS_HEADERS "*.h") list(SORT SIGNAL_SOURCE_GR_BLOCKS_HEADERS) add_library(signal_source_gr_blocks ${SIGNAL_SOURCE_GR_BLOCKS_SOURCES} ${SIGNAL_SOURCE_GR_BLOCKS_HEADERS}) source_group(Headers FILES ${SIGNAL_SOURCE_GR_BLOCKS_HEADERS}) -target_link_libraries(signal_source_gr_blocks signal_source_lib ${GNURADIO_RUNTIME_LIBRARIES} ${Boost_LIBRARIES}) +target_link_libraries(signal_source_gr_blocks + signal_source_lib + ${GNURADIO_RUNTIME_LIBRARIES} + ${Boost_LIBRARIES} + ${PCAP_LIBRARIES} +) add_dependencies(signal_source_gr_blocks glog-${glog_RELEASE}) diff --git a/src/algorithms/signal_source/gnuradio_blocks/raw_ip_packet_source.cc b/src/algorithms/signal_source/gnuradio_blocks/raw_ip_packet_source.cc new file mode 100644 index 000000000..5ec4c4a2c --- /dev/null +++ b/src/algorithms/signal_source/gnuradio_blocks/raw_ip_packet_source.cc @@ -0,0 +1,289 @@ +/*! + * \file raw_ip_packet_source.cc + * + * \brief Receives ip frames containing samples in UDP frame encapsulation + * using a high performance packet capture library (libpcap) + * \author Javier Arribas jarribas (at) cttc.es + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#include +#include "raw_ip_packet_source.h" + +#include +#include + + +#define FIFO_SIZE 1000000 + + +/* 4 bytes IP address */ +typedef struct gr_ip_address{ + u_char byte1; + u_char byte2; + u_char byte3; + u_char byte4; +}gr_ip_address; + +/* IPv4 header */ +typedef struct gr_ip_header{ + u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits) + u_char tos; // Type of service + u_short tlen; // Total length + u_short identification; // Identification + u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits) + u_char ttl; // Time to live + u_char proto; // Protocol + u_short crc; // Header checksum + gr_ip_address saddr; // Source address + gr_ip_address daddr; // Destination address + u_int op_pad; // Option + Padding +}gr_ip_header; + +/* UDP header*/ +typedef struct gr_udp_header{ + u_short sport; // Source port + u_short dport; // Destination port + u_short len; // Datagram length + u_short crc; // Checksum +}gr_udp_header; + +raw_ip_packet_source::sptr +raw_ip_packet_source::make(std::string src_device, std::string origin_address, int udp_port, int udp_packet_size) +{ + return gnuradio::get_initial_sptr + (new raw_ip_packet_source(src_device, origin_address, udp_port, udp_packet_size)); +} + +/* + * The private constructor + */ +raw_ip_packet_source::raw_ip_packet_source(std::string src_device, std::string origin_address, int udp_port, int udp_packet_size) +: gr::sync_block("raw_ip_packet_source", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(1, 1, sizeof(char))) +{ + + // constructor code here + std::cout<<"Start Ethernet packet capture\n"; + + d_src_device=src_device; + d_udp_port=udp_port; + d_udp_payload_size=udp_packet_size; + d_fifo_full=false; + d_last_frame_counter=0; + d_num_rx_errors=0; + + //allocate signal samples buffer + fifo_buff=new char[FIFO_SIZE]; + fifo_read_ptr=0; + fifo_write_ptr=0; + fifo_items=0; + + //open the ethernet device + if (open()==true) + { + // start pcap capture thread + d_pcap_thread=new boost::thread(boost::bind(&raw_ip_packet_source::my_pcap_loop_thread,this,descr)); + }else{ + exit(1); //ethernet error! + } +} + +bool raw_ip_packet_source::open() +{ + char errbuf[PCAP_ERRBUF_SIZE]; + boost::mutex::scoped_lock lock(d_mutex); // hold mutex for duration of this function + /* open device for reading */ + descr = pcap_open_live(d_src_device.c_str(),1500,1,1000,errbuf); + if(descr == NULL) + { + std::cout<<"Error openning Ethernet device "<join(); + pcap_close(descr); + } + + delete fifo_buff; + std::cout<<"Stop Ethernet packet capture\n"; + +} + +void raw_ip_packet_source::static_pcap_callback(u_char *args, const struct pcap_pkthdr* pkthdr, + const u_char* packet) +{ + raw_ip_packet_source *bridge=(raw_ip_packet_source*) args; + bridge->pcap_callback(args, pkthdr, packet); +} + +void raw_ip_packet_source::pcap_callback(u_char *args, const struct pcap_pkthdr* pkthdr, + const u_char* packet) +{ + boost::mutex::scoped_lock lock(d_mutex); // hold mutex for duration of this function + + gr_ip_header *ih; + gr_udp_header *uh; + + // eth frame parameters + // **** UDP RAW PACKET DECODER **** + if ((packet[12]==0x08) & (packet[13]==0x00)) //IP FRAME + { + + /* retireve the position of the ip header */ + ih = (gr_ip_header *) (packet + + 14); //length of ethernet header + + /* retireve the position of the udp header */ + u_int ip_len; + ip_len = (ih->ver_ihl & 0xf) * 4; + uh = (gr_udp_header *) ((u_char*)ih + ip_len); + + /* convert from network byte order to host byte order */ + u_short sport,dport; + dport = ntohs( uh->dport ); + sport = ntohs( uh->sport ); + if (dport==d_udp_port) + { + // print ip addresses and udp ports +// printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n", +// ih->saddr.byte1, +// ih->saddr.byte2, +// ih->saddr.byte3, +// ih->saddr.byte4, +// sport, +// ih->daddr.byte1, +// ih->daddr.byte2, +// ih->daddr.byte3, +// ih->daddr.byte4, +// dport); +// std::cout<<"d_udp_port:"<=d_udp_payload_size) + { + //write all in a single memcpy + memcpy(&fifo_buff[fifo_write_ptr],&udp_payload[0],d_udp_payload_size); //size in bytes + fifo_write_ptr+=d_udp_payload_size; + if (fifo_write_ptr==FIFO_SIZE) fifo_write_ptr=0; + fifo_items+=d_udp_payload_size; + }else{ + //two step wrap write + memcpy(&fifo_buff[fifo_write_ptr],&udp_payload[0],aligned_write_items); //size in bytes + fifo_write_ptr=d_udp_payload_size-aligned_write_items; + memcpy(&fifo_buff[0],&udp_payload[aligned_write_items],fifo_write_ptr); //size in bytes + fifo_items+=d_udp_payload_size; + } + }else{ + std::cout<<"Ou"<=num_samples_readed) + { + //read all in a single memcpy + memcpy(&((char*)output_items[0])[0],&fifo_buff[fifo_read_ptr],num_samples_readed); + fifo_read_ptr=fifo_read_ptr+num_samples_readed; //increase the fifo pointer + if (fifo_read_ptr==FIFO_SIZE) fifo_read_ptr=0; + }else{ + //two step wrap read + memcpy(&((char*)output_items[0])[0],&fifo_buff[fifo_read_ptr],aligned_read_items); + fifo_read_ptr=num_samples_readed-aligned_read_items;//increase the fifo pointer considering the rollover + memcpy(&((char*)output_items[0])[aligned_read_items],&fifo_buff[0],fifo_read_ptr); + } + + fifo_items=fifo_items-num_samples_readed; + + // Tell runtime system how many output items we produced. + //std::cout<<"fifo_items:"<. + * + * ------------------------------------------------------------------------- + */ + + +#ifndef INCLUDED_RAW_IP_PACKET_SOURCE_H +#define INCLUDED_RAW_IP_PACKET_SOURCE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class raw_ip_packet_source : virtual public gr::sync_block +{ +private: + boost::mutex d_mutex; + + pcap_t* descr; //ethernet pcap device descriptor + int fifo_pipe[2]; + + char *fifo_buff; + + int fifo_read_ptr; + int fifo_write_ptr; + int fifo_items; + int d_sock_raw; + int d_udp_port; + struct sockaddr_in si_me; + std::string d_src_device; + std::string d_origin_address; + int d_udp_payload_size; + bool d_fifo_full; + + int d_last_frame_counter; + int d_num_rx_errors; + + + boost::thread *d_pcap_thread; + /*! + * \brief + * Opens the ethernet device using libpcap raw capture mode + * If any of these fail, the fuction retuns the error and exits. + */ + bool open(); + + void my_pcap_loop_thread(pcap_t *pcap_handle); + + void pcap_callback(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char* packet); + + static void static_pcap_callback(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char* packet); + + +public: + + typedef boost::shared_ptr sptr; + static sptr make(std::string src_device, std::string origin_address, int udp_port, int udp_packet_size); + raw_ip_packet_source(std::string src_device, std::string origin_address, int udp_port, int udp_packet_size); + ~raw_ip_packet_source(); + + // Where all the action really happens + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_RAW_IP_PACKET_SOURCE_H */ + diff --git a/src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.cc b/src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.cc deleted file mode 100644 index ef24c829b..000000000 --- a/src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.cc +++ /dev/null @@ -1,215 +0,0 @@ -/* -*- 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 -#include -#include -#include -#include -#include -#include - -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(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 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 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(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; -} diff --git a/src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.h b/src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.h deleted file mode 100644 index 5bab10b4a..000000000 --- a/src/algorithms/signal_source/gnuradio_blocks/udp_gnss_rx_source.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- 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 -#include -#include -#include - -class udp_gnss_rx_source; - -typedef boost::shared_ptr 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 */ From 1bad4d3be605ffe4626ec4d2082230838890bfd6 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 15 May 2018 18:31:34 +0200 Subject: [PATCH 06/12] Catch exception by reference --- src/core/receiver/control_thread.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/receiver/control_thread.cc b/src/core/receiver/control_thread.cc index 0710da730..8eb49563c 100644 --- a/src/core/receiver/control_thread.cc +++ b/src/core/receiver/control_thread.cc @@ -114,7 +114,7 @@ void ControlThread::run() { flowgraph_->connect(); } - catch (const std::exception e) + catch (const std::exception &e) { LOG(ERROR) << e.what(); return; From 0d70b08288e7621ac750b5d52cd744c65304d49e Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 15 May 2018 18:38:26 +0200 Subject: [PATCH 07/12] Fix pedantic warning emitted by GCC 8.1.1 (fedora-rawhide) The warning was: type qualifiers ignored on cast result type [-Wignored-qualifiers] --- .../libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc index cf26c9bea..60fb651c0 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/lib/qa_utils.cc @@ -539,7 +539,7 @@ bool run_volk_gnsssdr_tests(volk_gnsssdr_func_desc_t desc, vlen = vlen + vlen_twiddle; const float tol_f = tol; - const unsigned int tol_i = static_cast(tol); + const unsigned int tol_i = static_cast(tol); //first let's get a list of available architectures for the test std::vector arch_list = get_arch_list(desc); From df0dd82843382184cb6e0af4b996d7c79936f8e6 Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Wed, 16 May 2018 10:49:27 +0200 Subject: [PATCH 08/12] Optimizing custom UDP packet source and applying code style --- conf/gnss-sdr_GPS_L1_2ch_udp.conf | 34 +- .../adapters/udp_signal_source.cc | 171 +++---- .../adapters/udp_signal_source.h | 23 +- .../gnuradio_blocks/CMakeLists.txt | 2 + .../gr_complex_ip_packet_source.cc | 439 ++++++++++++++++++ .../gr_complex_ip_packet_source.h | 117 +++++ .../unpack_byte_4bit_samples.cc | 86 ++++ .../unpack_byte_4bit_samples.h | 61 +++ 8 files changed, 789 insertions(+), 144 deletions(-) create mode 100644 src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.cc create mode 100644 src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.h create mode 100644 src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.cc create mode 100644 src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.h diff --git a/conf/gnss-sdr_GPS_L1_2ch_udp.conf b/conf/gnss-sdr_GPS_L1_2ch_udp.conf index d80ffda68..d63eac95d 100644 --- a/conf/gnss-sdr_GPS_L1_2ch_udp.conf +++ b/conf/gnss-sdr_GPS_L1_2ch_udp.conf @@ -6,23 +6,25 @@ ;######### GLOBAL OPTIONS ################## ;internal_fs_sps: Internal signal sampling frequency after the signal conditioning stage [Sps]. -;GNSS-SDR.internal_fs_sps=3312500 -GNSS-SDR.internal_fs_sps=2650000 +GNSS-SDR.internal_fs_sps=13250000 ;//66.25/5 +;GNSS-SDR.internal_fs_sps=6625000 ;//66.25/10 +;GNSS-SDR.internal_fs_sps=3312500 ;//66.25/20 +;GNSS-SDR.internal_fs_sps=2650000 ;//66.25/25 ;######### 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.filename=/home/javier/gnss/gnss-simulator/build/signal_out.bin ; <- PUT YOUR FILE HERE SignalSource.item_type=gr_complex SignalSource.origin_address=0.0.0.0 SignalSource.capture_device=eth0 SignalSource.port=1234 SignalSource.payload_bytes=1472 -SignalSource.sample_type=cbyte +;SignalSource.sample_type=cbyte +SignalSource.sample_type=c4bits +SignalSource.IQ_swap=false SignalSource.RF_channels=1 -SignalSource.select_single_channel=0 SignalSource.channels_in_udp=2 -SignalSource.IQ_swap=true SignalSource.dump=false SignalSource.dump_filename=./signal_source.dat @@ -33,12 +35,22 @@ SignalConditioner.implementation=Pass_Through ;SignalConditioner1.implementation=Pass_Through ;######### CHANNELS GLOBAL CONFIG ############ -Channels_1C.count=1 +Channels_1C.count=8 Channels.in_acquisition=1 ;# CHANNEL CONNECTION Channel.signal=1C -;Channel0.RF_channel_ID=0 +Channel0.RF_channel_ID=0 +Channel1.RF_channel_ID=0 +Channel2.RF_channel_ID=0 +Channel3.RF_channel_ID=0 +Channel4.RF_channel_ID=0 +Channel5.RF_channel_ID=0 +Channel6.RF_channel_ID=0 +Channel7.RF_channel_ID=0 +Channel8.RF_channel_ID=1 +Channel9.RF_channel_ID=1 + ;Channel0.signal=1C ;Channel1.RF_channel_ID=1 ;Channel1.signal=1C @@ -46,11 +58,11 @@ Channel.signal=1C ;######### ACQUISITION GLOBAL CONFIG ############ Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition Acquisition_1C.item_type=gr_complex -Acquisition_1C.threshold=60 +Acquisition_1C.threshold=17 Acquisition_1C.use_CFAR_algorithm=false Acquisition_1C.blocking=false Acquisition_1C.doppler_max=5000 -Acquisition_1C.doppler_step=500 +Acquisition_1C.doppler_step=250 Acquisition_1C.dump=false Acquisition_1C.dump_filename=./acq_dump.dat @@ -78,7 +90,7 @@ Observables.dump_filename=./observables.dat ;######### PVT CONFIG ############ PVT.implementation=RTKLIB_PVT -PVT.positioning_mode=Single ; options: Single, Static, Kinematic, PPP_Static, PPP_Kinematic +PVT.positioning_mode=PPP_Static ; 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 diff --git a/src/algorithms/signal_source/adapters/udp_signal_source.cc b/src/algorithms/signal_source/adapters/udp_signal_source.cc index ed79ff97f..93af9dd4a 100644 --- a/src/algorithms/signal_source/adapters/udp_signal_source.cc +++ b/src/algorithms/signal_source/adapters/udp_signal_source.cc @@ -1,13 +1,12 @@ /*! - * \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 + * \file udp_signal_source.cc * + * \brief Receives ip frames containing samples in UDP frame encapsulation + * using a high performance packet capture library (libpcap) + * \author Javier Arribas jarribas (at) cttc.es * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -30,6 +29,7 @@ * ------------------------------------------------------------------------- */ + #include "udp_signal_source.h" #include "configuration_interface.h" #include "GPS_L1_CA.h" @@ -64,58 +64,46 @@ UDPSignalSource::UDPSignalSource(ConfigurationInterface* configuration, RF_channels_ = configuration->property(role + ".RF_channels", 1); - select_single_channel_ = configuration->property(role + ".select_single_channel", 0); - channels_in_udp_= configuration->property(role + ".channels_in_udp", 1); - IQ_swap_= configuration->property(role + ".IQ_swap", false); + channels_in_udp_ = configuration->property(role + ".channels_in_udp", 1); + IQ_swap_ = configuration->property(role + ".IQ_swap", false); 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); - - if (sample_type.compare("cbyte")==0) - { - udp_gnss_rx_source_ = raw_ip_packet_source::make(capture_device, address, port, payload_bytes); - 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_ = raw_ip_packet_source::make(capture_device, address, port, payload_bytes); - demux_=gr::blocks::deinterleave::make(sizeof(char),1); - } - - //create I, Q -> gr_complex type conversion blocks - for (int n = 0; n < (channels_in_udp_ * 2); n++) - { - char_to_float_.push_back(gr::blocks::char_to_float::make()); - } - - for (int n = 0; n < channels_in_udp_; n++) - { - float_to_complex_.push_back(gr::blocks::float_to_complex::make()); - } - - if (channels_in_udp_>RF_channels_) - { - for (int n = 0; n < channels_in_udp_; n++) - { - null_sinks_.push_back(gr::blocks::null_sink::make(sizeof(gr_complex))); - } - }else - { - std::cout<<"Configuration error: RF_channels= RF_channels_) + { + for (int n = 0; n < channels_in_udp_; n++) + { + null_sinks_.push_back(gr::blocks::null_sink::make(sizeof(gr_complex))); + } + } + else + { + std::cout << "Configuration error: RF_channelsconnect(udp_gnss_rx_source_,0, demux_,0); - DLOG(INFO)<<"connected udp_source to demux"<connect(demux_, n, char_to_float_.at(n), 0); - DLOG(INFO) << "connected demux to char_to_float CH" << n; - } + //connect null sinks to unused streams for (int n = 0; n < channels_in_udp_; n++) { - if (!IQ_swap_) - { - 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); - } - else - { - top_block->connect(char_to_float_.at(n * 2), 0, float_to_complex_.at(n), 1); - top_block->connect(char_to_float_.at(n * 2 + 1), 0, float_to_complex_.at(n), 0); - } - DLOG(INFO) << "connected char_to_float to float_to_complex_ CH" << n; + top_block->connect(udp_gnss_rx_source_, n, null_sinks_.at(n), 0); } - - //connect null sinks to unused streams - if (channels_in_udp_>RF_channels_) - { - for (int n = 0; n < channels_in_udp_; n++) - { - top_block->connect(float_to_complex_.at(n),0,null_sinks_.at(n),0); - } - } + DLOG(INFO) << "connected udp_source to null_sinks to enable the use of spare channels" << std::endl; if (dump_) { for (int n = 0; n < channels_in_udp_; n++) - { - top_block->connect(float_to_complex_.at(n), 0, file_sink_.at(n), 0); - DLOG(INFO) << "connected source to file sink"; - } + { + top_block->connect(udp_gnss_rx_source_, n, 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 < (channels_in_udp_ * 2); n++) - { - top_block->disconnect(demux_, n, char_to_float_.at(n), 0); - DLOG(INFO) << "disconnect demux to char_to_float CH" << n; - } + //disconnect null sinks to unused streams for (int n = 0; n < channels_in_udp_; n++) { - if (!IQ_swap_) - { - 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); - } - else - { - top_block->disconnect(char_to_float_.at(n * 2), 0, float_to_complex_.at(n), 1); - top_block->disconnect(char_to_float_.at(n * 2 + 1), 0, float_to_complex_.at(n), 0); - } - DLOG(INFO) << "disconnect char_to_float to float_to_complex_ CH" << n; + top_block->disconnect(udp_gnss_rx_source_, n, null_sinks_.at(n), 0); } - - //disconnect null sinks to unused streams - if (channels_in_udp_>RF_channels_) - { - for (int n = 0; n < channels_in_udp_; n++) - { - top_block->disconnect(float_to_complex_.at(n),0,null_sinks_.at(n),0); - } - } - - if (dump_) { - for (int n = 0; n < channels_in_udp_; n++) - { - top_block->disconnect(float_to_complex_.at(n), 0, file_sink_.at(n), 0); - DLOG(INFO) << "disconnected source to file sink"; + for (int n = 0; n < channels_in_udp_; n++) + { + top_block->disconnect(udp_gnss_rx_source_, n, 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"< #include -#include #include #include -#include -#include #include #include #include @@ -90,7 +88,6 @@ private: bool IQ_swap_; int RF_channels_; - int select_single_channel_; int channels_in_udp_; unsigned int in_stream_; unsigned int out_stream_; @@ -99,12 +96,8 @@ private: size_t item_size_; bool dump_; std::string dump_filename_; - std::vector> char_to_float_; - std::vector> float_to_complex_; std::vector> null_sinks_; - - raw_ip_packet_source::sptr udp_gnss_rx_source_; - gr::blocks::deinterleave::sptr demux_; + gr_complex_ip_packet_source::sptr udp_gnss_rx_source_; std::vector> file_sink_; boost::shared_ptr queue_; }; diff --git a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt index 83a7ee7b2..55c8db1c9 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt @@ -20,12 +20,14 @@ set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES unpack_byte_2bit_samples.cc unpack_byte_2bit_cpx_samples.cc + unpack_byte_4bit_samples.cc unpack_intspir_1bit_samples.cc rtl_tcp_signal_source_c.cc unpack_2bit_samples.cc unpack_spir_gss6450_samples.cc labsat23_source.cc raw_ip_packet_source.cc + gr_complex_ip_packet_source.cc ) include_directories( diff --git a/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.cc b/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.cc new file mode 100644 index 000000000..038ea6fbe --- /dev/null +++ b/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.cc @@ -0,0 +1,439 @@ +/*! + * \file gr_complex_ip_packet_source.cc + * + * \brief Receives ip frames containing samples in UDP frame encapsulation + * using a high performance packet capture library (libpcap) + * \author Javier Arribas jarribas (at) cttc.es + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#include +#include "gr_complex_ip_packet_source.h" + +#include +#include + + +#define FIFO_SIZE 1472000 + + +/* 4 bytes IP address */ +typedef struct gr_ip_address +{ + u_char byte1; + u_char byte2; + u_char byte3; + u_char byte4; +} gr_ip_address; + +/* IPv4 header */ +typedef struct gr_ip_header +{ + u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits) + u_char tos; // Type of service + u_short tlen; // Total length + u_short identification; // Identification + u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits) + u_char ttl; // Time to live + u_char proto; // Protocol + u_short crc; // Header checksum + gr_ip_address saddr; // Source address + gr_ip_address daddr; // Destination address + u_int op_pad; // Option + Padding +} gr_ip_header; + +/* UDP header*/ +typedef struct gr_udp_header +{ + u_short sport; // Source port + u_short dport; // Destination port + u_short len; // Datagram length + u_short crc; // Checksum +} gr_udp_header; + +gr_complex_ip_packet_source::sptr +gr_complex_ip_packet_source::make(std::string src_device, + std::string origin_address, + int udp_port, + int udp_packet_size, + int n_baseband_channels, + std::string wire_sample_type, + size_t item_size, + bool IQ_swap_) +{ + return gnuradio::get_initial_sptr(new gr_complex_ip_packet_source(src_device, + origin_address, + udp_port, + udp_packet_size, + n_baseband_channels, + wire_sample_type, + item_size, + IQ_swap_)); +} + +/* + * The private constructor + */ +gr_complex_ip_packet_source::gr_complex_ip_packet_source(std::string src_device, + __attribute__((unused)) std::string origin_address, + int udp_port, + int udp_packet_size, + int n_baseband_channels, + std::string wire_sample_type, + size_t item_size, + bool IQ_swap_) + : gr::sync_block("gr_complex_ip_packet_source", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(1, 4, item_size)) //1 to 4 baseband complex channels +{ + // constructor code here + std::cout << "Start Ethernet packet capture\n"; + + d_n_baseband_channels = n_baseband_channels; + if (wire_sample_type.compare("cbyte") == 0) + { + d_wire_sample_type = 1; + d_bytes_per_sample = d_n_baseband_channels * 2; + } + else if (wire_sample_type.compare("c4bits") == 0) + { + d_wire_sample_type = 2; + d_bytes_per_sample = d_n_baseband_channels; + } + else + { + std::cout << "Unknown wire sample type\n"; + exit(0); + } + std::cout << "d_wire_sample_type:" << d_wire_sample_type << std::endl; + d_src_device = src_device; + d_udp_port = udp_port; + d_udp_payload_size = udp_packet_size; + d_fifo_full = false; + + //allocate signal samples buffer + fifo_buff = new char[FIFO_SIZE]; + fifo_read_ptr = 0; + fifo_write_ptr = 0; + fifo_items = 0; + d_item_size = item_size; + d_IQ_swap = IQ_swap_; + d_sock_raw = 0; + d_pcap_thread = NULL; + descr = NULL; +} + + +//Called by gnuradio to enable drivers, etc for i/o devices. +bool gr_complex_ip_packet_source::start() +{ + std::cout << "gr_complex_ip_packet_source START\n"; + //open the ethernet device + if (open() == true) + { + // start pcap capture thread + d_pcap_thread = new boost::thread(boost::bind(&gr_complex_ip_packet_source::my_pcap_loop_thread, this, descr)); + return true; + } + else + { + return false; + } +} + +//Called by gnuradio to disable drivers, etc for i/o devices. +bool gr_complex_ip_packet_source::stop() +{ + std::cout << "gr_complex_ip_packet_source STOP\n"; + if (descr != NULL) + { + pcap_breakloop(descr); + d_pcap_thread->join(); + pcap_close(descr); + } + return true; +} + +bool gr_complex_ip_packet_source::open() +{ + char errbuf[PCAP_ERRBUF_SIZE]; + boost::mutex::scoped_lock lock(d_mutex); // hold mutex for duration of this function + /* open device for reading */ + descr = pcap_open_live(d_src_device.c_str(), 1500, 1, 1000, errbuf); + if (descr == NULL) + { + std::cout << "Error openning Ethernet device " << d_src_device << std::endl; + printf("Fatal Error in pcap_open_live(): %s\n", errbuf); + return false; + } + //bind UDP port to avoid automatic reply with ICMP port ureacheable packets from kernel + d_sock_raw = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (d_sock_raw == -1) + { + std::cout << "Error openning UDP socket" << std::endl; + return false; + } + + // zero out the structure + memset((char *)&si_me, 0, sizeof(si_me)); + + si_me.sin_family = AF_INET; + si_me.sin_port = htons(d_udp_port); + si_me.sin_addr.s_addr = htonl(INADDR_ANY); + + //bind socket to port + if (bind(d_sock_raw, (struct sockaddr *)&si_me, sizeof(si_me)) == -1) + { + std::cout << "Error openning UDP socket" << std::endl; + return false; + } + return true; +} + +gr_complex_ip_packet_source::~gr_complex_ip_packet_source() +{ + if (d_pcap_thread != NULL) + { + delete d_pcap_thread; + } + delete fifo_buff; + std::cout << "Stop Ethernet packet capture\n"; +} + +void gr_complex_ip_packet_source::static_pcap_callback(u_char *args, const struct pcap_pkthdr *pkthdr, + const u_char *packet) +{ + gr_complex_ip_packet_source *bridge = (gr_complex_ip_packet_source *)args; + bridge->pcap_callback(args, pkthdr, packet); +} + +void gr_complex_ip_packet_source::pcap_callback(__attribute__((unused)) u_char *args, __attribute__((unused)) const struct pcap_pkthdr *pkthdr, + const u_char *packet) +{ + boost::mutex::scoped_lock lock(d_mutex); // hold mutex for duration of this function + + gr_ip_header *ih; + gr_udp_header *uh; + + // eth frame parameters + // **** UDP RAW PACKET DECODER **** + if ((packet[12] == 0x08) & (packet[13] == 0x00)) //IP FRAME + { + /* retireve the position of the ip header */ + ih = (gr_ip_header *)(packet + + 14); //length of ethernet header + + /* retireve the position of the udp header */ + u_int ip_len; + ip_len = (ih->ver_ihl & 0xf) * 4; + uh = (gr_udp_header *)((u_char *)ih + ip_len); + + /* convert from network byte order to host byte order */ + //u_short sport; + u_short dport; + dport = ntohs(uh->dport); + //sport = ntohs(uh->sport); + if (dport == d_udp_port) + { + // print ip addresses and udp ports + // printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n", + // ih->saddr.byte1, + // ih->saddr.byte2, + // ih->saddr.byte3, + // ih->saddr.byte4, + // sport, + // ih->daddr.byte1, + // ih->daddr.byte2, + // ih->daddr.byte3, + // ih->daddr.byte4, + // dport); + // std::cout<<"uh->len:"<len)<len) - 8; //total udp packet lenght minus the header lenght + //read the payload bytes and insert them into the shared circular buffer + u_char *udp_payload = ((u_char *)uh + sizeof(gr_udp_header)); + if (fifo_items <= (FIFO_SIZE - payload_lenght_bytes)) + { + int aligned_write_items = FIFO_SIZE - fifo_write_ptr; + if (aligned_write_items >= payload_lenght_bytes) + { + //write all in a single memcpy + memcpy(&fifo_buff[fifo_write_ptr], &udp_payload[0], payload_lenght_bytes); //size in bytes + fifo_write_ptr += payload_lenght_bytes; + if (fifo_write_ptr == FIFO_SIZE) fifo_write_ptr = 0; + fifo_items += payload_lenght_bytes; + } + else + { + //two step wrap write + memcpy(&fifo_buff[fifo_write_ptr], &udp_payload[0], aligned_write_items); //size in bytes + fifo_write_ptr = payload_lenght_bytes - aligned_write_items; + memcpy(&fifo_buff[0], &udp_payload[aligned_write_items], fifo_write_ptr); //size in bytes + fifo_items += payload_lenght_bytes; + } + } + else + { + //notify overflow + std::cout << "O" << std::flush; + } + } + } +} + +void gr_complex_ip_packet_source::my_pcap_loop_thread(pcap_t *pcap_handle) + +{ + pcap_loop(pcap_handle, -1, gr_complex_ip_packet_source::static_pcap_callback, (u_char *)this); +} + +void gr_complex_ip_packet_source::demux_samples(gr_vector_void_star output_items, int num_samples_readed) +{ + int8_t real; + int8_t imag; + uint8_t tmp_char2; + for (int n = 0; n < num_samples_readed; n++) + { + switch (d_wire_sample_type) + { + case 1: //interleaved byte samples + for (int i = 0; i < output_items.size(); i++) + { + real = fifo_buff[fifo_read_ptr++]; + imag = fifo_buff[fifo_read_ptr++]; + if (d_IQ_swap) + { + ((gr_complex *)output_items[i])[n] = gr_complex(real, imag); + } + else + { + ((gr_complex *)output_items[i])[n] = gr_complex(imag, real); + } + } + break; + case 2: // 4bits samples + for (int i = 0; i < output_items.size(); i++) + { + tmp_char2 = fifo_buff[fifo_read_ptr] & 0x0F; + if (tmp_char2 >= 8) + { + real = 2 * (tmp_char2 - 16) + 1; + } + else + { + real = 2 * tmp_char2 + 1; + } + tmp_char2 = fifo_buff[fifo_read_ptr++] >> 4; + tmp_char2 = tmp_char2 & 0x0F; + if (tmp_char2 >= 8) + { + imag = 2 * (tmp_char2 - 16) + 1; + } + else + { + imag = 2 * tmp_char2 + 1; + } + if (d_IQ_swap) + { + ((gr_complex *)output_items[i])[n] = gr_complex(imag, real); + } + else + { + ((gr_complex *)output_items[i])[n] = gr_complex(real, imag); + } + } + break; + default: + std::cout << "Unknown wire sample type\n"; + exit(0); + } + if (fifo_read_ptr == FIFO_SIZE) fifo_read_ptr = 0; + } +} + +int gr_complex_ip_packet_source::work(int noutput_items, + __attribute__((unused)) gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + // send samples to next GNU Radio block + boost::mutex::scoped_lock lock(d_mutex); // hold mutex for duration of this function + if (fifo_items == 0) return 0; + + if (output_items.size() > d_n_baseband_channels) + { + std::cout << "Configuration error: more baseband channels connected than the available in the UDP source\n"; + exit(0); + } + int num_samples_readed; + int bytes_requested; + switch (d_wire_sample_type) + { + case 1: //complex byte samples + bytes_requested = noutput_items * d_bytes_per_sample; + if (bytes_requested < fifo_items) + { + num_samples_readed = noutput_items; //read all + } + else + { + num_samples_readed = fifo_items / d_bytes_per_sample; //read what we have + } + break; + case 2: //complex 4 bits samples + bytes_requested = noutput_items * d_bytes_per_sample; + if (bytes_requested < fifo_items) + { + num_samples_readed = noutput_items; //read all + } + else + { + num_samples_readed = fifo_items / d_bytes_per_sample; //read what we have + } + break; + default: //complex byte samples + bytes_requested = noutput_items * d_bytes_per_sample; + if (bytes_requested < fifo_items) + { + num_samples_readed = noutput_items; //read all + } + else + { + num_samples_readed = fifo_items / d_bytes_per_sample; //read what we have + } + } + + bytes_requested = num_samples_readed * d_bytes_per_sample; + //read all in a single loop + demux_samples(output_items, num_samples_readed); // it also increases the fifo read pointer + //update fifo items + fifo_items = fifo_items - bytes_requested; + + for (int n = 0; n < output_items.size(); n++) + { + produce(n, num_samples_readed); + } + return this->WORK_CALLED_PRODUCE; +} diff --git a/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.h b/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.h new file mode 100644 index 000000000..7b8d9f58e --- /dev/null +++ b/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.h @@ -0,0 +1,117 @@ +/*! + * \file gr_complex_ip_packet_source.h + * + * \brief Receives ip frames containing samples in UDP frame encapsulation + * using a high performance packet capture library (libpcap) + * \author Javier Arribas jarribas (at) cttc.es + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2018 (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 . + * + * ------------------------------------------------------------------------- + */ + + +#ifndef INCLUDED_GR_COMPLEX_IP_PACKET_SOURCE_H +#define INCLUDED_GR_COMPLEX_IP_PACKET_SOURCE_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class gr_complex_ip_packet_source : virtual public gr::sync_block +{ +private: + boost::mutex d_mutex; + pcap_t *descr; //ethernet pcap device descriptor + + char *fifo_buff; + + int fifo_read_ptr; + int fifo_write_ptr; + int fifo_items; + int d_sock_raw; + int d_udp_port; + struct sockaddr_in si_me; + std::string d_src_device; + std::string d_origin_address; + int d_udp_payload_size; + bool d_fifo_full; + + int d_n_baseband_channels; + int d_wire_sample_type; + int d_bytes_per_sample; + size_t d_item_size; + bool d_IQ_swap; + + boost::thread *d_pcap_thread; + /*! + * \brief + * Opens the ethernet device using libpcap raw capture mode + * If any of these fail, the fuction retuns the error and exits. + */ + bool open(); + + void demux_samples(gr_vector_void_star output_items, int num_samples_readed); + void my_pcap_loop_thread(pcap_t *pcap_handle); + + void pcap_callback(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *packet); + + static void static_pcap_callback(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *packet); + + +public: + typedef boost::shared_ptr sptr; + static sptr make(std::string src_device, + std::string origin_address, + int udp_port, + int udp_packet_size, + int n_baseband_channels, + std::string wire_sample_type, + size_t item_size, + bool IQ_swap_); + gr_complex_ip_packet_source(std::string src_device, + std::string origin_address, + int udp_port, + int udp_packet_size, + int n_baseband_channels, + std::string wire_sample_type, + size_t item_size, + bool IQ_swap_); + ~gr_complex_ip_packet_source(); + + // Where all the action really happens + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + //Called by gnuradio to enable drivers, etc for i/o devices. + bool start(); + //Called by gnuradio to disable drivers, etc for i/o devices. + bool stop(); +}; + +#endif /* INCLUDED_GR_COMPLEX_IP_PACKET_SOURCE_H */ diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.cc b/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.cc new file mode 100644 index 000000000..ba9f9365e --- /dev/null +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.cc @@ -0,0 +1,86 @@ +/*! + * \file unpack_byte_4bit_samples.cc + * + * \brief Unpacks byte samples to 4 bits samples. + * Packing Order + * Packing order in Nibble I0 I1 I2 I3 I0 I1 I2 I3 + * \author Javier Arribas jarribas (at) cttc.es + * ------------------------------------------------------------------------- + * + * 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 . + * + * ------------------------------------------------------------------------- + */ + +#include "unpack_byte_4bit_samples.h" +#include + +unpack_byte_4bit_samples_sptr make_unpack_byte_4bit_samples() +{ + return unpack_byte_4bit_samples_sptr(new unpack_byte_4bit_samples()); +} + + +unpack_byte_4bit_samples::unpack_byte_4bit_samples() : sync_interpolator("unpack_byte_4bit_samples", + gr::io_signature::make(1, 1, sizeof(signed char)), + gr::io_signature::make(1, 1, sizeof(signed char)), + 2) +{ +} + + +unpack_byte_4bit_samples::~unpack_byte_4bit_samples() +{ +} + + +int unpack_byte_4bit_samples::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const signed char *in = reinterpret_cast(input_items[0]); + signed char *out = reinterpret_cast(output_items[0]); + int n = 0; + unsigned char tmp_char2; + for (int i = 0; i < noutput_items / 2; i++) + { + tmp_char2 = in[i] & 0x0F; + if (tmp_char2 >= 8) + { + out[n++] = 2 * (tmp_char2 - 16) + 1; + } + else + { + out[n++] = 2 * tmp_char2 + 1; + } + tmp_char2 = in[i] >> 4; + tmp_char2 = tmp_char2 & 0x0F; + if (tmp_char2 >= 8) + { + out[n++] = 2 * (tmp_char2 - 16) + 1; + } + else + { + out[n++] = 2 * tmp_char2 + 1; + } + } + return noutput_items; +} diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.h b/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.h new file mode 100644 index 000000000..ccfe699b5 --- /dev/null +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.h @@ -0,0 +1,61 @@ +/*! + * \file unpack_byte_4bit_samples.h + * + * \brief Unpacks byte samples to 4 bits samples. + * Packing Order + * Packing order in Nibble I0 I1 I2 I3 I0 I1 I2 I3 + * \author Javier Arribas jarribas (at) cttc.es + * ------------------------------------------------------------------------- + * + * 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 . + * + * ------------------------------------------------------------------------- + */ + +#ifndef GNSS_SDR_unpack_byte_4bit_samples_H +#define GNSS_SDR_unpack_byte_4bit_samples_H + +#include + +class unpack_byte_4bit_samples; + +typedef boost::shared_ptr unpack_byte_4bit_samples_sptr; + +unpack_byte_4bit_samples_sptr make_unpack_byte_4bit_samples(); + +/*! + * \brief This class implements conversion between byte packet samples to 4bit_cpx samples + * 1 byte = 1 x complex 4bit I, + 4bit Q samples + */ +class unpack_byte_4bit_samples : public gr::sync_interpolator +{ +private: + friend unpack_byte_4bit_samples_sptr make_unpack_byte_4bit_samples_sptr(); + +public: + unpack_byte_4bit_samples(); + ~unpack_byte_4bit_samples(); + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif From dfeb62871f58db2147e51d403ed52a2fb1b70c9c Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Wed, 16 May 2018 11:36:37 +0200 Subject: [PATCH 09/12] Adding optional compilation of the custom UDP packet source. Disabled by default --- CMakeLists.txt | 40 +-- .../signal_source/adapters/CMakeLists.txt | 33 +- ..._source.cc => custom_udp_signal_source.cc} | 16 +- ...al_source.h => custom_udp_signal_source.h} | 14 +- .../gnuradio_blocks/CMakeLists.txt | 38 ++- .../gnuradio_blocks/raw_ip_packet_source.cc | 289 ------------------ .../gnuradio_blocks/raw_ip_packet_source.h | 99 ------ src/core/receiver/CMakeLists.txt | 3 + src/core/receiver/gnss_block_factory.cc | 16 +- 9 files changed, 105 insertions(+), 443 deletions(-) rename src/algorithms/signal_source/adapters/{udp_signal_source.cc => custom_udp_signal_source.cc} (90%) rename src/algorithms/signal_source/adapters/{udp_signal_source.h => custom_udp_signal_source.h} (89%) delete mode 100644 src/algorithms/signal_source/gnuradio_blocks/raw_ip_packet_source.cc delete mode 100644 src/algorithms/signal_source/gnuradio_blocks/raw_ip_packet_source.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c2fe13617..954690ffb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,7 @@ option(ENABLE_GN3S "Enable the use of the GN3S dongle as signal source (experime option(ENABLE_PLUTOSDR "Enable the use of ADALM-PLUTO Evaluation Boards (Analog Devices Inc.), requires gr-iio" OFF) option(ENABLE_FMCOMMS2 "Enable the use of FMCOMMS4-EBZ + ZedBoard hardware, requires gr-iio" OFF) option(ENABLE_AD9361 "Enable the use of AD9361 directo to FPGA hardware, requires gr-iio" OFF) +option(ENABLE_RAW_UDP "Enable the use of high-optimized custom UDP packet sample source, requires libpcap" OFF) # Performance analysis tools option(ENABLE_GPERFTOOLS "Enable linking to Gperftools libraries (tcmalloc and profiler)" OFF) @@ -1321,6 +1322,16 @@ else(ENABLE_CUDA) message(STATUS "Enable it with 'cmake -DENABLE_CUDA=ON ../' to add support for GPU-based acceleration using CUDA." ) endif(ENABLE_CUDA) +############################################################################### +# CUSTOM UDP PACKET SOURCE (OPTIONAL) +############################################################################### +if(ENABLE_RAW_UDP) + message(STATUS "High-optimized custom UDP ip packet source will be enabled." ) + message(STATUS "You can disable it with 'cmake -DENABLE_RAW_UDP=OFF ../'" ) +else(ENABLE_RAW_UDP) + message(STATUS "High-optimized custom UDP ip packet source will be enabled." ) + message(STATUS "You can disable it with 'cmake -DENABLE_RAW_UDP=OFF ../'" ) +endif(ENABLE_RAW_UDP) ############################################################################### @@ -1455,35 +1466,6 @@ if(ENABLE_GPROF) endif(ENABLE_GPROF) -# - Try to find libpcap include dirs and libraries -# -# Usage of this module as follows: -# -# find_package(PCAP) -# -# Variables used by this module, they can change the default behaviour and need -# to be set before calling find_package: -# -# PCAP_ROOT_DIR Set this variable to the root installation of -# libpcap if the module has problems finding the -# proper installation path. -# -# Variables defined by this module: -# -# PCAP_FOUND System has libpcap, include and library dirs found -# PCAP_INCLUDE_DIR The libpcap include directories. -# PCAP_LIBRARY The libpcap library (possibly includes a thread -# library e.g. required by pf_ring's libpcap) -# HAVE_PF_RING If a found version of libpcap supports PF_RING -find_package(PCAP) -if(NOT PCAP_FOUND) - message(FATAL_ERROR "PCAP required to compile dbfcttc") -endif() -get_filename_component(PCAP_LIBRARY_DIRS ${PCAP_LIBRARY} DIRECTORY CACHE) - - - - ######################################################################## # Set compiler flags ######################################################################## diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index c1fc65c56..a591836e2 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -21,6 +21,38 @@ list(SORT SIGNAL_SOURCE_ADAPTER_HEADERS) # Optional drivers +if(ENABLE_RAW_UDP) + # - Try to find libpcap include dirs and libraries + # + # Usage of this module as follows: + # + # find_package(PCAP) + # + # Variables used by this module, they can change the default behaviour and need + # to be set before calling find_package: + # + # PCAP_ROOT_DIR Set this variable to the root installation of + # libpcap if the module has problems finding the + # proper installation path. + # + # Variables defined by this module: + # + # PCAP_FOUND System has libpcap, include and library dirs found + # PCAP_INCLUDE_DIR The libpcap include directories. + # PCAP_LIBRARY The libpcap library (possibly includes a thread + # library e.g. required by pf_ring's libpcap) + # HAVE_PF_RING If a found version of libpcap supports PF_RING + find_package(PCAP) + if(NOT PCAP_FOUND) + message(FATAL_ERROR "PCAP required to compile custom UDP packet sample source (ENABLE_RAW_UDP)") + endif() + get_filename_component(PCAP_LIBRARY_DIRS ${PCAP_LIBRARY} DIRECTORY CACHE) + set(OPT_LIBRARIES ${OPT_LIBRARIES} ${PCAP_LIBRARIES}) + set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${PCAP_INCLUDE_DIRS}) + set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} custom_udp_signal_source.cc) + +endif(ENABLE_RAW_UDP) + if(ENABLE_PLUTOSDR OR ENABLE_FMCOMMS2) find_package(iio REQUIRED) if(NOT IIO_FOUND) @@ -166,7 +198,6 @@ 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} ) diff --git a/src/algorithms/signal_source/adapters/udp_signal_source.cc b/src/algorithms/signal_source/adapters/custom_udp_signal_source.cc similarity index 90% rename from src/algorithms/signal_source/adapters/udp_signal_source.cc rename to src/algorithms/signal_source/adapters/custom_udp_signal_source.cc index 93af9dd4a..b754b5699 100644 --- a/src/algorithms/signal_source/adapters/udp_signal_source.cc +++ b/src/algorithms/signal_source/adapters/custom_udp_signal_source.cc @@ -30,7 +30,7 @@ */ -#include "udp_signal_source.h" +#include "custom_udp_signal_source.h" #include "configuration_interface.h" #include "GPS_L1_CA.h" #include @@ -41,7 +41,7 @@ using google::LogMessage; -UDPSignalSource::UDPSignalSource(ConfigurationInterface* configuration, +CustomUDPSignalSource::CustomUDPSignalSource(ConfigurationInterface* configuration, std::string role, unsigned int in_stream, unsigned int out_stream, boost::shared_ptr queue) : role_(role), in_stream_(in_stream), out_stream_(out_stream), queue_(queue) { @@ -107,12 +107,12 @@ UDPSignalSource::UDPSignalSource(ConfigurationInterface* configuration, } -UDPSignalSource::~UDPSignalSource() +CustomUDPSignalSource::~CustomUDPSignalSource() { } -void UDPSignalSource::connect(gr::top_block_sptr top_block) +void CustomUDPSignalSource::connect(gr::top_block_sptr top_block) { //connect null sinks to unused streams for (int n = 0; n < channels_in_udp_; n++) @@ -132,7 +132,7 @@ void UDPSignalSource::connect(gr::top_block_sptr top_block) } -void UDPSignalSource::disconnect(gr::top_block_sptr top_block) +void CustomUDPSignalSource::disconnect(gr::top_block_sptr top_block) { //disconnect null sinks to unused streams for (int n = 0; n < channels_in_udp_; n++) @@ -151,19 +151,19 @@ void UDPSignalSource::disconnect(gr::top_block_sptr top_block) } -gr::basic_block_sptr UDPSignalSource::get_left_block() +gr::basic_block_sptr CustomUDPSignalSource::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() +gr::basic_block_sptr CustomUDPSignalSource::get_right_block() { return udp_gnss_rx_source_; } -gr::basic_block_sptr UDPSignalSource::get_right_block(int RF_channel) +gr::basic_block_sptr CustomUDPSignalSource::get_right_block(__attribute__((unused)) int RF_channel) { return udp_gnss_rx_source_; } diff --git a/src/algorithms/signal_source/adapters/udp_signal_source.h b/src/algorithms/signal_source/adapters/custom_udp_signal_source.h similarity index 89% rename from src/algorithms/signal_source/adapters/udp_signal_source.h rename to src/algorithms/signal_source/adapters/custom_udp_signal_source.h index 3fc91b023..9bed9ae32 100644 --- a/src/algorithms/signal_source/adapters/udp_signal_source.h +++ b/src/algorithms/signal_source/adapters/custom_udp_signal_source.h @@ -30,8 +30,8 @@ */ -#ifndef GNSS_SDR_UDP_SIGNAL_SOURCE_H -#define GNSS_SDR_UDP_SIGNAL_SOURCE_H +#ifndef GNSS_SDR_CUSTOM_UDP_SIGNAL_SOURCE_H +#define GNSS_SDR_CUSTOM_UDP_SIGNAL_SOURCE_H #include "gnss_block_interface.h" #include "gr_complex_ip_packet_source.h" @@ -50,14 +50,14 @@ class ConfigurationInterface; * \brief This class reads from UDP packets, which streams interleaved * I/Q samples over a network. */ -class UDPSignalSource : public GNSSBlockInterface +class CustomUDPSignalSource : public GNSSBlockInterface { public: - UDPSignalSource(ConfigurationInterface* configuration, + CustomUDPSignalSource(ConfigurationInterface* configuration, std::string role, unsigned int in_stream, unsigned int out_stream, boost::shared_ptr queue); - virtual ~UDPSignalSource(); + virtual ~CustomUDPSignalSource(); inline std::string role() override { @@ -69,7 +69,7 @@ public: */ inline std::string implementation() override { - return "UDP_Signal_Source"; + return "Custom_UDP_Signal_Source"; } inline size_t item_size() override @@ -102,4 +102,4 @@ private: boost::shared_ptr queue_; }; -#endif /*GNSS_SDR_UDP_SIGNAL_SOURCE_H */ +#endif /*GNSS_SDR_CUSTOM_UDP_SIGNAL_SOURCE_H */ diff --git a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt index dd2101462..b35caa37d 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt @@ -17,6 +17,38 @@ # +if(ENABLE_RAW_UDP) + # - Try to find libpcap include dirs and libraries + # + # Usage of this module as follows: + # + # find_package(PCAP) + # + # Variables used by this module, they can change the default behaviour and need + # to be set before calling find_package: + # + # PCAP_ROOT_DIR Set this variable to the root installation of + # libpcap if the module has problems finding the + # proper installation path. + # + # Variables defined by this module: + # + # PCAP_FOUND System has libpcap, include and library dirs found + # PCAP_INCLUDE_DIR The libpcap include directories. + # PCAP_LIBRARY The libpcap library (possibly includes a thread + # library e.g. required by pf_ring's libpcap) + # HAVE_PF_RING If a found version of libpcap supports PF_RING + find_package(PCAP) + if(NOT PCAP_FOUND) + message(FATAL_ERROR "PCAP required to compile custom UDP packet sample source (ENABLE_RAW_UDP)") + endif() + get_filename_component(PCAP_LIBRARY_DIRS ${PCAP_LIBRARY} DIRECTORY CACHE) + set(OPT_LIBRARIES ${OPT_LIBRARIES} ${PCAP_LIBRARIES}) + set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${PCAP_INCLUDE_DIRS}) + set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} gr_complex_ip_packet_source.cc) + +endif(ENABLE_RAW_UDP) + set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES unpack_byte_2bit_samples.cc unpack_byte_2bit_cpx_samples.cc @@ -26,8 +58,7 @@ set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES unpack_2bit_samples.cc unpack_spir_gss6450_samples.cc labsat23_source.cc - raw_ip_packet_source.cc - gr_complex_ip_packet_source.cc + ${OPT_DRIVER_SOURCES} ) include_directories( @@ -37,6 +68,7 @@ include_directories( ${GFlags_INCLUDE_DIRS} ${GNURADIO_RUNTIME_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} + ${OPT_DRIVER_INCLUDE_DIRS} ) file(GLOB SIGNAL_SOURCE_GR_BLOCKS_HEADERS "*.h") @@ -47,6 +79,6 @@ target_link_libraries(signal_source_gr_blocks signal_source_lib ${GNURADIO_RUNTIME_LIBRARIES} ${Boost_LIBRARIES} - ${PCAP_LIBRARIES} + ${OPT_LIBRARIES} ) add_dependencies(signal_source_gr_blocks glog-${glog_RELEASE}) diff --git a/src/algorithms/signal_source/gnuradio_blocks/raw_ip_packet_source.cc b/src/algorithms/signal_source/gnuradio_blocks/raw_ip_packet_source.cc deleted file mode 100644 index 5ec4c4a2c..000000000 --- a/src/algorithms/signal_source/gnuradio_blocks/raw_ip_packet_source.cc +++ /dev/null @@ -1,289 +0,0 @@ -/*! - * \file raw_ip_packet_source.cc - * - * \brief Receives ip frames containing samples in UDP frame encapsulation - * using a high performance packet capture library (libpcap) - * \author Javier Arribas jarribas (at) cttc.es - * ------------------------------------------------------------------------- - * - * Copyright (C) 2010-2018 (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 . - * - * ------------------------------------------------------------------------- - */ - - -#include -#include "raw_ip_packet_source.h" - -#include -#include - - -#define FIFO_SIZE 1000000 - - -/* 4 bytes IP address */ -typedef struct gr_ip_address{ - u_char byte1; - u_char byte2; - u_char byte3; - u_char byte4; -}gr_ip_address; - -/* IPv4 header */ -typedef struct gr_ip_header{ - u_char ver_ihl; // Version (4 bits) + Internet header length (4 bits) - u_char tos; // Type of service - u_short tlen; // Total length - u_short identification; // Identification - u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits) - u_char ttl; // Time to live - u_char proto; // Protocol - u_short crc; // Header checksum - gr_ip_address saddr; // Source address - gr_ip_address daddr; // Destination address - u_int op_pad; // Option + Padding -}gr_ip_header; - -/* UDP header*/ -typedef struct gr_udp_header{ - u_short sport; // Source port - u_short dport; // Destination port - u_short len; // Datagram length - u_short crc; // Checksum -}gr_udp_header; - -raw_ip_packet_source::sptr -raw_ip_packet_source::make(std::string src_device, std::string origin_address, int udp_port, int udp_packet_size) -{ - return gnuradio::get_initial_sptr - (new raw_ip_packet_source(src_device, origin_address, udp_port, udp_packet_size)); -} - -/* - * The private constructor - */ -raw_ip_packet_source::raw_ip_packet_source(std::string src_device, std::string origin_address, int udp_port, int udp_packet_size) -: gr::sync_block("raw_ip_packet_source", - gr::io_signature::make(0, 0, 0), - gr::io_signature::make(1, 1, sizeof(char))) -{ - - // constructor code here - std::cout<<"Start Ethernet packet capture\n"; - - d_src_device=src_device; - d_udp_port=udp_port; - d_udp_payload_size=udp_packet_size; - d_fifo_full=false; - d_last_frame_counter=0; - d_num_rx_errors=0; - - //allocate signal samples buffer - fifo_buff=new char[FIFO_SIZE]; - fifo_read_ptr=0; - fifo_write_ptr=0; - fifo_items=0; - - //open the ethernet device - if (open()==true) - { - // start pcap capture thread - d_pcap_thread=new boost::thread(boost::bind(&raw_ip_packet_source::my_pcap_loop_thread,this,descr)); - }else{ - exit(1); //ethernet error! - } -} - -bool raw_ip_packet_source::open() -{ - char errbuf[PCAP_ERRBUF_SIZE]; - boost::mutex::scoped_lock lock(d_mutex); // hold mutex for duration of this function - /* open device for reading */ - descr = pcap_open_live(d_src_device.c_str(),1500,1,1000,errbuf); - if(descr == NULL) - { - std::cout<<"Error openning Ethernet device "<join(); - pcap_close(descr); - } - - delete fifo_buff; - std::cout<<"Stop Ethernet packet capture\n"; - -} - -void raw_ip_packet_source::static_pcap_callback(u_char *args, const struct pcap_pkthdr* pkthdr, - const u_char* packet) -{ - raw_ip_packet_source *bridge=(raw_ip_packet_source*) args; - bridge->pcap_callback(args, pkthdr, packet); -} - -void raw_ip_packet_source::pcap_callback(u_char *args, const struct pcap_pkthdr* pkthdr, - const u_char* packet) -{ - boost::mutex::scoped_lock lock(d_mutex); // hold mutex for duration of this function - - gr_ip_header *ih; - gr_udp_header *uh; - - // eth frame parameters - // **** UDP RAW PACKET DECODER **** - if ((packet[12]==0x08) & (packet[13]==0x00)) //IP FRAME - { - - /* retireve the position of the ip header */ - ih = (gr_ip_header *) (packet + - 14); //length of ethernet header - - /* retireve the position of the udp header */ - u_int ip_len; - ip_len = (ih->ver_ihl & 0xf) * 4; - uh = (gr_udp_header *) ((u_char*)ih + ip_len); - - /* convert from network byte order to host byte order */ - u_short sport,dport; - dport = ntohs( uh->dport ); - sport = ntohs( uh->sport ); - if (dport==d_udp_port) - { - // print ip addresses and udp ports -// printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n", -// ih->saddr.byte1, -// ih->saddr.byte2, -// ih->saddr.byte3, -// ih->saddr.byte4, -// sport, -// ih->daddr.byte1, -// ih->daddr.byte2, -// ih->daddr.byte3, -// ih->daddr.byte4, -// dport); -// std::cout<<"d_udp_port:"<=d_udp_payload_size) - { - //write all in a single memcpy - memcpy(&fifo_buff[fifo_write_ptr],&udp_payload[0],d_udp_payload_size); //size in bytes - fifo_write_ptr+=d_udp_payload_size; - if (fifo_write_ptr==FIFO_SIZE) fifo_write_ptr=0; - fifo_items+=d_udp_payload_size; - }else{ - //two step wrap write - memcpy(&fifo_buff[fifo_write_ptr],&udp_payload[0],aligned_write_items); //size in bytes - fifo_write_ptr=d_udp_payload_size-aligned_write_items; - memcpy(&fifo_buff[0],&udp_payload[aligned_write_items],fifo_write_ptr); //size in bytes - fifo_items+=d_udp_payload_size; - } - }else{ - std::cout<<"Ou"<=num_samples_readed) - { - //read all in a single memcpy - memcpy(&((char*)output_items[0])[0],&fifo_buff[fifo_read_ptr],num_samples_readed); - fifo_read_ptr=fifo_read_ptr+num_samples_readed; //increase the fifo pointer - if (fifo_read_ptr==FIFO_SIZE) fifo_read_ptr=0; - }else{ - //two step wrap read - memcpy(&((char*)output_items[0])[0],&fifo_buff[fifo_read_ptr],aligned_read_items); - fifo_read_ptr=num_samples_readed-aligned_read_items;//increase the fifo pointer considering the rollover - memcpy(&((char*)output_items[0])[aligned_read_items],&fifo_buff[0],fifo_read_ptr); - } - - fifo_items=fifo_items-num_samples_readed; - - // Tell runtime system how many output items we produced. - //std::cout<<"fifo_items:"<. - * - * ------------------------------------------------------------------------- - */ - - -#ifndef INCLUDED_RAW_IP_PACKET_SOURCE_H -#define INCLUDED_RAW_IP_PACKET_SOURCE_H - -#include -#include -#include -#include -#include -#include -#include -#include - -class raw_ip_packet_source : virtual public gr::sync_block -{ -private: - boost::mutex d_mutex; - - pcap_t* descr; //ethernet pcap device descriptor - int fifo_pipe[2]; - - char *fifo_buff; - - int fifo_read_ptr; - int fifo_write_ptr; - int fifo_items; - int d_sock_raw; - int d_udp_port; - struct sockaddr_in si_me; - std::string d_src_device; - std::string d_origin_address; - int d_udp_payload_size; - bool d_fifo_full; - - int d_last_frame_counter; - int d_num_rx_errors; - - - boost::thread *d_pcap_thread; - /*! - * \brief - * Opens the ethernet device using libpcap raw capture mode - * If any of these fail, the fuction retuns the error and exits. - */ - bool open(); - - void my_pcap_loop_thread(pcap_t *pcap_handle); - - void pcap_callback(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char* packet); - - static void static_pcap_callback(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char* packet); - - -public: - - typedef boost::shared_ptr sptr; - static sptr make(std::string src_device, std::string origin_address, int udp_port, int udp_packet_size); - raw_ip_packet_source(std::string src_device, std::string origin_address, int udp_port, int udp_packet_size); - ~raw_ip_packet_source(); - - // Where all the action really happens - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif /* INCLUDED_RAW_IP_PACKET_SOURCE_H */ - diff --git a/src/core/receiver/CMakeLists.txt b/src/core/receiver/CMakeLists.txt index 09b24de96..7be920a47 100644 --- a/src/core/receiver/CMakeLists.txt +++ b/src/core/receiver/CMakeLists.txt @@ -40,6 +40,9 @@ if(ENABLE_FPGA) add_definitions(-DENABLE_FPGA=1) endif(ENABLE_FPGA) +if(ENABLE_RAW_UDP) + add_definitions(-DRAW_UDP=1) +endif(ENABLE_RAW_UDP) if(Boost_VERSION LESS 105000) add_definitions(-DOLD_BOOST=1) diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 0b7ffb678..237f2df40 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -35,6 +35,7 @@ #include "gnss_block_factory.h" + #include "configuration_interface.h" #include "in_memory_configuration.h" #include "gnss_block_interface.h" @@ -45,7 +46,6 @@ #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" @@ -104,6 +104,10 @@ #include "hybrid_observables.h" #include "rtklib_pvt.h" +#if RAW_UDP +#include "custom_udp_signal_source.h" +#endif + #if ENABLE_FPGA #include "gps_l1_ca_pcps_acquisition_fpga.h" #include "gps_l1_ca_dll_pll_tracking_fpga.h" @@ -159,11 +163,7 @@ using google::LogMessage; GNSSBlockFactory::GNSSBlockFactory() {} - - GNSSBlockFactory::~GNSSBlockFactory() {} - - std::unique_ptr GNSSBlockFactory::GetSignalSource( std::shared_ptr configuration, gr::msg_queue::sptr queue, int ID) { @@ -1053,11 +1053,12 @@ std::unique_ptr GNSSBlockFactory::GetBlock( exit(1); } } - else if (implementation.compare("UDP_Signal_Source") == 0) +#if RAW_UDP + else if (implementation.compare("Custom_UDP_Signal_Source") == 0) { try { - std::unique_ptr block_(new UDPSignalSource(configuration.get(), role, in_streams, + std::unique_ptr block_(new CustomUDPSignalSource(configuration.get(), role, in_streams, out_streams, queue)); block = std::move(block_); } @@ -1068,6 +1069,7 @@ std::unique_ptr GNSSBlockFactory::GetBlock( exit(1); } } +#endif else if (implementation.compare("Nsr_File_Signal_Source") == 0) { try From 5956b710b92bb5f7ac7d85f2e03fc78a8519554e Mon Sep 17 00:00:00 2001 From: Javier Arribas Date: Wed, 16 May 2018 15:38:35 +0200 Subject: [PATCH 10/12] Updating configuration example for Custom UDP packet signal source --- conf/gnss-sdr_GPS_L1_2ch_udp.conf | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/conf/gnss-sdr_GPS_L1_2ch_udp.conf b/conf/gnss-sdr_GPS_L1_2ch_udp.conf index d63eac95d..6dd703fa6 100644 --- a/conf/gnss-sdr_GPS_L1_2ch_udp.conf +++ b/conf/gnss-sdr_GPS_L1_2ch_udp.conf @@ -12,9 +12,7 @@ GNSS-SDR.internal_fs_sps=13250000 ;//66.25/5 ;GNSS-SDR.internal_fs_sps=2650000 ;//66.25/25 ;######### 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.implementation=Custom_UDP_Signal_Source SignalSource.item_type=gr_complex SignalSource.origin_address=0.0.0.0 SignalSource.capture_device=eth0 From 1195234df15525c770f2bdb4d595e8edc8df1e72 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 16 May 2018 18:32:27 +0200 Subject: [PATCH 11/12] Fix warnings raised by GCC 8.1.1 --- src/algorithms/PVT/libs/rtklib_solver.cc | 4 +- src/algorithms/libs/rtklib/rtklib_pntpos.cc | 10 +-- src/algorithms/libs/rtklib/rtklib_rtkcmn.cc | 28 ++++++-- src/algorithms/libs/rtklib/rtklib_stream.cc | 71 +++++++++++++++++---- 4 files changed, 86 insertions(+), 27 deletions(-) diff --git a/src/algorithms/PVT/libs/rtklib_solver.cc b/src/algorithms/PVT/libs/rtklib_solver.cc index 8d74aea20..a0650d768 100644 --- a/src/algorithms/PVT/libs/rtklib_solver.cc +++ b/src/algorithms/PVT/libs/rtklib_solver.cc @@ -463,14 +463,14 @@ bool rtklib_solver::get_PVT(const std::map& gnss_observables_ unsigned int used_sats = 0; for (unsigned int i = 0; i < MAXSAT; i++) { - if (int vsat = rtk_.ssat[i].vsat[0] == 1) used_sats++; + if (rtk_.ssat[i].vsat[0] == 1) used_sats++; } double azel[used_sats * 2]; unsigned int index_aux = 0; for (unsigned int i = 0; i < MAXSAT; i++) { - if (int vsat = rtk_.ssat[i].vsat[0] == 1) + if (rtk_.ssat[i].vsat[0] == 1) { azel[2 * index_aux] = rtk_.ssat[i].azel[0]; azel[2 * index_aux + 1] = rtk_.ssat[i].azel[1]; diff --git a/src/algorithms/libs/rtklib/rtklib_pntpos.cc b/src/algorithms/libs/rtklib/rtklib_pntpos.cc index 31b60c8e6..d4a10fe65 100644 --- a/src/algorithms/libs/rtklib/rtklib_pntpos.cc +++ b/src/algorithms/libs/rtklib/rtklib_pntpos.cc @@ -130,11 +130,11 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel, double P1_P2 = 0.0; double P1_C1 = 0.0; double P2_C2 = 0.0; - //Intersignal corrections (m). See GPS IS-200 CNAV message - double ISCl1 = 0.0; + // Intersignal corrections (m). See GPS IS-200 CNAV message + //double ISCl1 = 0.0; double ISCl2 = 0.0; double ISCl5i = 0.0; - double ISCl5q = 0.0; + //double ISCl5q = 0.0; double gamma_ = 0.0; int i = 0; int j = 1; @@ -209,10 +209,10 @@ double prange(const obsd_t *obs, const nav_t *nav, const double *azel, if (sys == SYS_GPS) { - ISCl1 = getiscl1(obs->sat, nav); + // ISCl1 = getiscl1(obs->sat, nav); ISCl2 = getiscl2(obs->sat, nav); ISCl5i = getiscl5i(obs->sat, nav); - ISCl5q = getiscl5q(obs->sat, nav); + // ISCl5q = getiscl5q(obs->sat, nav); } //CHECK IF IT IS STILL NEEDED diff --git a/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc b/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc index 20f939dd4..88cc2ca38 100644 --- a/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc +++ b/src/algorithms/libs/rtklib/rtklib_rtkcmn.cc @@ -54,6 +54,8 @@ //#include #include #include +#include +#include #include #include #include @@ -253,11 +255,12 @@ const unsigned int tbl_CRC24Q[] = { 0x42FA2F, 0xC4B6D4, 0xC82F22, 0x4E63D9, 0xD11CCE, 0x575035, 0x5BC9C3, 0xDD8538}; -extern "C" { -void dgemm_(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *); -extern void dgetrf_(int *, int *, double *, int *, int *, int *); -extern void dgetri_(int *, double *, int *, int *, double *, int *, int *); -extern void dgetrs_(char *, int *, int *, double *, int *, int *, double *, int *, int *); +extern "C" +{ + void dgemm_(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *); + extern void dgetrf_(int *, int *, double *, int *, int *, int *); + extern void dgetri_(int *, double *, int *, int *, double *, int *, int *); + extern void dgetrs_(char *, int *, int *, double *, int *, int *, double *, int *, int *); } @@ -2562,7 +2565,8 @@ void readpos(const char *file, const char *rcv, double *pos) if (buff[0] == '%' || buff[0] == '#') continue; if (sscanf(buff, "%lf %lf %lf %s", &poss[np][0], &poss[np][1], &poss[np][2], str) < 4) continue; - strncpy(stas[np], str, 15); + // strncpy(stas[np], str, 15); This line triggers a warning. Replaced by: + memcpy(stas[np], str, 15 * sizeof(stas[np][0])); stas[np++][15] = '\0'; } fclose(fp); @@ -4264,7 +4268,17 @@ int rtk_uncompress(const char *file, char *uncfile) dir = fname; fname = p + 1; } - sprintf(cmd, "tar -C \"%s\" -xf \"%s\"", dir, tmpfile); + // sprintf(cmd, "tar -C \"%s\" -xf \"%s\"", dir, tmpfile); + // NOTE: This sprintf triggers a format overflow warning. Replaced by: + std::ostringstream temp; + std::string s_aux1(dir); + std::string s_aux2(tmpfile); + temp << "tar -C " << s_aux1 << " -xf " << s_aux2; + std::string s_aux = temp.str(); + int n = s_aux.length(); + if (n < 2048) + for (int i = 0; i < n; i++) cmd[i] = s_aux[i]; + if (execcmd(cmd)) { if (stat) diff --git a/src/algorithms/libs/rtklib/rtklib_stream.cc b/src/algorithms/libs/rtklib/rtklib_stream.cc index 6dafde2ac..3de693e65 100644 --- a/src/algorithms/libs/rtklib/rtklib_stream.cc +++ b/src/algorithms/libs/rtklib/rtklib_stream.cc @@ -64,6 +64,7 @@ #include #include #include +#include /* global options ------------------------------------------------------------*/ @@ -115,7 +116,12 @@ serial_t *openserial(const char *path, int mode, char *msg) } parity = (char)toupper((int)parity); - sprintf(dev, "/dev/%s", port); + // sprintf(dev, "/dev/%s", port); This line triggers a warning. Replaced by: + std::string s_aux = "/dev/" + std::string(port); + s_aux.resize(128, '\0'); + int n = s_aux.length(); + if (n < 128) + for (int i = 0; i < n; i++) dev[i] = s_aux[i]; if ((mode & STR_MODE_R) && (mode & STR_MODE_W)) rw = O_RDWR; @@ -1224,7 +1230,11 @@ int rspntrip_s(ntrip_t *ntrip, char *msg) else if ((p = strstr((char *)ntrip->buff, NTRIP_RSP_ERROR))) { /* error */ nb = ntrip->nb < MAXSTATMSG ? ntrip->nb : MAXSTATMSG; - strncpy(msg, (char *)ntrip->buff, nb); + // strncpy(msg, (char *)ntrip->buff, nb); This line triggers a warning. Replaced by; + std::string s_aux((char *)ntrip->buff); + s_aux.resize(nb, '\0'); + for (int i = 0; i < nb; i++) msg[i] = s_aux[i]; + msg[nb] = 0; tracet(1, "rspntrip_s: %s nb=%d\n", msg, ntrip->nb); ntrip->nb = 0; @@ -1380,7 +1390,11 @@ ntrip_t *openntrip(const char *path, int type, char *msg) /* ntrip access via proxy server */ if (*proxyaddr) { - sprintf(ntrip->url, "http://%s", tpath); + // sprintf(ntrip->url, "http://%s", tpath); This line triggers a warning. Replaced by: + std::string s_aux = "http://" + std::string(tpath); + int n = s_aux.length(); + if (n < 256) + for (int k = 0; k < n; k++) ntrip->url[k] = s_aux[k]; strcpy(tpath, proxyaddr); } /* open tcp client stream */ @@ -1545,8 +1559,17 @@ void *ftpthread(void *arg) p++; else p = remote; - sprintf(local, "%s%c%s", localdir, FILEPATHSEP, p); - sprintf(errfile, "%s.err", local); + // sprintf(local, "%s%c%s", localdir, FILEPATHSEP, p); This line triggers a warning. Replaced by: + std::string s_aux = std::string(localdir) + std::to_string(FILEPATHSEP) + std::string(p); + int n = s_aux.length(); + if (n < 1024) + for (int i = 0; i < n; i++) local[i] = s_aux[i]; + + // sprintf(errfile, "%s.err", local); This line triggers a warning. Replaced by: + std::string s_aux2 = std::string(local) + ".err"; + n = s_aux2.length(); + if (n < 1024) + for (int i = 0; i < n; i++) errfile[i] = s_aux2[i]; /* if local file exist, skip download */ strcpy(tmpfile, local); @@ -1574,16 +1597,35 @@ void *ftpthread(void *arg) /* download command (ref [2]) */ if (ftp->proto == 0) { /* ftp */ - sprintf(opt, "--ftp-user=%s --ftp-password=%s --glob=off --passive-ftp %s-t 1 -T %d -O \"%s\"", - ftp->user, ftp->passwd, proxyopt, FTP_TIMEOUT, local); - sprintf(cmd, "%s%s %s \"ftp://%s/%s\" 2> \"%s\"\n", env, FTP_CMD, opt, ftp->addr, - remote, errfile); + // sprintf(opt, "--ftp-user=%s --ftp-password=%s --glob=off --passive-ftp %s-t 1 -T %d -O \"%s\"", + // ftp->user, ftp->passwd, proxyopt, FTP_TIMEOUT, local); This line triggers a warning. Replaced by: + std::string s_aux = "--ftp-user=" + std::string(ftp->user) + " --ftp-password=" + std::string(ftp->passwd) + + " --glob=off --passive-ftp " + std::string(proxyopt) + "s-t 1 -T " + std::to_string(FTP_TIMEOUT) + + " -O \"" + std::string(local) + "\""; + int k = s_aux.length(); + if (k < 2048) + for (int i = 0; i < k; i++) opt[i] = s_aux[i]; + + // sprintf(cmd, "%s%s %s \"ftp://%s/%s\" 2> \"%s\"\n", env, FTP_CMD, opt, ftp->addr, + // remote, errfile); This line triggers a warning. Replaced by: + std::string s_aux2 = std::string(env) + std::string(FTP_CMD) + " " + std::string(opt) + " " + + "\"ftp://" + std::string(ftp->addr) + "/" + std::string(remote) + "\" 2> \"" + std::string(errfile) + "\"\n"; + k = s_aux2.length(); + for (int i = 0; (i < k) && (i < 1024); i++) cmd[i] = s_aux2[i]; } else { /* http */ - sprintf(opt, "%s-t 1 -T %d -O \"%s\"", proxyopt, FTP_TIMEOUT, local); - sprintf(cmd, "%s%s %s \"http://%s/%s\" 2> \"%s\"\n", env, FTP_CMD, opt, ftp->addr, - remote, errfile); + // sprintf(opt, "%s-t 1 -T %d -O \"%s\"", proxyopt, FTP_TIMEOUT, local); This line triggers a warning. Replaced by: + std::string s_aux = std::string(proxyopt) + " -t 1 -T " + std::to_string(FTP_TIMEOUT) + " -O \"" + std::string(local) + "\""; + int l = s_aux.length(); + for (int i = 0; (i < l) && (i < 1024); i++) opt[i] = s_aux[i]; + + // sprintf(cmd, "%s%s %s \"http://%s/%s\" 2> \"%s\"\n", env, FTP_CMD, opt, ftp->addr, + // remote, errfile); This line triggers a warning. Replaced by: + std::string s_aux2 = std::string(env) + std::string(FTP_CMD) + " " + std::string(opt) + " " + + "\"http://" + std::string(ftp->addr) + "/" + std::string(remote) + "\" 2> \"" + std::string(errfile) + "\"\n"; + l = s_aux2.length(); + for (int i = 0; (i < l) && (i < 1024); i++) cmd[i] = s_aux2[i]; } /* execute download command */ if ((ret = execcmd(cmd))) @@ -2049,7 +2091,10 @@ int strstat(stream_t *stream, char *msg) strlock(stream); if (msg) { - strncpy(msg, stream->msg, MAXSTRMSG - 1); + // strncpy(msg, stream->msg, MAXSTRMSG - 1); This line triggers a warning. Replaced by: + std::string aux_s(stream->msg); + aux_s.resize(MAXSTRMSG - 1, '0'); + for (int i = 0; i < MAXSTRMSG - 1; i++) msg[i] = aux_s[i]; msg[MAXSTRMSG - 1] = '\0'; } if (!stream->port) From 87fb81b9725bbce8bec985ca34447686885d7963 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 16 May 2018 20:00:14 +0200 Subject: [PATCH 12/12] Use https instead of http in links when available. Minor fixes --- cmake/Modules/FindPCAP.cmake | 5 +- .../signal_source/adapters/CMakeLists.txt | 50 +++++++++--------- .../adapters/custom_udp_signal_source.cc | 14 +++-- .../adapters/custom_udp_signal_source.h | 2 +- .../gnuradio_blocks/CMakeLists.txt | 51 +++++++++---------- .../gr_complex_ip_packet_source.cc | 7 ++- .../gr_complex_ip_packet_source.h | 10 ++-- .../unpack_byte_4bit_samples.cc | 4 +- .../unpack_byte_4bit_samples.h | 4 +- 9 files changed, 70 insertions(+), 77 deletions(-) diff --git a/cmake/Modules/FindPCAP.cmake b/cmake/Modules/FindPCAP.cmake index 7e0ea6995..3be89420e 100644 --- a/cmake/Modules/FindPCAP.cmake +++ b/cmake/Modules/FindPCAP.cmake @@ -1,4 +1,3 @@ - ################################################################### # # Copyright (c) 2006 Frederic Heem, @@ -112,11 +111,11 @@ CHECK_FUNCTION_EXISTS("pcap_set_datalink" HAVE_PCAP_SET_DATALINK) #Is pcap found ? IF(PCAP_INCLUDE_DIRS AND PCAP_LIBRARIES) - SET( PCAP_FOUND "YES" ) + SET( PCAP_FOUND true ) ENDIF(PCAP_INCLUDE_DIRS AND PCAP_LIBRARIES) MARK_AS_ADVANCED( PCAP_LIBRARIES PCAP_INCLUDE_DIRS -) \ No newline at end of file +) diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index a591836e2..120fff27b 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -22,31 +22,31 @@ list(SORT SIGNAL_SOURCE_ADAPTER_HEADERS) # Optional drivers if(ENABLE_RAW_UDP) - # - Try to find libpcap include dirs and libraries - # - # Usage of this module as follows: - # - # find_package(PCAP) - # - # Variables used by this module, they can change the default behaviour and need - # to be set before calling find_package: - # - # PCAP_ROOT_DIR Set this variable to the root installation of - # libpcap if the module has problems finding the - # proper installation path. - # - # Variables defined by this module: - # - # PCAP_FOUND System has libpcap, include and library dirs found - # PCAP_INCLUDE_DIR The libpcap include directories. - # PCAP_LIBRARY The libpcap library (possibly includes a thread - # library e.g. required by pf_ring's libpcap) - # HAVE_PF_RING If a found version of libpcap supports PF_RING - find_package(PCAP) - if(NOT PCAP_FOUND) - message(FATAL_ERROR "PCAP required to compile custom UDP packet sample source (ENABLE_RAW_UDP)") - endif() - get_filename_component(PCAP_LIBRARY_DIRS ${PCAP_LIBRARY} DIRECTORY CACHE) + # - Try to find libpcap include dirs and libraries + # + # Usage of this module as follows: + # + # find_package(PCAP) + # + # Variables used by this module, they can change the default behaviour and need + # to be set before calling find_package: + # + # PCAP_ROOT_DIR Set this variable to the root installation of + # libpcap if the module has problems finding the + # proper installation path. + # + # Variables defined by this module: + # + # PCAP_FOUND System has libpcap, include and library dirs found + # PCAP_INCLUDE_DIR The libpcap include directories. + # PCAP_LIBRARY The libpcap library (possibly includes a thread + # library e.g. required by pf_ring's libpcap) + # HAVE_PF_RING If a found version of libpcap supports PF_RING + find_package(PCAP) + if(NOT PCAP_FOUND) + message(FATAL_ERROR "PCAP required to compile custom UDP packet sample source (ENABLE_RAW_UDP)") + endif() + get_filename_component(PCAP_LIBRARY_DIRS ${PCAP_LIBRARY} DIRECTORY CACHE) set(OPT_LIBRARIES ${OPT_LIBRARIES} ${PCAP_LIBRARIES}) set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${PCAP_INCLUDE_DIRS}) set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} custom_udp_signal_source.cc) diff --git a/src/algorithms/signal_source/adapters/custom_udp_signal_source.cc b/src/algorithms/signal_source/adapters/custom_udp_signal_source.cc index b754b5699..2ed2dd5ae 100644 --- a/src/algorithms/signal_source/adapters/custom_udp_signal_source.cc +++ b/src/algorithms/signal_source/adapters/custom_udp_signal_source.cc @@ -24,7 +24,7 @@ * 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 . + * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- */ @@ -50,8 +50,7 @@ CustomUDPSignalSource::CustomUDPSignalSource(ConfigurationInterface* configurati 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); + dump_filename_ = configuration->property(role + ".dump_filename", default_dump_file); // network PARAMETERS std::string default_capture_device = "eth0"; @@ -62,7 +61,6 @@ CustomUDPSignalSource::CustomUDPSignalSource(ConfigurationInterface* configurati int port = configuration->property(role + ".port", default_port); int payload_bytes = configuration->property(role + ".payload_bytes", 1024); - RF_channels_ = configuration->property(role + ".RF_channels", 1); channels_in_udp_ = configuration->property(role + ".channels_in_udp", 1); IQ_swap_ = configuration->property(role + ".IQ_swap", false); @@ -70,7 +68,7 @@ CustomUDPSignalSource::CustomUDPSignalSource(ConfigurationInterface* configurati 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); - //output item size is always gr_complex + // output item size is always gr_complex item_size_ = sizeof(gr_complex); udp_gnss_rx_source_ = gr_complex_ip_packet_source::make(capture_device, @@ -95,7 +93,6 @@ CustomUDPSignalSource::CustomUDPSignalSource(ConfigurationInterface* configurati exit(0); } - if (dump_) { for (int n = 0; n < channels_in_udp_; n++) @@ -114,7 +111,7 @@ CustomUDPSignalSource::~CustomUDPSignalSource() void CustomUDPSignalSource::connect(gr::top_block_sptr top_block) { - //connect null sinks to unused streams + // connect null sinks to unused streams for (int n = 0; n < channels_in_udp_; n++) { top_block->connect(udp_gnss_rx_source_, n, null_sinks_.at(n), 0); @@ -134,7 +131,7 @@ void CustomUDPSignalSource::connect(gr::top_block_sptr top_block) void CustomUDPSignalSource::disconnect(gr::top_block_sptr top_block) { - //disconnect null sinks to unused streams + // disconnect null sinks to unused streams for (int n = 0; n < channels_in_udp_; n++) { top_block->disconnect(udp_gnss_rx_source_, n, null_sinks_.at(n), 0); @@ -163,6 +160,7 @@ gr::basic_block_sptr CustomUDPSignalSource::get_right_block() return udp_gnss_rx_source_; } + gr::basic_block_sptr CustomUDPSignalSource::get_right_block(__attribute__((unused)) int RF_channel) { return udp_gnss_rx_source_; diff --git a/src/algorithms/signal_source/adapters/custom_udp_signal_source.h b/src/algorithms/signal_source/adapters/custom_udp_signal_source.h index 9bed9ae32..fcd42071d 100644 --- a/src/algorithms/signal_source/adapters/custom_udp_signal_source.h +++ b/src/algorithms/signal_source/adapters/custom_udp_signal_source.h @@ -24,7 +24,7 @@ * 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 . + * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- */ diff --git a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt index b35caa37d..fdeb71c47 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt @@ -18,35 +18,34 @@ if(ENABLE_RAW_UDP) - # - Try to find libpcap include dirs and libraries - # - # Usage of this module as follows: - # - # find_package(PCAP) - # - # Variables used by this module, they can change the default behaviour and need - # to be set before calling find_package: - # - # PCAP_ROOT_DIR Set this variable to the root installation of - # libpcap if the module has problems finding the - # proper installation path. - # - # Variables defined by this module: - # - # PCAP_FOUND System has libpcap, include and library dirs found - # PCAP_INCLUDE_DIR The libpcap include directories. - # PCAP_LIBRARY The libpcap library (possibly includes a thread - # library e.g. required by pf_ring's libpcap) - # HAVE_PF_RING If a found version of libpcap supports PF_RING - find_package(PCAP) - if(NOT PCAP_FOUND) - message(FATAL_ERROR "PCAP required to compile custom UDP packet sample source (ENABLE_RAW_UDP)") - endif() - get_filename_component(PCAP_LIBRARY_DIRS ${PCAP_LIBRARY} DIRECTORY CACHE) + # - Try to find libpcap include dirs and libraries + # + # Usage of this module as follows: + # + # find_package(PCAP) + # + # Variables used by this module, they can change the default behaviour and need + # to be set before calling find_package: + # + # PCAP_ROOT_DIR Set this variable to the root installation of + # libpcap if the module has problems finding the + # proper installation path. + # + # Variables defined by this module: + # + # PCAP_FOUND System has libpcap, include and library dirs found + # PCAP_INCLUDE_DIR The libpcap include directories. + # PCAP_LIBRARY The libpcap library (possibly includes a thread + # library e.g. required by pf_ring's libpcap) + # HAVE_PF_RING If a found version of libpcap supports PF_RING + find_package(PCAP) + if(NOT PCAP_FOUND) + message(FATAL_ERROR "PCAP required to compile custom UDP packet sample source (ENABLE_RAW_UDP)") + endif() + get_filename_component(PCAP_LIBRARY_DIRS ${PCAP_LIBRARY} DIRECTORY CACHE) set(OPT_LIBRARIES ${OPT_LIBRARIES} ${PCAP_LIBRARIES}) set(OPT_DRIVER_INCLUDE_DIRS ${OPT_DRIVER_INCLUDE_DIRS} ${PCAP_INCLUDE_DIRS}) set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} gr_complex_ip_packet_source.cc) - endif(ENABLE_RAW_UDP) set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES diff --git a/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.cc b/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.cc index 038ea6fbe..8da6d4a5d 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.cc @@ -24,17 +24,16 @@ * 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 . + * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- */ -#include #include "gr_complex_ip_packet_source.h" +#include -#include -#include +//#include #define FIFO_SIZE 1472000 diff --git a/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.h b/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.h index 7b8d9f58e..0661e0911 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.h +++ b/src/algorithms/signal_source/gnuradio_blocks/gr_complex_ip_packet_source.h @@ -24,7 +24,7 @@ * 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 . + * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- */ @@ -40,6 +40,7 @@ #include #include #include +#include #include class gr_complex_ip_packet_source : virtual public gr::sync_block @@ -77,12 +78,9 @@ private: void demux_samples(gr_vector_void_star output_items, int num_samples_readed); void my_pcap_loop_thread(pcap_t *pcap_handle); - void pcap_callback(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *packet); - static void static_pcap_callback(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *packet); - public: typedef boost::shared_ptr sptr; static sptr make(std::string src_device, @@ -108,9 +106,9 @@ public: gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); - //Called by gnuradio to enable drivers, etc for i/o devices. + // Called by gnuradio to enable drivers, etc for i/o devices. bool start(); - //Called by gnuradio to disable drivers, etc for i/o devices. + // Called by gnuradio to disable drivers, etc for i/o devices. bool stop(); }; diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.cc b/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.cc index ba9f9365e..b3a1d61f7 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.cc @@ -7,7 +7,7 @@ * \author Javier Arribas jarribas (at) cttc.es * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -25,7 +25,7 @@ * 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 . + * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- */ diff --git a/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.h b/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.h index ccfe699b5..0a48bcb5f 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.h +++ b/src/algorithms/signal_source/gnuradio_blocks/unpack_byte_4bit_samples.h @@ -7,7 +7,7 @@ * \author Javier Arribas jarribas (at) cttc.es * ------------------------------------------------------------------------- * - * Copyright (C) 2010-2015 (see AUTHORS file for a list of contributors) + * Copyright (C) 2010-2018 (see AUTHORS file for a list of contributors) * * GNSS-SDR is a software defined Global Navigation * Satellite Systems receiver @@ -25,7 +25,7 @@ * 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 . + * along with GNSS-SDR. If not, see . * * ------------------------------------------------------------------------- */