mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-30 23:03:05 +00:00 
			
		
		
		
	Merge branch 'lenhart-fifo_source' into next
This commit is contained in:
		
							
								
								
									
										1
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								AUTHORS
									
									
									
									
									
								
							| @@ -54,6 +54,7 @@ Gerald LaMountain       gerald@gece.neu.edu              Contributor | ||||
| Jim Melton              jim.melton@sncorp.com            Contributor | ||||
| Josh Schindehette       jschindehette@geontech.com       Contributor | ||||
| Leonardo Tonetto        tonetto.dev@gmail.com            Contributor | ||||
| Malte Lenhart           malte.lenhart@mailbox.org        Contributor | ||||
| Mara Branzanti          mara.branzanti@gmail.com         Contributor | ||||
| Marc Molina             marc.molina.pena@gmail.com       Contributor | ||||
| Marc Sales              marcsales92@gmail.com            Contributor | ||||
|   | ||||
							
								
								
									
										56
									
								
								conf/gnss-sdr_GPS_L1_fifo.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								conf/gnss-sdr_GPS_L1_fifo.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| ; This is a GNSS-SDR configuration file | ||||
| ; The configuration API is described at https://gnss-sdr.org/docs/sp-blocks/ | ||||
| ; SPDX-License-Identifier: GPL-3.0-or-later | ||||
| ; SPDX-FileCopyrightText: (C) 2010-2021  (see AUTHORS file for a list of contributors) | ||||
|  | ||||
| ; You can define your own receiver and invoke it by doing | ||||
| ; gnss-sdr --config_file=my_GNSS_SDR_configuration.conf | ||||
| ; | ||||
|  | ||||
| [GNSS-SDR] | ||||
|  | ||||
| ;######### GLOBAL OPTIONS ################## | ||||
| GNSS-SDR.internal_fs_sps=25000000 | ||||
|  | ||||
| ;######### SIGNAL_SOURCE CONFIG ############ | ||||
| SignalSource.implementation=Fifo_Signal_Source | ||||
| SignalSource.filename=fifo.fifo	; example usage: mkfifo fifo.fifo && cat path_to.bin >> fifo.fifo | ||||
| SignalSource.sample_type=ishort;	; sample representation in fifo stream - will always output gr_complex | ||||
| SignalSource.dump=false | ||||
| ;SignalSource.dump_filename=dump | ||||
|  | ||||
| ;######### SIGNAL_CONDITIONER CONFIG ############ | ||||
| SignalConditioner.implementation=Pass_Through | ||||
|  | ||||
| ;######### CHANNELS GLOBAL CONFIG ############ | ||||
| Channels_1C.count=8 | ||||
| Channels.in_acquisition=1 | ||||
| Channel.signal=1C | ||||
|  | ||||
| ;######### ACQUISITION GLOBAL CONFIG ############ | ||||
| Acquisition_1C.implementation=GPS_L1_CA_PCPS_Acquisition | ||||
| Acquisition_1C.item_type=gr_complex | ||||
| Acquisition_1C.pfa=0.01 | ||||
| Acquisition_1C.doppler_max=10000 | ||||
| Acquisition_1C.doppler_step=250 | ||||
|  | ||||
| ;######### TRACKING GLOBAL CONFIG ############ | ||||
| Tracking_1C.implementation=GPS_L1_CA_DLL_PLL_Tracking | ||||
| Tracking_1C.item_type=gr_complex | ||||
| Tracking_1C.pll_bw_hz=40.0; | ||||
| Tracking_1C.dll_bw_hz=4.0; | ||||
|  | ||||
| ;######### TELEMETRY DECODER GPS CONFIG ############ | ||||
| TelemetryDecoder_1C.implementation=GPS_L1_CA_Telemetry_Decoder | ||||
|  | ||||
| ;######### OBSERVABLES CONFIG ############ | ||||
| Observables.implementation=Hybrid_Observables | ||||
|  | ||||
| ;######### PVT CONFIG ############ | ||||
| PVT.implementation=RTKLIB_PVT | ||||
| PVT.positioning_mode=Single | ||||
| PVT.output_rate_ms=100 | ||||
| PVT.display_rate_ms=500 | ||||
| PVT.iono_model=Broadcast | ||||
| PVT.trop_model=Saastamoinen | ||||
| PVT.output_path=./files | ||||
| @@ -62,6 +62,11 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc | ||||
|  | ||||
| ### Improvements in Usability: | ||||
|  | ||||
| - Added a new `Fifo_Signal_Source` implementation that allows using a | ||||
|   [Unix FIFO](https://en.wikipedia.org/wiki/Named_pipe) as a signal source, thus | ||||
|   allowing to multiplex signal streams outside of `gnss-sdr`, letting another | ||||
|   program to hold access to the receiver, or allowing signal sources that are | ||||
|   not supported by `gnss-sdr` but can dump the signal to a FIFO. | ||||
| - Avoid segmentation faults in the flow graph connection and/or starting due to | ||||
|   some common inconsistencies in the configuration file. | ||||
| - Provide hints to the user in case of failed flow graph connection due to | ||||
|   | ||||
| @@ -272,7 +272,7 @@ void signal_generator_c::generate_codes() | ||||
|                                 { | ||||
|                                     for (unsigned int i = 0; i < vector_length_; i++) | ||||
|                                         { | ||||
|                                             sampled_code_pilot_[sat][i] *= sqrt(std::pow(10.0F, CN0_dB_[sat] / 10.0F) / BW_BB_ / 2.0F); | ||||
|                                             sampled_code_pilot_[sat][i] *= std::sqrt(std::pow(10.0F, CN0_dB_[sat] / 10.0F) / BW_BB_ / 2.0F); | ||||
|                                         } | ||||
|                                 } | ||||
|                         } | ||||
| @@ -313,7 +313,7 @@ void signal_generator_c::generate_codes() | ||||
|                                 { | ||||
|                                     for (unsigned int i = 0; i < vector_length_; i++) | ||||
|                                         { | ||||
|                                             sampled_code_pilot_[sat][i] *= sqrt(std::pow(10.0F, CN0_dB_[sat] / 10.0F) / BW_BB_ / 2.0F); | ||||
|                                             sampled_code_pilot_[sat][i] *= std::sqrt(std::pow(10.0F, CN0_dB_[sat] / 10.0F) / BW_BB_ / 2.0F); | ||||
|                                         } | ||||
|                                 } | ||||
|                         } | ||||
|   | ||||
| @@ -95,6 +95,7 @@ set(SIGNAL_SOURCE_ADAPTER_SOURCES | ||||
|     signal_source_base.cc | ||||
|     file_source_base.cc | ||||
|     file_signal_source.cc | ||||
|     fifo_signal_source.cc | ||||
|     multichannel_file_signal_source.cc | ||||
|     gen_signal_source.cc | ||||
|     nsr_file_signal_source.cc | ||||
| @@ -111,6 +112,7 @@ set(SIGNAL_SOURCE_ADAPTER_HEADERS | ||||
|     signal_source_base.h | ||||
|     file_source_base.h | ||||
|     file_signal_source.h | ||||
|     fifo_signal_source.h | ||||
|     multichannel_file_signal_source.h | ||||
|     gen_signal_source.h | ||||
|     nsr_file_signal_source.h | ||||
|   | ||||
							
								
								
									
										93
									
								
								src/algorithms/signal_source/adapters/fifo_signal_source.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								src/algorithms/signal_source/adapters/fifo_signal_source.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| /*! | ||||
|  * \file fifo_signal_source.cc | ||||
|  * | ||||
|  * \brief Implementation of the class for retrieving samples through a Unix FIFO | ||||
|  * \author Malte Lenhart, 2021. malte.lenhart(at)mailbox.org | ||||
|  * | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  * | ||||
|  * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * Copyright (C) 2010-2021  (see AUTHORS file for a list of contributors) | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later | ||||
|  * | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include "fifo_signal_source.h" | ||||
| #include "configuration_interface.h" | ||||
| #include "fifo_reader.h" | ||||
| #include "gnss_sdr_string_literals.h" | ||||
| #include <glog/logging.h> | ||||
| #include <gnuradio/blocks/file_sink.h> | ||||
| #include <gnuradio/blocks/file_source.h> | ||||
|  | ||||
|  | ||||
| using namespace std::string_literals; | ||||
|  | ||||
| FifoSignalSource::FifoSignalSource(ConfigurationInterface const* configuration, | ||||
|     std::string const& role, unsigned int in_streams, unsigned int out_streams, | ||||
|     [[maybe_unused]] Concurrent_Queue<pmt::pmt_t>* queue) | ||||
|     : SignalSourceBase(configuration, role, "Fifo_Signal_Source"s), | ||||
|       item_size_(sizeof(gr_complex)),  // currenty output item size is always gr_complex | ||||
|       fifo_reader_(FifoReader::make(configuration->property(role + ".filename"s, "../data/example_capture.dat"s), | ||||
|           configuration->property(role + ".sample_type"s, "ishort"s))), | ||||
|       dump_(configuration->property(role + ".dump", false)), | ||||
|       dump_filename_(configuration->property(role + ".dump_filename"s, "./data/signal_source.dat"s)) | ||||
| { | ||||
|     if (dump_) | ||||
|         { | ||||
|             DLOG(INFO) << "Dumping output into file " << (dump_filename_ + ".bin"s); | ||||
|             file_sink_ = gr::blocks::file_sink::make(item_size_, (dump_filename_ + ".bin").c_str()); | ||||
|         } | ||||
|  | ||||
|     if (in_streams > 0) | ||||
|         { | ||||
|             LOG(ERROR) << "A signal source does not have an input stream"; | ||||
|         } | ||||
|     if (out_streams > 1) | ||||
|         { | ||||
|             LOG(ERROR) << "This implementation only supports one output stream"; | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| void FifoSignalSource::connect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     // here we could add a throttle as done in the file_source_base if required | ||||
|     if (dump_) | ||||
|         { | ||||
|             top_block->connect(fifo_reader_, 0, file_sink_, 0); | ||||
|             DLOG(INFO) << "connected source to file sink"; | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| void FifoSignalSource::disconnect(gr::top_block_sptr top_block) | ||||
| { | ||||
|     if (dump_) | ||||
|         { | ||||
|             top_block->disconnect(fifo_reader_, 0, file_sink_, 0); | ||||
|             DLOG(INFO) << "disconnected source from file sink"; | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| size_t FifoSignalSource::item_size() | ||||
| { | ||||
|     return item_size_; | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr FifoSignalSource::get_left_block() | ||||
| { | ||||
|     LOG(WARNING) << "Left block of a signal source should not be retrieved"; | ||||
|     return gr::blocks::file_source::sptr(); | ||||
| } | ||||
|  | ||||
|  | ||||
| gr::basic_block_sptr FifoSignalSource::get_right_block() | ||||
| { | ||||
|     return fifo_reader_; | ||||
| } | ||||
							
								
								
									
										79
									
								
								src/algorithms/signal_source/adapters/fifo_signal_source.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/algorithms/signal_source/adapters/fifo_signal_source.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| /*! | ||||
|  * \file fifo_signal_source.h | ||||
|  * | ||||
|  * \brief Header file of the class for retrieving samples through a Unix FIFO | ||||
|  * \author Malte Lenhart, 2021. malte.lenhart(at)mailbox.org | ||||
|  * | ||||
|  * | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  * | ||||
|  * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * Copyright (C) 2010-2021  (see AUTHORS file for a list of contributors) | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later | ||||
|  * | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #ifndef GNSS_SDR_FIFO_SIGNAL_SOURCE_H | ||||
| #define GNSS_SDR_FIFO_SIGNAL_SOURCE_H | ||||
|  | ||||
| #include "concurrent_queue.h" | ||||
| #include "signal_source_base.h" | ||||
| #include <pmt/pmt.h> | ||||
|  | ||||
|  | ||||
| /** \addtogroup Signal_Source | ||||
|  * \{ */ | ||||
| /** \addtogroup Signal_Source_adapters | ||||
|  * \{ */ | ||||
|  | ||||
| // forward declaration to avoid include in header | ||||
| class ConfigurationInterface; | ||||
|  | ||||
| //! \brief Class that reads a sample stream from a Unix FIFO. | ||||
| //! | ||||
| //! This class supports the following properties: | ||||
| //! | ||||
| //!   .filename - the path to the input file | ||||
| //!             - may be overridden by the -signal_source or -s command-line arguments | ||||
| //! | ||||
| //!   .sample_type - data type read out from the FIFO. default ishort ; | ||||
| //!                - note: not output format. that is always gr_complex | ||||
| //! | ||||
| //!   .dump     - whether to archive input data | ||||
| //! | ||||
| //!   .dump_filename - if dumping, path to file for output | ||||
| //! | ||||
| class FifoSignalSource : public SignalSourceBase | ||||
| { | ||||
| public: | ||||
|     FifoSignalSource(const ConfigurationInterface* configuration, const std::string& role, | ||||
|         unsigned int in_streams, unsigned int out_streams, | ||||
|         Concurrent_Queue<pmt::pmt_t>* queue); | ||||
|  | ||||
|     ~FifoSignalSource() = default; | ||||
|  | ||||
|     //! override methods from GNSSBlockInterface | ||||
|     void connect(gr::top_block_sptr top_block) override; | ||||
|     void disconnect(gr::top_block_sptr top_block) override; | ||||
|     size_t item_size() override; | ||||
|     gr::basic_block_sptr get_left_block() override; | ||||
|     gr::basic_block_sptr get_right_block() override; | ||||
|  | ||||
| protected: | ||||
| private: | ||||
|     //! output size - always gr_complex | ||||
|     const size_t item_size_; | ||||
|     //! internal fifo_reader_ class acts as signal source | ||||
|     const gnss_shared_ptr<gr::block> fifo_reader_; | ||||
|  | ||||
|     gnss_shared_ptr<gr::block> file_sink_; | ||||
|     const bool dump_; | ||||
|     const std::string dump_filename_; | ||||
| }; | ||||
|  | ||||
| /** \} */ | ||||
| /** \} */ | ||||
| #endif  // GNSS_SDR_FIFO_SIGNAL_SOURCE_H | ||||
| @@ -261,7 +261,7 @@ uint64_t FileSourceBase::samples() const | ||||
|  | ||||
| std::tuple<size_t, bool> FileSourceBase::itemTypeToSize() | ||||
| { | ||||
|     auto is_complex_t = false; | ||||
|     auto is_interleaved = false; | ||||
|     auto item_size = size_t(0); | ||||
|  | ||||
|     if (item_type_ == "gr_complex") | ||||
| @@ -279,7 +279,7 @@ std::tuple<size_t, bool> FileSourceBase::itemTypeToSize() | ||||
|     else if (item_type_ == "ishort") | ||||
|         { | ||||
|             item_size = sizeof(int16_t); | ||||
|             is_complex_t = true; | ||||
|             is_interleaved = true; | ||||
|         } | ||||
|     else if (item_type_ == "byte") | ||||
|         { | ||||
| @@ -288,7 +288,7 @@ std::tuple<size_t, bool> FileSourceBase::itemTypeToSize() | ||||
|     else if (item_type_ == "ibyte") | ||||
|         { | ||||
|             item_size = sizeof(int8_t); | ||||
|             is_complex_t = true; | ||||
|             is_interleaved = true; | ||||
|         } | ||||
|     else | ||||
|         { | ||||
| @@ -297,7 +297,7 @@ std::tuple<size_t, bool> FileSourceBase::itemTypeToSize() | ||||
|             item_size = sizeof(gr_complex); | ||||
|         } | ||||
|  | ||||
|     return std::make_tuple(item_size, is_complex_t); | ||||
|     return std::make_tuple(item_size, is_interleaved); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -338,7 +338,7 @@ size_t FileSourceBase::samplesToSkip() const | ||||
|  | ||||
| size_t FileSourceBase::computeSamplesInFile() const | ||||
| { | ||||
|     auto n_samples = size_t(samples()); | ||||
|     auto n_samples = static_cast<size_t>(samples()); | ||||
|  | ||||
|     // if configured with 0 samples (read the whole file), figure out how many samples are in the file, and go from there | ||||
|     if (n_samples == 0) | ||||
| @@ -467,7 +467,7 @@ gnss_shared_ptr<gr::block> FileSourceBase::create_valve() | ||||
|     if (samples() > 0) | ||||
|         { | ||||
|             // if a number of samples is specified, honor it by creating a valve | ||||
|             // In practice, this is always true | ||||
|             // in practice, this is always true | ||||
|             valve_ = gnss_sdr_make_valve(source_item_size(), samples(), queue_); | ||||
|             DLOG(INFO) << "valve(" << valve_->unique_id() << ")"; | ||||
|  | ||||
| @@ -499,7 +499,7 @@ void FileSourceBase::create_valve_hook() {} | ||||
| void FileSourceBase::create_sink_hook() {} | ||||
|  | ||||
|  | ||||
| // Subclass hooks for connection/disconnectino | ||||
| // Subclass hooks for connection/disconnection | ||||
| void FileSourceBase::pre_connect_hook(gr::top_block_sptr top_block [[maybe_unused]]) {}      // NOLINT(performance-unnecessary-value-param) | ||||
| void FileSourceBase::post_connect_hook(gr::top_block_sptr top_block [[maybe_unused]]) {}     // NOLINT(performance-unnecessary-value-param) | ||||
| void FileSourceBase::pre_disconnect_hook(gr::top_block_sptr top_block [[maybe_unused]]) {}   // NOLINT(performance-unnecessary-value-param) | ||||
|   | ||||
| @@ -14,6 +14,7 @@ endif() | ||||
|  | ||||
|  | ||||
| set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES | ||||
|     fifo_reader.cc | ||||
|     unpack_byte_2bit_samples.cc | ||||
|     unpack_byte_2bit_cpx_samples.cc | ||||
|     unpack_byte_4bit_samples.cc | ||||
| @@ -27,6 +28,7 @@ set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES | ||||
|  | ||||
|  | ||||
| set(SIGNAL_SOURCE_GR_BLOCKS_HEADERS | ||||
|     fifo_reader.h | ||||
|     unpack_byte_2bit_samples.h | ||||
|     unpack_byte_2bit_cpx_samples.h | ||||
|     unpack_byte_4bit_samples.h | ||||
|   | ||||
							
								
								
									
										114
									
								
								src/algorithms/signal_source/gnuradio_blocks/fifo_reader.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/algorithms/signal_source/gnuradio_blocks/fifo_reader.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| /*! | ||||
|  * \file fifo_reader.cc | ||||
|  * | ||||
|  * \brief Implementation of the class to retrieve samples from an existing Unix FIFO | ||||
|  * \author Malte Lenhart, 2021. malte.lenhart(at)mailbox.org | ||||
|  * | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  * | ||||
|  * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * Copyright (C) 2010-2020  (see AUTHORS file for a list of contributors) | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later | ||||
|  * | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #include "fifo_reader.h" | ||||
| #include <glog/logging.h> | ||||
|  | ||||
| // initial construction; pass to private constructor | ||||
| FifoReader::sptr FifoReader::make(const std::string &file_name, const std::string &sample_type) | ||||
| { | ||||
|     return gnuradio::get_initial_sptr(new FifoReader(file_name, sample_type)); | ||||
| } | ||||
|  | ||||
| // private constructor called by ::make | ||||
| FifoReader::FifoReader(const std::string &file_name, const std::string &sample_type) | ||||
|     : gr::sync_block("fifo_reader", | ||||
|           gr::io_signature::make(0, 0, 0),                    // no input | ||||
|           gr::io_signature::make(1, 1, sizeof(gr_complex))),  // <+MIN_OUT+>, <+MAX_OUT+>, sizeof(<+OTYPE+>) | ||||
|       file_name_(file_name), | ||||
|       sample_type_(sample_type) | ||||
| { | ||||
|     DLOG(INFO) << "Starting FifoReader"; | ||||
| } | ||||
|  | ||||
| bool FifoReader::start() | ||||
| { | ||||
|     fifo_.open(file_name_, std::ios::binary); | ||||
|     if (!fifo_.is_open()) | ||||
|         { | ||||
|             LOG(ERROR) << "Error opening FIFO"; | ||||
|             return false; | ||||
|         } | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| // work loop | ||||
| // taken from here: https://stackoverflow.com/questions/25546619/work-with-fifo-in-c-blocking-read | ||||
| int FifoReader::work(int noutput_items, | ||||
|     __attribute__((unused)) gr_vector_const_void_star &input_items, | ||||
|     gr_vector_void_star &output_items) | ||||
| { | ||||
|     if (output_items.size() > 1) | ||||
|         { | ||||
|             LOG(ERROR) << "FifoReader connected to too many outputs"; | ||||
|         } | ||||
|  | ||||
|     // read samples out | ||||
|     size_t items_retrieved = 0; | ||||
|     if (sample_type_ == "ishort") | ||||
|         { | ||||
|             // ishort == int16_t | ||||
|             items_retrieved = read_interleaved<int16_t>(noutput_items, output_items); | ||||
|         } | ||||
|     else if (sample_type_ == "gr_complex") | ||||
|         { | ||||
|             LOG(WARNING) << sample_type_ << " is not yet tested. Please consider removing this warning if tested successfully"; | ||||
|             items_retrieved = read_gr_complex(noutput_items, output_items); | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             // please see gr_complex_ip_packet_source for inspiration on how to implement other sample types | ||||
|             LOG(ERROR) << sample_type_ << " is unfortunately not yet implemented as sample type"; | ||||
|         } | ||||
|  | ||||
|     // we return varying number of data -> call produce & return flag | ||||
|     produce(0, items_retrieved); | ||||
|     return this->WORK_CALLED_PRODUCE; | ||||
| } | ||||
|  | ||||
| // read gr_complex items from fifo | ||||
| // this fct has duplicate code with the templated read_interleaved fct in header | ||||
| size_t FifoReader::read_gr_complex(int noutput_items, gr_vector_void_star &output_items) | ||||
| { | ||||
|     size_t items_retrieved = 0; | ||||
|     for (int n = 0; n < noutput_items; n++) | ||||
|         { | ||||
|             gr_complex sample; | ||||
|             fifo_.read(reinterpret_cast<char *>(&sample), sizeof(sample)); | ||||
|             if (fifo_.good()) | ||||
|                 { | ||||
|                     static_cast<gr_complex *>(output_items.at(0))[n] = sample; | ||||
|                     items_retrieved++; | ||||
|                 } | ||||
|             else if (fifo_.eof()) | ||||
|                 { | ||||
|                     fifo_.clear(); | ||||
|                     break; | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     fifo_error_output(); | ||||
|                     break; | ||||
|                 } | ||||
|         } | ||||
|     return items_retrieved; | ||||
| } | ||||
|  | ||||
| void FifoReader::fifo_error_output() const | ||||
| { | ||||
|     LOG(ERROR) << "unhandled FIFO event"; | ||||
| } | ||||
							
								
								
									
										99
									
								
								src/algorithms/signal_source/gnuradio_blocks/fifo_reader.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/algorithms/signal_source/gnuradio_blocks/fifo_reader.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| /*! | ||||
|  * \file fifo_reader.h | ||||
|  * | ||||
|  * \brief Header file to retrieve samples from an existing Unix FIFO | ||||
|  * \author Malte Lenhart, 2021. malte.lenhart(at)mailbox.org | ||||
|  * | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  * | ||||
|  * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. | ||||
|  * This file is part of GNSS-SDR. | ||||
|  * | ||||
|  * Copyright (C) 2010-2020  (see AUTHORS file for a list of contributors) | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later | ||||
|  * | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  */ | ||||
|  | ||||
| #ifndef GNSS_SDR_FIFO_READER_H_ | ||||
| #define GNSS_SDR_FIFO_READER_H_ | ||||
|  | ||||
| #include "gnss_block_interface.h" | ||||
| #include <gnuradio/sync_block.h> | ||||
| #include <fstream>  // std::ifstream | ||||
|  | ||||
| /** \addtogroup Signal_Source | ||||
|  * \{ */ | ||||
| /** \addtogroup Signal_Source_gnuradio_blocks | ||||
|  * \{ */ | ||||
| class FifoReader : virtual public gr::sync_block | ||||
| { | ||||
| public: | ||||
|     //! \brief static function to create a class instance | ||||
|     using sptr = gnss_shared_ptr<FifoReader>; | ||||
|     static sptr make(const std::string &file_name, const std::string &sample_type); | ||||
|  | ||||
|     ~FifoReader() = default; | ||||
|  | ||||
|     //! initialize istream resource for FIFO | ||||
|     bool start(); | ||||
|  | ||||
|     // gnu radio work cycle function | ||||
|     int work(int noutput_items, | ||||
|         gr_vector_const_void_star &input_items, | ||||
|         gr_vector_void_star &output_items); | ||||
|  | ||||
| private: | ||||
|     //! \brief Constructor | ||||
|     //! private constructor called by function make | ||||
|     //! (gr handles this with public and private header pair) | ||||
|     FifoReader(const std::string &file_name, const std::string &sample_type); | ||||
|  | ||||
|     size_t read_gr_complex(int noutput_items, gr_vector_void_star &output_items); | ||||
|     //! function to read data out of FIFO which is stored as interleaved I/Q stream. | ||||
|     //! template argument determines sample_type | ||||
|     template <typename Type> | ||||
|     size_t read_interleaved(int noutput_items, gr_vector_void_star &output_items) | ||||
|     { | ||||
|         size_t items_retrieved = 0; | ||||
|         for (int n = 0; n < noutput_items; n++) | ||||
|             { | ||||
|                 // TODO: try if performance increases if we copy larger chunks to vector. | ||||
|                 // how to read from stream: https://en.cppreference.com/w/cpp/io/basic_ifstream | ||||
|                 std::array<char, 4> buffer;  // gr_complex is 32bit = 4*char | ||||
|                 fifo_.read(reinterpret_cast<char *>(&buffer[0]), buffer.size()); | ||||
|                 if (fifo_.good()) | ||||
|                     { | ||||
|                         Type real; | ||||
|                         Type imag; | ||||
|                         memcpy(&real, &buffer[0], sizeof(real)); | ||||
|                         memcpy(&imag, &buffer[2], sizeof(imag)); | ||||
|                         static_cast<gr_complex *>(output_items.at(0))[n] = gr_complex(real, imag); | ||||
|                         items_retrieved++; | ||||
|                     } | ||||
|                 else if (fifo_.eof()) | ||||
|                     { | ||||
|                         fifo_.clear(); | ||||
|                         break; | ||||
|                     } | ||||
|                 else | ||||
|                     { | ||||
|                         fifo_error_output(); | ||||
|                         break; | ||||
|                     } | ||||
|             } | ||||
|         return items_retrieved; | ||||
|     } | ||||
|  | ||||
|     //! this function moves logging output from this header into the source file | ||||
|     //! thereby eliminating the need to include glog/logging.h in this header | ||||
|     void fifo_error_output() const; | ||||
|  | ||||
|     const std::string file_name_; | ||||
|     const std::string sample_type_; | ||||
|     std::ifstream fifo_; | ||||
| }; | ||||
|  | ||||
| /** \} */ | ||||
| /** \} */ | ||||
| #endif /* GNSS_SDR_FIFO_READER_H_ */ | ||||
| @@ -104,6 +104,7 @@ Gr_Complex_Ip_Packet_Source::Gr_Complex_Ip_Packet_Source(std::string src_device, | ||||
|           gr::io_signature::make(1, 4, item_size))  // 1 to 4 baseband complex channels | ||||
| { | ||||
|     std::cout << "Start Ethernet packet capture\n"; | ||||
|     std::cout << "Overflow events will be indicated by o's\n"; | ||||
|  | ||||
|     d_n_baseband_channels = n_baseband_channels; | ||||
|     if (wire_sample_type == "cbyte") | ||||
| @@ -121,6 +122,11 @@ Gr_Complex_Ip_Packet_Source::Gr_Complex_Ip_Packet_Source(std::string src_device, | ||||
|             d_wire_sample_type = 3; | ||||
|             d_bytes_per_sample = d_n_baseband_channels * 8; | ||||
|         } | ||||
|     else if (wire_sample_type == "ishort") | ||||
|         { | ||||
|             d_wire_sample_type = 4; | ||||
|             d_bytes_per_sample = d_n_baseband_channels * 4; | ||||
|         } | ||||
|     else | ||||
|         { | ||||
|             std::cout << "Unknown wire sample type\n"; | ||||
| @@ -307,7 +313,7 @@ void Gr_Complex_Ip_Packet_Source::pcap_callback(__attribute__((unused)) u_char * | ||||
|                     else | ||||
|                         { | ||||
|                             // notify overflow | ||||
|                             std::cout << "O" << std::flush; | ||||
|                             std::cout << "o" << std::flush; | ||||
|                         } | ||||
|                 } | ||||
|         } | ||||
| @@ -397,6 +403,25 @@ void Gr_Complex_Ip_Packet_Source::demux_samples(const gr_vector_void_star &outpu | ||||
|                                 } | ||||
|                         } | ||||
|                     break; | ||||
|                 case 4:  // interleaved short samples | ||||
|                     for (const auto &output_item : output_items) | ||||
|                         { | ||||
|                             int16_t real; | ||||
|                             int16_t imag; | ||||
|                             memcpy(&real, &fifo_buff[fifo_read_ptr], sizeof(real)); | ||||
|                             fifo_read_ptr += 2;  // two bytes in short | ||||
|                             memcpy(&imag, &fifo_buff[fifo_read_ptr], sizeof(imag)); | ||||
|                             fifo_read_ptr += 2;  // two bytes in short | ||||
|                             if (d_IQ_swap) | ||||
|                                 { | ||||
|                                     static_cast<gr_complex *>(output_item)[n] = gr_complex(real, imag); | ||||
|                                 } | ||||
|                             else | ||||
|                                 { | ||||
|                                     static_cast<gr_complex *>(output_item)[n] = gr_complex(imag, real); | ||||
|                                 } | ||||
|                         } | ||||
|                     break; | ||||
|                 default: | ||||
|                     std::cout << "Unknown wire sample type\n"; | ||||
|                     exit(0); | ||||
| @@ -422,16 +447,12 @@ int Gr_Complex_Ip_Packet_Source::work(int noutput_items, | ||||
|  | ||||
|     if (output_items.size() > static_cast<uint64_t>(d_n_baseband_channels)) | ||||
|         { | ||||
|             std::cout << "Configuration error: more baseband channels connected than the available in the UDP source\n"; | ||||
|             std::cout << "Configuration error: more baseband channels connected than 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 | ||||
|         case 2:  // complex 4 bits samples | ||||
|         case 3:  // complex float samples | ||||
|  | ||||
|     bytes_requested = noutput_items * d_bytes_per_sample; | ||||
|     if (bytes_requested < fifo_items) | ||||
|         { | ||||
| @@ -441,18 +462,6 @@ int Gr_Complex_Ip_Packet_Source::work(int noutput_items, | ||||
|         { | ||||
|             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 | ||||
|   | ||||
| @@ -37,6 +37,7 @@ | ||||
| #include "channel.h" | ||||
| #include "configuration_interface.h" | ||||
| #include "direct_resampler_conditioner.h" | ||||
| #include "fifo_signal_source.h" | ||||
| #include "file_signal_source.h" | ||||
| #include "fir_filter.h" | ||||
| #include "freq_xlating_fir_filter.h" | ||||
| @@ -647,6 +648,12 @@ std::unique_ptr<GNSSBlockInterface> GNSSBlockFactory::GetBlock( | ||||
|                 } | ||||
|  | ||||
|             // SIGNAL SOURCES ---------------------------------------------------------- | ||||
|             else if (implementation == "Fifo_Signal_Source") | ||||
|                 { | ||||
|                     std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<FifoSignalSource>(configuration, role, in_streams, | ||||
|                         out_streams, queue); | ||||
|                     block = std::move(block_); | ||||
|                 } | ||||
|             else if (implementation == "File_Signal_Source") | ||||
|                 { | ||||
|                     std::unique_ptr<GNSSBlockInterface> block_ = std::make_unique<FileSignalSource>(configuration, role, in_streams, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Carles Fernandez
					Carles Fernandez