From dbd94e005d5b0352874b5918a16772dfc54e54b1 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Mon, 24 Jun 2024 04:15:33 +0200 Subject: [PATCH 01/34] Fix CMakeLists header file list in signal source libs Header file paths were being appended to the source files list. This is not that important since, in general, you don't need to add the header files to the cmake target. --- src/algorithms/signal_source/libs/CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index 3506dc4f7..fd5c664d5 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -9,7 +9,7 @@ set(OPT_SIGNAL_SOURCE_LIB_SOURCES "") set(OPT_SIGNAL_SOURCE_LIB_HEADERS "") if(ENABLE_FMCOMMS2 OR ENABLE_AD9361) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad9361_manager.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad9361_manager.h) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ad9361_manager.h) endif() if(ENABLE_MAX2771) @@ -36,12 +36,12 @@ endif() if(ENABLE_PLUTOSDR) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad936x_iio_samples.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad936x_iio_samples.h) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ad936x_iio_samples.h) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad936x_iio_custom.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad936x_iio_custom.h) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} pps_samplestamp.h) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ad936x_iio_custom.h) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} pps_samplestamp.h) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ppstcprx.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ppstcprx.h) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ppstcprx.h) endif() From 1f3047c67acd926146746b6e80b8580066f4c23e Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Mon, 24 Jun 2024 04:17:40 +0200 Subject: [PATCH 02/34] Added ION GNSS SDR Metadata Standard signal source --- CMakeLists.txt | 15 + .../signal_source/adapters/CMakeLists.txt | 2 + .../adapters/ion_gnss_ms_signal_source.cc | 119 +++++++ .../adapters/ion_gnss_ms_signal_source.h | 78 +++++ .../signal_source/libs/CMakeLists.txt | 11 + .../libs/ion_gnss_sdr_metadata_standard.cc | 304 +++++++++++++++++ .../libs/ion_gnss_sdr_metadata_standard.h | 319 ++++++++++++++++++ src/core/receiver/gnss_block_factory.cc | 7 + 8 files changed, 855 insertions(+) create mode 100644 src/algorithms/signal_source/adapters/ion_gnss_ms_signal_source.cc create mode 100644 src/algorithms/signal_source/adapters/ion_gnss_ms_signal_source.h create mode 100644 src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc create mode 100644 src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ffa66cf5b..0bb716ad9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,8 @@ option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal option(ENABLE_ZMQ "Enable GNU Radio ZeroMQ Messaging, requires gr-zeromq" ON) +option(ENABLE_ION "Enable ION GNSS-SDR Metadata Standard signal source" ON) + # Performance analysis tools option(ENABLE_GPERFTOOLS "Enable linking to Gperftools libraries (tcmalloc and profiler)" OFF) @@ -1422,6 +1424,19 @@ else() endif() +################################################################################ +# ION GNSS-SDR Metadata Standard +################################################################################ +include(FetchContent) +FetchContent_Declare( + gnss_metadata_standard + GIT_REPOSITORY https://github.com/IonMetadataWorkingGroup/GNSS-Metadata-Standard + GIT_TAG master + SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/gnss-metadata-standard + CMAKE_ARGS -DABSL_PROPAGATE_CXX_STD=ON -ABSL_BUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/gnss-metadata-standard ${ABSEIL_TOOLCHAIN_FILE} + BINARY_DIR ${GNSSSDR_BINARY_DIR}/gnss-metadata-standard +) +FetchContent_MakeAvailable(gnss_metadata_standard) ################################################################################ # Abseil C++ - https://abseil.io/docs/cpp/ diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index 0aa745101..54d577c53 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -119,6 +119,7 @@ set(SIGNAL_SOURCE_ADAPTER_SOURCES two_bit_packed_file_signal_source.cc four_bit_cpx_file_signal_source.cc file_timestamp_signal_source.cc + ion_gnss_ms_signal_source.cc ${OPT_DRIVER_SOURCES} ) @@ -138,6 +139,7 @@ set(SIGNAL_SOURCE_ADAPTER_HEADERS two_bit_packed_file_signal_source.h four_bit_cpx_file_signal_source.h file_timestamp_signal_source.h + ion_gnss_ms_signal_source.h ${OPT_DRIVER_HEADERS} ) diff --git a/src/algorithms/signal_source/adapters/ion_gnss_ms_signal_source.cc b/src/algorithms/signal_source/adapters/ion_gnss_ms_signal_source.cc new file mode 100644 index 000000000..fe81e4556 --- /dev/null +++ b/src/algorithms/signal_source/adapters/ion_gnss_ms_signal_source.cc @@ -0,0 +1,119 @@ +/*! + * \file file_timestamp_signal_source.cc + * \brief This class reads samples stored in a file and generate stream tags + * with its timestamp information stored in separated file + * \author Javier Arribas, jarribas(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * 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 "ion_gnss_ms_signal_source.h" +#include "gnss_sdr_flags.h" +#include "gnss_sdr_string_literals.h" +#include +#include +#include + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +using namespace std::string_literals; + +std::vector parse_comma_list(const std::string& str) +{ + std::vector list{}; + std::size_t prev_comma_at{0}; + + while (prev_comma_at < str.size()) + { + std::size_t comma_at = str.find_first_of(',', prev_comma_at); + if (comma_at == std::string::npos) + { + comma_at = str.size(); + } + list.emplace_back(str.substr(prev_comma_at, (comma_at - prev_comma_at))); + prev_comma_at = comma_at + 1; + } + + return list; +} + +IONMetadataStandardSignalSource::IONMetadataStandardSignalSource(const ConfigurationInterface* configuration, + const std::string& role, + unsigned int in_streams, + unsigned int out_streams, + Concurrent_Queue* queue) + : SignalSourceBase(configuration, role, "ION_Metadata_Standard_Signal_Source"s), + metadata_file_(configuration->property(role + ".metadata_filename"s, "../data/example_capture_metadata.sdrx"s)), + stream_ids_(parse_comma_list(configuration->property(role + ".streams"s, ""s))), + metadata_(metadata_file_), + timestamp_clock_offset_ms_(configuration->property(role + ".timestamp_clock_offset_ms"s, 0.0)) +{ + if (in_streams > 0) + { + LOG(ERROR) << "A signal source does not have an input stream"; + } + + sources_ = metadata_.make_stream_sources(stream_ids_); + + for (const auto& source : sources_) + { + for (int i = 0; i < source->output_stream_count(); ++i) + { + copy_blocks_.push_back(gr::blocks::copy::make(source->output_stream_item_size(i))); + } + } +} + + +void IONMetadataStandardSignalSource::connect(gr::top_block_sptr top_block) +{ + std::size_t cumulative_index = 0; + for (const auto& source : sources_) + { + for (int i = 0; i < source->output_stream_count(); ++i, ++cumulative_index) + { + top_block->connect(source, i, copy_blocks_[cumulative_index], 0); + } + } +} + +void IONMetadataStandardSignalSource::disconnect(gr::top_block_sptr top_block) +{ + std::size_t cumulative_index = 0; + for (const auto& source : sources_) + { + for (int i = 0; i < source->output_stream_count(); ++i, ++cumulative_index) + { + top_block->disconnect(source, i, copy_blocks_[cumulative_index], 0); + } + } +} + +gr::basic_block_sptr IONMetadataStandardSignalSource::get_left_block() +{ + LOG(WARNING) << "Trying to get signal source left block."; + // return gr_basic_block_sptr(); + return IONMetadataStdFileSource::sptr(); +} + +gr::basic_block_sptr IONMetadataStandardSignalSource::get_right_block() +{ + return get_right_block(0); +} + +gr::basic_block_sptr IONMetadataStandardSignalSource::get_right_block(int RF_channel) +{ + return copy_blocks_[RF_channel]; +} diff --git a/src/algorithms/signal_source/adapters/ion_gnss_ms_signal_source.h b/src/algorithms/signal_source/adapters/ion_gnss_ms_signal_source.h new file mode 100644 index 000000000..ed84cab5c --- /dev/null +++ b/src/algorithms/signal_source/adapters/ion_gnss_ms_signal_source.h @@ -0,0 +1,78 @@ +/*! + * \file file_timestamp_signal_source.h + * \brief This class reads samples stored in a file and generate stream tags + * with its timestamp information stored in separated file + * \author Javier Arribas, jarribas(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * 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_ION_METADATA_STANDARD_SIGNAL_SOURCE_H +#define GNSS_SDR_ION_METADATA_STANDARD_SIGNAL_SOURCE_H + +#include "configuration_interface.h" +#include "file_source_base.h" +#include "gnss_sdr_timestamp.h" +#include "ion_gnss_sdr_metadata_standard.h" +#include + +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_adapters + * \{ */ + +/*! + * \brief Class that reads signals samples from a file + * and adapts it to a SignalSourceInterface + */ +class IONMetadataStandardSignalSource : public SignalSourceBase +{ +public: + IONMetadataStandardSignalSource(const ConfigurationInterface* configuration, const std::string& role, + unsigned int in_streams, unsigned int out_streams, + Concurrent_Queue* queue); + + ~IONMetadataStandardSignalSource() override = default; + +protected: + // std::tuple itemTypeToSize() override; + // double packetsPerSample() const override; + 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; + + inline size_t item_size() override + { + return (*sources_.begin())->output_stream_item_size(0); + } +private: + std::string metadata_file_; + std::vector stream_ids_; + std::vector sources_; + std::vector> copy_blocks_; + GnssMetadataHandler metadata_; + + gnss_shared_ptr timestamp_block_; + std::string timestamp_file_; + double timestamp_clock_offset_ms_; + + uint32_t in_streams_; + uint32_t out_streams_; +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_ION_METADATA_STANDARD_SIGNAL_SOURCE_H diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index fd5c664d5..f0b2c09fd 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -7,6 +7,7 @@ set(OPT_SIGNAL_SOURCE_LIB_SOURCES "") set(OPT_SIGNAL_SOURCE_LIB_HEADERS "") + if(ENABLE_FMCOMMS2 OR ENABLE_AD9361) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ad9361_manager.cc) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ad9361_manager.h) @@ -44,6 +45,11 @@ if(ENABLE_PLUTOSDR) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ppstcprx.h) endif() +if(ENABLE_ION) + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gnss_sdr_metadata_standard.cc) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gnss_sdr_metadata_standard.h) +endif() + set(SIGNAL_SOURCE_LIB_SOURCES rtl_tcp_commands.cc @@ -139,6 +145,11 @@ if(ENABLE_CLANG_TIDY) endif() endif() +if(ENABLE_ION) + target_include_directories(signal_source_libs PUBLIC ${GNSSSDR_BINARY_DIR}/thirdparty/gnss-metadata-standard/source/api/inc) + target_link_libraries(signal_source_libs PUBLIC api xml) +endif() + set_property(TARGET signal_source_libs APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $ ) diff --git a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc new file mode 100644 index 000000000..c31ec3d1d --- /dev/null +++ b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc @@ -0,0 +1,304 @@ +// +// Created by castle on 6/24/24. +// + +#include "ion_gnss_sdr_metadata_standard.h" + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +GnssMetadataHandler::GnssMetadataHandler(const std::string& metadata_filepath) + : metadata_filepath_(metadata_filepath) +{ + load_metadata(); +} + +const std::string& GnssMetadataHandler::metadata_filepath() const +{ + return metadata_filepath_; +} + +void GnssMetadataHandler::load_metadata() +{ + try + { + GnssMetadata::XmlProcessor xml_proc; + if (!xml_proc.Load(metadata_filepath_.c_str(), false, metadata_)) + { + LOG(ERROR) << "Could not load XML metadata file:"; + } + } + catch (GnssMetadata::ApiException& e) + { + LOG(ERROR) << "API Exception while loadind XML metadata file: " << e.what(); + } + catch (std::exception& e) + { + LOG(ERROR) << "Exception while loading XML metadata file: " << e.what(); + } +} + +std::vector GnssMetadataHandler::make_stream_sources(const std::vector& stream_ids) const +{ + std::vector sources{}; + for (const auto& file : metadata_.Files()) + { + for (const auto& block : file.Lane().Blocks()) + { + for (const auto& chunk : block.Chunks()) + { + for (const auto& lump : chunk.Lumps()) + { + for (const auto& stream : lump.Streams()) + { + if (std::ranges::any_of(stream_ids.begin(), stream_ids.end(), [&](const std::string& it) { + return stream.Id() == it; + })) + { + auto source = gnss_make_shared( + file, + block, + stream_ids); + + sources.push_back(source); + + // This file source will take care of any other matching streams in this block + // We can skip the rest of this block + goto next_block; + } + } + } + } + next_block: + } + } + + return sources; +} + + +IONMetadataStdFileSource::IONMetadataStdFileSource( + const GnssMetadata::File& file, + const GnssMetadata::Block& block, + const std::vector& stream_ids) + : gr::sync_block( + "ion_metadata_standard_source", + gr::io_signature::make(0, 0, 0), + make_output_signature(block)), + file_metadata_(file), + block_metadata_(block) +{ + fd_ = std::fopen(file.Url().Value().c_str(), "rb"); + std::size_t block_offset = file.Offset(); + std::fseek(fd_, file.Offset() + block_offset + block.SizeHeader(), SEEK_SET); + + std::size_t output_stream_offset = 0; + for (const auto& chunk : block.Chunks()) + { + chunk_data_.emplace_back(std::make_shared(chunk, stream_ids, output_stream_offset)); + const std::size_t out_count = chunk_data_.back()->output_stream_count(); + output_stream_offset += out_count; + for (std::size_t i = 0; i < out_count; ++i) + { + output_stream_item_sizes_.push_back(chunk_data_.back()->output_stream_item_size(i)); + } + } + output_stream_count_ = output_stream_offset; +} + +IONMetadataStdFileSource::~IONMetadataStdFileSource() +{ + std::fclose(fd_); +} + +int IONMetadataStdFileSource::work( + int noutput_items, + gr_vector_const_void_star& input_items, + gr_vector_void_star& output_items) +{ + for (int i = 0; i < noutput_items; ++i) + { + read_chunk_pattern(output_items); + } + return WORK_CALLED_PRODUCE; +} + +std::size_t IONMetadataStdFileSource::output_stream_count() const +{ + return output_stream_count_; +} + +std::size_t IONMetadataStdFileSource::output_stream_item_size(std::size_t stream_index) const +{ + return output_stream_item_sizes_[stream_index]; +} + + +void IONMetadataStdFileSource::read_chunk_pattern(gr_vector_void_star& output_items) +{ + gr_vector_void_star chunk_outputs = output_items; + for (auto& c : chunk_data_) + { + c->read_from_file(fd_); + c->write_to_output(output_items, [this](int output, int nitems) { + produce(output, nitems); + }); + } +} + +gr::io_signature::sptr IONMetadataStdFileSource::make_output_signature(const GnssMetadata::Block& block) +{ + int nstreams = 0; + std::vector item_sizes{}; + + for (const auto& chunk : block.Chunks()) + { + for (const auto& lump : chunk.Lumps()) + { + for (const auto& stream : lump.Streams()) + { + ++nstreams; + item_sizes.emplace_back(stream.RateFactor() * stream.Quantization()); + } + } + } + + return gr::io_signature::make( + nstreams, + nstreams, + item_sizes); +} + + +chunk_data_t::chunk_data_t(const GnssMetadata::Chunk& chunk, const std::vector& stream_ids, std::size_t output_stream_offset) + : chunk_(chunk), + sizeword_(chunk_.SizeWord()), + countwords_(chunk_.CountWords()) +{ + switch (sizeword_) + { + case 1: + buffer_ = new uint8_t[countwords_]; + break; + case 2: + buffer_ = new uint16_t[countwords_]; + break; + case 4: + buffer_ = new uint32_t[countwords_]; + break; + case 8: + buffer_ = new uint64_t[countwords_]; + break; + default: + LOG(ERROR) << "Unknown word size: " << std::to_string(sizeword_); + break; + } + + + const std::size_t total_bitsize = sizeword_ * countwords_ * 8; + std::size_t used_bitsize = 0; + std::size_t output_streams = 0; + for (const auto& lump : chunk.Lumps()) + { + for (const auto& stream : lump.Streams()) + { + used_bitsize += stream.Packedbits(); + + if (std::ranges::any_of(stream_ids.begin(), stream_ids.end(), [&](const std::string& it) { + return stream.Id() == it; + })) + { + streams_.emplace_back(lump, stream, output_streams + output_stream_offset); + ++output_streams; + std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + if (sample_bitsize <= 8) + { + output_stream_item_size_.push_back(1); + } + else if (sample_bitsize <= 16) + { + output_stream_item_size_.push_back(2); + } + else if (sample_bitsize <= 32) + { + output_stream_item_size_.push_back(4); + } + else if (sample_bitsize <= 64) + { + output_stream_item_size_.push_back(8); + } + else + { + // This shouldn't happen + output_stream_item_size_.push_back(1); + } + } + else + { + streams_.emplace_back(lump, stream, -1); + } + } + } + + output_stream_count_ = output_streams; + padding_bitsize_ = total_bitsize - used_bitsize; +} +chunk_data_t::~chunk_data_t() +{ + switch (sizeword_) + { + case 1: + delete[] static_cast(buffer_); + break; + case 2: + delete[] static_cast(buffer_); + break; + case 4: + delete[] static_cast(buffer_); + break; + case 8: + delete[] static_cast(buffer_); + break; + default: + break; + } +} + +void chunk_data_t::read_from_file(FILE* fd) +{ + std::fread(buffer_, sizeword_, countwords_, fd); +} + +void chunk_data_t::write_to_output(gr_vector_void_star& outputs, const std::function& produce) +{ + switch (sizeword_) + { + case 1: + unpack_words(outputs, produce); + break; + case 2: + unpack_words(outputs, produce); + break; + case 4: + unpack_words(outputs, produce); + break; + case 8: + unpack_words(outputs, produce); + break; + default: + break; + } +} + +std::size_t chunk_data_t::output_stream_count() const +{ + return output_stream_count_; +} + +std::size_t chunk_data_t::output_stream_item_size(std::size_t stream_index) const +{ + return output_stream_item_size_[stream_index]; +} diff --git a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h new file mode 100644 index 000000000..badf834c1 --- /dev/null +++ b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h @@ -0,0 +1,319 @@ +// +// Created by castle on 6/24/24. +// + +#ifndef GNSS_SDR_ION_GNSS_SDR_METADATA_STANDARD_H +#define GNSS_SDR_ION_GNSS_SDR_METADATA_STANDARD_H + +#include "GnssMetadata.h" +#include "gnss_block_interface.h" +#include +#include + +class chunk_data_t +{ +public: + chunk_data_t(const GnssMetadata::Chunk& chunk, const std::vector& stream_ids, std::size_t output_stream_offset); + + ~chunk_data_t(); + + chunk_data_t(const chunk_data_t& rhl) = delete; + chunk_data_t& operator=(const chunk_data_t& rhl) = delete; + + chunk_data_t(chunk_data_t&& rhl) = delete; + chunk_data_t& operator=(chunk_data_t&& rhl) = delete; + + void read_from_file(FILE* fd); + + void write_to_output(gr_vector_void_star& outputs, const std::function& produce); + + std::size_t output_stream_count() const; + std::size_t output_stream_item_size(std::size_t stream_index) const; + +private: + template + struct unpacking_context_t + { + WT* iterator_; + WT current_word_; + uint8_t bitshift_ = 0; + }; + + template + void unpack_words(gr_vector_void_star& outputs, const std::function& produce) + { + WT* data = static_cast(buffer_); + // TODO - Swap endiannes if needed + + unpacking_context_t ctx{}; + if (chunk_.Shift() == GnssMetadata::Chunk::Left) + { + ctx.iterator_ = data; + } + else if (chunk_.Shift() == GnssMetadata::Chunk::Right) + { + ctx.iterator_ = &data[countwords_]; + } + advance_word(ctx); // Initializes ctx.current_word_ + + // Head padding + if (padding_bitsize_ > 0 && chunk_.Padding() == GnssMetadata::Chunk::Head) + { + shift_padding(ctx, padding_bitsize_); + } + + // Samples + for (const auto& [lump, stream, output_index] : streams_) + { + if (output_index == -1) + { + skip_stream(ctx, lump, stream); + } + else + { + produce(output_index, write_stream_samples(ctx, lump, stream, outputs[output_index])); + } + } + } + + template + void skip_stream( + unpacking_context_t& ctx, + const GnssMetadata::Lump& lump, + const GnssMetadata::IonStream& stream) + { + shift_padding(ctx, stream.Packedbits()); + } + + template + std::size_t write_stream_samples( + unpacking_context_t& ctx, + const GnssMetadata::Lump& lump, + const GnssMetadata::IonStream& stream, + void*& out) + { + std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + std::size_t sample_count = stream.RateFactor(); + if (sample_bitsize <= 8) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, out); + } + else if (sample_bitsize <= 16) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, out); + } + else if (sample_bitsize <= 32) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, out); + } + else if (sample_bitsize <= 64) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, out); + } + + return sample_count; + } + + template + void write_n_samples( + unpacking_context_t& ctx, + GnssMetadata::Lump::LumpShift lump_shift, + uint8_t sample_bitsize, + std::size_t sample_count, + void*& out) + { + if (lump_shift == GnssMetadata::Lump::shiftLeft) + { + auto* sample = static_cast(out); + for (int i = 0; i < sample_count; ++i) + { + shift_sample(ctx, sample_bitsize, sample); + ++sample; + } + } + else if (lump_shift == GnssMetadata::Lump::shiftRight) + { + auto* sample = static_cast(out); + sample += sample_count; + for (int i = 0; i < sample_count; ++i) + { + shift_sample(ctx, sample_bitsize, sample); + --sample; + } + } + } + + template + void shift_sample(unpacking_context_t& ctx, uint8_t sample_bitsize, OT* output, uint8_t output_bit_offset = 0) + { + const uint8_t word_bitsize = sizeword_ * 8; + + if ((sample_bitsize + (ctx.bitshift_ % word_bitsize)) > word_bitsize) + { + uint8_t bits_shifted = word_bitsize - (ctx.bitshift_ % word_bitsize); + + if (chunk_.Shift() == GnssMetadata::Chunk::Left) + { + WT mask = ~((1 << (word_bitsize - bits_shifted)) - 1); + *output |= ((ctx.current_word_ & mask) >> output_bit_offset); + ctx.current_word_ <<= bits_shifted; + } + else if (chunk_.Shift() == GnssMetadata::Chunk::Right) + { + WT mask = ((1 << (bits_shifted)) - 1); + *output |= (ctx.current_word_ & mask) << output_bit_offset; + // TODO - reverse bit order of sample? maybe? + ctx.current_word_ >>= bits_shifted; + } + + advance_word(ctx); + ctx.bitshift_ += bits_shifted; + shift_sample(ctx, sample_bitsize - bits_shifted, output, bits_shifted); + } + else + { + if (chunk_.Shift() == GnssMetadata::Chunk::Left) + { + WT mask = ~((1 << (word_bitsize - sample_bitsize)) - 1); + *output |= (ctx.current_word_ & mask) >> output_bit_offset; + ctx.current_word_ <<= sample_bitsize; + } + else if (chunk_.Shift() == GnssMetadata::Chunk::Right) + { + WT mask = ((1 << (sample_bitsize)) - 1); + *output |= (ctx.current_word_ & mask) << output_bit_offset; + // TODO - reverse bit order of sample? maybe? + ctx.current_word_ >>= sample_bitsize; + } + + ctx.bitshift_ += sample_bitsize; + } + } + + template + void shift_padding(unpacking_context_t& ctx, uint8_t n_bits) + { + const uint8_t word_bitsize = sizeword_ * 8; + + if ((n_bits + (ctx.bitshift_ % word_bitsize)) > word_bitsize) + { + uint8_t bits_shifted = word_bitsize - (ctx.bitshift_ % word_bitsize); + + if (chunk_.Shift() == GnssMetadata::Chunk::Left) + { + ctx.current_word_ <<= bits_shifted; + } + else if (chunk_.Shift() == GnssMetadata::Chunk::Right) + { + ctx.current_word_ >>= bits_shifted; + } + + advance_word(ctx); + ctx.bitshift_ += bits_shifted; + shift_padding(ctx, n_bits - bits_shifted); + } + else + { + if (chunk_.Shift() == GnssMetadata::Chunk::Left) + { + ctx.current_word_ <<= n_bits; + } + else if (chunk_.Shift() == GnssMetadata::Chunk::Right) + { + ctx.current_word_ >>= n_bits; + } + + ctx.bitshift_ += n_bits; + } + } + + template + void advance_word(unpacking_context_t& ctx) + { + WT word = *ctx.iterator_; + if (chunk_.Shift() == GnssMetadata::Chunk::Left) + { + ++ctx.iterator_; + } + else if (chunk_.Shift() == GnssMetadata::Chunk::Right) + { + --ctx.iterator_; + } + + ctx.current_word_ = word; + } + +private: + const GnssMetadata::Chunk& chunk_; + uint8_t sizeword_; + uint8_t countwords_; + uint8_t padding_bitsize_; + std::size_t output_stream_count_; + std::vector output_stream_item_size_; + + struct stream_metadata_t + { + const GnssMetadata::Lump& lump; + const GnssMetadata::IonStream& stream; + int output_index = -1; + }; + std::vector streams_; + + void* buffer_; +}; + +class IONMetadataStdFileSource : public gr::sync_block +{ +public: + using sptr = gnss_shared_ptr; + + IONMetadataStdFileSource( + const GnssMetadata::File& file, + const GnssMetadata::Block& block, + const std::vector& stream_ids); + + ~IONMetadataStdFileSource() override; + + int work( + int noutput_items, + gr_vector_const_void_star& input_items, + gr_vector_void_star& output_items) override; + + std::size_t output_stream_count() const; + std::size_t output_stream_item_size(std::size_t stream_index) const; + +private: + void read_chunk_pattern(gr_vector_void_star& output_items); + +private: + static gr::io_signature::sptr make_output_signature(const GnssMetadata::Block& block); + +private: + const GnssMetadata::File& file_metadata_; + const GnssMetadata::Block& block_metadata_; + FILE* fd_; + std::size_t output_stream_count_; + std::vector output_stream_item_sizes_; + std::vector> chunk_data_; +}; + +class GnssMetadataHandler +{ +public: + explicit GnssMetadataHandler(const std::string& metadata_filepath); + + std::vector make_stream_sources(const std::vector& stream_ids) const; + +public: // Getters + const std::string& metadata_filepath() const; + +private: + void load_metadata(); + +private: + std::string metadata_filepath_; + GnssMetadata::Metadata metadata_; +}; + + +#endif // GNSS_SDR_ION_GNSS_SDR_METADATA_STANDARD_H diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index ce77442ee..69406a711 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -113,6 +113,7 @@ #include "tracking_interface.h" #include "two_bit_cpx_file_signal_source.h" #include "two_bit_packed_file_signal_source.h" +#include "ion_gnss_ms_signal_source.h" #include // for exit #include // for exception #include // for cerr @@ -759,6 +760,12 @@ std::unique_ptr GNSSBlockFactory::GetBlock( block = std::move(block_); } #endif + else if (implementation == "ION_Metadata_Standard_Signal_Source") + { + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + out_streams, queue); + block = std::move(block_); + } #if RAW_ARRAY_DRIVER else if (implementation == "Raw_Array_Signal_Source") From 38d548ba5090b193bb0681fccd7edd526e30a92e Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Mon, 24 Jun 2024 18:03:36 +0200 Subject: [PATCH 03/34] Only specify outputs for the requested streams --- .../libs/ion_gnss_sdr_metadata_standard.cc | 34 ++++++++++++++++--- .../libs/ion_gnss_sdr_metadata_standard.h | 2 +- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc index c31ec3d1d..9466e798f 100644 --- a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc +++ b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc @@ -87,7 +87,7 @@ IONMetadataStdFileSource::IONMetadataStdFileSource( : gr::sync_block( "ion_metadata_standard_source", gr::io_signature::make(0, 0, 0), - make_output_signature(block)), + make_output_signature(block, stream_ids)), file_metadata_(file), block_metadata_(block) { @@ -149,7 +149,7 @@ void IONMetadataStdFileSource::read_chunk_pattern(gr_vector_void_star& output_it } } -gr::io_signature::sptr IONMetadataStdFileSource::make_output_signature(const GnssMetadata::Block& block) +gr::io_signature::sptr IONMetadataStdFileSource::make_output_signature(const GnssMetadata::Block& block, const std::vector& stream_ids) { int nstreams = 0; std::vector item_sizes{}; @@ -160,8 +160,34 @@ gr::io_signature::sptr IONMetadataStdFileSource::make_output_signature(const Gns { for (const auto& stream : lump.Streams()) { - ++nstreams; - item_sizes.emplace_back(stream.RateFactor() * stream.Quantization()); + if (std::ranges::any_of(stream_ids.begin(), stream_ids.end(), [&](const std::string& it) { + return stream.Id() == it; + })) + { + ++nstreams; + std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + if (sample_bitsize <= 8) + { + item_sizes.push_back(1); + } + else if (sample_bitsize <= 16) + { + item_sizes.push_back(2); + } + else if (sample_bitsize <= 32) + { + item_sizes.push_back(4); + } + else if (sample_bitsize <= 64) + { + item_sizes.push_back(8); + } + else + { + // This shouldn't happen + item_sizes.push_back(1); + } + } } } } diff --git a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h index badf834c1..b97a84576 100644 --- a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h +++ b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h @@ -286,7 +286,7 @@ private: void read_chunk_pattern(gr_vector_void_star& output_items); private: - static gr::io_signature::sptr make_output_signature(const GnssMetadata::Block& block); + static gr::io_signature::sptr make_output_signature(const GnssMetadata::Block& block, const std::vector& stream_ids); private: const GnssMetadata::File& file_metadata_; From 5c442c8aae637510d05276890dfb7f08106f35bd Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Mon, 24 Jun 2024 18:06:01 +0200 Subject: [PATCH 04/34] Fixed block iteration withing a file The `File` object only holds a shallow reference to its `Lane` (without the list of blocks). So we must retrieve the full reference manually. --- .../libs/ion_gnss_sdr_metadata_standard.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc index 9466e798f..45e3eebbe 100644 --- a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc +++ b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc @@ -46,10 +46,14 @@ std::vector GnssMetadataHandler::make_stream_sou std::vector sources{}; for (const auto& file : metadata_.Files()) { - for (const auto& block : file.Lane().Blocks()) + for (const auto& lane : metadata_.Lanes()) { - for (const auto& chunk : block.Chunks()) + if (lane.Id() == file.Lane().Id()) { + for (const auto& block : lane.Blocks()) + { + for (const auto& chunk : block.Chunks()) + { for (const auto& lump : chunk.Lumps()) { for (const auto& stream : lump.Streams()) @@ -71,8 +75,11 @@ std::vector GnssMetadataHandler::make_stream_sou } } } + } + next_block: + } + break; } - next_block: } } From 598fa283b80ca5873d7eb0e78195442548c1aa6f Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Mon, 24 Jun 2024 18:08:40 +0200 Subject: [PATCH 05/34] Treat data file paths as relative to the metadata file The data file paths are actually not native paths but URLs, this covers most cases but not all of them. --- .../libs/ion_gnss_sdr_metadata_standard.cc | 39 ++++++++++--------- .../libs/ion_gnss_sdr_metadata_standard.h | 2 + 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc index 45e3eebbe..3c8f1809d 100644 --- a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc +++ b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc @@ -54,28 +54,29 @@ std::vector GnssMetadataHandler::make_stream_sou { for (const auto& chunk : block.Chunks()) { - for (const auto& lump : chunk.Lumps()) - { - for (const auto& stream : lump.Streams()) - { - if (std::ranges::any_of(stream_ids.begin(), stream_ids.end(), [&](const std::string& it) { - return stream.Id() == it; - })) + for (const auto& lump : chunk.Lumps()) { - auto source = gnss_make_shared( - file, - block, - stream_ids); + for (const auto& stream : lump.Streams()) + { + if (std::ranges::any_of(stream_ids.begin(), stream_ids.end(), [&](const std::string& it) { + return stream.Id() == it; + })) + { + auto source = gnss_make_shared( + metadata_filepath_, + file, + block, + stream_ids); - sources.push_back(source); + sources.push_back(source); - // This file source will take care of any other matching streams in this block - // We can skip the rest of this block - goto next_block; + // This file source will take care of any other matching streams in this block + // We can skip the rest of this block + goto next_block; + } + } } } - } - } next_block: } break; @@ -88,6 +89,7 @@ std::vector GnssMetadataHandler::make_stream_sou IONMetadataStdFileSource::IONMetadataStdFileSource( + const std::filesystem::path& metadata_filepath, const GnssMetadata::File& file, const GnssMetadata::Block& block, const std::vector& stream_ids) @@ -98,7 +100,8 @@ IONMetadataStdFileSource::IONMetadataStdFileSource( file_metadata_(file), block_metadata_(block) { - fd_ = std::fopen(file.Url().Value().c_str(), "rb"); + std::filesystem::path data_filepath = metadata_filepath.parent_path() / file.Url().Value(); + fd_ = std::fopen(data_filepath.c_str(), "rb"); std::size_t block_offset = file.Offset(); std::fseek(fd_, file.Offset() + block_offset + block.SizeHeader(), SEEK_SET); diff --git a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h index b97a84576..0543de71d 100644 --- a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h +++ b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h @@ -9,6 +9,7 @@ #include "gnss_block_interface.h" #include #include +#include class chunk_data_t { @@ -268,6 +269,7 @@ public: using sptr = gnss_shared_ptr; IONMetadataStdFileSource( + const std::filesystem::path& metadata_filepath, const GnssMetadata::File& file, const GnssMetadata::Block& block, const std::vector& stream_ids); From 469eaf76e5cc241e1f0c452e1a1665292c3ff6b8 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Tue, 23 Jul 2024 01:13:34 +0200 Subject: [PATCH 06/34] Fixed decoding errors and refactored each class into its own file --- .../signal_source/adapters/CMakeLists.txt | 4 +- ...al_source.cc => ion_gsms_signal_source.cc} | 27 +- ...gnal_source.h => ion_gsms_signal_source.h} | 19 +- .../signal_source/libs/CMakeLists.txt | 8 +- .../libs/ion_gnss_sdr_metadata_standard.cc | 340 ------------ .../libs/ion_gnss_sdr_metadata_standard.h | 321 ----------- src/algorithms/signal_source/libs/ion_gsms.cc | 123 +++++ src/algorithms/signal_source/libs/ion_gsms.h | 64 +++ .../signal_source/libs/ion_gsms_chunk_data.cc | 108 ++++ .../signal_source/libs/ion_gsms_chunk_data.h | 510 ++++++++++++++++++ .../libs/ion_gsms_metadata_handler.cc | 101 ++++ .../libs/ion_gsms_metadata_handler.h | 47 ++ src/core/receiver/gnss_block_factory.cc | 6 +- 13 files changed, 987 insertions(+), 691 deletions(-) rename src/algorithms/signal_source/adapters/{ion_gnss_ms_signal_source.cc => ion_gsms_signal_source.cc} (78%) rename src/algorithms/signal_source/adapters/{ion_gnss_ms_signal_source.h => ion_gsms_signal_source.h} (76%) delete mode 100644 src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc delete mode 100644 src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h create mode 100644 src/algorithms/signal_source/libs/ion_gsms.cc create mode 100644 src/algorithms/signal_source/libs/ion_gsms.h create mode 100644 src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc create mode 100644 src/algorithms/signal_source/libs/ion_gsms_chunk_data.h create mode 100644 src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc create mode 100644 src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index 54d577c53..9ff0ab434 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -119,7 +119,7 @@ set(SIGNAL_SOURCE_ADAPTER_SOURCES two_bit_packed_file_signal_source.cc four_bit_cpx_file_signal_source.cc file_timestamp_signal_source.cc - ion_gnss_ms_signal_source.cc + ion_gsms_signal_source.cc ${OPT_DRIVER_SOURCES} ) @@ -139,7 +139,7 @@ set(SIGNAL_SOURCE_ADAPTER_HEADERS two_bit_packed_file_signal_source.h four_bit_cpx_file_signal_source.h file_timestamp_signal_source.h - ion_gnss_ms_signal_source.h + ion_gsms_signal_source.h ${OPT_DRIVER_HEADERS} ) diff --git a/src/algorithms/signal_source/adapters/ion_gnss_ms_signal_source.cc b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc similarity index 78% rename from src/algorithms/signal_source/adapters/ion_gnss_ms_signal_source.cc rename to src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc index fe81e4556..e4becf5e3 100644 --- a/src/algorithms/signal_source/adapters/ion_gnss_ms_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc @@ -1,8 +1,7 @@ /*! - * \file file_timestamp_signal_source.cc - * \brief This class reads samples stored in a file and generate stream tags - * with its timestamp information stored in separated file - * \author Javier Arribas, jarribas(at)cttc.es + * \file ion_gsms_signal_source.h + * \brief GNSS-SDR Signal Source that reads sample streams following ION's GNSS-SDR metadata standard + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com * * ----------------------------------------------------------------------------- * @@ -15,9 +14,9 @@ * ----------------------------------------------------------------------------- */ -#include "ion_gnss_ms_signal_source.h" #include "gnss_sdr_flags.h" #include "gnss_sdr_string_literals.h" +#include "ion_gsms_signal_source.h" #include #include #include @@ -49,7 +48,7 @@ std::vector parse_comma_list(const std::string& str) return list; } -IONMetadataStandardSignalSource::IONMetadataStandardSignalSource(const ConfigurationInterface* configuration, +IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, unsigned int out_streams, @@ -58,7 +57,9 @@ IONMetadataStandardSignalSource::IONMetadataStandardSignalSource(const Configura metadata_file_(configuration->property(role + ".metadata_filename"s, "../data/example_capture_metadata.sdrx"s)), stream_ids_(parse_comma_list(configuration->property(role + ".streams"s, ""s))), metadata_(metadata_file_), - timestamp_clock_offset_ms_(configuration->property(role + ".timestamp_clock_offset_ms"s, 0.0)) + timestamp_clock_offset_ms_(configuration->property(role + ".timestamp_clock_offset_ms"s, 0.0)), + in_streams_(in_streams), + out_streams_(out_streams) { if (in_streams > 0) { @@ -77,7 +78,7 @@ IONMetadataStandardSignalSource::IONMetadataStandardSignalSource(const Configura } -void IONMetadataStandardSignalSource::connect(gr::top_block_sptr top_block) +void IONGSMSSignalSource::connect(gr::top_block_sptr top_block) { std::size_t cumulative_index = 0; for (const auto& source : sources_) @@ -89,7 +90,7 @@ void IONMetadataStandardSignalSource::connect(gr::top_block_sptr top_block) } } -void IONMetadataStandardSignalSource::disconnect(gr::top_block_sptr top_block) +void IONGSMSSignalSource::disconnect(gr::top_block_sptr top_block) { std::size_t cumulative_index = 0; for (const auto& source : sources_) @@ -101,19 +102,19 @@ void IONMetadataStandardSignalSource::disconnect(gr::top_block_sptr top_block) } } -gr::basic_block_sptr IONMetadataStandardSignalSource::get_left_block() +gr::basic_block_sptr IONGSMSSignalSource::get_left_block() { LOG(WARNING) << "Trying to get signal source left block."; // return gr_basic_block_sptr(); - return IONMetadataStdFileSource::sptr(); + return IONGSMSFileSource::sptr(); } -gr::basic_block_sptr IONMetadataStandardSignalSource::get_right_block() +gr::basic_block_sptr IONGSMSSignalSource::get_right_block() { return get_right_block(0); } -gr::basic_block_sptr IONMetadataStandardSignalSource::get_right_block(int RF_channel) +gr::basic_block_sptr IONGSMSSignalSource::get_right_block(int RF_channel) { return copy_blocks_[RF_channel]; } diff --git a/src/algorithms/signal_source/adapters/ion_gnss_ms_signal_source.h b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h similarity index 76% rename from src/algorithms/signal_source/adapters/ion_gnss_ms_signal_source.h rename to src/algorithms/signal_source/adapters/ion_gsms_signal_source.h index ed84cab5c..9d959279f 100644 --- a/src/algorithms/signal_source/adapters/ion_gnss_ms_signal_source.h +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h @@ -1,8 +1,7 @@ /*! - * \file file_timestamp_signal_source.h - * \brief This class reads samples stored in a file and generate stream tags - * with its timestamp information stored in separated file - * \author Javier Arribas, jarribas(at)cttc.es + * \file ion_gsms_signal_source.h + * \brief GNSS-SDR Signal Source that reads sample streams following ION's GNSS-SDR metadata standard + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com * * ----------------------------------------------------------------------------- * @@ -22,7 +21,7 @@ #include "configuration_interface.h" #include "file_source_base.h" #include "gnss_sdr_timestamp.h" -#include "ion_gnss_sdr_metadata_standard.h" +#include "ion_gsms.h" #include /** \addtogroup Signal_Source @@ -34,14 +33,14 @@ * \brief Class that reads signals samples from a file * and adapts it to a SignalSourceInterface */ -class IONMetadataStandardSignalSource : public SignalSourceBase +class IONGSMSSignalSource : public SignalSourceBase { public: - IONMetadataStandardSignalSource(const ConfigurationInterface* configuration, const std::string& role, + IONGSMSSignalSource(const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, unsigned int out_streams, Concurrent_Queue* queue); - ~IONMetadataStandardSignalSource() override = default; + ~IONGSMSSignalSource() override = default; protected: // std::tuple itemTypeToSize() override; @@ -60,9 +59,9 @@ protected: private: std::string metadata_file_; std::vector stream_ids_; - std::vector sources_; + std::vector sources_; std::vector> copy_blocks_; - GnssMetadataHandler metadata_; + IONGSMSMetadataHandler metadata_; gnss_shared_ptr timestamp_block_; std::string timestamp_file_; diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index f0b2c09fd..fb7faf9ee 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -46,8 +46,12 @@ if(ENABLE_PLUTOSDR) endif() if(ENABLE_ION) - set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gnss_sdr_metadata_standard.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gnss_sdr_metadata_standard.h) + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gsms.cc) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms.h) + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gsms_chunk_data.cc) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_chunk_data.h) + set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gsms_metadata_handler.cc) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_metadata_handler.h) endif() diff --git a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc deleted file mode 100644 index 3c8f1809d..000000000 --- a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.cc +++ /dev/null @@ -1,340 +0,0 @@ -// -// Created by castle on 6/24/24. -// - -#include "ion_gnss_sdr_metadata_standard.h" - -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif - -GnssMetadataHandler::GnssMetadataHandler(const std::string& metadata_filepath) - : metadata_filepath_(metadata_filepath) -{ - load_metadata(); -} - -const std::string& GnssMetadataHandler::metadata_filepath() const -{ - return metadata_filepath_; -} - -void GnssMetadataHandler::load_metadata() -{ - try - { - GnssMetadata::XmlProcessor xml_proc; - if (!xml_proc.Load(metadata_filepath_.c_str(), false, metadata_)) - { - LOG(ERROR) << "Could not load XML metadata file:"; - } - } - catch (GnssMetadata::ApiException& e) - { - LOG(ERROR) << "API Exception while loadind XML metadata file: " << e.what(); - } - catch (std::exception& e) - { - LOG(ERROR) << "Exception while loading XML metadata file: " << e.what(); - } -} - -std::vector GnssMetadataHandler::make_stream_sources(const std::vector& stream_ids) const -{ - std::vector sources{}; - for (const auto& file : metadata_.Files()) - { - for (const auto& lane : metadata_.Lanes()) - { - if (lane.Id() == file.Lane().Id()) - { - for (const auto& block : lane.Blocks()) - { - for (const auto& chunk : block.Chunks()) - { - for (const auto& lump : chunk.Lumps()) - { - for (const auto& stream : lump.Streams()) - { - if (std::ranges::any_of(stream_ids.begin(), stream_ids.end(), [&](const std::string& it) { - return stream.Id() == it; - })) - { - auto source = gnss_make_shared( - metadata_filepath_, - file, - block, - stream_ids); - - sources.push_back(source); - - // This file source will take care of any other matching streams in this block - // We can skip the rest of this block - goto next_block; - } - } - } - } - next_block: - } - break; - } - } - } - - return sources; -} - - -IONMetadataStdFileSource::IONMetadataStdFileSource( - const std::filesystem::path& metadata_filepath, - const GnssMetadata::File& file, - const GnssMetadata::Block& block, - const std::vector& stream_ids) - : gr::sync_block( - "ion_metadata_standard_source", - gr::io_signature::make(0, 0, 0), - make_output_signature(block, stream_ids)), - file_metadata_(file), - block_metadata_(block) -{ - std::filesystem::path data_filepath = metadata_filepath.parent_path() / file.Url().Value(); - fd_ = std::fopen(data_filepath.c_str(), "rb"); - std::size_t block_offset = file.Offset(); - std::fseek(fd_, file.Offset() + block_offset + block.SizeHeader(), SEEK_SET); - - std::size_t output_stream_offset = 0; - for (const auto& chunk : block.Chunks()) - { - chunk_data_.emplace_back(std::make_shared(chunk, stream_ids, output_stream_offset)); - const std::size_t out_count = chunk_data_.back()->output_stream_count(); - output_stream_offset += out_count; - for (std::size_t i = 0; i < out_count; ++i) - { - output_stream_item_sizes_.push_back(chunk_data_.back()->output_stream_item_size(i)); - } - } - output_stream_count_ = output_stream_offset; -} - -IONMetadataStdFileSource::~IONMetadataStdFileSource() -{ - std::fclose(fd_); -} - -int IONMetadataStdFileSource::work( - int noutput_items, - gr_vector_const_void_star& input_items, - gr_vector_void_star& output_items) -{ - for (int i = 0; i < noutput_items; ++i) - { - read_chunk_pattern(output_items); - } - return WORK_CALLED_PRODUCE; -} - -std::size_t IONMetadataStdFileSource::output_stream_count() const -{ - return output_stream_count_; -} - -std::size_t IONMetadataStdFileSource::output_stream_item_size(std::size_t stream_index) const -{ - return output_stream_item_sizes_[stream_index]; -} - - -void IONMetadataStdFileSource::read_chunk_pattern(gr_vector_void_star& output_items) -{ - gr_vector_void_star chunk_outputs = output_items; - for (auto& c : chunk_data_) - { - c->read_from_file(fd_); - c->write_to_output(output_items, [this](int output, int nitems) { - produce(output, nitems); - }); - } -} - -gr::io_signature::sptr IONMetadataStdFileSource::make_output_signature(const GnssMetadata::Block& block, const std::vector& stream_ids) -{ - int nstreams = 0; - std::vector item_sizes{}; - - for (const auto& chunk : block.Chunks()) - { - for (const auto& lump : chunk.Lumps()) - { - for (const auto& stream : lump.Streams()) - { - if (std::ranges::any_of(stream_ids.begin(), stream_ids.end(), [&](const std::string& it) { - return stream.Id() == it; - })) - { - ++nstreams; - std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); - if (sample_bitsize <= 8) - { - item_sizes.push_back(1); - } - else if (sample_bitsize <= 16) - { - item_sizes.push_back(2); - } - else if (sample_bitsize <= 32) - { - item_sizes.push_back(4); - } - else if (sample_bitsize <= 64) - { - item_sizes.push_back(8); - } - else - { - // This shouldn't happen - item_sizes.push_back(1); - } - } - } - } - } - - return gr::io_signature::make( - nstreams, - nstreams, - item_sizes); -} - - -chunk_data_t::chunk_data_t(const GnssMetadata::Chunk& chunk, const std::vector& stream_ids, std::size_t output_stream_offset) - : chunk_(chunk), - sizeword_(chunk_.SizeWord()), - countwords_(chunk_.CountWords()) -{ - switch (sizeword_) - { - case 1: - buffer_ = new uint8_t[countwords_]; - break; - case 2: - buffer_ = new uint16_t[countwords_]; - break; - case 4: - buffer_ = new uint32_t[countwords_]; - break; - case 8: - buffer_ = new uint64_t[countwords_]; - break; - default: - LOG(ERROR) << "Unknown word size: " << std::to_string(sizeword_); - break; - } - - - const std::size_t total_bitsize = sizeword_ * countwords_ * 8; - std::size_t used_bitsize = 0; - std::size_t output_streams = 0; - for (const auto& lump : chunk.Lumps()) - { - for (const auto& stream : lump.Streams()) - { - used_bitsize += stream.Packedbits(); - - if (std::ranges::any_of(stream_ids.begin(), stream_ids.end(), [&](const std::string& it) { - return stream.Id() == it; - })) - { - streams_.emplace_back(lump, stream, output_streams + output_stream_offset); - ++output_streams; - std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); - if (sample_bitsize <= 8) - { - output_stream_item_size_.push_back(1); - } - else if (sample_bitsize <= 16) - { - output_stream_item_size_.push_back(2); - } - else if (sample_bitsize <= 32) - { - output_stream_item_size_.push_back(4); - } - else if (sample_bitsize <= 64) - { - output_stream_item_size_.push_back(8); - } - else - { - // This shouldn't happen - output_stream_item_size_.push_back(1); - } - } - else - { - streams_.emplace_back(lump, stream, -1); - } - } - } - - output_stream_count_ = output_streams; - padding_bitsize_ = total_bitsize - used_bitsize; -} -chunk_data_t::~chunk_data_t() -{ - switch (sizeword_) - { - case 1: - delete[] static_cast(buffer_); - break; - case 2: - delete[] static_cast(buffer_); - break; - case 4: - delete[] static_cast(buffer_); - break; - case 8: - delete[] static_cast(buffer_); - break; - default: - break; - } -} - -void chunk_data_t::read_from_file(FILE* fd) -{ - std::fread(buffer_, sizeword_, countwords_, fd); -} - -void chunk_data_t::write_to_output(gr_vector_void_star& outputs, const std::function& produce) -{ - switch (sizeword_) - { - case 1: - unpack_words(outputs, produce); - break; - case 2: - unpack_words(outputs, produce); - break; - case 4: - unpack_words(outputs, produce); - break; - case 8: - unpack_words(outputs, produce); - break; - default: - break; - } -} - -std::size_t chunk_data_t::output_stream_count() const -{ - return output_stream_count_; -} - -std::size_t chunk_data_t::output_stream_item_size(std::size_t stream_index) const -{ - return output_stream_item_size_[stream_index]; -} diff --git a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h b/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h deleted file mode 100644 index 0543de71d..000000000 --- a/src/algorithms/signal_source/libs/ion_gnss_sdr_metadata_standard.h +++ /dev/null @@ -1,321 +0,0 @@ -// -// Created by castle on 6/24/24. -// - -#ifndef GNSS_SDR_ION_GNSS_SDR_METADATA_STANDARD_H -#define GNSS_SDR_ION_GNSS_SDR_METADATA_STANDARD_H - -#include "GnssMetadata.h" -#include "gnss_block_interface.h" -#include -#include -#include - -class chunk_data_t -{ -public: - chunk_data_t(const GnssMetadata::Chunk& chunk, const std::vector& stream_ids, std::size_t output_stream_offset); - - ~chunk_data_t(); - - chunk_data_t(const chunk_data_t& rhl) = delete; - chunk_data_t& operator=(const chunk_data_t& rhl) = delete; - - chunk_data_t(chunk_data_t&& rhl) = delete; - chunk_data_t& operator=(chunk_data_t&& rhl) = delete; - - void read_from_file(FILE* fd); - - void write_to_output(gr_vector_void_star& outputs, const std::function& produce); - - std::size_t output_stream_count() const; - std::size_t output_stream_item_size(std::size_t stream_index) const; - -private: - template - struct unpacking_context_t - { - WT* iterator_; - WT current_word_; - uint8_t bitshift_ = 0; - }; - - template - void unpack_words(gr_vector_void_star& outputs, const std::function& produce) - { - WT* data = static_cast(buffer_); - // TODO - Swap endiannes if needed - - unpacking_context_t ctx{}; - if (chunk_.Shift() == GnssMetadata::Chunk::Left) - { - ctx.iterator_ = data; - } - else if (chunk_.Shift() == GnssMetadata::Chunk::Right) - { - ctx.iterator_ = &data[countwords_]; - } - advance_word(ctx); // Initializes ctx.current_word_ - - // Head padding - if (padding_bitsize_ > 0 && chunk_.Padding() == GnssMetadata::Chunk::Head) - { - shift_padding(ctx, padding_bitsize_); - } - - // Samples - for (const auto& [lump, stream, output_index] : streams_) - { - if (output_index == -1) - { - skip_stream(ctx, lump, stream); - } - else - { - produce(output_index, write_stream_samples(ctx, lump, stream, outputs[output_index])); - } - } - } - - template - void skip_stream( - unpacking_context_t& ctx, - const GnssMetadata::Lump& lump, - const GnssMetadata::IonStream& stream) - { - shift_padding(ctx, stream.Packedbits()); - } - - template - std::size_t write_stream_samples( - unpacking_context_t& ctx, - const GnssMetadata::Lump& lump, - const GnssMetadata::IonStream& stream, - void*& out) - { - std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); - std::size_t sample_count = stream.RateFactor(); - if (sample_bitsize <= 8) - { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, out); - } - else if (sample_bitsize <= 16) - { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, out); - } - else if (sample_bitsize <= 32) - { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, out); - } - else if (sample_bitsize <= 64) - { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, out); - } - - return sample_count; - } - - template - void write_n_samples( - unpacking_context_t& ctx, - GnssMetadata::Lump::LumpShift lump_shift, - uint8_t sample_bitsize, - std::size_t sample_count, - void*& out) - { - if (lump_shift == GnssMetadata::Lump::shiftLeft) - { - auto* sample = static_cast(out); - for (int i = 0; i < sample_count; ++i) - { - shift_sample(ctx, sample_bitsize, sample); - ++sample; - } - } - else if (lump_shift == GnssMetadata::Lump::shiftRight) - { - auto* sample = static_cast(out); - sample += sample_count; - for (int i = 0; i < sample_count; ++i) - { - shift_sample(ctx, sample_bitsize, sample); - --sample; - } - } - } - - template - void shift_sample(unpacking_context_t& ctx, uint8_t sample_bitsize, OT* output, uint8_t output_bit_offset = 0) - { - const uint8_t word_bitsize = sizeword_ * 8; - - if ((sample_bitsize + (ctx.bitshift_ % word_bitsize)) > word_bitsize) - { - uint8_t bits_shifted = word_bitsize - (ctx.bitshift_ % word_bitsize); - - if (chunk_.Shift() == GnssMetadata::Chunk::Left) - { - WT mask = ~((1 << (word_bitsize - bits_shifted)) - 1); - *output |= ((ctx.current_word_ & mask) >> output_bit_offset); - ctx.current_word_ <<= bits_shifted; - } - else if (chunk_.Shift() == GnssMetadata::Chunk::Right) - { - WT mask = ((1 << (bits_shifted)) - 1); - *output |= (ctx.current_word_ & mask) << output_bit_offset; - // TODO - reverse bit order of sample? maybe? - ctx.current_word_ >>= bits_shifted; - } - - advance_word(ctx); - ctx.bitshift_ += bits_shifted; - shift_sample(ctx, sample_bitsize - bits_shifted, output, bits_shifted); - } - else - { - if (chunk_.Shift() == GnssMetadata::Chunk::Left) - { - WT mask = ~((1 << (word_bitsize - sample_bitsize)) - 1); - *output |= (ctx.current_word_ & mask) >> output_bit_offset; - ctx.current_word_ <<= sample_bitsize; - } - else if (chunk_.Shift() == GnssMetadata::Chunk::Right) - { - WT mask = ((1 << (sample_bitsize)) - 1); - *output |= (ctx.current_word_ & mask) << output_bit_offset; - // TODO - reverse bit order of sample? maybe? - ctx.current_word_ >>= sample_bitsize; - } - - ctx.bitshift_ += sample_bitsize; - } - } - - template - void shift_padding(unpacking_context_t& ctx, uint8_t n_bits) - { - const uint8_t word_bitsize = sizeword_ * 8; - - if ((n_bits + (ctx.bitshift_ % word_bitsize)) > word_bitsize) - { - uint8_t bits_shifted = word_bitsize - (ctx.bitshift_ % word_bitsize); - - if (chunk_.Shift() == GnssMetadata::Chunk::Left) - { - ctx.current_word_ <<= bits_shifted; - } - else if (chunk_.Shift() == GnssMetadata::Chunk::Right) - { - ctx.current_word_ >>= bits_shifted; - } - - advance_word(ctx); - ctx.bitshift_ += bits_shifted; - shift_padding(ctx, n_bits - bits_shifted); - } - else - { - if (chunk_.Shift() == GnssMetadata::Chunk::Left) - { - ctx.current_word_ <<= n_bits; - } - else if (chunk_.Shift() == GnssMetadata::Chunk::Right) - { - ctx.current_word_ >>= n_bits; - } - - ctx.bitshift_ += n_bits; - } - } - - template - void advance_word(unpacking_context_t& ctx) - { - WT word = *ctx.iterator_; - if (chunk_.Shift() == GnssMetadata::Chunk::Left) - { - ++ctx.iterator_; - } - else if (chunk_.Shift() == GnssMetadata::Chunk::Right) - { - --ctx.iterator_; - } - - ctx.current_word_ = word; - } - -private: - const GnssMetadata::Chunk& chunk_; - uint8_t sizeword_; - uint8_t countwords_; - uint8_t padding_bitsize_; - std::size_t output_stream_count_; - std::vector output_stream_item_size_; - - struct stream_metadata_t - { - const GnssMetadata::Lump& lump; - const GnssMetadata::IonStream& stream; - int output_index = -1; - }; - std::vector streams_; - - void* buffer_; -}; - -class IONMetadataStdFileSource : public gr::sync_block -{ -public: - using sptr = gnss_shared_ptr; - - IONMetadataStdFileSource( - const std::filesystem::path& metadata_filepath, - const GnssMetadata::File& file, - const GnssMetadata::Block& block, - const std::vector& stream_ids); - - ~IONMetadataStdFileSource() override; - - int work( - int noutput_items, - gr_vector_const_void_star& input_items, - gr_vector_void_star& output_items) override; - - std::size_t output_stream_count() const; - std::size_t output_stream_item_size(std::size_t stream_index) const; - -private: - void read_chunk_pattern(gr_vector_void_star& output_items); - -private: - static gr::io_signature::sptr make_output_signature(const GnssMetadata::Block& block, const std::vector& stream_ids); - -private: - const GnssMetadata::File& file_metadata_; - const GnssMetadata::Block& block_metadata_; - FILE* fd_; - std::size_t output_stream_count_; - std::vector output_stream_item_sizes_; - std::vector> chunk_data_; -}; - -class GnssMetadataHandler -{ -public: - explicit GnssMetadataHandler(const std::string& metadata_filepath); - - std::vector make_stream_sources(const std::vector& stream_ids) const; - -public: // Getters - const std::string& metadata_filepath() const; - -private: - void load_metadata(); - -private: - std::string metadata_filepath_; - GnssMetadata::Metadata metadata_; -}; - - -#endif // GNSS_SDR_ION_GNSS_SDR_METADATA_STANDARD_H diff --git a/src/algorithms/signal_source/libs/ion_gsms.cc b/src/algorithms/signal_source/libs/ion_gsms.cc new file mode 100644 index 000000000..8110b3af1 --- /dev/null +++ b/src/algorithms/signal_source/libs/ion_gsms.cc @@ -0,0 +1,123 @@ +/*! + * \file ion_gsms.cc + * \brief GNU Radio block that reads a Block from a file following ION's GNSS-SDR metadata standard + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * 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 "gnuradio/block.h" +#include "ion_gsms.h" + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include + +#include +#endif + + +IONGSMSFileSource::IONGSMSFileSource( + const std::filesystem::path& metadata_filepath, + const GnssMetadata::File& file, + const GnssMetadata::Block& block, + const std::vector& stream_ids) + : gr::sync_block( + "ion_metadata_standard_source", + gr::io_signature::make(0, 0, 0), + make_output_signature(block, stream_ids)), + file_metadata_(file), + block_metadata_(block) +{ + std::filesystem::path data_filepath = metadata_filepath.parent_path() / file.Url().Value(); + fd_ = std::fopen(data_filepath.c_str(), "rb"); + std::size_t block_offset = file.Offset(); + std::fseek(fd_, file.Offset() + block_offset + block.SizeHeader(), SEEK_SET); + + std::size_t output_stream_offset = 0; + for (const auto& chunk : block.Chunks()) + { + chunk_data_.emplace_back(std::make_shared(chunk, stream_ids, output_stream_offset)); + const std::size_t out_count = chunk_data_.back()->output_stream_count(); + output_stream_offset += out_count; + for (std::size_t i = 0; i < out_count; ++i) + { + output_stream_item_sizes_.push_back(chunk_data_.back()->output_stream_item_size(i)); + } + } + output_stream_count_ = output_stream_offset; +} + +IONGSMSFileSource::~IONGSMSFileSource() +{ + std::fclose(fd_); +} + +int IONGSMSFileSource::work( + int noutput_items, + gr_vector_const_void_star& input_items, + gr_vector_void_star& output_items) +{ + // for (int i = 0; i < noutput_items; ++i) + // { + for (auto& c : chunk_data_) + { + c->read_from_file(fd_); + c->write_to_output(output_items, [&](int output, int nitems) { + produce(output, nitems); + }); + } + // } + return WORK_CALLED_PRODUCE; +} + +std::size_t IONGSMSFileSource::output_stream_count() const +{ + return output_stream_count_; +} + +std::size_t IONGSMSFileSource::output_stream_item_size(std::size_t stream_index) const +{ + return output_stream_item_sizes_[stream_index]; +} + + +gr::io_signature::sptr IONGSMSFileSource::make_output_signature(const GnssMetadata::Block& block, const std::vector& stream_ids) +{ + int nstreams = 0; + std::vector item_sizes{}; + + for (const auto& chunk : block.Chunks()) + { + for (const auto& lump : chunk.Lumps()) + { + for (const auto& stream : lump.Streams()) + { + if (std::ranges::any_of(stream_ids.begin(), stream_ids.end(), [&](const std::string& it) { + return stream.Id() == it; + })) + { + ++nstreams; + const std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + item_sizes.push_back(bits_to_item_size(sample_bitsize)); + } + } + } + } + + return gr::io_signature::make( + nstreams, + nstreams, + item_sizes); +} + + diff --git a/src/algorithms/signal_source/libs/ion_gsms.h b/src/algorithms/signal_source/libs/ion_gsms.h new file mode 100644 index 000000000..a15206b84 --- /dev/null +++ b/src/algorithms/signal_source/libs/ion_gsms.h @@ -0,0 +1,64 @@ +/*! + * \file ion_gsms.h + * \brief GNU Radio block that reads a Block from a file following ION's GNSS-SDR metadata standard + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * 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_ION_GNSS_SDR_METADATA_STANDARD_H +#define GNSS_SDR_ION_GNSS_SDR_METADATA_STANDARD_H + +#include "gnss_block_interface.h" +#include "ion_gsms_chunk_data.h" +#include +#include +#include +#include + + +class IONGSMSFileSource : public gr::sync_block +{ +public: + using sptr = gnss_shared_ptr; + + IONGSMSFileSource( + const std::filesystem::path& metadata_filepath, + const GnssMetadata::File& file, + const GnssMetadata::Block& block, + const std::vector& stream_ids); + + ~IONGSMSFileSource() override; + + int work( + int noutput_items, + gr_vector_const_void_star& input_items, + gr_vector_void_star& output_items) override; + + std::size_t output_stream_count() const; + std::size_t output_stream_item_size(std::size_t stream_index) const; + +private: + static gr::io_signature::sptr make_output_signature(const GnssMetadata::Block& block, const std::vector& stream_ids); + +private: + const GnssMetadata::File& file_metadata_; + const GnssMetadata::Block& block_metadata_; + FILE* fd_; + std::size_t output_stream_count_; + std::vector output_stream_item_sizes_; + std::vector> chunk_data_; +}; + +#include "ion_gsms_metadata_handler.h" + + +#endif // GNSS_SDR_ION_GNSS_SDR_METADATA_STANDARD_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc new file mode 100644 index 000000000..f961772a0 --- /dev/null +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc @@ -0,0 +1,108 @@ +/*! + * \file ion_gsms_chunk_data.cc + * \brief Holds logic for reading and decoding samples from a chunk + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * 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 "ion_gsms_chunk_data.h" +#include + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +IONGSMSChunkData::IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std::vector& stream_ids, std::size_t output_stream_offset) + : chunk_(chunk), + sizeword_(chunk_.SizeWord()), + countwords_(chunk_.CountWords()) +{ + with_word_type(sizeword_, [&] + { + buffer_ = new WordType[countwords_]; + }); + + const std::size_t total_bitsize = sizeword_ * countwords_ * 8; + std::size_t used_bitsize = 0; + std::size_t output_streams = 0; + for (const auto& lump : chunk.Lumps()) + { + for (const auto& stream : lump.Streams()) + { + used_bitsize += stream.Packedbits(); + + if (std::ranges::any_of(stream_ids.begin(), stream_ids.end(), [&](const std::string& it) { + return stream.Id() == it; + })) + { + streams_.emplace_back(lump, stream, GnssMetadata::encoding_from_string(stream.Encoding()),output_streams + output_stream_offset); + ++output_streams; + const std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + output_stream_item_size_.push_back(bits_to_item_size(sample_bitsize)); + } + else + { + streams_.emplace_back(lump, stream, GnssMetadata::encoding_from_string(stream.Encoding()), -1); + } + } + } + + output_stream_count_ = output_streams; + padding_bitsize_ = total_bitsize - used_bitsize; +} + + +IONGSMSChunkData::~IONGSMSChunkData() +{ + with_word_type(sizeword_, [&] + { + delete[] static_cast(buffer_); + }); +} + +void IONGSMSChunkData::read_from_file(FILE* fd) +{ + std::fread(buffer_, sizeword_, countwords_, fd); +} + +void IONGSMSChunkData::write_to_output(gr_vector_void_star& outputs, const std::function& produce) +{ + with_word_type(sizeword_, [&] + { + unpack_words(outputs, produce); + }); +} + +std::size_t IONGSMSChunkData::output_stream_count() const +{ + return output_stream_count_; +} + +std::size_t IONGSMSChunkData::output_stream_item_size(std::size_t stream_index) const +{ + return output_stream_item_size_[stream_index]; +} + + + +void IONGSMSChunkData::dump_sample(auto value) +{ + static int count = 100; + if (count > 0) + { + --count; + std::cout << "SAMPLE: " << std::bitset<32>(value) << std::endl; + } +} + diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h new file mode 100644 index 000000000..f87a03aef --- /dev/null +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h @@ -0,0 +1,510 @@ +/*! + * \file ion_gsms_chunk_data.h + * \brief Holds logic for reading and decoding samples from a chunk + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * 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 ION_GSM_CHUNK_DATA_H +#define ION_GSM_CHUNK_DATA_H + +#include "GnssMetadata.h" +#include + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +inline std::size_t bits_to_item_size(const std::size_t bit_count) +{ + if (bit_count <= 8) + { + return 1; + } + if (bit_count <= 16) + { + return 2; + } + if (bit_count <= 32) + { + return 4; + } + if (bit_count <= 64) + { + return 8; + } + + // You are asking too much of this humble processor + LOG(ERROR) << "Item size too large (" << std::to_string(bit_count) << "), returning nonsense."; + return 1; +} + +void with_word_type(const uint8_t word_size, auto&& callback) +{ + switch (word_size) + { + case 1: + callback.template operator()(); + break; + case 2: + callback.template operator()(); + break; + case 4: + callback.template operator()(); + break; + case 8: + callback.template operator()(); + break; + default: + LOG(ERROR) << "Unknown word size (" << std::to_string(word_size) << "), returning nonsense."; + break; + } +} + +namespace GnssMetadata +{ + using StreamEncoding = unsigned char; + + namespace StreamEncodings + { + constexpr unsigned char SIGN = 0; + constexpr unsigned char OB = 1; + constexpr unsigned char SM = 2; + constexpr unsigned char MS = 3; + constexpr unsigned char TC = 4; + constexpr unsigned char OG = 5; + constexpr unsigned char OBA = 6; + constexpr unsigned char SMA = 7; + constexpr unsigned char MSA = 8; + constexpr unsigned char TCA = 9; + constexpr unsigned char OGA = 10; + constexpr unsigned char FP = 11; + } + + inline StreamEncoding encoding_from_string(const std::string& str) + { + if (str == "SIGN") + { + return StreamEncodings::SIGN; + } + if (str == "OB") + { + return StreamEncodings::OB; + } + if (str == "SM") + { + return StreamEncodings::SM; + } + if (str == "MS") + { + return StreamEncodings::MS; + } + if (str == "TC") + { + return StreamEncodings::TC; + } + if (str == "OG") + { + return StreamEncodings::OG; + } + if (str == "OBA") + { + return StreamEncodings::OBA; + } + if (str == "SMA") + { + return StreamEncodings::SMA; + } + if (str == "MSA") + { + return StreamEncodings::MSA; + } + if (str == "TCA") + { + return StreamEncodings::TCA; + } + if (str == "OGA") + { + return StreamEncodings::OGA; + } + if (str == "FP") + { + return StreamEncodings::FP; + } + return 0; + } + + template + inline T two_bit_look_up[11][4] + { + [0] = {}, + [1 /*OB*/] = {-2, -1, 0, 1}, + [2 /*SM*/] = {0, 1, 0, -1}, + [3 /*MS*/] = {0, 0, 1, -1}, + [4 /*TC*/] = {0, 1, -2, -1}, + [5 /*OG*/] = {-2, -1, 1, 0}, + [6 /*OBA*/] = {-3, -1, 1, 3}, + [7 /*SMA*/] = {1, 3, -1, -3}, + [8 /*MSA*/] = {1, -1, 3, -3}, + [9 /*TCA*/] = {1, 3, -3, -1}, + [10 /*OGA*/] = {-3, -1, 3, 1}, + }; + + template + inline T three_bit_look_up[11][8] + { + [0] = {}, + [1 /*OB*/] = {-4, -3, -2, -1, 0, 1, 2, 3}, + [2 /*SM*/] = {0, 1, 2, 3, 0, -1, -2, -3}, + [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1}, + [4 /*TC*/] = {0, 1, 2, 3, -4, -3, -2, -1}, + [5 /*OG*/] = {-4, -3, -1, -2, 3, 2, 0, 1}, + [6 /*OBA*/] = {-7, -5, -3, -1, 1, 3, 5, 7}, + [7 /*SMA*/] = {1, 3, 5, 7, -1, -3, -5, -7}, + [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7}, + [9 /*TCA*/] = {1, 3, 5, 7, -7, -5, -3, -1}, + [10 /*OGA*/] = {-7, -5, -1, -3, 7, 5, 1, 3}, + }; + + template + inline T four_bit_look_up[11][16] + { + [0] = {}, + [1 /*OB*/] = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}, + [2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7}, + [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, + [4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}, + [5 /*OG*/] = {-8, -7, -5, -6, -1, -2, -4, -3, 7, 6, 4, 5, 0, 1, 3, 2}, + [6 /*OBA*/] = {-15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15}, + [7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15}, + [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15}, + [9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -15, -13, -11, -9, -7, -5, -3, -1}, + [10 /*OGA*/] = {-15, -13, -9, -11, -1, -3, -7, -5, 15, 13, 9, 11, 1, 3, 7, 5}, + }; + + template + inline T five_bit_look_up[11][32] + { + [0] = {}, + [1 /*OB*/] = {-16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + [2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15}, + [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, + [4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1}, + [5 /*OG*/] = {-16, -15, -13, -14, -9, -10, -12, -11, -1, -2, -4, -3, -8, -7, -5, -6, 15, 14, 12, 13, 8, 9, 11, 10, 0, 1, 3, 2, 7, 6, 4, 5}, + [6 /*OBA*/] = {-31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, + [7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -1, -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -23, -25, -27, -29, -31}, + [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15, 17, -17, 19, -19, 21, -21, 23, -23, 25, -25, 27, -27, 29, -29, 31, -31}, + [9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1}, + [10 /*OGA*/] = {-31, -29, -25, -27, -17, -19, -23, -21, -1, -3, -7, -5, -15, -13, -9, -11, 31, 29, 25, 27, 17, 19, 23, 21, 1, 3, 7, 5, 15, 13, 9, 11}, + }; +} + +class IONGSMSChunkData +{ +public: + IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std::vector& stream_ids, std::size_t output_stream_offset); + + ~IONGSMSChunkData(); + + IONGSMSChunkData(const IONGSMSChunkData& rhl) = delete; + IONGSMSChunkData& operator=(const IONGSMSChunkData& rhl) = delete; + + IONGSMSChunkData(IONGSMSChunkData&& rhl) = delete; + IONGSMSChunkData& operator=(IONGSMSChunkData&& rhl) = delete; + + void read_from_file(FILE* fd); + + void write_to_output(gr_vector_void_star& outputs, const std::function& produce); + + std::size_t output_stream_count() const; + std::size_t output_stream_item_size(std::size_t stream_index) const; + +private: + template + struct unpacking_context_t + { + WT* iterator_; + WT current_word_; + uint8_t bitshift_ = 0; + }; + + template + void unpack_words(gr_vector_void_star& outputs, const std::function& produce) + { + WT* data = static_cast(buffer_); + // TODO - Swap endiannes if needed + + unpacking_context_t ctx{}; + if (chunk_.Shift() == GnssMetadata::Chunk::Left) + { + ctx.iterator_ = data; + } + else if (chunk_.Shift() == GnssMetadata::Chunk::Right) + { + ctx.iterator_ = &data[countwords_]; + } + advance_word(ctx); // Initializes ctx.current_word_ + + // Head padding + if (padding_bitsize_ > 0 && chunk_.Padding() == GnssMetadata::Chunk::Head) + { + shift_padding(ctx, padding_bitsize_); + } + + // Samples + for (const auto& [lump, stream, encoding, output_index] : streams_) + { + if (output_index == -1) + { + skip_stream(ctx, lump, stream); + } + else + { + produce(output_index, write_stream_samples(ctx, lump, stream, encoding, outputs[output_index])); + } + } + } + + template + void skip_stream( + unpacking_context_t& ctx, + const GnssMetadata::Lump& lump, + const GnssMetadata::IonStream& stream) + { + shift_padding(ctx, stream.Packedbits()); + } + + template + std::size_t write_stream_samples( + unpacking_context_t& ctx, + const GnssMetadata::Lump& lump, + const GnssMetadata::IonStream& stream, + const GnssMetadata::StreamEncoding stream_encoding, + void*& out) + { + std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + std::size_t sample_count = stream.RateFactor(); + + if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization()) + { + // Samples have 'Complex' format + sample_bitsize /= 2; + sample_count *= 2; + } + + if (sample_bitsize <= 8) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); + } + else if (sample_bitsize <= 16) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); + } + else if (sample_bitsize <= 32) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); + } + else if (sample_bitsize <= 64) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); + } + + return sample_count; + } + + template + void write_n_samples( + unpacking_context_t& ctx, + GnssMetadata::Lump::LumpShift lump_shift, + uint8_t sample_bitsize, + std::size_t sample_count, + GnssMetadata::StreamEncoding stream_encoding, + void*& out) + { + if (lump_shift == GnssMetadata::Lump::shiftRight) + { + auto* sample = static_cast(out); + sample += sample_count; + for (std::size_t i = 0; i < sample_count; ++i) + { + shift_sample(ctx, sample_bitsize, sample); + decode_sample(sample_bitsize, sample, stream_encoding); + --sample; + } + } + else // if (lump_shift == GnssMetadata::Lump::shiftLeft || lump_shift == GnssMetadata::Lump::shiftUndefined) + { + auto* sample = static_cast(out); + for (std::size_t i = 0; i < sample_count; ++i) + { + shift_sample(ctx, sample_bitsize, sample); + decode_sample(sample_bitsize, sample, stream_encoding); + ++sample; + } + } + } + + template + void shift_sample(unpacking_context_t& ctx, uint8_t sample_bitsize, OT* output, uint8_t output_bit_offset = 0) + { + const uint8_t word_bitsize = sizeword_ * 8; + + if ((sample_bitsize + (ctx.bitshift_ % word_bitsize)) > word_bitsize) + { + uint8_t bits_shifted = word_bitsize - (ctx.bitshift_ % word_bitsize); + + if (chunk_.Shift() == GnssMetadata::Chunk::Left) + { + WT mask = ~((1 << (word_bitsize - bits_shifted)) - 1); + dump_sample(ctx.current_word_ & mask); + *output |= ((ctx.current_word_ & mask) >> output_bit_offset); + ctx.current_word_ <<= bits_shifted; + } + else if (chunk_.Shift() == GnssMetadata::Chunk::Right) + { + WT mask = ((1 << (bits_shifted)) - 1); + dump_sample(ctx.current_word_ & mask); + *output |= (ctx.current_word_ & mask) << output_bit_offset; + // TODO - reverse bit order of sample? maybe? + ctx.current_word_ >>= bits_shifted; + } + + advance_word(ctx); + ctx.bitshift_ += bits_shifted; + shift_sample(ctx, sample_bitsize - bits_shifted, output, bits_shifted); + } + else + { + if (chunk_.Shift() == GnssMetadata::Chunk::Left) + { + WT mask = ~((1 << (word_bitsize - sample_bitsize)) - 1); + OT sample = (ctx.current_word_ & mask) >> (word_bitsize - sample_bitsize); + dump_sample(sample); + *output |= (sample) >> output_bit_offset; + ctx.current_word_ <<= sample_bitsize; + } + else if (chunk_.Shift() == GnssMetadata::Chunk::Right) + { + WT mask = ((1 << (sample_bitsize)) - 1); + dump_sample(ctx.current_word_ & mask); + *output |= (ctx.current_word_ & mask) << output_bit_offset; + // TODO - reverse bit order of sample? maybe? + ctx.current_word_ >>= sample_bitsize; + } + + ctx.bitshift_ += sample_bitsize; + } + } + + template + void shift_padding(unpacking_context_t& ctx, uint8_t n_bits) + { + if(n_bits == 0) return; + + const uint8_t word_bitsize = sizeword_ * 8; + + if ((n_bits + (ctx.bitshift_ % word_bitsize)) >= word_bitsize) + { + uint8_t bits_shifted = word_bitsize - (ctx.bitshift_ % word_bitsize); + + if (chunk_.Shift() == GnssMetadata::Chunk::Left) + { + ctx.current_word_ <<= bits_shifted; + } + else if (chunk_.Shift() == GnssMetadata::Chunk::Right) + { + ctx.current_word_ >>= bits_shifted; + } + + advance_word(ctx); + ctx.bitshift_ += bits_shifted; + shift_padding(ctx, n_bits - bits_shifted); + } + else + { + if (chunk_.Shift() == GnssMetadata::Chunk::Left) + { + ctx.current_word_ <<= n_bits; + } + else if (chunk_.Shift() == GnssMetadata::Chunk::Right) + { + ctx.current_word_ >>= n_bits; + } + + ctx.bitshift_ += n_bits; + } + } + + template + void advance_word(unpacking_context_t& ctx) + { + WT word = *ctx.iterator_; + if (chunk_.Shift() == GnssMetadata::Chunk::Left) + { + ++ctx.iterator_; + } + else if (chunk_.Shift() == GnssMetadata::Chunk::Right) + { + --ctx.iterator_; + } + + ctx.current_word_ = word; + } + + template + static void decode_sample(const uint8_t sample_bitsize, ST* sample, const GnssMetadata::StreamEncoding encoding) + { + switch (sample_bitsize) + { + case 2: + *sample = GnssMetadata::two_bit_look_up[encoding][*sample]; + break; + case 3: + *sample = GnssMetadata::three_bit_look_up[encoding][*sample]; + break; + case 4: + *sample = GnssMetadata::four_bit_look_up[encoding][*sample]; + break; + case 5: + *sample = GnssMetadata::five_bit_look_up[encoding][*sample]; + break; + default: + // TODO - Is this an error that can happen? + break; + } + } + + static void dump_sample(auto value); + +private: + const GnssMetadata::Chunk& chunk_; + uint8_t sizeword_; + uint8_t countwords_; + uint8_t padding_bitsize_; + std::size_t output_stream_count_; + std::vector output_stream_item_size_; + + struct stream_metadata_t + { + const GnssMetadata::Lump& lump; + const GnssMetadata::IonStream& stream; + GnssMetadata::StreamEncoding stream_encoding; + int output_index = -1; + }; + std::vector streams_; + + void* buffer_; +}; + +#endif //ION_GSM_CHUNK_DATA_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc new file mode 100644 index 000000000..48aced035 --- /dev/null +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc @@ -0,0 +1,101 @@ +/*! + * \file ion_gsms_metadata_handler.cc + * \brief Build instances of IONGSMSFileSource as needed given a list of stream ids + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * 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 "ion_gsms.h" + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +IONGSMSMetadataHandler::IONGSMSMetadataHandler(const std::string& metadata_filepath) + : metadata_filepath_(metadata_filepath) +{ + load_metadata(); +} + +const std::string& IONGSMSMetadataHandler::metadata_filepath() const +{ + return metadata_filepath_; +} + +void IONGSMSMetadataHandler::load_metadata() +{ + try + { + GnssMetadata::XmlProcessor xml_proc; + if (!xml_proc.Load(metadata_filepath_.c_str(), false, metadata_)) + { + LOG(ERROR) << "Could not load XML metadata file:"; + } + } + catch (GnssMetadata::ApiException& e) + { + LOG(ERROR) << "API Exception while loadind XML metadata file: " << e.what(); + } + catch (std::exception& e) + { + LOG(ERROR) << "Exception while loading XML metadata file: " << e.what(); + } +} + +std::vector IONGSMSMetadataHandler::make_stream_sources(const std::vector& stream_ids) const +{ + std::vector sources{}; + for (const auto& file : metadata_.Files()) + { + for (const auto& lane : metadata_.Lanes()) + { + if (lane.Id() == file.Lane().Id()) + { + for (const auto& block : lane.Blocks()) + { + for (const auto& chunk : block.Chunks()) + { + for (const auto& lump : chunk.Lumps()) + { + for (const auto& stream : lump.Streams()) + { + if (std::ranges::any_of(stream_ids.begin(), stream_ids.end(), [&](const std::string& it) { + return stream.Id() == it; + })) + { + auto source = gnss_make_shared( + metadata_filepath_, + file, + block, + stream_ids); + + sources.push_back(source); + + // This file source will take care of any other matching streams in this block + // We can skip the rest of this block + goto next_block; + } + } + } + } + next_block: + } + break; + } + } + } + + return sources; +} + diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h new file mode 100644 index 000000000..0cbf634f6 --- /dev/null +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h @@ -0,0 +1,47 @@ +/*! + * \file ion_gsms_metadata_handler.h + * \brief Build instances of IONGSMSFileSource as needed given a list of stream ids + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * 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 ION_GSMS_METADATA_HANDLER_H +#define ION_GSMS_METADATA_HANDLER_H + +#include "GnssMetadata.h" +#include + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +class IONGSMSMetadataHandler +{ +public: + explicit IONGSMSMetadataHandler(const std::string& metadata_filepath); + + std::vector make_stream_sources(const std::vector& stream_ids) const; + +public: // Getters + const std::string& metadata_filepath() const; + +private: // Private methods + void load_metadata(); + +private: // State + std::string metadata_filepath_; + GnssMetadata::Metadata metadata_; +}; + +#endif //ION_GSMS_METADATA_HANDLER_H diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 69406a711..99a05e95c 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -93,6 +93,7 @@ #include "ibyte_to_complex.h" #include "ibyte_to_cshort.h" #include "in_memory_configuration.h" +#include "ion_gsms_signal_source.h" #include "ishort_to_complex.h" #include "ishort_to_cshort.h" #include "labsat_signal_source.h" @@ -113,7 +114,6 @@ #include "tracking_interface.h" #include "two_bit_cpx_file_signal_source.h" #include "two_bit_packed_file_signal_source.h" -#include "ion_gnss_ms_signal_source.h" #include // for exit #include // for exception #include // for cerr @@ -760,9 +760,9 @@ std::unique_ptr GNSSBlockFactory::GetBlock( block = std::move(block_); } #endif - else if (implementation == "ION_Metadata_Standard_Signal_Source") + else if (implementation == "ION_GSMS_Signal_Source") { - std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, + std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams, queue); block = std::move(block_); } From 00fd1821b17f0512b13dc556d6478989c7271c95 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Tue, 23 Jul 2024 15:24:28 +0200 Subject: [PATCH 07/34] Fixed sample count error & refactored --- .../adapters/ion_gsms_signal_source.cc | 2 +- .../signal_source/libs/CMakeLists.txt | 2 + src/algorithms/signal_source/libs/ion_gsms.cc | 9 +- .../signal_source/libs/ion_gsms_chunk_data.cc | 140 ++++++- .../signal_source/libs/ion_gsms_chunk_data.h | 386 +----------------- .../libs/ion_gsms_chunk_unpacking_ctx.h | 153 +++++++ .../libs/ion_gsms_stream_encodings.h | 164 ++++++++ 7 files changed, 474 insertions(+), 382 deletions(-) create mode 100644 src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h create mode 100644 src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc index e4becf5e3..d01268d67 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc @@ -53,7 +53,7 @@ IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configura unsigned int in_streams, unsigned int out_streams, Concurrent_Queue* queue) - : SignalSourceBase(configuration, role, "ION_Metadata_Standard_Signal_Source"s), + : SignalSourceBase(configuration, role, "ION_GSMS_Signal_Source"s), metadata_file_(configuration->property(role + ".metadata_filename"s, "../data/example_capture_metadata.sdrx"s)), stream_ids_(parse_comma_list(configuration->property(role + ".streams"s, ""s))), metadata_(metadata_file_), diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index fb7faf9ee..36f327931 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -52,6 +52,8 @@ if(ENABLE_ION) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_chunk_data.h) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gsms_metadata_handler.cc) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_metadata_handler.h) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_stream_encodings.h) + set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_chunk_unpacking_ctx.h) endif() diff --git a/src/algorithms/signal_source/libs/ion_gsms.cc b/src/algorithms/signal_source/libs/ion_gsms.cc index 8110b3af1..2034f12d1 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.cc +++ b/src/algorithms/signal_source/libs/ion_gsms.cc @@ -32,7 +32,7 @@ IONGSMSFileSource::IONGSMSFileSource( const GnssMetadata::Block& block, const std::vector& stream_ids) : gr::sync_block( - "ion_metadata_standard_source", + "ion_gsms_file_source", gr::io_signature::make(0, 0, 0), make_output_signature(block, stream_ids)), file_metadata_(file), @@ -107,7 +107,12 @@ gr::io_signature::sptr IONGSMSFileSource::make_output_signature(const GnssMetada })) { ++nstreams; - const std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization()) + { + // Samples have 'Complex' format + sample_bitsize /= 2; + } item_sizes.push_back(bits_to_item_size(sample_bitsize)); } } diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc index f961772a0..8a0d1a7b4 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc @@ -48,7 +48,12 @@ IONGSMSChunkData::IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std:: { streams_.emplace_back(lump, stream, GnssMetadata::encoding_from_string(stream.Encoding()),output_streams + output_stream_offset); ++output_streams; - const std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization()) + { + // Samples have 'Complex' format + sample_bitsize /= 2; + } output_stream_item_size_.push_back(bits_to_item_size(sample_bitsize)); } else @@ -95,6 +100,137 @@ std::size_t IONGSMSChunkData::output_stream_item_size(std::size_t stream_index) } +template +void IONGSMSChunkData::unpack_words(gr_vector_void_star& outputs, const std::function& produce) +{ + WT* data = static_cast(buffer_); + // TODO - Swap endiannes if needed + + IONGSMSChunkUnpackingCtx ctx{ + chunk_.Shift(), + data, + countwords_, + }; + + // Head padding + if (padding_bitsize_ > 0 && chunk_.Padding() == GnssMetadata::Chunk::Head) + { + ctx.shift_padding(padding_bitsize_); + } + + // Samples + for (const auto& [lump, stream, encoding, output_index] : streams_) + { + if (output_index == -1) + { + // skip stream + ctx.shift_padding(stream.Packedbits()); + } + else + { + produce(output_index, write_stream_samples(ctx, lump, stream, encoding, outputs[output_index])); + } + } +} + +template +std::size_t IONGSMSChunkData::write_stream_samples( + IONGSMSChunkUnpackingCtx& ctx, + const GnssMetadata::Lump& lump, + const GnssMetadata::IonStream& stream, + const GnssMetadata::StreamEncoding stream_encoding, + void*& out) +{ + std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + std::size_t sample_count = stream.RateFactor(); + + if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization()) + { + // Samples have 'Complex' format + sample_bitsize /= 2; + sample_count *= 2; + } + + if (sample_bitsize <= 8) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); + } + else if (sample_bitsize <= 16) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); + } + else if (sample_bitsize <= 32) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); + } + else if (sample_bitsize <= 64) + { + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); + } + + return sample_count; +} + +template +void IONGSMSChunkData::write_n_samples( + IONGSMSChunkUnpackingCtx& ctx, + GnssMetadata::Lump::LumpShift lump_shift, + uint8_t sample_bitsize, + std::size_t sample_count, + GnssMetadata::StreamEncoding stream_encoding, + void*& out) +{ + if (lump_shift == GnssMetadata::Lump::shiftRight) + { + auto* sample = static_cast(out); + sample += sample_count; + for (std::size_t i = 0; i < sample_count; ++i) + { + ctx.shift_sample(sample_bitsize, sample); + dump_sample(*sample); + decode_sample(sample_bitsize, sample, stream_encoding); + --sample; + } + } + else // if (lump_shift == GnssMetadata::Lump::shiftLeft || lump_shift == GnssMetadata::Lump::shiftUndefined) + { + auto* sample = static_cast(out); + for (std::size_t i = 0; i < sample_count; ++i) + { + ctx.shift_sample(sample_bitsize, sample); + dump_sample(*sample); + decode_sample(sample_bitsize, sample, stream_encoding); + ++sample; + } + } +} + + + +// Static utilities +void IONGSMSChunkData::decode_sample(const uint8_t sample_bitsize, auto* sample, const GnssMetadata::StreamEncoding encoding) +{ + using SampleType = std::remove_pointer_t; + switch (sample_bitsize) + { + case 2: + *sample = GnssMetadata::two_bit_look_up[encoding][*sample]; + break; + case 3: + *sample = GnssMetadata::three_bit_look_up[encoding][*sample]; + break; + case 4: + *sample = GnssMetadata::four_bit_look_up[encoding][*sample]; + break; + case 5: + *sample = GnssMetadata::five_bit_look_up[encoding][*sample]; + break; + default: + // TODO - Is this an error that can happen? + // for now we'll just do nothing, if the sample is this wide it may need no decoding + break; + } +} void IONGSMSChunkData::dump_sample(auto value) { @@ -102,7 +238,7 @@ void IONGSMSChunkData::dump_sample(auto value) if (count > 0) { --count; - std::cout << "SAMPLE: " << std::bitset<32>(value) << std::endl; + // std::cout << "SAMPLE: [0x" << std::hex << value << "] " << std::bitset<32>(value) << std::endl; } } diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h index f87a03aef..c5fc3e6f7 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h @@ -18,6 +18,8 @@ #define ION_GSM_CHUNK_DATA_H #include "GnssMetadata.h" +#include "ion_gsms_stream_encodings.h" +#include "ion_gsms_chunk_unpacking_ctx.h" #include #if USE_GLOG_AND_GFLAGS @@ -72,144 +74,6 @@ void with_word_type(const uint8_t word_size, auto&& callback) } } -namespace GnssMetadata -{ - using StreamEncoding = unsigned char; - - namespace StreamEncodings - { - constexpr unsigned char SIGN = 0; - constexpr unsigned char OB = 1; - constexpr unsigned char SM = 2; - constexpr unsigned char MS = 3; - constexpr unsigned char TC = 4; - constexpr unsigned char OG = 5; - constexpr unsigned char OBA = 6; - constexpr unsigned char SMA = 7; - constexpr unsigned char MSA = 8; - constexpr unsigned char TCA = 9; - constexpr unsigned char OGA = 10; - constexpr unsigned char FP = 11; - } - - inline StreamEncoding encoding_from_string(const std::string& str) - { - if (str == "SIGN") - { - return StreamEncodings::SIGN; - } - if (str == "OB") - { - return StreamEncodings::OB; - } - if (str == "SM") - { - return StreamEncodings::SM; - } - if (str == "MS") - { - return StreamEncodings::MS; - } - if (str == "TC") - { - return StreamEncodings::TC; - } - if (str == "OG") - { - return StreamEncodings::OG; - } - if (str == "OBA") - { - return StreamEncodings::OBA; - } - if (str == "SMA") - { - return StreamEncodings::SMA; - } - if (str == "MSA") - { - return StreamEncodings::MSA; - } - if (str == "TCA") - { - return StreamEncodings::TCA; - } - if (str == "OGA") - { - return StreamEncodings::OGA; - } - if (str == "FP") - { - return StreamEncodings::FP; - } - return 0; - } - - template - inline T two_bit_look_up[11][4] - { - [0] = {}, - [1 /*OB*/] = {-2, -1, 0, 1}, - [2 /*SM*/] = {0, 1, 0, -1}, - [3 /*MS*/] = {0, 0, 1, -1}, - [4 /*TC*/] = {0, 1, -2, -1}, - [5 /*OG*/] = {-2, -1, 1, 0}, - [6 /*OBA*/] = {-3, -1, 1, 3}, - [7 /*SMA*/] = {1, 3, -1, -3}, - [8 /*MSA*/] = {1, -1, 3, -3}, - [9 /*TCA*/] = {1, 3, -3, -1}, - [10 /*OGA*/] = {-3, -1, 3, 1}, - }; - - template - inline T three_bit_look_up[11][8] - { - [0] = {}, - [1 /*OB*/] = {-4, -3, -2, -1, 0, 1, 2, 3}, - [2 /*SM*/] = {0, 1, 2, 3, 0, -1, -2, -3}, - [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1}, - [4 /*TC*/] = {0, 1, 2, 3, -4, -3, -2, -1}, - [5 /*OG*/] = {-4, -3, -1, -2, 3, 2, 0, 1}, - [6 /*OBA*/] = {-7, -5, -3, -1, 1, 3, 5, 7}, - [7 /*SMA*/] = {1, 3, 5, 7, -1, -3, -5, -7}, - [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7}, - [9 /*TCA*/] = {1, 3, 5, 7, -7, -5, -3, -1}, - [10 /*OGA*/] = {-7, -5, -1, -3, 7, 5, 1, 3}, - }; - - template - inline T four_bit_look_up[11][16] - { - [0] = {}, - [1 /*OB*/] = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}, - [2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7}, - [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, - [4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}, - [5 /*OG*/] = {-8, -7, -5, -6, -1, -2, -4, -3, 7, 6, 4, 5, 0, 1, 3, 2}, - [6 /*OBA*/] = {-15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15}, - [7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15}, - [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15}, - [9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -15, -13, -11, -9, -7, -5, -3, -1}, - [10 /*OGA*/] = {-15, -13, -9, -11, -1, -3, -7, -5, 15, 13, 9, 11, 1, 3, 7, 5}, - }; - - template - inline T five_bit_look_up[11][32] - { - [0] = {}, - [1 /*OB*/] = {-16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, - [2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15}, - [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, - [4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1}, - [5 /*OG*/] = {-16, -15, -13, -14, -9, -10, -12, -11, -1, -2, -4, -3, -8, -7, -5, -6, 15, 14, 12, 13, 8, 9, 11, 10, 0, 1, 3, 2, 7, 6, 4, 5}, - [6 /*OBA*/] = {-31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, - [7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -1, -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -23, -25, -27, -29, -31}, - [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15, 17, -17, 19, -19, 21, -21, 23, -23, 25, -25, 27, -27, 29, -29, 31, -31}, - [9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1}, - [10 /*OGA*/] = {-31, -29, -25, -27, -17, -19, -23, -21, -1, -3, -7, -5, -15, -13, -9, -11, 31, 29, 25, 27, 17, 19, 23, 21, 1, 3, 7, 5, 15, 13, 9, 11}, - }; -} - class IONGSMSChunkData { public: @@ -232,258 +96,26 @@ public: private: template - struct unpacking_context_t - { - WT* iterator_; - WT current_word_; - uint8_t bitshift_ = 0; - }; - - template - void unpack_words(gr_vector_void_star& outputs, const std::function& produce) - { - WT* data = static_cast(buffer_); - // TODO - Swap endiannes if needed - - unpacking_context_t ctx{}; - if (chunk_.Shift() == GnssMetadata::Chunk::Left) - { - ctx.iterator_ = data; - } - else if (chunk_.Shift() == GnssMetadata::Chunk::Right) - { - ctx.iterator_ = &data[countwords_]; - } - advance_word(ctx); // Initializes ctx.current_word_ - - // Head padding - if (padding_bitsize_ > 0 && chunk_.Padding() == GnssMetadata::Chunk::Head) - { - shift_padding(ctx, padding_bitsize_); - } - - // Samples - for (const auto& [lump, stream, encoding, output_index] : streams_) - { - if (output_index == -1) - { - skip_stream(ctx, lump, stream); - } - else - { - produce(output_index, write_stream_samples(ctx, lump, stream, encoding, outputs[output_index])); - } - } - } - - template - void skip_stream( - unpacking_context_t& ctx, - const GnssMetadata::Lump& lump, - const GnssMetadata::IonStream& stream) - { - shift_padding(ctx, stream.Packedbits()); - } + void unpack_words(gr_vector_void_star& outputs, const std::function& produce); template std::size_t write_stream_samples( - unpacking_context_t& ctx, + IONGSMSChunkUnpackingCtx& ctx, const GnssMetadata::Lump& lump, const GnssMetadata::IonStream& stream, - const GnssMetadata::StreamEncoding stream_encoding, - void*& out) - { - std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); - std::size_t sample_count = stream.RateFactor(); - - if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization()) - { - // Samples have 'Complex' format - sample_bitsize /= 2; - sample_count *= 2; - } - - if (sample_bitsize <= 8) - { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); - } - else if (sample_bitsize <= 16) - { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); - } - else if (sample_bitsize <= 32) - { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); - } - else if (sample_bitsize <= 64) - { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); - } - - return sample_count; - } + GnssMetadata::StreamEncoding stream_encoding, + void*& out); template void write_n_samples( - unpacking_context_t& ctx, + IONGSMSChunkUnpackingCtx& ctx, GnssMetadata::Lump::LumpShift lump_shift, uint8_t sample_bitsize, std::size_t sample_count, GnssMetadata::StreamEncoding stream_encoding, - void*& out) - { - if (lump_shift == GnssMetadata::Lump::shiftRight) - { - auto* sample = static_cast(out); - sample += sample_count; - for (std::size_t i = 0; i < sample_count; ++i) - { - shift_sample(ctx, sample_bitsize, sample); - decode_sample(sample_bitsize, sample, stream_encoding); - --sample; - } - } - else // if (lump_shift == GnssMetadata::Lump::shiftLeft || lump_shift == GnssMetadata::Lump::shiftUndefined) - { - auto* sample = static_cast(out); - for (std::size_t i = 0; i < sample_count; ++i) - { - shift_sample(ctx, sample_bitsize, sample); - decode_sample(sample_bitsize, sample, stream_encoding); - ++sample; - } - } - } + void*& out); - template - void shift_sample(unpacking_context_t& ctx, uint8_t sample_bitsize, OT* output, uint8_t output_bit_offset = 0) - { - const uint8_t word_bitsize = sizeword_ * 8; - - if ((sample_bitsize + (ctx.bitshift_ % word_bitsize)) > word_bitsize) - { - uint8_t bits_shifted = word_bitsize - (ctx.bitshift_ % word_bitsize); - - if (chunk_.Shift() == GnssMetadata::Chunk::Left) - { - WT mask = ~((1 << (word_bitsize - bits_shifted)) - 1); - dump_sample(ctx.current_word_ & mask); - *output |= ((ctx.current_word_ & mask) >> output_bit_offset); - ctx.current_word_ <<= bits_shifted; - } - else if (chunk_.Shift() == GnssMetadata::Chunk::Right) - { - WT mask = ((1 << (bits_shifted)) - 1); - dump_sample(ctx.current_word_ & mask); - *output |= (ctx.current_word_ & mask) << output_bit_offset; - // TODO - reverse bit order of sample? maybe? - ctx.current_word_ >>= bits_shifted; - } - - advance_word(ctx); - ctx.bitshift_ += bits_shifted; - shift_sample(ctx, sample_bitsize - bits_shifted, output, bits_shifted); - } - else - { - if (chunk_.Shift() == GnssMetadata::Chunk::Left) - { - WT mask = ~((1 << (word_bitsize - sample_bitsize)) - 1); - OT sample = (ctx.current_word_ & mask) >> (word_bitsize - sample_bitsize); - dump_sample(sample); - *output |= (sample) >> output_bit_offset; - ctx.current_word_ <<= sample_bitsize; - } - else if (chunk_.Shift() == GnssMetadata::Chunk::Right) - { - WT mask = ((1 << (sample_bitsize)) - 1); - dump_sample(ctx.current_word_ & mask); - *output |= (ctx.current_word_ & mask) << output_bit_offset; - // TODO - reverse bit order of sample? maybe? - ctx.current_word_ >>= sample_bitsize; - } - - ctx.bitshift_ += sample_bitsize; - } - } - - template - void shift_padding(unpacking_context_t& ctx, uint8_t n_bits) - { - if(n_bits == 0) return; - - const uint8_t word_bitsize = sizeword_ * 8; - - if ((n_bits + (ctx.bitshift_ % word_bitsize)) >= word_bitsize) - { - uint8_t bits_shifted = word_bitsize - (ctx.bitshift_ % word_bitsize); - - if (chunk_.Shift() == GnssMetadata::Chunk::Left) - { - ctx.current_word_ <<= bits_shifted; - } - else if (chunk_.Shift() == GnssMetadata::Chunk::Right) - { - ctx.current_word_ >>= bits_shifted; - } - - advance_word(ctx); - ctx.bitshift_ += bits_shifted; - shift_padding(ctx, n_bits - bits_shifted); - } - else - { - if (chunk_.Shift() == GnssMetadata::Chunk::Left) - { - ctx.current_word_ <<= n_bits; - } - else if (chunk_.Shift() == GnssMetadata::Chunk::Right) - { - ctx.current_word_ >>= n_bits; - } - - ctx.bitshift_ += n_bits; - } - } - - template - void advance_word(unpacking_context_t& ctx) - { - WT word = *ctx.iterator_; - if (chunk_.Shift() == GnssMetadata::Chunk::Left) - { - ++ctx.iterator_; - } - else if (chunk_.Shift() == GnssMetadata::Chunk::Right) - { - --ctx.iterator_; - } - - ctx.current_word_ = word; - } - - template - static void decode_sample(const uint8_t sample_bitsize, ST* sample, const GnssMetadata::StreamEncoding encoding) - { - switch (sample_bitsize) - { - case 2: - *sample = GnssMetadata::two_bit_look_up[encoding][*sample]; - break; - case 3: - *sample = GnssMetadata::three_bit_look_up[encoding][*sample]; - break; - case 4: - *sample = GnssMetadata::four_bit_look_up[encoding][*sample]; - break; - case 5: - *sample = GnssMetadata::five_bit_look_up[encoding][*sample]; - break; - default: - // TODO - Is this an error that can happen? - break; - } - } + static void decode_sample(uint8_t sample_bitsize, auto* sample, GnssMetadata::StreamEncoding encoding); static void dump_sample(auto value); diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h new file mode 100644 index 000000000..249063e4d --- /dev/null +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h @@ -0,0 +1,153 @@ +/*! + * \file ion_gsms_chunk_unpacking_ctx.h + * \brief Holds state and provides utilities for unpacking samples from a chunk + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * This is a template class, and thus, its member functions must be defined in the header file. + * + * ----------------------------------------------------------------------------- + * + * 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 ION_GSM_CHUNK_UNPACKING_CTX_H +#define ION_GSM_CHUNK_UNPACKING_CTX_H + +#include "GnssMetadata.h" +#include + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +template +struct IONGSMSChunkUnpackingCtx +{ + static constexpr uint8_t word_bitsize_ = sizeof(WT) * 8; + + const GnssMetadata::Chunk::WordShift word_shift_direction_; + WT* iterator_; // Not owned by this class, must not destroy + WT current_word_; + uint8_t bitshift_ = 0; + + IONGSMSChunkUnpackingCtx( + const GnssMetadata::Chunk::WordShift word_shift, + WT* data_buffer, + uint8_t data_buffer_word_count) : word_shift_direction_(word_shift) + { + if (word_shift_direction_ == GnssMetadata::Chunk::Left) + { + iterator_ = data_buffer; + } + else if (word_shift_direction_ == GnssMetadata::Chunk::Right) + { + iterator_ = &data_buffer[data_buffer_word_count]; + } + advance_word(); // Initializes current_word_ + } + + void advance_word() + { + WT word = *iterator_; + if (word_shift_direction_ == GnssMetadata::Chunk::Left) + { + ++iterator_; + } + else if (word_shift_direction_ == GnssMetadata::Chunk::Right) + { + --iterator_; + } + + current_word_ = word; + } + + void shift_current_word(uint8_t n) + { + if (word_shift_direction_ == GnssMetadata::Chunk::Left) + { + current_word_ <<= n; + } + else if (word_shift_direction_ == GnssMetadata::Chunk::Right) + { + current_word_ >>= n; + } + + bitshift_ += n; + if (bitshift_ >= word_bitsize_) + { + advance_word(); + bitshift_ -= word_bitsize_; + } + } + + void shift_padding(uint8_t n_bits) + { + if (n_bits == 0) + { + return; + } + + if ((n_bits + (bitshift_ % word_bitsize_)) >= word_bitsize_) + { + const uint8_t bits_shifted = word_bitsize_ - (bitshift_ % word_bitsize_); + + shift_current_word(bits_shifted); + shift_padding(n_bits - bits_shifted); + } + else + { + shift_current_word(n_bits); + } + } + + template + void shift_sample(const uint8_t sample_bitsize, OT* output, uint8_t output_bit_offset = 0) + { + if ((sample_bitsize + (bitshift_ % word_bitsize_)) > word_bitsize_) + { + const uint8_t bits_shifted = word_bitsize_ - (bitshift_ % word_bitsize_); + + if (word_shift_direction_ == GnssMetadata::Chunk::Left) + { + WT mask = ~((1 << (word_bitsize_ - bits_shifted)) - 1); + *output |= ((current_word_ & mask) >> output_bit_offset); + } + else if (word_shift_direction_ == GnssMetadata::Chunk::Right) + { + WT mask = ((1 << (bits_shifted)) - 1); + *output |= (current_word_ & mask) << output_bit_offset; + // TODO - reverse bit order of sample? maybe? + } + + shift_current_word(bits_shifted); + shift_sample(sample_bitsize - bits_shifted, output, bits_shifted); + } + else + { + if (word_shift_direction_ == GnssMetadata::Chunk::Left) + { + WT mask = ~((1 << (word_bitsize_ - sample_bitsize)) - 1); + OT sample = (current_word_ & mask) >> (word_bitsize_ - sample_bitsize); + *output |= (sample) >> output_bit_offset; + } + else if (word_shift_direction_ == GnssMetadata::Chunk::Right) + { + WT mask = ((1 << (sample_bitsize)) - 1); + *output |= (current_word_ & mask) << output_bit_offset; + // TODO - reverse bit order of sample? maybe? + } + + shift_current_word(sample_bitsize); + } + } +}; + +#endif //ION_GSM_CHUNK_UNPACKING_CTX_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h b/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h new file mode 100644 index 000000000..8f965ad99 --- /dev/null +++ b/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h @@ -0,0 +1,164 @@ +/*! + * \file ion_gsms_stream_encodings.h + * \brief Implements look up tables for all encodings in the standard + * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com + * + * ----------------------------------------------------------------------------- + * + * 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 ION_GSM_STREAM_ENCODINGS_H +#define ION_GSM_STREAM_ENCODINGS_H + +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + +namespace GnssMetadata +{ + using StreamEncoding = unsigned char; + + namespace StreamEncodings + { + constexpr unsigned char SIGN = 0; + constexpr unsigned char OB = 1; + constexpr unsigned char SM = 2; + constexpr unsigned char MS = 3; + constexpr unsigned char TC = 4; + constexpr unsigned char OG = 5; + constexpr unsigned char OBA = 6; + constexpr unsigned char SMA = 7; + constexpr unsigned char MSA = 8; + constexpr unsigned char TCA = 9; + constexpr unsigned char OGA = 10; + constexpr unsigned char FP = 11; + } + + inline StreamEncoding encoding_from_string(const std::string& str) + { + if (str == "SIGN") + { + return StreamEncodings::SIGN; + } + if (str == "OB") + { + return StreamEncodings::OB; + } + if (str == "SM") + { + return StreamEncodings::SM; + } + if (str == "MS") + { + return StreamEncodings::MS; + } + if (str == "TC") + { + return StreamEncodings::TC; + } + if (str == "OG") + { + return StreamEncodings::OG; + } + if (str == "OBA") + { + return StreamEncodings::OBA; + } + if (str == "SMA") + { + return StreamEncodings::SMA; + } + if (str == "MSA") + { + return StreamEncodings::MSA; + } + if (str == "TCA") + { + return StreamEncodings::TCA; + } + if (str == "OGA") + { + return StreamEncodings::OGA; + } + if (str == "FP") + { + return StreamEncodings::FP; + } + return 0; + } + + template + inline T two_bit_look_up[11][4] + { + [0] = {}, + [1 /*OB*/] = {-2, -1, 0, 1}, + [2 /*SM*/] = {0, 1, 0, -1}, + [3 /*MS*/] = {0, 0, 1, -1}, + [4 /*TC*/] = {0, 1, -2, -1}, + [5 /*OG*/] = {-2, -1, 1, 0}, + [6 /*OBA*/] = {-3, -1, 1, 3}, + [7 /*SMA*/] = {1, 3, -1, -3}, + [8 /*MSA*/] = {1, -1, 3, -3}, + [9 /*TCA*/] = {1, 3, -3, -1}, + [10 /*OGA*/] = {-3, -1, 3, 1}, + }; + + template + inline T three_bit_look_up[11][8] + { + [0] = {}, + [1 /*OB*/] = {-4, -3, -2, -1, 0, 1, 2, 3}, + [2 /*SM*/] = {0, 1, 2, 3, 0, -1, -2, -3}, + [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1}, + [4 /*TC*/] = {0, 1, 2, 3, -4, -3, -2, -1}, + [5 /*OG*/] = {-4, -3, -1, -2, 3, 2, 0, 1}, + [6 /*OBA*/] = {-7, -5, -3, -1, 1, 3, 5, 7}, + [7 /*SMA*/] = {1, 3, 5, 7, -1, -3, -5, -7}, + [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7}, + [9 /*TCA*/] = {1, 3, 5, 7, -7, -5, -3, -1}, + [10 /*OGA*/] = {-7, -5, -1, -3, 7, 5, 1, 3}, + }; + + template + inline T four_bit_look_up[11][16] + { + [0] = {}, + [1 /*OB*/] = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}, + [2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7}, + [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, + [4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}, + [5 /*OG*/] = {-8, -7, -5, -6, -1, -2, -4, -3, 7, 6, 4, 5, 0, 1, 3, 2}, + [6 /*OBA*/] = {-15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15}, + [7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15}, + [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15}, + [9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -15, -13, -11, -9, -7, -5, -3, -1}, + [10 /*OGA*/] = {-15, -13, -9, -11, -1, -3, -7, -5, 15, 13, 9, 11, 1, 3, 7, 5}, + }; + + template + inline T five_bit_look_up[11][32] + { + [0] = {}, + [1 /*OB*/] = {-16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + [2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15}, + [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, + [4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1}, + [5 /*OG*/] = {-16, -15, -13, -14, -9, -10, -12, -11, -1, -2, -4, -3, -8, -7, -5, -6, 15, 14, 12, 13, 8, 9, 11, 10, 0, 1, 3, 2, 7, 6, 4, 5}, + [6 /*OBA*/] = {-31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, + [7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -1, -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -23, -25, -27, -29, -31}, + [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15, 17, -17, 19, -19, 21, -21, 23, -23, 25, -25, 27, -27, 29, -29, 31, -31}, + [9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1}, + [10 /*OGA*/] = {-31, -29, -25, -27, -17, -19, -23, -21, -1, -3, -7, -5, -15, -13, -9, -11, 31, 29, 25, 27, 17, 19, 23, 21, 1, 3, 7, 5, 15, 13, 9, 11}, + }; +} + +#endif //ION_GSM_STREAM_ENCODINGS_H From cd2614a4dc2d6acaca3f1ee90ae4137ee765f53f Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Sun, 28 Jul 2024 17:36:29 +0200 Subject: [PATCH 08/34] Bufferef IO & propagate configuration inside ION source --- .../adapters/ion_gsms_signal_source.cc | 2 +- src/algorithms/signal_source/libs/ion_gsms.cc | 43 ++++++++++++++++--- src/algorithms/signal_source/libs/ion_gsms.h | 7 +++ .../signal_source/libs/ion_gsms_chunk_data.cc | 9 +++- .../signal_source/libs/ion_gsms_chunk_data.h | 2 +- .../libs/ion_gsms_metadata_handler.cc | 4 +- .../libs/ion_gsms_metadata_handler.h | 3 +- 7 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc index d01268d67..0be954a4a 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc @@ -66,7 +66,7 @@ IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configura LOG(ERROR) << "A signal source does not have an input stream"; } - sources_ = metadata_.make_stream_sources(stream_ids_); + sources_ = metadata_.make_stream_sources(configuration, role, stream_ids_); for (const auto& source : sources_) { diff --git a/src/algorithms/signal_source/libs/ion_gsms.cc b/src/algorithms/signal_source/libs/ion_gsms.cc index 2034f12d1..66acb865c 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.cc +++ b/src/algorithms/signal_source/libs/ion_gsms.cc @@ -25,8 +25,11 @@ #include #endif +using namespace std::string_literals; IONGSMSFileSource::IONGSMSFileSource( + const ConfigurationInterface* configuration, + const std::string& role, const std::filesystem::path& metadata_filepath, const GnssMetadata::File& file, const GnssMetadata::Block& block, @@ -36,7 +39,9 @@ IONGSMSFileSource::IONGSMSFileSource( gr::io_signature::make(0, 0, 0), make_output_signature(block, stream_ids)), file_metadata_(file), - block_metadata_(block) + block_metadata_(block), + io_buffer_offset_(0), + chunk_cycle_length_(0) { std::filesystem::path data_filepath = metadata_filepath.parent_path() / file.Url().Value(); fd_ = std::fopen(data_filepath.c_str(), "rb"); @@ -47,6 +52,7 @@ IONGSMSFileSource::IONGSMSFileSource( for (const auto& chunk : block.Chunks()) { chunk_data_.emplace_back(std::make_shared(chunk, stream_ids, output_stream_offset)); + chunk_cycle_length_ += chunk.CountWords() * chunk.SizeWord(); const std::size_t out_count = chunk_data_.back()->output_stream_count(); output_stream_offset += out_count; for (std::size_t i = 0; i < out_count; ++i) @@ -55,6 +61,8 @@ IONGSMSFileSource::IONGSMSFileSource( } } output_stream_count_ = output_stream_offset; + + io_buffer_.resize(1024 * chunk_cycle_length_); } IONGSMSFileSource::~IONGSMSFileSource() @@ -67,16 +75,39 @@ int IONGSMSFileSource::work( gr_vector_const_void_star& input_items, gr_vector_void_star& output_items) { - // for (int i = 0; i < noutput_items; ++i) - // { + io_buffer_offset_ = 0; + std::fread(io_buffer_.data(), sizeof(decltype(io_buffer_)::value_type), io_buffer_.size(), fd_); + std::vector items_produced{}; + + items_produced.resize(output_items.size()); + for (int i = 0; i < items_produced.size(); ++i) + { + items_produced[i] = 0; + } + + + while (io_buffer_offset_ < io_buffer_.size()) + { for (auto& c : chunk_data_) { - c->read_from_file(fd_); + io_buffer_offset_ += c->read_from_buffer(io_buffer_.data(), io_buffer_offset_); c->write_to_output(output_items, [&](int output, int nitems) { - produce(output, nitems); + items_produced[output] += nitems; + + // if (nitems_written(output) % 100 == 0) + // { + // add_item_tag(output, nitems_written(output), pmt::mp("tag_test"), pmt::from_uint64(nitems_written(output))); + // } }); } - // } + } + + std::cout << "produced: " << std::to_string(items_produced[0]) << std::endl; + for (int i = 0; i < items_produced.size(); ++i) + { + produce(i, items_produced[i]); + } + return WORK_CALLED_PRODUCE; } diff --git a/src/algorithms/signal_source/libs/ion_gsms.h b/src/algorithms/signal_source/libs/ion_gsms.h index a15206b84..a1091e700 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.h +++ b/src/algorithms/signal_source/libs/ion_gsms.h @@ -19,10 +19,12 @@ #include "gnss_block_interface.h" #include "ion_gsms_chunk_data.h" +#include "configuration_interface.h" #include #include #include #include +#include class IONGSMSFileSource : public gr::sync_block @@ -31,6 +33,8 @@ public: using sptr = gnss_shared_ptr; IONGSMSFileSource( + const ConfigurationInterface* configuration, + const std::string& role, const std::filesystem::path& metadata_filepath, const GnssMetadata::File& file, const GnssMetadata::Block& block, @@ -53,9 +57,12 @@ private: const GnssMetadata::File& file_metadata_; const GnssMetadata::Block& block_metadata_; FILE* fd_; + std::vector io_buffer_; + std::size_t io_buffer_offset_; std::size_t output_stream_count_; std::vector output_stream_item_sizes_; std::vector> chunk_data_; + std::size_t chunk_cycle_length_; }; #include "ion_gsms_metadata_handler.h" diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc index 8a0d1a7b4..54d74e084 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc @@ -76,9 +76,11 @@ IONGSMSChunkData::~IONGSMSChunkData() }); } -void IONGSMSChunkData::read_from_file(FILE* fd) +std::size_t IONGSMSChunkData::read_from_buffer(uint8_t* buffer, std::size_t offset) { - std::fread(buffer_, sizeword_, countwords_, fd); + memset(buffer_, 0, sizeword_ * countwords_); + memcpy(buffer_, &buffer[offset], sizeword_ * countwords_); + return sizeword_ * countwords_; } void IONGSMSChunkData::write_to_output(gr_vector_void_star& outputs, const std::function& produce) @@ -89,6 +91,7 @@ void IONGSMSChunkData::write_to_output(gr_vector_void_star& outputs, const std:: }); } + std::size_t IONGSMSChunkData::output_stream_count() const { return output_stream_count_; @@ -203,6 +206,8 @@ void IONGSMSChunkData::write_n_samples( ++sample; } } + + out += sample_count * sizeof(OT); } diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h index c5fc3e6f7..6a4f7e49e 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h @@ -87,7 +87,7 @@ public: IONGSMSChunkData(IONGSMSChunkData&& rhl) = delete; IONGSMSChunkData& operator=(IONGSMSChunkData&& rhl) = delete; - void read_from_file(FILE* fd); + std::size_t read_from_buffer(uint8_t* buffer, std::size_t offset); void write_to_output(gr_vector_void_star& outputs, const std::function& produce); diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc index 48aced035..e9568bb93 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc @@ -53,7 +53,7 @@ void IONGSMSMetadataHandler::load_metadata() } } -std::vector IONGSMSMetadataHandler::make_stream_sources(const std::vector& stream_ids) const +std::vector IONGSMSMetadataHandler::make_stream_sources(const ConfigurationInterface* configuration, const std::string& role, const std::vector& stream_ids) const { std::vector sources{}; for (const auto& file : metadata_.Files()) @@ -75,6 +75,8 @@ std::vector IONGSMSMetadataHandler::make_stream_sources })) { auto source = gnss_make_shared( + configuration, + role, metadata_filepath_, file, block, diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h index 0cbf634f6..28da13564 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h @@ -18,6 +18,7 @@ #define ION_GSMS_METADATA_HANDLER_H #include "GnssMetadata.h" +#include "configuration_interface.h" #include #if USE_GLOG_AND_GFLAGS @@ -31,7 +32,7 @@ class IONGSMSMetadataHandler public: explicit IONGSMSMetadataHandler(const std::string& metadata_filepath); - std::vector make_stream_sources(const std::vector& stream_ids) const; + std::vector make_stream_sources(const ConfigurationInterface* configuration, const std::string& role, const std::vector& stream_ids) const; public: // Getters const std::string& metadata_filepath() const; From 38a24f525040e4079ac86984e0b8bc2fd9aef8b1 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Fri, 16 Aug 2024 15:51:24 +0200 Subject: [PATCH 09/34] Reset sample value before writing new one Sample values are ORed into the output buffer because they may need a few read/write operations depending on alignment. So, if we don't set the value to 0 before doing this, all samples quickly become 0xFF after a few cycles of the output buffer. --- src/algorithms/signal_source/libs/ion_gsms.cc | 4 ++-- src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc | 2 ++ .../signal_source/libs/ion_gsms_metadata_handler.cc | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/algorithms/signal_source/libs/ion_gsms.cc b/src/algorithms/signal_source/libs/ion_gsms.cc index 66acb865c..fed13c8a2 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.cc +++ b/src/algorithms/signal_source/libs/ion_gsms.cc @@ -62,7 +62,7 @@ IONGSMSFileSource::IONGSMSFileSource( } output_stream_count_ = output_stream_offset; - io_buffer_.resize(1024 * chunk_cycle_length_); + io_buffer_.resize((16*1024 - 1) * chunk_cycle_length_); } IONGSMSFileSource::~IONGSMSFileSource() @@ -102,7 +102,7 @@ int IONGSMSFileSource::work( } } - std::cout << "produced: " << std::to_string(items_produced[0]) << std::endl; + // std::cout << "produced: " << std::to_string(items_produced[0]) << " out of " << std::to_string(noutput_items) << std::endl; for (int i = 0; i < items_produced.size(); ++i) { produce(i, items_produced[i]); diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc index 54d74e084..e8fb0157a 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc @@ -189,6 +189,7 @@ void IONGSMSChunkData::write_n_samples( sample += sample_count; for (std::size_t i = 0; i < sample_count; ++i) { + *sample = 0; ctx.shift_sample(sample_bitsize, sample); dump_sample(*sample); decode_sample(sample_bitsize, sample, stream_encoding); @@ -200,6 +201,7 @@ void IONGSMSChunkData::write_n_samples( auto* sample = static_cast(out); for (std::size_t i = 0; i < sample_count; ++i) { + *sample = 0; ctx.shift_sample(sample_bitsize, sample); dump_sample(*sample); decode_sample(sample_bitsize, sample, stream_encoding); diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc index e9568bb93..47ae4e6ed 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc @@ -45,7 +45,7 @@ void IONGSMSMetadataHandler::load_metadata() } catch (GnssMetadata::ApiException& e) { - LOG(ERROR) << "API Exception while loadind XML metadata file: " << e.what(); + LOG(ERROR) << "API Exception while loading XML metadata file: " << std::to_string(e.Error()); } catch (std::exception& e) { From 01bbc39fa64f018839f035644f5d4a6fd45f858b Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Sat, 17 Aug 2024 20:14:31 +0200 Subject: [PATCH 10/34] Simpler handling of simpler bit formats If a sample is the same size as a word, it is much easier to read. --- .../libs/ion_gsms_chunk_unpacking_ctx.h | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h index 249063e4d..758e9b197 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h @@ -34,7 +34,7 @@ struct IONGSMSChunkUnpackingCtx static constexpr uint8_t word_bitsize_ = sizeof(WT) * 8; const GnssMetadata::Chunk::WordShift word_shift_direction_; - WT* iterator_; // Not owned by this class, must not destroy + WT* iterator_; // Not owned by this class, MUST NOT destroy WT current_word_; uint8_t bitshift_ = 0; @@ -71,6 +71,15 @@ struct IONGSMSChunkUnpackingCtx void shift_current_word(uint8_t n) { + if ((n % word_bitsize_) == 0) + { + for (uint8_t i = 0; i < (n / word_bitsize_); ++i) + { + advance_word(); + } + return; + } + if (word_shift_direction_ == GnssMetadata::Chunk::Left) { current_word_ <<= n; @@ -111,7 +120,24 @@ struct IONGSMSChunkUnpackingCtx template void shift_sample(const uint8_t sample_bitsize, OT* output, uint8_t output_bit_offset = 0) { - if ((sample_bitsize + (bitshift_ % word_bitsize_)) > word_bitsize_) + if (sample_bitsize % word_bitsize_ == 0) + { + const uint8_t words_per_sample = sample_bitsize / word_bitsize_; + for (uint8_t i = 0; i < words_per_sample; ++i) + { + if (word_shift_direction_ == GnssMetadata::Chunk::Left) + { + *output |= (current_word_ << ((words_per_sample - 1 - i) * word_bitsize_)); + } + else if (word_shift_direction_ == GnssMetadata::Chunk::Right) + { + *output |= (current_word_ << (i * word_bitsize_)); + // TODO - reverse bit order of sample? maybe? + } + advance_word(); + } + } + else if ((sample_bitsize + (bitshift_ % word_bitsize_)) > word_bitsize_) { const uint8_t bits_shifted = word_bitsize_ - (bitshift_ % word_bitsize_); From 33067d631d1398c5b41ec7f952fee93d00858426 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Sat, 17 Aug 2024 20:20:27 +0200 Subject: [PATCH 11/34] Less callback shenanigans --- src/algorithms/signal_source/libs/ion_gsms.cc | 25 ++++++----------- src/algorithms/signal_source/libs/ion_gsms.h | 1 + .../signal_source/libs/ion_gsms_chunk_data.cc | 28 ++++++++++++++----- .../signal_source/libs/ion_gsms_chunk_data.h | 4 +-- 4 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/algorithms/signal_source/libs/ion_gsms.cc b/src/algorithms/signal_source/libs/ion_gsms.cc index fed13c8a2..1f6841224 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.cc +++ b/src/algorithms/signal_source/libs/ion_gsms.cc @@ -77,35 +77,26 @@ int IONGSMSFileSource::work( { io_buffer_offset_ = 0; std::fread(io_buffer_.data(), sizeof(decltype(io_buffer_)::value_type), io_buffer_.size(), fd_); - std::vector items_produced{}; - items_produced.resize(output_items.size()); - for (int i = 0; i < items_produced.size(); ++i) + items_produced_.resize(output_items.size()); + for (int i = 0; i < items_produced_.size(); ++i) { - items_produced[i] = 0; + items_produced_[i] = 0; } - while (io_buffer_offset_ < io_buffer_.size()) { for (auto& c : chunk_data_) { - io_buffer_offset_ += c->read_from_buffer(io_buffer_.data(), io_buffer_offset_); - c->write_to_output(output_items, [&](int output, int nitems) { - items_produced[output] += nitems; - - // if (nitems_written(output) % 100 == 0) - // { - // add_item_tag(output, nitems_written(output), pmt::mp("tag_test"), pmt::from_uint64(nitems_written(output))); - // } - }); + auto* chunk = c.get(); + io_buffer_offset_ += chunk->read_from_buffer(io_buffer_.data(), io_buffer_offset_); + chunk->write_to_output(output_items, items_produced_); } } - // std::cout << "produced: " << std::to_string(items_produced[0]) << " out of " << std::to_string(noutput_items) << std::endl; - for (int i = 0; i < items_produced.size(); ++i) + for (int i = 0; i < items_produced_.size(); ++i) { - produce(i, items_produced[i]); + produce(i, items_produced_[i]); } return WORK_CALLED_PRODUCE; diff --git a/src/algorithms/signal_source/libs/ion_gsms.h b/src/algorithms/signal_source/libs/ion_gsms.h index a1091e700..629e00866 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.h +++ b/src/algorithms/signal_source/libs/ion_gsms.h @@ -59,6 +59,7 @@ private: FILE* fd_; std::vector io_buffer_; std::size_t io_buffer_offset_; + std::vector items_produced_; std::size_t output_stream_count_; std::vector output_stream_item_sizes_; std::vector> chunk_data_; diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc index e8fb0157a..dd2a09865 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc @@ -83,12 +83,26 @@ std::size_t IONGSMSChunkData::read_from_buffer(uint8_t* buffer, std::size_t offs return sizeword_ * countwords_; } -void IONGSMSChunkData::write_to_output(gr_vector_void_star& outputs, const std::function& produce) +void IONGSMSChunkData::write_to_output(gr_vector_void_star& outputs, std::vector& output_items) { - with_word_type(sizeword_, [&] - { - unpack_words(outputs, produce); - }); + switch (sizeword_) + { + case 1: + unpack_words(outputs, output_items); + break; + case 2: + unpack_words(outputs, output_items); + break; + case 4: + unpack_words(outputs, output_items); + break; + case 8: + unpack_words(outputs, output_items); + break; + default: + LOG(ERROR) << "Unknown word size (" << std::to_string(sizeword_) << "), unpacking nothing."; + break; + } } @@ -104,7 +118,7 @@ std::size_t IONGSMSChunkData::output_stream_item_size(std::size_t stream_index) template -void IONGSMSChunkData::unpack_words(gr_vector_void_star& outputs, const std::function& produce) +void IONGSMSChunkData::unpack_words(gr_vector_void_star& outputs, std::vector& output_items) { WT* data = static_cast(buffer_); // TODO - Swap endiannes if needed @@ -131,7 +145,7 @@ void IONGSMSChunkData::unpack_words(gr_vector_void_star& outputs, const std::fun } else { - produce(output_index, write_stream_samples(ctx, lump, stream, encoding, outputs[output_index])); + output_items[output_index] += write_stream_samples(ctx, lump, stream, encoding, outputs[output_index]); } } } diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h index 6a4f7e49e..4f517cf3f 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h @@ -89,14 +89,14 @@ public: std::size_t read_from_buffer(uint8_t* buffer, std::size_t offset); - void write_to_output(gr_vector_void_star& outputs, const std::function& produce); + void write_to_output(gr_vector_void_star& outputs, std::vector& output_items); std::size_t output_stream_count() const; std::size_t output_stream_item_size(std::size_t stream_index) const; private: template - void unpack_words(gr_vector_void_star& outputs, const std::function& produce); + void unpack_words(gr_vector_void_star& outputs, std::vector& output_items); template std::size_t write_stream_samples( From b36894246393f691b211432e8a475393e05029d7 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Sat, 17 Aug 2024 20:22:39 +0200 Subject: [PATCH 12/34] Fix wrong buffer size --- src/algorithms/signal_source/libs/ion_gsms.cc | 6 ++++-- src/algorithms/signal_source/libs/ion_gsms.h | 1 + src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc | 8 ++++++++ src/algorithms/signal_source/libs/ion_gsms_chunk_data.h | 2 ++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/algorithms/signal_source/libs/ion_gsms.cc b/src/algorithms/signal_source/libs/ion_gsms.cc index 1f6841224..d7036907a 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.cc +++ b/src/algorithms/signal_source/libs/ion_gsms.cc @@ -41,6 +41,7 @@ IONGSMSFileSource::IONGSMSFileSource( file_metadata_(file), block_metadata_(block), io_buffer_offset_(0), + maximum_item_rate_(0), chunk_cycle_length_(0) { std::filesystem::path data_filepath = metadata_filepath.parent_path() / file.Url().Value(); @@ -58,11 +59,10 @@ IONGSMSFileSource::IONGSMSFileSource( for (std::size_t i = 0; i < out_count; ++i) { output_stream_item_sizes_.push_back(chunk_data_.back()->output_stream_item_size(i)); + maximum_item_rate_ = std::max(chunk_data_.back()->output_stream_item_rate(i), maximum_item_rate_); } } output_stream_count_ = output_stream_offset; - - io_buffer_.resize((16*1024 - 1) * chunk_cycle_length_); } IONGSMSFileSource::~IONGSMSFileSource() @@ -75,6 +75,8 @@ int IONGSMSFileSource::work( gr_vector_const_void_star& input_items, gr_vector_void_star& output_items) { + const std::size_t max_sample_output = std::floor((noutput_items-1.0) / maximum_item_rate_); + io_buffer_.resize(max_sample_output * chunk_cycle_length_); io_buffer_offset_ = 0; std::fread(io_buffer_.data(), sizeof(decltype(io_buffer_)::value_type), io_buffer_.size(), fd_); diff --git a/src/algorithms/signal_source/libs/ion_gsms.h b/src/algorithms/signal_source/libs/ion_gsms.h index 629e00866..443ed3a81 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.h +++ b/src/algorithms/signal_source/libs/ion_gsms.h @@ -62,6 +62,7 @@ private: std::vector items_produced_; std::size_t output_stream_count_; std::vector output_stream_item_sizes_; + std::size_t maximum_item_rate_; std::vector> chunk_data_; std::size_t chunk_cycle_length_; }; diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc index dd2a09865..229d7a0d5 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc @@ -49,12 +49,15 @@ IONGSMSChunkData::IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std:: streams_.emplace_back(lump, stream, GnssMetadata::encoding_from_string(stream.Encoding()),output_streams + output_stream_offset); ++output_streams; std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); + std::size_t sample_rate = stream.RateFactor(); if (stream.Packedbits() >= 2 * stream.RateFactor() * stream.Quantization()) { // Samples have 'Complex' format sample_bitsize /= 2; + sample_rate *= 2; } output_stream_item_size_.push_back(bits_to_item_size(sample_bitsize)); + output_stream_item_rate_.push_back(sample_rate); } else { @@ -116,6 +119,11 @@ std::size_t IONGSMSChunkData::output_stream_item_size(std::size_t stream_index) return output_stream_item_size_[stream_index]; } +std::size_t IONGSMSChunkData::output_stream_item_rate(std::size_t stream_index) const +{ + return output_stream_item_rate_[stream_index]; +} + template void IONGSMSChunkData::unpack_words(gr_vector_void_star& outputs, std::vector& output_items) diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h index 4f517cf3f..97ce022c4 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h @@ -93,6 +93,7 @@ public: std::size_t output_stream_count() const; std::size_t output_stream_item_size(std::size_t stream_index) const; + std::size_t output_stream_item_rate(std::size_t stream_index) const; private: template @@ -126,6 +127,7 @@ private: uint8_t padding_bitsize_; std::size_t output_stream_count_; std::vector output_stream_item_size_; + std::vector output_stream_item_rate_; struct stream_metadata_t { From cf01a2d37a3ab9317489bad69792db7f7ff81e82 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Sat, 17 Aug 2024 20:40:13 +0200 Subject: [PATCH 13/34] Fixed conditional compilation issues And added a comment --- .../signal_source/libs/ion_gsms_stream_encodings.h | 2 ++ src/core/receiver/CMakeLists.txt | 4 ++++ src/core/receiver/gnss_block_factory.cc | 8 ++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h b/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h index 8f965ad99..f8551159b 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h +++ b/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h @@ -3,6 +3,8 @@ * \brief Implements look up tables for all encodings in the standard * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com * + * These tables are taken from the stardard's official document. + * * ----------------------------------------------------------------------------- * * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. diff --git a/src/core/receiver/CMakeLists.txt b/src/core/receiver/CMakeLists.txt index cacef7f6f..604449390 100644 --- a/src/core/receiver/CMakeLists.txt +++ b/src/core/receiver/CMakeLists.txt @@ -70,6 +70,10 @@ if(ENABLE_FPGA) target_compile_definitions(core_receiver PUBLIC -DENABLE_FPGA=1) endif() +if(ENABLE_ION) + target_compile_definitions(core_receiver PRIVATE -DENABLE_ION_SOURCE=1) +endif() + if(GNURADIO_USES_STD_POINTERS) target_compile_definitions(core_receiver PUBLIC -DGNURADIO_USES_STD_POINTERS=1) endif() diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 99a05e95c..07069ed9e 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -93,7 +93,6 @@ #include "ibyte_to_complex.h" #include "ibyte_to_cshort.h" #include "in_memory_configuration.h" -#include "ion_gsms_signal_source.h" #include "ishort_to_complex.h" #include "ishort_to_cshort.h" #include "labsat_signal_source.h" @@ -197,6 +196,10 @@ #include "gps_l1_ca_dll_pll_tracking_gpu.h" #endif +#if ENABLE_ION_SOURCE +#include "ion_gsms_signal_source.h" +#endif + using namespace std::string_literals; namespace @@ -760,13 +763,14 @@ std::unique_ptr GNSSBlockFactory::GetBlock( block = std::move(block_); } #endif +#if ENABLE_ION_SOURCE else if (implementation == "ION_GSMS_Signal_Source") { std::unique_ptr block_ = std::make_unique(configuration, role, in_streams, out_streams, queue); block = std::move(block_); } - +#endif #if RAW_ARRAY_DRIVER else if (implementation == "Raw_Array_Signal_Source") { From 61a9e179b061aa2432aa1b0b6c26423b7c854415 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Sat, 17 Aug 2024 23:05:38 +0200 Subject: [PATCH 14/34] Linting fixes --- .../adapters/ion_gsms_signal_source.cc | 1 + .../adapters/ion_gsms_signal_source.h | 1 + src/algorithms/signal_source/libs/ion_gsms.cc | 3 + src/algorithms/signal_source/libs/ion_gsms.h | 3 +- .../signal_source/libs/ion_gsms_chunk_data.cc | 4 +- .../signal_source/libs/ion_gsms_chunk_data.h | 4 +- .../libs/ion_gsms_chunk_unpacking_ctx.h | 2 +- .../libs/ion_gsms_metadata_handler.h | 8 +- .../libs/ion_gsms_stream_encodings.h | 266 +++++++++--------- 9 files changed, 155 insertions(+), 137 deletions(-) diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc index 0be954a4a..9a6d9d9a0 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc @@ -19,6 +19,7 @@ #include "ion_gsms_signal_source.h" #include #include +#include #include #if USE_GLOG_AND_GFLAGS diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h index 9d959279f..19d91083c 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h @@ -23,6 +23,7 @@ #include "gnss_sdr_timestamp.h" #include "ion_gsms.h" #include +#include /** \addtogroup Signal_Source * \{ */ diff --git a/src/algorithms/signal_source/libs/ion_gsms.cc b/src/algorithms/signal_source/libs/ion_gsms.cc index d7036907a..c19011dfd 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.cc +++ b/src/algorithms/signal_source/libs/ion_gsms.cc @@ -16,6 +16,9 @@ #include "gnuradio/block.h" #include "ion_gsms.h" +#include +#include +#include #if USE_GLOG_AND_GFLAGS #include diff --git a/src/algorithms/signal_source/libs/ion_gsms.h b/src/algorithms/signal_source/libs/ion_gsms.h index 443ed3a81..b7aa06b0b 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.h +++ b/src/algorithms/signal_source/libs/ion_gsms.h @@ -24,7 +24,8 @@ #include #include #include -#include +#include +#include class IONGSMSFileSource : public gr::sync_block diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc index 229d7a0d5..03bcab79c 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc @@ -16,6 +16,8 @@ #include "ion_gsms_chunk_data.h" #include +#include +#include #if USE_GLOG_AND_GFLAGS #include @@ -46,7 +48,7 @@ IONGSMSChunkData::IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std:: return stream.Id() == it; })) { - streams_.emplace_back(lump, stream, GnssMetadata::encoding_from_string(stream.Encoding()),output_streams + output_stream_offset); + streams_.emplace_back(lump, stream, GnssMetadata::encoding_from_string(stream.Encoding()), output_streams + output_stream_offset); ++output_streams; std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); std::size_t sample_rate = stream.RateFactor(); diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h index 97ce022c4..bc0c5834d 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h @@ -21,6 +21,8 @@ #include "ion_gsms_stream_encodings.h" #include "ion_gsms_chunk_unpacking_ctx.h" #include +#include +#include #if USE_GLOG_AND_GFLAGS #include @@ -141,4 +143,4 @@ private: void* buffer_; }; -#endif //ION_GSM_CHUNK_DATA_H +#endif // ION_GSM_CHUNK_DATA_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h index 758e9b197..1dad11902 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h @@ -176,4 +176,4 @@ struct IONGSMSChunkUnpackingCtx } }; -#endif //ION_GSM_CHUNK_UNPACKING_CTX_H +#endif // ION_GSM_CHUNK_UNPACKING_CTX_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h index 28da13564..710233d72 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h @@ -20,6 +20,8 @@ #include "GnssMetadata.h" #include "configuration_interface.h" #include +#include +#include #if USE_GLOG_AND_GFLAGS #include @@ -37,12 +39,12 @@ public: public: // Getters const std::string& metadata_filepath() const; -private: // Private methods +private: // Private methods void load_metadata(); -private: // State +private: // State std::string metadata_filepath_; GnssMetadata::Metadata metadata_; }; -#endif //ION_GSMS_METADATA_HANDLER_H +#endif // ION_GSMS_METADATA_HANDLER_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h b/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h index f8551159b..8bae4b7e5 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h +++ b/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h @@ -19,6 +19,8 @@ #ifndef ION_GSM_STREAM_ENCODINGS_H #define ION_GSM_STREAM_ENCODINGS_H +#include + #if USE_GLOG_AND_GFLAGS #include #else @@ -27,140 +29,144 @@ namespace GnssMetadata { - using StreamEncoding = unsigned char; - namespace StreamEncodings - { - constexpr unsigned char SIGN = 0; - constexpr unsigned char OB = 1; - constexpr unsigned char SM = 2; - constexpr unsigned char MS = 3; - constexpr unsigned char TC = 4; - constexpr unsigned char OG = 5; - constexpr unsigned char OBA = 6; - constexpr unsigned char SMA = 7; - constexpr unsigned char MSA = 8; - constexpr unsigned char TCA = 9; - constexpr unsigned char OGA = 10; - constexpr unsigned char FP = 11; - } +using StreamEncoding = unsigned char; - inline StreamEncoding encoding_from_string(const std::string& str) - { - if (str == "SIGN") - { - return StreamEncodings::SIGN; - } - if (str == "OB") - { - return StreamEncodings::OB; - } - if (str == "SM") - { - return StreamEncodings::SM; - } - if (str == "MS") - { - return StreamEncodings::MS; - } - if (str == "TC") - { - return StreamEncodings::TC; - } - if (str == "OG") - { - return StreamEncodings::OG; - } - if (str == "OBA") - { - return StreamEncodings::OBA; - } - if (str == "SMA") - { - return StreamEncodings::SMA; - } - if (str == "MSA") - { - return StreamEncodings::MSA; - } - if (str == "TCA") - { - return StreamEncodings::TCA; - } - if (str == "OGA") - { - return StreamEncodings::OGA; - } - if (str == "FP") - { - return StreamEncodings::FP; - } - return 0; - } +namespace StreamEncodings +{ - template - inline T two_bit_look_up[11][4] - { - [0] = {}, - [1 /*OB*/] = {-2, -1, 0, 1}, - [2 /*SM*/] = {0, 1, 0, -1}, - [3 /*MS*/] = {0, 0, 1, -1}, - [4 /*TC*/] = {0, 1, -2, -1}, - [5 /*OG*/] = {-2, -1, 1, 0}, - [6 /*OBA*/] = {-3, -1, 1, 3}, - [7 /*SMA*/] = {1, 3, -1, -3}, - [8 /*MSA*/] = {1, -1, 3, -3}, - [9 /*TCA*/] = {1, 3, -3, -1}, - [10 /*OGA*/] = {-3, -1, 3, 1}, - }; +constexpr unsigned char SIGN = 0; +constexpr unsigned char OB = 1; +constexpr unsigned char SM = 2; +constexpr unsigned char MS = 3; +constexpr unsigned char TC = 4; +constexpr unsigned char OG = 5; +constexpr unsigned char OBA = 6; +constexpr unsigned char SMA = 7; +constexpr unsigned char MSA = 8; +constexpr unsigned char TCA = 9; +constexpr unsigned char OGA = 10; +constexpr unsigned char FP = 11; - template - inline T three_bit_look_up[11][8] - { - [0] = {}, - [1 /*OB*/] = {-4, -3, -2, -1, 0, 1, 2, 3}, - [2 /*SM*/] = {0, 1, 2, 3, 0, -1, -2, -3}, - [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1}, - [4 /*TC*/] = {0, 1, 2, 3, -4, -3, -2, -1}, - [5 /*OG*/] = {-4, -3, -1, -2, 3, 2, 0, 1}, - [6 /*OBA*/] = {-7, -5, -3, -1, 1, 3, 5, 7}, - [7 /*SMA*/] = {1, 3, 5, 7, -1, -3, -5, -7}, - [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7}, - [9 /*TCA*/] = {1, 3, 5, 7, -7, -5, -3, -1}, - [10 /*OGA*/] = {-7, -5, -1, -3, 7, 5, 1, 3}, - }; +} // namespace StreamEncodings - template - inline T four_bit_look_up[11][16] - { - [0] = {}, - [1 /*OB*/] = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}, - [2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7}, - [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, - [4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}, - [5 /*OG*/] = {-8, -7, -5, -6, -1, -2, -4, -3, 7, 6, 4, 5, 0, 1, 3, 2}, - [6 /*OBA*/] = {-15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15}, - [7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15}, - [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15}, - [9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -15, -13, -11, -9, -7, -5, -3, -1}, - [10 /*OGA*/] = {-15, -13, -9, -11, -1, -3, -7, -5, 15, 13, 9, 11, 1, 3, 7, 5}, - }; - - template - inline T five_bit_look_up[11][32] - { - [0] = {}, - [1 /*OB*/] = {-16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, - [2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15}, - [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, - [4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1}, - [5 /*OG*/] = {-16, -15, -13, -14, -9, -10, -12, -11, -1, -2, -4, -3, -8, -7, -5, -6, 15, 14, 12, 13, 8, 9, 11, 10, 0, 1, 3, 2, 7, 6, 4, 5}, - [6 /*OBA*/] = {-31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, - [7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -1, -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -23, -25, -27, -29, -31}, - [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15, 17, -17, 19, -19, 21, -21, 23, -23, 25, -25, 27, -27, 29, -29, 31, -31}, - [9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1}, - [10 /*OGA*/] = {-31, -29, -25, -27, -17, -19, -23, -21, -1, -3, -7, -5, -15, -13, -9, -11, 31, 29, 25, 27, 17, 19, 23, 21, 1, 3, 7, 5, 15, 13, 9, 11}, - }; +inline StreamEncoding encoding_from_string(const std::string& str) +{ + if (str == "SIGN") + { + return StreamEncodings::SIGN; + } + if (str == "OB") + { + return StreamEncodings::OB; + } + if (str == "SM") + { + return StreamEncodings::SM; + } + if (str == "MS") + { + return StreamEncodings::MS; + } + if (str == "TC") + { + return StreamEncodings::TC; + } + if (str == "OG") + { + return StreamEncodings::OG; + } + if (str == "OBA") + { + return StreamEncodings::OBA; + } + if (str == "SMA") + { + return StreamEncodings::SMA; + } + if (str == "MSA") + { + return StreamEncodings::MSA; + } + if (str == "TCA") + { + return StreamEncodings::TCA; + } + if (str == "OGA") + { + return StreamEncodings::OGA; + } + if (str == "FP") + { + return StreamEncodings::FP; + } + return 0; } -#endif //ION_GSM_STREAM_ENCODINGS_H +template +inline T two_bit_look_up[11][4] +{ + [0] = {}, + [1 /*OB*/] = {-2, -1, 0, 1}, + [2 /*SM*/] = {0, 1, 0, -1}, + [3 /*MS*/] = {0, 0, 1, -1}, + [4 /*TC*/] = {0, 1, -2, -1}, + [5 /*OG*/] = {-2, -1, 1, 0}, + [6 /*OBA*/] = {-3, -1, 1, 3}, + [7 /*SMA*/] = {1, 3, -1, -3}, + [8 /*MSA*/] = {1, -1, 3, -3}, + [9 /*TCA*/] = {1, 3, -3, -1}, + [10 /*OGA*/] = {-3, -1, 3, 1}, +}; + +template +inline T three_bit_look_up[11][8] +{ + [0] = {}, + [1 /*OB*/] = {-4, -3, -2, -1, 0, 1, 2, 3}, + [2 /*SM*/] = {0, 1, 2, 3, 0, -1, -2, -3}, + [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1}, + [4 /*TC*/] = {0, 1, 2, 3, -4, -3, -2, -1}, + [5 /*OG*/] = {-4, -3, -1, -2, 3, 2, 0, 1}, + [6 /*OBA*/] = {-7, -5, -3, -1, 1, 3, 5, 7}, + [7 /*SMA*/] = {1, 3, 5, 7, -1, -3, -5, -7}, + [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7}, + [9 /*TCA*/] = {1, 3, 5, 7, -7, -5, -3, -1}, + [10 /*OGA*/] = {-7, -5, -1, -3, 7, 5, 1, 3}, +}; + +template +inline T four_bit_look_up[11][16] +{ + [0] = {}, + [1 /*OB*/] = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}, + [2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7}, + [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, + [4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}, + [5 /*OG*/] = {-8, -7, -5, -6, -1, -2, -4, -3, 7, 6, 4, 5, 0, 1, 3, 2}, + [6 /*OBA*/] = {-15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15}, + [7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15}, + [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15}, + [9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -15, -13, -11, -9, -7, -5, -3, -1}, + [10 /*OGA*/] = {-15, -13, -9, -11, -1, -3, -7, -5, 15, 13, 9, 11, 1, 3, 7, 5}, +}; + +template +inline T five_bit_look_up[11][32] +{ + [0] = {}, + [1 /*OB*/] = {-16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + [2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15}, + [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, + [4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1}, + [5 /*OG*/] = {-16, -15, -13, -14, -9, -10, -12, -11, -1, -2, -4, -3, -8, -7, -5, -6, 15, 14, 12, 13, 8, 9, 11, 10, 0, 1, 3, 2, 7, 6, 4, 5}, + [6 /*OBA*/] = {-31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, + [7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -1, -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -23, -25, -27, -29, -31}, + [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15, 17, -17, 19, -19, 21, -21, 23, -23, 25, -25, 27, -27, 29, -29, 31, -31}, + [9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1}, + [10 /*OGA*/] = {-31, -29, -25, -27, -17, -19, -23, -21, -1, -3, -7, -5, -15, -13, -9, -11, 31, 29, 25, 27, 17, 19, 23, 21, 1, 3, 7, 5, 15, 13, 9, 11}, +}; + +} // namespace GnssMetadata + +#endif // ION_GSM_STREAM_ENCODINGS_H From a99ceafe851ecccaca2633af258bee3e39179080 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Sat, 17 Aug 2024 23:06:24 +0200 Subject: [PATCH 15/34] Fixed arithmetic operations on pointers --- src/algorithms/signal_source/libs/ion_gsms.cc | 4 ++-- .../signal_source/libs/ion_gsms_chunk_data.cc | 20 +++++++++---------- .../signal_source/libs/ion_gsms_chunk_data.h | 4 ++-- .../libs/ion_gsms_metadata_handler.cc | 13 +++++++++--- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/algorithms/signal_source/libs/ion_gsms.cc b/src/algorithms/signal_source/libs/ion_gsms.cc index c19011dfd..0c9670030 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.cc +++ b/src/algorithms/signal_source/libs/ion_gsms.cc @@ -84,7 +84,7 @@ int IONGSMSFileSource::work( std::fread(io_buffer_.data(), sizeof(decltype(io_buffer_)::value_type), io_buffer_.size(), fd_); items_produced_.resize(output_items.size()); - for (int i = 0; i < items_produced_.size(); ++i) + for (std::size_t i = 0; i < items_produced_.size(); ++i) { items_produced_[i] = 0; } @@ -99,7 +99,7 @@ int IONGSMSFileSource::work( } } - for (int i = 0; i < items_produced_.size(); ++i) + for (std::size_t i = 0; i < items_produced_.size(); ++i) { produce(i, items_produced_[i]); } diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc index 03bcab79c..6e64e23a9 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc @@ -155,7 +155,7 @@ void IONGSMSChunkData::unpack_words(gr_vector_void_star& outputs, std::vector(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, (int8_t**)(out)); } else if (sample_bitsize <= 16) { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, (int16_t**)(out)); } else if (sample_bitsize <= 32) { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, (int32_t**)(out)); } else if (sample_bitsize <= 64) { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, out); + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, (int64_t**)(out)); } return sample_count; @@ -205,11 +205,11 @@ void IONGSMSChunkData::write_n_samples( uint8_t sample_bitsize, std::size_t sample_count, GnssMetadata::StreamEncoding stream_encoding, - void*& out) + OT** out) { if (lump_shift == GnssMetadata::Lump::shiftRight) { - auto* sample = static_cast(out); + auto* sample = static_cast(*out); sample += sample_count; for (std::size_t i = 0; i < sample_count; ++i) { @@ -222,7 +222,7 @@ void IONGSMSChunkData::write_n_samples( } else // if (lump_shift == GnssMetadata::Lump::shiftLeft || lump_shift == GnssMetadata::Lump::shiftUndefined) { - auto* sample = static_cast(out); + auto* sample = static_cast(*out); for (std::size_t i = 0; i < sample_count; ++i) { *sample = 0; @@ -233,7 +233,7 @@ void IONGSMSChunkData::write_n_samples( } } - out += sample_count * sizeof(OT); + (*out) += sample_count; } diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h index bc0c5834d..3081c823b 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h @@ -107,7 +107,7 @@ private: const GnssMetadata::Lump& lump, const GnssMetadata::IonStream& stream, GnssMetadata::StreamEncoding stream_encoding, - void*& out); + void** out); template void write_n_samples( @@ -116,7 +116,7 @@ private: uint8_t sample_bitsize, std::size_t sample_count, GnssMetadata::StreamEncoding stream_encoding, - void*& out); + OT** out); static void decode_sample(uint8_t sample_bitsize, auto* sample, GnssMetadata::StreamEncoding encoding); diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc index 47ae4e6ed..c5fccef61 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc @@ -70,9 +70,16 @@ std::vector IONGSMSMetadataHandler::make_stream_sources { for (const auto& stream : lump.Streams()) { - if (std::ranges::any_of(stream_ids.begin(), stream_ids.end(), [&](const std::string& it) { - return stream.Id() == it; - })) + bool found = false; + for (const auto & stream_id : stream_ids) + { + if (stream_id == stream.Id()) + { + found = true; + break; + } + } + if (found) { auto source = gnss_make_shared( configuration, From 27465f6a70d0a7ce4e90e7254915943ee5ce6249 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Sat, 17 Aug 2024 23:31:27 +0200 Subject: [PATCH 16/34] Fix formatting --- .../adapters/ion_gsms_signal_source.cc | 12 +-- .../adapters/ion_gsms_signal_source.h | 1 + src/algorithms/signal_source/libs/ion_gsms.cc | 36 ++++--- src/algorithms/signal_source/libs/ion_gsms.h | 4 +- .../signal_source/libs/ion_gsms_chunk_data.cc | 37 +++---- .../signal_source/libs/ion_gsms_chunk_data.h | 15 ++- .../libs/ion_gsms_metadata_handler.cc | 17 ++- .../libs/ion_gsms_stream_encodings.h | 100 +++++++++--------- src/core/receiver/gnss_block_factory.cc | 1 + 9 files changed, 117 insertions(+), 106 deletions(-) diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc index 9a6d9d9a0..b4edd615f 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc @@ -14,13 +14,13 @@ * ----------------------------------------------------------------------------- */ +#include "ion_gsms_signal_source.h" #include "gnss_sdr_flags.h" #include "gnss_sdr_string_literals.h" -#include "ion_gsms_signal_source.h" #include #include -#include #include +#include #if USE_GLOG_AND_GFLAGS #include @@ -53,7 +53,7 @@ IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configura const std::string& role, unsigned int in_streams, unsigned int out_streams, - Concurrent_Queue* queue) + Concurrent_Queue* queue __attribute__((unused))) : SignalSourceBase(configuration, role, "ION_GSMS_Signal_Source"s), metadata_file_(configuration->property(role + ".metadata_filename"s, "../data/example_capture_metadata.sdrx"s)), stream_ids_(parse_comma_list(configuration->property(role + ".streams"s, ""s))), @@ -71,7 +71,7 @@ IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configura for (const auto& source : sources_) { - for (int i = 0; i < source->output_stream_count(); ++i) + for (std::size_t i = 0; i < source->output_stream_count(); ++i) { copy_blocks_.push_back(gr::blocks::copy::make(source->output_stream_item_size(i))); } @@ -84,7 +84,7 @@ void IONGSMSSignalSource::connect(gr::top_block_sptr top_block) std::size_t cumulative_index = 0; for (const auto& source : sources_) { - for (int i = 0; i < source->output_stream_count(); ++i, ++cumulative_index) + for (std::size_t i = 0; i < source->output_stream_count(); ++i, ++cumulative_index) { top_block->connect(source, i, copy_blocks_[cumulative_index], 0); } @@ -96,7 +96,7 @@ void IONGSMSSignalSource::disconnect(gr::top_block_sptr top_block) std::size_t cumulative_index = 0; for (const auto& source : sources_) { - for (int i = 0; i < source->output_stream_count(); ++i, ++cumulative_index) + for (std::size_t i = 0; i < source->output_stream_count(); ++i, ++cumulative_index) { top_block->disconnect(source, i, copy_blocks_[cumulative_index], 0); } diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h index 19d91083c..5063b4e80 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h @@ -57,6 +57,7 @@ protected: { return (*sources_.begin())->output_stream_item_size(0); } + private: std::string metadata_file_; std::vector stream_ids_; diff --git a/src/algorithms/signal_source/libs/ion_gsms.cc b/src/algorithms/signal_source/libs/ion_gsms.cc index 0c9670030..8389afd10 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.cc +++ b/src/algorithms/signal_source/libs/ion_gsms.cc @@ -14,25 +14,24 @@ * ----------------------------------------------------------------------------- */ -#include "gnuradio/block.h" #include "ion_gsms.h" -#include +#include "gnuradio/block.h" #include +#include #include #if USE_GLOG_AND_GFLAGS #include #else #include - #include #endif using namespace std::string_literals; IONGSMSFileSource::IONGSMSFileSource( - const ConfigurationInterface* configuration, - const std::string& role, + const ConfigurationInterface* configuration __attribute__((unused)), + const std::string& role __attribute__((unused)), const std::filesystem::path& metadata_filepath, const GnssMetadata::File& file, const GnssMetadata::Block& block, @@ -75,18 +74,18 @@ IONGSMSFileSource::~IONGSMSFileSource() int IONGSMSFileSource::work( int noutput_items, - gr_vector_const_void_star& input_items, + gr_vector_const_void_star& input_items __attribute__((unused)), gr_vector_void_star& output_items) { - const std::size_t max_sample_output = std::floor((noutput_items-1.0) / maximum_item_rate_); + const std::size_t max_sample_output = std::floor((noutput_items - 1.0) / maximum_item_rate_); io_buffer_.resize(max_sample_output * chunk_cycle_length_); io_buffer_offset_ = 0; std::fread(io_buffer_.data(), sizeof(decltype(io_buffer_)::value_type), io_buffer_.size(), fd_); items_produced_.resize(output_items.size()); - for (std::size_t i = 0; i < items_produced_.size(); ++i) + for (int& i : items_produced_) { - items_produced_[i] = 0; + i = 0; } while (io_buffer_offset_ < io_buffer_.size()) @@ -121,7 +120,7 @@ std::size_t IONGSMSFileSource::output_stream_item_size(std::size_t stream_index) gr::io_signature::sptr IONGSMSFileSource::make_output_signature(const GnssMetadata::Block& block, const std::vector& stream_ids) { int nstreams = 0; - std::vector item_sizes{}; + std::vector item_sizes{}; for (const auto& chunk : block.Chunks()) { @@ -129,9 +128,16 @@ gr::io_signature::sptr IONGSMSFileSource::make_output_signature(const GnssMetada { for (const auto& stream : lump.Streams()) { - if (std::ranges::any_of(stream_ids.begin(), stream_ids.end(), [&](const std::string& it) { - return stream.Id() == it; - })) + bool found = false; + for (const auto& stream_id : stream_ids) + { + if (stream_id == stream.Id()) + { + found = true; + break; + } + } + if (found) { ++nstreams; std::size_t sample_bitsize = stream.Packedbits() / stream.RateFactor(); @@ -146,10 +152,8 @@ gr::io_signature::sptr IONGSMSFileSource::make_output_signature(const GnssMetada } } - return gr::io_signature::make( + return gr::io_signature::makev( nstreams, nstreams, item_sizes); } - - diff --git a/src/algorithms/signal_source/libs/ion_gsms.h b/src/algorithms/signal_source/libs/ion_gsms.h index b7aa06b0b..5164e3581 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.h +++ b/src/algorithms/signal_source/libs/ion_gsms.h @@ -17,14 +17,14 @@ #ifndef GNSS_SDR_ION_GNSS_SDR_METADATA_STANDARD_H #define GNSS_SDR_ION_GNSS_SDR_METADATA_STANDARD_H +#include "configuration_interface.h" #include "gnss_block_interface.h" #include "ion_gsms_chunk_data.h" -#include "configuration_interface.h" #include #include #include -#include #include +#include #include diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc index 6e64e23a9..f6d1b18b9 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc @@ -30,9 +30,8 @@ IONGSMSChunkData::IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std:: sizeword_(chunk_.SizeWord()), countwords_(chunk_.CountWords()) { - with_word_type(sizeword_, [&] - { - buffer_ = new WordType[countwords_]; + with_word_type(sizeword_, [&] { + buffer_ = new WordType[countwords_]; }); const std::size_t total_bitsize = sizeword_ * countwords_ * 8; @@ -44,9 +43,16 @@ IONGSMSChunkData::IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std:: { used_bitsize += stream.Packedbits(); - if (std::ranges::any_of(stream_ids.begin(), stream_ids.end(), [&](const std::string& it) { - return stream.Id() == it; - })) + bool found = false; + for (const auto& stream_id : stream_ids) + { + if (stream_id == stream.Id()) + { + found = true; + break; + } + } + if (found) { streams_.emplace_back(lump, stream, GnssMetadata::encoding_from_string(stream.Encoding()), output_streams + output_stream_offset); ++output_streams; @@ -75,9 +81,8 @@ IONGSMSChunkData::IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std:: IONGSMSChunkData::~IONGSMSChunkData() { - with_word_type(sizeword_, [&] - { - delete[] static_cast(buffer_); + with_word_type(sizeword_, [&] { + delete[] static_cast(buffer_); }); } @@ -215,7 +220,6 @@ void IONGSMSChunkData::write_n_samples( { *sample = 0; ctx.shift_sample(sample_bitsize, sample); - dump_sample(*sample); decode_sample(sample_bitsize, sample, stream_encoding); --sample; } @@ -227,7 +231,6 @@ void IONGSMSChunkData::write_n_samples( { *sample = 0; ctx.shift_sample(sample_bitsize, sample); - dump_sample(*sample); decode_sample(sample_bitsize, sample, stream_encoding); ++sample; } @@ -237,7 +240,6 @@ void IONGSMSChunkData::write_n_samples( } - // Static utilities void IONGSMSChunkData::decode_sample(const uint8_t sample_bitsize, auto* sample, const GnssMetadata::StreamEncoding encoding) { @@ -262,14 +264,3 @@ void IONGSMSChunkData::decode_sample(const uint8_t sample_bitsize, auto* sample, break; } } - -void IONGSMSChunkData::dump_sample(auto value) -{ - static int count = 100; - if (count > 0) - { - --count; - // std::cout << "SAMPLE: [0x" << std::hex << value << "] " << std::bitset<32>(value) << std::endl; - } -} - diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h index 3081c823b..881c431f6 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h @@ -18,8 +18,8 @@ #define ION_GSM_CHUNK_DATA_H #include "GnssMetadata.h" -#include "ion_gsms_stream_encodings.h" #include "ion_gsms_chunk_unpacking_ctx.h" +#include "ion_gsms_stream_encodings.h" #include #include #include @@ -120,8 +120,6 @@ private: static void decode_sample(uint8_t sample_bitsize, auto* sample, GnssMetadata::StreamEncoding encoding); - static void dump_sample(auto value); - private: const GnssMetadata::Chunk& chunk_; uint8_t sizeword_; @@ -137,6 +135,17 @@ private: const GnssMetadata::IonStream& stream; GnssMetadata::StreamEncoding stream_encoding; int output_index = -1; + + stream_metadata_t( + const GnssMetadata::Lump& lump_, + const GnssMetadata::IonStream& stream_, + GnssMetadata::StreamEncoding stream_encoding_, + int output_index_ = -1) : lump(lump_), + stream(stream_), + stream_encoding(stream_encoding_), + output_index(output_index_) + { + } }; std::vector streams_; diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc index c5fccef61..9a05e372d 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc @@ -64,6 +64,7 @@ std::vector IONGSMSMetadataHandler::make_stream_sources { for (const auto& block : lane.Blocks()) { + bool block_done = false; for (const auto& chunk : block.Chunks()) { for (const auto& lump : chunk.Lumps()) @@ -71,7 +72,7 @@ std::vector IONGSMSMetadataHandler::make_stream_sources for (const auto& stream : lump.Streams()) { bool found = false; - for (const auto & stream_id : stream_ids) + for (const auto& stream_id : stream_ids) { if (stream_id == stream.Id()) { @@ -93,12 +94,21 @@ std::vector IONGSMSMetadataHandler::make_stream_sources // This file source will take care of any other matching streams in this block // We can skip the rest of this block - goto next_block; + block_done = true; + break; } } + + if (block_done) + { + break; + } + } + if (block_done) + { + break; } } - next_block: } break; } @@ -107,4 +117,3 @@ std::vector IONGSMSMetadataHandler::make_stream_sources return sources; } - diff --git a/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h b/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h index 8bae4b7e5..443a6e823 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h +++ b/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h @@ -104,67 +104,63 @@ inline StreamEncoding encoding_from_string(const std::string& str) } template -inline T two_bit_look_up[11][4] -{ - [0] = {}, - [1 /*OB*/] = {-2, -1, 0, 1}, - [2 /*SM*/] = {0, 1, 0, -1}, - [3 /*MS*/] = {0, 0, 1, -1}, - [4 /*TC*/] = {0, 1, -2, -1}, - [5 /*OG*/] = {-2, -1, 1, 0}, - [6 /*OBA*/] = {-3, -1, 1, 3}, - [7 /*SMA*/] = {1, 3, -1, -3}, - [8 /*MSA*/] = {1, -1, 3, -3}, - [9 /*TCA*/] = {1, 3, -3, -1}, - [10 /*OGA*/] = {-3, -1, 3, 1}, +inline T two_bit_look_up[11][4]{ + {}, // [0] + {-2, -1, 0, 1}, // [1 /*OB*/] + {0, 1, 0, -1}, // [2 /*SM*/] + {0, 0, 1, -1}, // [3 /*MS*/] + {0, 1, -2, -1}, // [4 /*TC*/] + {-2, -1, 1, 0}, // [5 /*OG*/] + {-3, -1, 1, 3}, // [6 /*OBA*/] + {1, 3, -1, -3}, // [7 /*SMA*/] + {1, -1, 3, -3}, // [8 /*MSA*/] + {1, 3, -3, -1}, // [9 /*TCA*/] + {-3, -1, 3, 1}, // [10 /*OGA*/] }; template -inline T three_bit_look_up[11][8] -{ - [0] = {}, - [1 /*OB*/] = {-4, -3, -2, -1, 0, 1, 2, 3}, - [2 /*SM*/] = {0, 1, 2, 3, 0, -1, -2, -3}, - [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1}, - [4 /*TC*/] = {0, 1, 2, 3, -4, -3, -2, -1}, - [5 /*OG*/] = {-4, -3, -1, -2, 3, 2, 0, 1}, - [6 /*OBA*/] = {-7, -5, -3, -1, 1, 3, 5, 7}, - [7 /*SMA*/] = {1, 3, 5, 7, -1, -3, -5, -7}, - [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7}, - [9 /*TCA*/] = {1, 3, 5, 7, -7, -5, -3, -1}, - [10 /*OGA*/] = {-7, -5, -1, -3, 7, 5, 1, 3}, +inline T three_bit_look_up[11][8]{ + {}, // [0] + {-4, -3, -2, -1, 0, 1, 2, 3}, // [1 /*OB*/] + {0, 1, 2, 3, 0, -1, -2, -3}, // [2 /*SM*/] + {0, 0, 1, -1, 0, 0, 1, -1}, // [3 /*MS*/] + {0, 1, 2, 3, -4, -3, -2, -1}, // [4 /*TC*/] + {-4, -3, -1, -2, 3, 2, 0, 1}, // [5 /*OG*/] + {-7, -5, -3, -1, 1, 3, 5, 7}, // [6 /*OBA*/] + {1, 3, 5, 7, -1, -3, -5, -7}, // [7 /*SMA*/] + {1, -1, 3, -3, 5, -5, 7, -7}, // [8 /*MSA*/] + {1, 3, 5, 7, -7, -5, -3, -1}, // [9 /*TCA*/] + {-7, -5, -1, -3, 7, 5, 1, 3}, // [10 /*OGA*/] }; template -inline T four_bit_look_up[11][16] -{ - [0] = {}, - [1 /*OB*/] = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}, - [2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7}, - [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, - [4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}, - [5 /*OG*/] = {-8, -7, -5, -6, -1, -2, -4, -3, 7, 6, 4, 5, 0, 1, 3, 2}, - [6 /*OBA*/] = {-15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15}, - [7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15}, - [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15}, - [9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, -15, -13, -11, -9, -7, -5, -3, -1}, - [10 /*OGA*/] = {-15, -13, -9, -11, -1, -3, -7, -5, 15, 13, 9, 11, 1, 3, 7, 5}, +inline T four_bit_look_up[11][16]{ + {}, // [0] + {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}, // [1 /*OB*/] + {0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7}, // [2 /*SM*/] + {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, // [3 /*MS*/] + {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}, // [4 /*TC*/] + {-8, -7, -5, -6, -1, -2, -4, -3, 7, 6, 4, 5, 0, 1, 3, 2}, // [5 /*OG*/] + {-15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15}, // [6 /*OBA*/] + {1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15}, // [7 /*SMA*/] + {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15}, // [8 /*MSA*/] + {1, 3, 5, 7, 9, 11, 13, 15, -15, -13, -11, -9, -7, -5, -3, -1}, // [9 /*TCA*/] + {-15, -13, -9, -11, -1, -3, -7, -5, 15, 13, 9, 11, 1, 3, 7, 5}, // [10 /*OGA*/] }; template -inline T five_bit_look_up[11][32] -{ - [0] = {}, - [1 /*OB*/] = {-16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, - [2 /*SM*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15}, - [3 /*MS*/] = {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, - [4 /*TC*/] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1}, - [5 /*OG*/] = {-16, -15, -13, -14, -9, -10, -12, -11, -1, -2, -4, -3, -8, -7, -5, -6, 15, 14, 12, 13, 8, 9, 11, 10, 0, 1, 3, 2, 7, 6, 4, 5}, - [6 /*OBA*/] = {-31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, - [7 /*SMA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -1, -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -23, -25, -27, -29, -31}, - [8 /*MSA*/] = {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15, 17, -17, 19, -19, 21, -21, 23, -23, 25, -25, 27, -27, 29, -29, 31, -31}, - [9 /*TCA*/] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1}, - [10 /*OGA*/] = {-31, -29, -25, -27, -17, -19, -23, -21, -1, -3, -7, -5, -15, -13, -9, -11, 31, 29, 25, 27, 17, 19, 23, 21, 1, 3, 7, 5, 15, 13, 9, 11}, +inline T five_bit_look_up[11][32]{ + {}, // [0] + {-16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, // [1 /*OB*/] + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15}, // [2 /*SM*/] + {0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1, 0, 0, 1, -1}, // [3 /*MS*/] + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1}, // [4 /*TC*/] + {-16, -15, -13, -14, -9, -10, -12, -11, -1, -2, -4, -3, -8, -7, -5, -6, 15, 14, 12, 13, 8, 9, 11, 10, 0, 1, 3, 2, 7, 6, 4, 5}, // [5 /*OG*/] + {-31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, // [6 /*OBA*/] + {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -1, -3, -5, -7, -9, -11, -13, -15, -17, -19, -21, -23, -25, -27, -29, -31}, // [7 /*SMA*/] + {1, -1, 3, -3, 5, -5, 7, -7, 9, -9, 11, -11, 13, -13, 15, -15, 17, -17, 19, -19, 21, -21, 23, -23, 25, -25, 27, -27, 29, -29, 31, -31}, // [8 /*MSA*/] + {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, -31, -29, -27, -25, -23, -21, -19, -17, -15, -13, -11, -9, -7, -5, -3, -1}, // [9 /*TCA*/] + {-31, -29, -25, -27, -17, -19, -23, -21, -1, -3, -7, -5, -15, -13, -9, -11, 31, 29, 25, 27, 17, 19, 23, 21, 1, 3, 7, 5, 15, 13, 9, 11}, // [10 /*OGA*/] }; } // namespace GnssMetadata diff --git a/src/core/receiver/gnss_block_factory.cc b/src/core/receiver/gnss_block_factory.cc index 07069ed9e..222b93cad 100644 --- a/src/core/receiver/gnss_block_factory.cc +++ b/src/core/receiver/gnss_block_factory.cc @@ -197,6 +197,7 @@ #endif #if ENABLE_ION_SOURCE +#undef Owner #include "ion_gsms_signal_source.h" #endif From 62cb96ae03a5f3ae14b6ba7062e93ffdf7e67e2e Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 19 Aug 2024 09:25:05 +0200 Subject: [PATCH 17/34] Create a CMake target for the ION dependency for consistency --- CMakeLists.txt | 68 +++++++++++++++---- .../signal_source/libs/CMakeLists.txt | 9 ++- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f70609a92..8b081522b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,7 @@ option(ENABLE_ARRAY "Enable the use of CTTC's antenna array front-end as signal option(ENABLE_ZMQ "Enable GNU Radio ZeroMQ Messaging, requires gr-zeromq" ON) -option(ENABLE_ION "Enable ION GNSS-SDR Metadata Standard signal source" ON) +option(ENABLE_ION "Enable ION GNSS-SDR Metadata Standard signal source" OFF) # Performance analysis tools option(ENABLE_GPERFTOOLS "Enable linking to Gperftools libraries (tcmalloc and profiler)" OFF) @@ -1424,20 +1424,6 @@ else() endif() -################################################################################ -# ION GNSS-SDR Metadata Standard -################################################################################ -include(FetchContent) -FetchContent_Declare( - gnss_metadata_standard - GIT_REPOSITORY https://github.com/IonMetadataWorkingGroup/GNSS-Metadata-Standard - GIT_TAG master - SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/gnss-metadata-standard - CMAKE_ARGS -DABSL_PROPAGATE_CXX_STD=ON -ABSL_BUILD_TESTING=OFF -DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/gnss-metadata-standard ${ABSEIL_TOOLCHAIN_FILE} - BINARY_DIR ${GNSSSDR_BINARY_DIR}/gnss-metadata-standard -) -FetchContent_MakeAvailable(gnss_metadata_standard) - ################################################################################ # Abseil C++ - https://abseil.io/docs/cpp/ ################################################################################ @@ -3371,6 +3357,57 @@ if(ENABLE_AD9361 OR ENABLE_FMCOMMS2) endif() +################################################################################ +# ION GNSS-SDR Metadata Standard https://sdr.ion.org/ (OPTIONAL) +################################################################################ +if(ENABLE_ION) + include(FetchContent) + set(CMAKE_POLICY_DEFAULT_CMP0063 NEW) + FetchContent_Declare( + gnss_metadata_standard + GIT_REPOSITORY https://github.com/IonMetadataWorkingGroup/GNSS-Metadata-Standard + GIT_TAG origin/master + SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/gnss-metadata-standard + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/gnss-metadata-standard + BINARY_DIR ${GNSSSDR_BINARY_DIR}/gnss-metadata-standard + ) + FetchContent_MakeAvailable(gnss_metadata_standard) + + if(NOT TARGET ION::ion) + add_library(ION::ion STATIC IMPORTED) + add_dependencies(ION::ion gnss_metadata_standard) + if(CMAKE_GENERATOR STREQUAL "Xcode") + set_target_properties(ION::ion PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION_DEBUG "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}" + IMPORTED_LOCATION_RELEASE "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Release/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}" + IMPORTED_LOCATION_RELWITHDEBINFO "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}" + IMPORTED_LOCATION_MINSIZEREL "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}" + INTERFACE_INCLUDE_DIRECTORIES "${GNSSSDR_BINARY_DIR}/thirdparty/gnss-metadata-standard/source/api/inc" + ) + set_property(TARGET ION::ion APPEND PROPERTY + INTERFACE_LINK_LIBRARIES + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Release/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Release/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/MinSizeRel/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/RelWithDebInfo/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + "$<$:${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/Debug/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}>" + ) + else() + set_target_properties(ION::ion PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX}" + INTERFACE_INCLUDE_DIRECTORIES "${GNSSSDR_BINARY_DIR}/thirdparty/gnss-metadata-standard/source/api/inc" + INTERFACE_LINK_LIBRARIES "${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/GnssMetadata/${CMAKE_FIND_LIBRARY_PREFIXES}api${CMAKE_STATIC_LIBRARY_SUFFIX};${GNSSSDR_BINARY_DIR}/gnss-metadata-standard/source/api/lib/tinyxml2/${CMAKE_FIND_LIBRARY_PREFIXES}xml${CMAKE_STATIC_LIBRARY_SUFFIX}" + ) + endif() + endif() +endif() + ##################################################################### # Check signal sources related to FPGA only. @@ -3684,6 +3721,7 @@ add_feature_info(ENABLE_RAW_UDP ENABLE_RAW_UDP "Enables Custom_UDP_Signal_Source add_feature_info(ENABLE_FLEXIBAND ENABLE_FLEXIBAND "Enables Flexiband_Signal_Source for using Teleorbit's Flexiband RF front-end. Requires gr-teleorbit.") add_feature_info(ENABLE_ARRAY ENABLE_ARRAY "Enables Raw_Array_Signal_Source and Array_Signal_Conditioner for using CTTC's antenna array. Requires gr-dbfcttc.") add_feature_info(ENABLE_ZMQ ENABLE_ZMQ "Enables ZMQ_Signal_Source for GNU Radio ZeroMQ messages. Requires gr-zeromq.") +add_feature_info(ENABLE_ION ENABLE_ION "Enables ION_GSMS_Signal_Source for the ION Metadata Standard.") add_feature_info(ENABLE_GPERFTOOLS ENABLE_GPERFTOOLS "Enables performance analysis. Requires Gperftools.") add_feature_info(ENABLE_GPROF ENABLE_GPROF "Enables performance analysis with 'gprof'.") add_feature_info(ENABLE_CLANG_TIDY ENABLE_CLANG_TIDY "Runs clang-tidy along with the compiler. Requires Clang.") diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index 36f327931..aa4fa8eea 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -142,6 +142,10 @@ if(ENABLE_FPGA OR ENABLE_AD9361) ) endif() +if(ENABLE_ION) + target_link_libraries(signal_source_libs PUBLIC ION::ion algorithms_libs) +endif() + if(ENABLE_CLANG_TIDY) if(CLANG_TIDY_EXE) set_target_properties(signal_source_libs @@ -151,11 +155,6 @@ if(ENABLE_CLANG_TIDY) endif() endif() -if(ENABLE_ION) - target_include_directories(signal_source_libs PUBLIC ${GNSSSDR_BINARY_DIR}/thirdparty/gnss-metadata-standard/source/api/inc) - target_link_libraries(signal_source_libs PUBLIC api xml) -endif() - set_property(TARGET signal_source_libs APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $ ) From da21ff4fd9747ec52c7122c370e652bc943e1850 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 19 Aug 2024 09:26:21 +0200 Subject: [PATCH 18/34] Improve formatting, add missing include --- .../adapters/ion_gsms_signal_source.cc | 13 +++++++++++-- .../signal_source/adapters/ion_gsms_signal_source.h | 5 ++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc index b4edd615f..c0db26e71 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc @@ -8,7 +8,7 @@ * 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) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- @@ -49,6 +49,7 @@ std::vector parse_comma_list(const std::string& str) return list; } + IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configuration, const std::string& role, unsigned int in_streams, @@ -62,10 +63,14 @@ IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configura in_streams_(in_streams), out_streams_(out_streams) { - if (in_streams > 0) + if (in_streams_ > 0) { LOG(ERROR) << "A signal source does not have an input stream"; } + if (out_streams_ <= 0) + { + LOG(ERROR) << "A signal source does not have an output stream"; + } sources_ = metadata_.make_stream_sources(configuration, role, stream_ids_); @@ -91,6 +96,7 @@ void IONGSMSSignalSource::connect(gr::top_block_sptr top_block) } } + void IONGSMSSignalSource::disconnect(gr::top_block_sptr top_block) { std::size_t cumulative_index = 0; @@ -103,6 +109,7 @@ void IONGSMSSignalSource::disconnect(gr::top_block_sptr top_block) } } + gr::basic_block_sptr IONGSMSSignalSource::get_left_block() { LOG(WARNING) << "Trying to get signal source left block."; @@ -110,11 +117,13 @@ gr::basic_block_sptr IONGSMSSignalSource::get_left_block() return IONGSMSFileSource::sptr(); } + gr::basic_block_sptr IONGSMSSignalSource::get_right_block() { return get_right_block(0); } + gr::basic_block_sptr IONGSMSSignalSource::get_right_block(int RF_channel) { return copy_blocks_[RF_channel]; diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h index 5063b4e80..d724d101b 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h @@ -8,7 +8,7 @@ * 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) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- @@ -22,6 +22,7 @@ #include "file_source_base.h" #include "gnss_sdr_timestamp.h" #include "ion_gsms.h" +#include #include #include @@ -44,8 +45,6 @@ public: ~IONGSMSSignalSource() override = default; protected: - // std::tuple itemTypeToSize() override; - // double packetsPerSample() const override; void connect(gr::top_block_sptr top_block) override; void disconnect(gr::top_block_sptr top_block) override; From e37855d43ee85d10c5ac2ac7e247349407ad6700 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 19 Aug 2024 09:27:29 +0200 Subject: [PATCH 19/34] Fixes for C++ standards older than 20. Avoid C++20-specific lambda templates --- src/algorithms/signal_source/libs/ion_gsms.cc | 22 +++---- src/algorithms/signal_source/libs/ion_gsms.h | 18 +++--- .../signal_source/libs/ion_gsms_chunk_data.cc | 47 ++++++++------- .../signal_source/libs/ion_gsms_chunk_data.h | 57 +++++++++++++++---- .../libs/ion_gsms_chunk_unpacking_ctx.h | 16 +++--- .../libs/ion_gsms_metadata_handler.cc | 19 +++++-- .../libs/ion_gsms_metadata_handler.h | 21 +++---- .../libs/ion_gsms_stream_encodings.h | 14 +++-- 8 files changed, 132 insertions(+), 82 deletions(-) diff --git a/src/algorithms/signal_source/libs/ion_gsms.cc b/src/algorithms/signal_source/libs/ion_gsms.cc index 8389afd10..e44c0abab 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.cc +++ b/src/algorithms/signal_source/libs/ion_gsms.cc @@ -8,7 +8,7 @@ * 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) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- @@ -17,22 +17,14 @@ #include "ion_gsms.h" #include "gnuradio/block.h" #include -#include -#include - -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#include -#endif +#include using namespace std::string_literals; IONGSMSFileSource::IONGSMSFileSource( const ConfigurationInterface* configuration __attribute__((unused)), const std::string& role __attribute__((unused)), - const std::filesystem::path& metadata_filepath, + const fs::path& metadata_filepath, const GnssMetadata::File& file, const GnssMetadata::Block& block, const std::vector& stream_ids) @@ -40,13 +32,11 @@ IONGSMSFileSource::IONGSMSFileSource( "ion_gsms_file_source", gr::io_signature::make(0, 0, 0), make_output_signature(block, stream_ids)), - file_metadata_(file), - block_metadata_(block), io_buffer_offset_(0), maximum_item_rate_(0), chunk_cycle_length_(0) { - std::filesystem::path data_filepath = metadata_filepath.parent_path() / file.Url().Value(); + fs::path data_filepath = metadata_filepath.parent_path() / file.Url().Value(); fd_ = std::fopen(data_filepath.c_str(), "rb"); std::size_t block_offset = file.Offset(); std::fseek(fd_, file.Offset() + block_offset + block.SizeHeader(), SEEK_SET); @@ -67,11 +57,13 @@ IONGSMSFileSource::IONGSMSFileSource( output_stream_count_ = output_stream_offset; } + IONGSMSFileSource::~IONGSMSFileSource() { std::fclose(fd_); } + int IONGSMSFileSource::work( int noutput_items, gr_vector_const_void_star& input_items __attribute__((unused)), @@ -106,11 +98,13 @@ int IONGSMSFileSource::work( return WORK_CALLED_PRODUCE; } + std::size_t IONGSMSFileSource::output_stream_count() const { return output_stream_count_; } + std::size_t IONGSMSFileSource::output_stream_item_size(std::size_t stream_index) const { return output_stream_item_sizes_[stream_index]; diff --git a/src/algorithms/signal_source/libs/ion_gsms.h b/src/algorithms/signal_source/libs/ion_gsms.h index 5164e3581..054b1e9dd 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.h +++ b/src/algorithms/signal_source/libs/ion_gsms.h @@ -8,7 +8,7 @@ * 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) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- @@ -19,14 +19,20 @@ #include "configuration_interface.h" #include "gnss_block_interface.h" +#include "gnss_sdr_filesystem.h" #include "ion_gsms_chunk_data.h" #include #include -#include +#include +#include #include #include #include +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_libs + * \{ */ class IONGSMSFileSource : public gr::sync_block { @@ -36,7 +42,7 @@ public: IONGSMSFileSource( const ConfigurationInterface* configuration, const std::string& role, - const std::filesystem::path& metadata_filepath, + const fs::path& metadata_filepath, const GnssMetadata::File& file, const GnssMetadata::Block& block, const std::vector& stream_ids); @@ -54,9 +60,6 @@ public: private: static gr::io_signature::sptr make_output_signature(const GnssMetadata::Block& block, const std::vector& stream_ids); -private: - const GnssMetadata::File& file_metadata_; - const GnssMetadata::Block& block_metadata_; FILE* fd_; std::vector io_buffer_; std::size_t io_buffer_offset_; @@ -70,5 +73,6 @@ private: #include "ion_gsms_metadata_handler.h" - +/** \} */ +/** \} */ #endif // GNSS_SDR_ION_GNSS_SDR_METADATA_STANDARD_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc index f6d1b18b9..5a8cd823c 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.cc @@ -8,31 +8,30 @@ * 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) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- */ #include "ion_gsms_chunk_data.h" -#include -#include -#include - +#include #if USE_GLOG_AND_GFLAGS #include #else #include #endif + IONGSMSChunkData::IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std::vector& stream_ids, std::size_t output_stream_offset) : chunk_(chunk), sizeword_(chunk_.SizeWord()), countwords_(chunk_.CountWords()) { - with_word_type(sizeword_, [&] { - buffer_ = new WordType[countwords_]; - }); + // Instantiate the Allocator functor + Allocator allocator(countwords_, buffer_); + // Call with_word_type with the Allocator functor + with_word_type(sizeword_, allocator); const std::size_t total_bitsize = sizeword_ * countwords_ * 8; std::size_t used_bitsize = 0; @@ -81,11 +80,11 @@ IONGSMSChunkData::IONGSMSChunkData(const GnssMetadata::Chunk& chunk, const std:: IONGSMSChunkData::~IONGSMSChunkData() { - with_word_type(sizeword_, [&] { - delete[] static_cast(buffer_); - }); + Deleter deleter(static_cast(buffer_)); + with_word_type(sizeword_, deleter); } + std::size_t IONGSMSChunkData::read_from_buffer(uint8_t* buffer, std::size_t offset) { memset(buffer_, 0, sizeword_ * countwords_); @@ -93,6 +92,7 @@ std::size_t IONGSMSChunkData::read_from_buffer(uint8_t* buffer, std::size_t offs return sizeword_ * countwords_; } + void IONGSMSChunkData::write_to_output(gr_vector_void_star& outputs, std::vector& output_items) { switch (sizeword_) @@ -121,11 +121,13 @@ std::size_t IONGSMSChunkData::output_stream_count() const return output_stream_count_; } + std::size_t IONGSMSChunkData::output_stream_item_size(std::size_t stream_index) const { return output_stream_item_size_[stream_index]; } + std::size_t IONGSMSChunkData::output_stream_item_rate(std::size_t stream_index) const { return output_stream_item_rate_[stream_index]; @@ -165,6 +167,7 @@ void IONGSMSChunkData::unpack_words(gr_vector_void_star& outputs, std::vector std::size_t IONGSMSChunkData::write_stream_samples( IONGSMSChunkUnpackingCtx& ctx, @@ -185,24 +188,25 @@ std::size_t IONGSMSChunkData::write_stream_samples( if (sample_bitsize <= 8) { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, (int8_t**)(out)); + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, reinterpret_cast(out)); } else if (sample_bitsize <= 16) { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, (int16_t**)(out)); + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, reinterpret_cast(out)); } else if (sample_bitsize <= 32) { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, (int32_t**)(out)); + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, reinterpret_cast(out)); } else if (sample_bitsize <= 64) { - write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, (int64_t**)(out)); + write_n_samples(ctx, lump.Shift(), sample_bitsize, sample_count, stream_encoding, reinterpret_cast(out)); } return sample_count; } + template void IONGSMSChunkData::write_n_samples( IONGSMSChunkUnpackingCtx& ctx, @@ -241,22 +245,23 @@ void IONGSMSChunkData::write_n_samples( // Static utilities -void IONGSMSChunkData::decode_sample(const uint8_t sample_bitsize, auto* sample, const GnssMetadata::StreamEncoding encoding) +template +void IONGSMSChunkData::decode_sample(const uint8_t sample_bitsize, Sample* sample, const GnssMetadata::StreamEncoding encoding) { - using SampleType = std::remove_pointer_t; + // using SampleType = std::remove_pointer_t; switch (sample_bitsize) { case 2: - *sample = GnssMetadata::two_bit_look_up[encoding][*sample]; + *sample = GnssMetadata::two_bit_look_up[encoding][*sample]; break; case 3: - *sample = GnssMetadata::three_bit_look_up[encoding][*sample]; + *sample = GnssMetadata::three_bit_look_up[encoding][*sample]; break; case 4: - *sample = GnssMetadata::four_bit_look_up[encoding][*sample]; + *sample = GnssMetadata::four_bit_look_up[encoding][*sample]; break; case 5: - *sample = GnssMetadata::five_bit_look_up[encoding][*sample]; + *sample = GnssMetadata::five_bit_look_up[encoding][*sample]; break; default: // TODO - Is this an error that can happen? diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h index 881c431f6..5a6b98aba 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h @@ -8,7 +8,7 @@ * 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) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- @@ -21,16 +21,14 @@ #include "ion_gsms_chunk_unpacking_ctx.h" #include "ion_gsms_stream_encodings.h" #include +#include +#include +#include #include #include -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif -inline std::size_t bits_to_item_size(const std::size_t bit_count) +inline std::size_t bits_to_item_size(std::size_t bit_count) { if (bit_count <= 8) { @@ -50,11 +48,46 @@ inline std::size_t bits_to_item_size(const std::size_t bit_count) } // You are asking too much of this humble processor - LOG(ERROR) << "Item size too large (" << std::to_string(bit_count) << "), returning nonsense."; + std::cerr << "Item size too large (" << std::to_string(bit_count) << "), returning nonsense.\n"; return 1; } -void with_word_type(const uint8_t word_size, auto&& callback) + +// Define a functor that has a templated operator() +struct Allocator +{ + size_t countwords_; + void*& buffer_; // Using void* to hold any type of pointer + + Allocator(size_t countwords, void*& buffer) + : countwords_(countwords), buffer_(buffer) {} + + template + void operator()() const + { + buffer_ = new WordType[countwords_]; + } +}; + + +// Define a functor to delete the allocated memory +struct Deleter +{ + void* buffer_; + + explicit Deleter(void* buffer) + : buffer_(buffer) {} + + template + void operator()() const + { + delete[] static_cast(buffer_); + } +}; + + +template +void with_word_type(uint8_t word_size, Callback callback) { switch (word_size) { @@ -71,7 +104,7 @@ void with_word_type(const uint8_t word_size, auto&& callback) callback.template operator()(); break; default: - LOG(ERROR) << "Unknown word size (" << std::to_string(word_size) << "), returning nonsense."; + std::cerr << "Unknown word size (" << std::to_string(word_size) << "), returning nonsense.\n"; break; } } @@ -118,9 +151,9 @@ private: GnssMetadata::StreamEncoding stream_encoding, OT** out); - static void decode_sample(uint8_t sample_bitsize, auto* sample, GnssMetadata::StreamEncoding encoding); + template + static void decode_sample(uint8_t sample_bitsize, Sample* sample, GnssMetadata::StreamEncoding encoding); -private: const GnssMetadata::Chunk& chunk_; uint8_t sizeword_; uint8_t countwords_; diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h index 1dad11902..c4d839de1 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h @@ -10,7 +10,7 @@ * 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) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- @@ -21,12 +21,12 @@ #include "GnssMetadata.h" #include +#include -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_libs + * \{ */ template struct IONGSMSChunkUnpackingCtx @@ -118,7 +118,7 @@ struct IONGSMSChunkUnpackingCtx } template - void shift_sample(const uint8_t sample_bitsize, OT* output, uint8_t output_bit_offset = 0) + void shift_sample(uint8_t sample_bitsize, OT* output, uint8_t output_bit_offset = 0) { if (sample_bitsize % word_bitsize_ == 0) { @@ -176,4 +176,6 @@ struct IONGSMSChunkUnpackingCtx } }; +/** \} */ +/** \} */ #endif // ION_GSM_CHUNK_UNPACKING_CTX_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc index 9a05e372d..eea6e9c5f 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc @@ -8,14 +8,14 @@ * 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) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- */ #include "ion_gsms.h" - +#include #if USE_GLOG_AND_GFLAGS #include #else @@ -40,16 +40,25 @@ void IONGSMSMetadataHandler::load_metadata() GnssMetadata::XmlProcessor xml_proc; if (!xml_proc.Load(metadata_filepath_.c_str(), false, metadata_)) { - LOG(ERROR) << "Could not load XML metadata file:"; + LOG(WARNING) << "Could not load XML metadata file " << metadata_filepath_; + std::cerr << "Could not load XML metadata file " << metadata_filepath_ << std::endl; + std::cout << "GNSS-SDR program ended.\n"; + exit(1); } } catch (GnssMetadata::ApiException& e) { - LOG(ERROR) << "API Exception while loading XML metadata file: " << std::to_string(e.Error()); + LOG(WARNING) << "API Exception while loading XML metadata file: " << std::to_string(e.Error()); + std::cerr << "Could not load XML metadata file " << metadata_filepath_ << " : " << std::to_string(e.Error()) << std::endl; + std::cout << "GNSS-SDR program ended.\n"; + exit(1); } catch (std::exception& e) { - LOG(ERROR) << "Exception while loading XML metadata file: " << e.what(); + LOG(WARNING) << "Exception while loading XML metadata file: " << e.what(); + std::cerr << "Could not load XML metadata file " << metadata_filepath_ << " : " << e.what() << std::endl; + std::cout << "GNSS-SDR program ended.\n"; + exit(1); } } diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h index 710233d72..62077c82a 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h @@ -8,7 +8,7 @@ * 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) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- @@ -23,11 +23,11 @@ #include #include -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_libs + * \{ */ + class IONGSMSMetadataHandler { @@ -35,16 +35,17 @@ public: explicit IONGSMSMetadataHandler(const std::string& metadata_filepath); std::vector make_stream_sources(const ConfigurationInterface* configuration, const std::string& role, const std::vector& stream_ids) const; - -public: // Getters const std::string& metadata_filepath() const; -private: // Private methods +private: void load_metadata(); -private: // State + // State std::string metadata_filepath_; GnssMetadata::Metadata metadata_; }; + +/** \} */ +/** \} */ #endif // ION_GSMS_METADATA_HANDLER_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h b/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h index 443a6e823..90ba15cac 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h +++ b/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h @@ -10,7 +10,7 @@ * 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) + * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) * SPDX-License-Identifier: GPL-3.0-or-later * * ----------------------------------------------------------------------------- @@ -21,11 +21,10 @@ #include -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif +/** \addtogroup Signal_Source + * \{ */ +/** \addtogroup Signal_Source_libs + * \{ */ namespace GnssMetadata { @@ -165,4 +164,7 @@ inline T five_bit_look_up[11][32]{ } // namespace GnssMetadata + +/** \} */ +/** \} */ #endif // ION_GSM_STREAM_ENCODINGS_H From bc2a1e02b893be7fafcbf40baa384e41f2cb6d58 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 19 Aug 2024 09:28:03 +0200 Subject: [PATCH 20/34] Update changelog --- docs/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 931e8988f..abdc04427 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -41,6 +41,11 @@ All notable changes to GNSS-SDR will be documented in this file. - `-DENABLE_DMA_PROXY`: Checks if the DMA proxy driver is installed for controlling the DMA in the FPGA and enables its usage. +- Add the `ION_GSMS_Signal_Source`, which is able to process raw data files + described with the + [ION GNSS Software Defined Receiver Metadata Standard](https://sdr.ion.org/). + It requires the `-DENABLE_ION=ON` building configuration option. + ### Improvements in Portability: - Fix building against google-glog 0.7.x. From fc5148bf44377e9062a697f4d1ae01b9d8276ae6 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 19 Aug 2024 09:28:35 +0200 Subject: [PATCH 21/34] Add Victor to the list of authors --- AUTHORS | 1 + CITATION.cff | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/AUTHORS b/AUTHORS index ad0660662..d1251f1fc 100644 --- a/AUTHORS +++ b/AUTHORS @@ -64,6 +64,7 @@ Marc Sales marcsales92@gmail.com Contributor Piyush Gupta piyush04111999@gmail.com Contributor Rodrigo Muñoz rodrigo.munoz@proteinlab.cl Contributor Stefan van der Linden spvdlinden@gmail.com Contributor +Victor Castillo-Agüero victorcastilloaguero@gmail.com Contributor Will Silberman wsilberm@google.com Contributor Carlos Paniego carpanie@hotmail.com Artwork diff --git a/CITATION.cff b/CITATION.cff index 0f11b55f1..2be1e1880 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -34,6 +34,11 @@ authors: email: mara.branzanti@gmail.com family-names: Branzanti given-names: Mara + - alias: castle055 + affiliation: "Instituto Nacional de Técnica Aeroespacial" + email: victorcastilloaguero@gmail.com + family-names: "Castillo-Agüero" + given-names: Victor - alias: acebrianjuan email: acebrianjuan@gmail.com family-names: "Cebrián-Juan" From c212bac26d856308bd01040625639b39a280c2af Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 19 Aug 2024 09:58:33 +0200 Subject: [PATCH 22/34] Fix CMake error --- src/algorithms/signal_source/adapters/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index 9ff0ab434..d6491098f 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -171,7 +171,7 @@ target_include_directories(signal_source_adapters ${GNSSSDR_SOURCE_DIR}/src/core/interfaces ) -if(ENABLE_FPGA OR ENABLE_AD9361) +if(ENABLE_FPGA OR ENABLE_AD9361 OR ENABLE_ION) target_link_libraries(signal_source_adapters PUBLIC signal_source_libs From 614693ea0f34fed42aa35c5e4fa788c05a116478 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 19 Aug 2024 10:21:51 +0200 Subject: [PATCH 23/34] Fix building error --- src/algorithms/signal_source/libs/ion_gsms_chunk_data.h | 2 +- .../signal_source/libs/ion_gsms_chunk_unpacking_ctx.h | 2 +- src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h index 5a6b98aba..1dd712351 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h @@ -17,10 +17,10 @@ #ifndef ION_GSM_CHUNK_DATA_H #define ION_GSM_CHUNK_DATA_H -#include "GnssMetadata.h" #include "ion_gsms_chunk_unpacking_ctx.h" #include "ion_gsms_stream_encodings.h" #include +#include #include #include #include diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h index c4d839de1..44c125889 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h @@ -19,8 +19,8 @@ #ifndef ION_GSM_CHUNK_UNPACKING_CTX_H #define ION_GSM_CHUNK_UNPACKING_CTX_H -#include "GnssMetadata.h" #include +#include #include /** \addtogroup Signal_Source diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h index 62077c82a..2431fbec8 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h @@ -17,9 +17,9 @@ #ifndef ION_GSMS_METADATA_HANDLER_H #define ION_GSMS_METADATA_HANDLER_H -#include "GnssMetadata.h" #include "configuration_interface.h" #include +#include #include #include From f3ba1822b17d95bc1eb25d0ddd18481183aff238 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 19 Aug 2024 10:24:48 +0200 Subject: [PATCH 24/34] Fix building --- src/algorithms/signal_source/adapters/CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/algorithms/signal_source/adapters/CMakeLists.txt b/src/algorithms/signal_source/adapters/CMakeLists.txt index d6491098f..6b58e1abe 100644 --- a/src/algorithms/signal_source/adapters/CMakeLists.txt +++ b/src/algorithms/signal_source/adapters/CMakeLists.txt @@ -103,6 +103,11 @@ if(ENABLE_ZMQ) list(APPEND OPT_DRIVER_HEADERS zmq_signal_source.h) endif() +if(ENABLE_ION) + list(APPEND OPT_DRIVER_SOURCES ion_gsms_signal_source.cc) + list(APPEND OPT_DRIVER_HEADERS ion_gsms_signal_source.h) +endif() + set(SIGNAL_SOURCE_ADAPTER_SOURCES signal_source_base.cc file_source_base.cc @@ -119,7 +124,6 @@ set(SIGNAL_SOURCE_ADAPTER_SOURCES two_bit_packed_file_signal_source.cc four_bit_cpx_file_signal_source.cc file_timestamp_signal_source.cc - ion_gsms_signal_source.cc ${OPT_DRIVER_SOURCES} ) @@ -139,7 +143,6 @@ set(SIGNAL_SOURCE_ADAPTER_HEADERS two_bit_packed_file_signal_source.h four_bit_cpx_file_signal_source.h file_timestamp_signal_source.h - ion_gsms_signal_source.h ${OPT_DRIVER_HEADERS} ) From 45d31cb3b9a637b14adc4bb497fb1336c27cfd06 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 19 Aug 2024 10:29:48 +0200 Subject: [PATCH 25/34] Add -DENABLE_ION=ON to CI jobs --- .github/workflows/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 32dc29f9b..7bc294b0f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,7 +28,7 @@ jobs: libgnutls-openssl-dev libmatio-dev googletest protobuf-compiler libprotobuf-dev \ python3-mako liborc-0.4-dev - name: configure - run: cd build && cmake -GNinja .. + run: cd build && cmake -GNinja -DENABLE_ION=ON .. - name: build run: cd build && ninja - name: check @@ -60,7 +60,7 @@ jobs: brew install ninja hdf5 automake armadillo lapack libmatio gnuradio openssl pugixml protobuf pip3 install mako - name: configure - run: cd build && cmake -GNinja .. + run: cd build && cmake -GNinja -DENABLE_ION=ON .. - name: build run: cd build && ninja - name: check @@ -92,7 +92,7 @@ jobs: brew install ninja pkg-config hdf5 automake armadillo lapack libmatio gnuradio openssl pugixml protobuf pip3 install mako - name: configure - run: cd build && cmake -GXcode .. + run: cd build && cmake -GXcode -DENABLE_ION=ON .. - name: build run: cd build && xcodebuild -configuration Release - name: check From 4d1540181d7dd98ce4fa73db68b4454c052a01c5 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Mon, 19 Aug 2024 15:36:03 +0200 Subject: [PATCH 26/34] Removed unused member fields and function parameters --- .../signal_source/adapters/ion_gsms_signal_source.cc | 5 ++--- .../signal_source/adapters/ion_gsms_signal_source.h | 1 - src/algorithms/signal_source/libs/ion_gsms.cc | 2 -- src/algorithms/signal_source/libs/ion_gsms.h | 3 --- .../signal_source/libs/ion_gsms_metadata_handler.cc | 4 +--- .../signal_source/libs/ion_gsms_metadata_handler.h | 2 +- 6 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc index c0db26e71..5dde9915c 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc @@ -56,9 +56,8 @@ IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configura unsigned int out_streams, Concurrent_Queue* queue __attribute__((unused))) : SignalSourceBase(configuration, role, "ION_GSMS_Signal_Source"s), - metadata_file_(configuration->property(role + ".metadata_filename"s, "../data/example_capture_metadata.sdrx"s)), stream_ids_(parse_comma_list(configuration->property(role + ".streams"s, ""s))), - metadata_(metadata_file_), + metadata_(configuration->property(role + ".metadata_filename"s, "../data/example_capture_metadata.sdrx"s)), timestamp_clock_offset_ms_(configuration->property(role + ".timestamp_clock_offset_ms"s, 0.0)), in_streams_(in_streams), out_streams_(out_streams) @@ -72,7 +71,7 @@ IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configura LOG(ERROR) << "A signal source does not have an output stream"; } - sources_ = metadata_.make_stream_sources(configuration, role, stream_ids_); + sources_ = metadata_.make_stream_sources(stream_ids_); for (const auto& source : sources_) { diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h index d724d101b..6e0aa6364 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h @@ -58,7 +58,6 @@ protected: } private: - std::string metadata_file_; std::vector stream_ids_; std::vector sources_; std::vector> copy_blocks_; diff --git a/src/algorithms/signal_source/libs/ion_gsms.cc b/src/algorithms/signal_source/libs/ion_gsms.cc index e44c0abab..78f9060bd 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.cc +++ b/src/algorithms/signal_source/libs/ion_gsms.cc @@ -22,8 +22,6 @@ using namespace std::string_literals; IONGSMSFileSource::IONGSMSFileSource( - const ConfigurationInterface* configuration __attribute__((unused)), - const std::string& role __attribute__((unused)), const fs::path& metadata_filepath, const GnssMetadata::File& file, const GnssMetadata::Block& block, diff --git a/src/algorithms/signal_source/libs/ion_gsms.h b/src/algorithms/signal_source/libs/ion_gsms.h index 054b1e9dd..64a3e8c16 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.h +++ b/src/algorithms/signal_source/libs/ion_gsms.h @@ -17,7 +17,6 @@ #ifndef GNSS_SDR_ION_GNSS_SDR_METADATA_STANDARD_H #define GNSS_SDR_ION_GNSS_SDR_METADATA_STANDARD_H -#include "configuration_interface.h" #include "gnss_block_interface.h" #include "gnss_sdr_filesystem.h" #include "ion_gsms_chunk_data.h" @@ -40,8 +39,6 @@ public: using sptr = gnss_shared_ptr; IONGSMSFileSource( - const ConfigurationInterface* configuration, - const std::string& role, const fs::path& metadata_filepath, const GnssMetadata::File& file, const GnssMetadata::Block& block, diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc index eea6e9c5f..7d4c96fa5 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc @@ -62,7 +62,7 @@ void IONGSMSMetadataHandler::load_metadata() } } -std::vector IONGSMSMetadataHandler::make_stream_sources(const ConfigurationInterface* configuration, const std::string& role, const std::vector& stream_ids) const +std::vector IONGSMSMetadataHandler::make_stream_sources(const std::vector& stream_ids) const { std::vector sources{}; for (const auto& file : metadata_.Files()) @@ -92,8 +92,6 @@ std::vector IONGSMSMetadataHandler::make_stream_sources if (found) { auto source = gnss_make_shared( - configuration, - role, metadata_filepath_, file, block, diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h index 2431fbec8..969a3f4be 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h @@ -34,7 +34,7 @@ class IONGSMSMetadataHandler public: explicit IONGSMSMetadataHandler(const std::string& metadata_filepath); - std::vector make_stream_sources(const ConfigurationInterface* configuration, const std::string& role, const std::vector& stream_ids) const; + std::vector make_stream_sources(const std::vector& stream_ids) const; const std::string& metadata_filepath() const; private: From f1957476b8b83438a994542b82b10117d63b3587 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Mon, 19 Aug 2024 15:37:58 +0200 Subject: [PATCH 27/34] Use std::ifstream instead of FILE for reading sample data --- src/algorithms/signal_source/libs/ion_gsms.cc | 14 ++++---------- src/algorithms/signal_source/libs/ion_gsms.h | 7 +++---- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/algorithms/signal_source/libs/ion_gsms.cc b/src/algorithms/signal_source/libs/ion_gsms.cc index 78f9060bd..ca46c7c53 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.cc +++ b/src/algorithms/signal_source/libs/ion_gsms.cc @@ -30,14 +30,14 @@ IONGSMSFileSource::IONGSMSFileSource( "ion_gsms_file_source", gr::io_signature::make(0, 0, 0), make_output_signature(block, stream_ids)), + file_stream_(metadata_filepath.parent_path() / file.Url().Value()), io_buffer_offset_(0), maximum_item_rate_(0), chunk_cycle_length_(0) { fs::path data_filepath = metadata_filepath.parent_path() / file.Url().Value(); - fd_ = std::fopen(data_filepath.c_str(), "rb"); std::size_t block_offset = file.Offset(); - std::fseek(fd_, file.Offset() + block_offset + block.SizeHeader(), SEEK_SET); + file_stream_.seekg(file.Offset() + block_offset + block.SizeHeader()); std::size_t output_stream_offset = 0; for (const auto& chunk : block.Chunks()) @@ -56,12 +56,6 @@ IONGSMSFileSource::IONGSMSFileSource( } -IONGSMSFileSource::~IONGSMSFileSource() -{ - std::fclose(fd_); -} - - int IONGSMSFileSource::work( int noutput_items, gr_vector_const_void_star& input_items __attribute__((unused)), @@ -70,7 +64,7 @@ int IONGSMSFileSource::work( const std::size_t max_sample_output = std::floor((noutput_items - 1.0) / maximum_item_rate_); io_buffer_.resize(max_sample_output * chunk_cycle_length_); io_buffer_offset_ = 0; - std::fread(io_buffer_.data(), sizeof(decltype(io_buffer_)::value_type), io_buffer_.size(), fd_); + file_stream_.read(io_buffer_.data(), sizeof(decltype(io_buffer_)::value_type) * io_buffer_.size()); items_produced_.resize(output_items.size()); for (int& i : items_produced_) @@ -83,7 +77,7 @@ int IONGSMSFileSource::work( for (auto& c : chunk_data_) { auto* chunk = c.get(); - io_buffer_offset_ += chunk->read_from_buffer(io_buffer_.data(), io_buffer_offset_); + io_buffer_offset_ += chunk->read_from_buffer(reinterpret_cast(io_buffer_.data()), io_buffer_offset_); chunk->write_to_output(output_items, items_produced_); } } diff --git a/src/algorithms/signal_source/libs/ion_gsms.h b/src/algorithms/signal_source/libs/ion_gsms.h index 64a3e8c16..c9bc8efd2 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.h +++ b/src/algorithms/signal_source/libs/ion_gsms.h @@ -27,6 +27,7 @@ #include #include #include +#include /** \addtogroup Signal_Source * \{ */ @@ -44,8 +45,6 @@ public: const GnssMetadata::Block& block, const std::vector& stream_ids); - ~IONGSMSFileSource() override; - int work( int noutput_items, gr_vector_const_void_star& input_items, @@ -57,8 +56,8 @@ public: private: static gr::io_signature::sptr make_output_signature(const GnssMetadata::Block& block, const std::vector& stream_ids); - FILE* fd_; - std::vector io_buffer_; + std::ifstream file_stream_; + std::vector io_buffer_; std::size_t io_buffer_offset_; std::vector items_produced_; std::size_t output_stream_count_; From 3bdc7b9f21452c91a143e68d323ea87765998e28 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Mon, 19 Aug 2024 15:39:17 +0200 Subject: [PATCH 28/34] Fixed includes and code style --- .../signal_source/adapters/ion_gsms_signal_source.h | 2 +- src/algorithms/signal_source/libs/ion_gsms.cc | 5 +---- src/algorithms/signal_source/libs/ion_gsms.h | 2 -- .../signal_source/libs/ion_gsms_metadata_handler.cc | 2 +- .../signal_source/libs/ion_gsms_metadata_handler.h | 2 +- 5 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h index 6e0aa6364..5bddfc147 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h @@ -21,7 +21,7 @@ #include "configuration_interface.h" #include "file_source_base.h" #include "gnss_sdr_timestamp.h" -#include "ion_gsms.h" +#include "ion_gsms_metadata_handler.h" #include #include #include diff --git a/src/algorithms/signal_source/libs/ion_gsms.cc b/src/algorithms/signal_source/libs/ion_gsms.cc index ca46c7c53..515bb1cf5 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.cc +++ b/src/algorithms/signal_source/libs/ion_gsms.cc @@ -66,11 +66,8 @@ int IONGSMSFileSource::work( io_buffer_offset_ = 0; file_stream_.read(io_buffer_.data(), sizeof(decltype(io_buffer_)::value_type) * io_buffer_.size()); + items_produced_.clear(); items_produced_.resize(output_items.size()); - for (int& i : items_produced_) - { - i = 0; - } while (io_buffer_offset_ < io_buffer_.size()) { diff --git a/src/algorithms/signal_source/libs/ion_gsms.h b/src/algorithms/signal_source/libs/ion_gsms.h index c9bc8efd2..a4f7e2625 100644 --- a/src/algorithms/signal_source/libs/ion_gsms.h +++ b/src/algorithms/signal_source/libs/ion_gsms.h @@ -67,8 +67,6 @@ private: std::size_t chunk_cycle_length_; }; -#include "ion_gsms_metadata_handler.h" - /** \} */ /** \} */ #endif // GNSS_SDR_ION_GNSS_SDR_METADATA_STANDARD_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc index 7d4c96fa5..154ad6904 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc @@ -14,7 +14,7 @@ * ----------------------------------------------------------------------------- */ -#include "ion_gsms.h" +#include "ion_gsms_metadata_handler.h" #include #if USE_GLOG_AND_GFLAGS #include diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h index 969a3f4be..4b6f5be81 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h @@ -17,7 +17,7 @@ #ifndef ION_GSMS_METADATA_HANDLER_H #define ION_GSMS_METADATA_HANDLER_H -#include "configuration_interface.h" +#include "ion_gsms.h" #include #include #include From 7cdda8e0dc1a82e444106c65118d7a13aab47947 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Mon, 19 Aug 2024 15:42:26 +0200 Subject: [PATCH 29/34] Simplified disconnect() function We can disconnect the sources directly instead of disconnecting each of their outputs. --- .../signal_source/adapters/ion_gsms_signal_source.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc index 5dde9915c..0a4f065ee 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc @@ -98,13 +98,9 @@ void IONGSMSSignalSource::connect(gr::top_block_sptr top_block) void IONGSMSSignalSource::disconnect(gr::top_block_sptr top_block) { - std::size_t cumulative_index = 0; for (const auto& source : sources_) { - for (std::size_t i = 0; i < source->output_stream_count(); ++i, ++cumulative_index) - { - top_block->disconnect(source, i, copy_blocks_[cumulative_index], 0); - } + top_block->disconnect(source); } } From 174364af319a6686757249dd1f4aca873867ec87 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Mon, 19 Aug 2024 15:46:28 +0200 Subject: [PATCH 30/34] Implemented range check in `IONGSMSSignalSource::get_right_block(int)` --- .../signal_source/adapters/ion_gsms_signal_source.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc index 0a4f065ee..e608cf10b 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc @@ -121,5 +121,10 @@ gr::basic_block_sptr IONGSMSSignalSource::get_right_block() gr::basic_block_sptr IONGSMSSignalSource::get_right_block(int RF_channel) { + if (RF_channel < 0 || RF_channel >= static_cast(copy_blocks_.size())) + { + LOG(WARNING) << "'RF_channel' out of bounds while trying to get signal source right block."; + return copy_blocks_[0]; + } return copy_blocks_[RF_channel]; } From c10eceb9731c67014935cbfbd397ca364eb52491 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Mon, 19 Aug 2024 15:58:37 +0200 Subject: [PATCH 31/34] Moved ION GSMS file source to `gnuradio_blocks/` directory Also fixed some header guards. --- src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt | 5 +++++ .../signal_source/{libs => gnuradio_blocks}/ion_gsms.cc | 0 .../signal_source/{libs => gnuradio_blocks}/ion_gsms.h | 0 src/algorithms/signal_source/libs/CMakeLists.txt | 2 -- src/algorithms/signal_source/libs/ion_gsms_chunk_data.h | 6 +++--- .../signal_source/libs/ion_gsms_chunk_unpacking_ctx.h | 6 +++--- .../signal_source/libs/ion_gsms_metadata_handler.h | 6 +++--- .../signal_source/libs/ion_gsms_stream_encodings.h | 6 +++--- 8 files changed, 17 insertions(+), 14 deletions(-) rename src/algorithms/signal_source/{libs => gnuradio_blocks}/ion_gsms.cc (100%) rename src/algorithms/signal_source/{libs => gnuradio_blocks}/ion_gsms.h (100%) diff --git a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt index 24f067be6..a217648b4 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt +++ b/src/algorithms/signal_source/gnuradio_blocks/CMakeLists.txt @@ -21,6 +21,11 @@ if(ENABLE_PLUTOSDR) set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} ad936x_iio_source.h) endif() +if(ENABLE_ION) + set(OPT_DRIVER_SOURCES ${OPT_DRIVER_SOURCES} ion_gsms.cc) + set(OPT_DRIVER_HEADERS ${OPT_DRIVER_HEADERS} ion_gsms.h) +endif() + set(SIGNAL_SOURCE_GR_BLOCKS_SOURCES fifo_reader.cc unpack_byte_2bit_samples.cc diff --git a/src/algorithms/signal_source/libs/ion_gsms.cc b/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.cc similarity index 100% rename from src/algorithms/signal_source/libs/ion_gsms.cc rename to src/algorithms/signal_source/gnuradio_blocks/ion_gsms.cc diff --git a/src/algorithms/signal_source/libs/ion_gsms.h b/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.h similarity index 100% rename from src/algorithms/signal_source/libs/ion_gsms.h rename to src/algorithms/signal_source/gnuradio_blocks/ion_gsms.h diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index aa4fa8eea..b674ef5f5 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -46,8 +46,6 @@ if(ENABLE_PLUTOSDR) endif() if(ENABLE_ION) - set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gsms.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms.h) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gsms_chunk_data.cc) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_chunk_data.h) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gsms_metadata_handler.cc) diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h index 1dd712351..5170af848 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_data.h @@ -14,8 +14,8 @@ * ----------------------------------------------------------------------------- */ -#ifndef ION_GSM_CHUNK_DATA_H -#define ION_GSM_CHUNK_DATA_H +#ifndef GNSS_SDR_ION_GSMS_CHUNK_DATA_H +#define GNSS_SDR_ION_GSMS_CHUNK_DATA_H #include "ion_gsms_chunk_unpacking_ctx.h" #include "ion_gsms_stream_encodings.h" @@ -185,4 +185,4 @@ private: void* buffer_; }; -#endif // ION_GSM_CHUNK_DATA_H +#endif // GNSS_SDR_ION_GSMS_CHUNK_DATA_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h b/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h index 44c125889..3c5d7b662 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h +++ b/src/algorithms/signal_source/libs/ion_gsms_chunk_unpacking_ctx.h @@ -16,8 +16,8 @@ * ----------------------------------------------------------------------------- */ -#ifndef ION_GSM_CHUNK_UNPACKING_CTX_H -#define ION_GSM_CHUNK_UNPACKING_CTX_H +#ifndef GNSS_SDR_ION_GSMS_CHUNK_UNPACKING_CTX_H +#define GNSS_SDR_ION_GSMS_CHUNK_UNPACKING_CTX_H #include #include @@ -178,4 +178,4 @@ struct IONGSMSChunkUnpackingCtx /** \} */ /** \} */ -#endif // ION_GSM_CHUNK_UNPACKING_CTX_H +#endif // GNSS_SDR_ION_GSMS_CHUNK_UNPACKING_CTX_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h index 4b6f5be81..6d01567c5 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h +++ b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h @@ -14,8 +14,8 @@ * ----------------------------------------------------------------------------- */ -#ifndef ION_GSMS_METADATA_HANDLER_H -#define ION_GSMS_METADATA_HANDLER_H +#ifndef GNSS_SDR_ION_GSMSS_METADATA_HANDLER_H +#define GNSS_SDR_ION_GSMSS_METADATA_HANDLER_H #include "ion_gsms.h" #include @@ -48,4 +48,4 @@ private: /** \} */ /** \} */ -#endif // ION_GSMS_METADATA_HANDLER_H +#endif // GNSS_SDR_ION_GSMSS_METADATA_HANDLER_H diff --git a/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h b/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h index 90ba15cac..5b39e6497 100644 --- a/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h +++ b/src/algorithms/signal_source/libs/ion_gsms_stream_encodings.h @@ -16,8 +16,8 @@ * ----------------------------------------------------------------------------- */ -#ifndef ION_GSM_STREAM_ENCODINGS_H -#define ION_GSM_STREAM_ENCODINGS_H +#ifndef GNSS_SDR_ION_GSMS_STREAM_ENCODINGS_H +#define GNSS_SDR_ION_GSMS_STREAM_ENCODINGS_H #include @@ -167,4 +167,4 @@ inline T five_bit_look_up[11][32]{ /** \} */ /** \} */ -#endif // ION_GSM_STREAM_ENCODINGS_H +#endif // GNSS_SDR_ION_GSMS_STREAM_ENCODINGS_H From 54e18adb61fc39b741b6ab97de3642814815409d Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Mon, 19 Aug 2024 17:39:33 +0200 Subject: [PATCH 32/34] Fixed ION GNSS Metadata Standard dependency version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b081522b..781e98a23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3366,7 +3366,7 @@ if(ENABLE_ION) FetchContent_Declare( gnss_metadata_standard GIT_REPOSITORY https://github.com/IonMetadataWorkingGroup/GNSS-Metadata-Standard - GIT_TAG origin/master + GIT_TAG 220d116e10db5e403e21b77a1fa25aa35feda198 SOURCE_DIR ${GNSSSDR_BINARY_DIR}/thirdparty/gnss-metadata-standard CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${GNSSSDR_BINARY_DIR}/gnss-metadata-standard BINARY_DIR ${GNSSSDR_BINARY_DIR}/gnss-metadata-standard From 92dcec67e076d9db0a0d590d7fadd2eb76ce2663 Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Mon, 19 Aug 2024 17:43:18 +0200 Subject: [PATCH 33/34] Simplified by removing a very shallow class `ion_gnss_metadata_handler` was only reading the metadata file, which can easily be done in `ion_gsms_signal_source`. --- .../adapters/ion_gsms_signal_source.cc | 99 +++++++++++++- .../adapters/ion_gsms_signal_source.h | 12 +- .../signal_source/libs/CMakeLists.txt | 2 - .../libs/ion_gsms_metadata_handler.cc | 126 ------------------ .../libs/ion_gsms_metadata_handler.h | 51 ------- 5 files changed, 107 insertions(+), 183 deletions(-) delete mode 100644 src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc delete mode 100644 src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc index e608cf10b..ba02529b6 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc @@ -57,7 +57,7 @@ IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configura Concurrent_Queue* queue __attribute__((unused))) : SignalSourceBase(configuration, role, "ION_GSMS_Signal_Source"s), stream_ids_(parse_comma_list(configuration->property(role + ".streams"s, ""s))), - metadata_(configuration->property(role + ".metadata_filename"s, "../data/example_capture_metadata.sdrx"s)), + metadata_filepath_(configuration->property(role + ".metadata_filename"s, "../data/example_capture_metadata.sdrx"s)), timestamp_clock_offset_ms_(configuration->property(role + ".timestamp_clock_offset_ms"s, 0.0)), in_streams_(in_streams), out_streams_(out_streams) @@ -71,7 +71,11 @@ IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configura LOG(ERROR) << "A signal source does not have an output stream"; } - sources_ = metadata_.make_stream_sources(stream_ids_); + // Parse XML metadata file + load_metadata(); + + // Make source vector + sources_ = make_stream_sources(stream_ids_); for (const auto& source : sources_) { @@ -82,6 +86,97 @@ IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configura } } +void IONGSMSSignalSource::load_metadata() +{ + try + { + GnssMetadata::XmlProcessor xml_proc; + if (!xml_proc.Load(metadata_filepath_.c_str(), false, metadata_)) + { + LOG(WARNING) << "Could not load XML metadata file " << metadata_filepath_; + std::cerr << "Could not load XML metadata file " << metadata_filepath_ << std::endl; + std::cout << "GNSS-SDR program ended.\n"; + exit(1); + } + } + catch (GnssMetadata::ApiException& e) + { + LOG(WARNING) << "API Exception while loading XML metadata file: " << std::to_string(e.Error()); + std::cerr << "Could not load XML metadata file " << metadata_filepath_ << " : " << std::to_string(e.Error()) << std::endl; + std::cout << "GNSS-SDR program ended.\n"; + exit(1); + } + catch (std::exception& e) + { + LOG(WARNING) << "Exception while loading XML metadata file: " << e.what(); + std::cerr << "Could not load XML metadata file " << metadata_filepath_ << " : " << e.what() << std::endl; + std::cout << "GNSS-SDR program ended.\n"; + exit(1); + } +} + +std::vector IONGSMSSignalSource::make_stream_sources(const std::vector& stream_ids) const +{ + std::vector sources{}; + for (const auto& file : metadata_.Files()) + { + for (const auto& lane : metadata_.Lanes()) + { + if (lane.Id() == file.Lane().Id()) + { + for (const auto& block : lane.Blocks()) + { + bool block_done = false; + for (const auto& chunk : block.Chunks()) + { + for (const auto& lump : chunk.Lumps()) + { + for (const auto& stream : lump.Streams()) + { + bool found = false; + for (const auto& stream_id : stream_ids) + { + if (stream_id == stream.Id()) + { + found = true; + break; + } + } + if (found) + { + auto source = gnss_make_shared( + metadata_filepath_, + file, + block, + stream_ids); + + sources.push_back(source); + + // This file source will take care of any other matching streams in this block + // We can skip the rest of this block + block_done = true; + break; + } + } + + if (block_done) + { + break; + } + } + if (block_done) + { + break; + } + } + } + break; + } + } + } + + return sources; +} void IONGSMSSignalSource::connect(gr::top_block_sptr top_block) { diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h index 5bddfc147..31d0f7815 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.h @@ -21,7 +21,8 @@ #include "configuration_interface.h" #include "file_source_base.h" #include "gnss_sdr_timestamp.h" -#include "ion_gsms_metadata_handler.h" +#include "ion_gsms.h" +#include #include #include #include @@ -58,10 +59,17 @@ protected: } private: + std::vector make_stream_sources(const std::vector& stream_ids) const; + + void load_metadata(); + std::vector stream_ids_; std::vector sources_; std::vector> copy_blocks_; - IONGSMSMetadataHandler metadata_; + std::vector> valves_; + + std::string metadata_filepath_; + GnssMetadata::Metadata metadata_; gnss_shared_ptr timestamp_block_; std::string timestamp_file_; diff --git a/src/algorithms/signal_source/libs/CMakeLists.txt b/src/algorithms/signal_source/libs/CMakeLists.txt index b674ef5f5..4ad4caf93 100644 --- a/src/algorithms/signal_source/libs/CMakeLists.txt +++ b/src/algorithms/signal_source/libs/CMakeLists.txt @@ -48,8 +48,6 @@ endif() if(ENABLE_ION) set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gsms_chunk_data.cc) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_chunk_data.h) - set(OPT_SIGNAL_SOURCE_LIB_SOURCES ${OPT_SIGNAL_SOURCE_LIB_SOURCES} ion_gsms_metadata_handler.cc) - set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_metadata_handler.h) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_stream_encodings.h) set(OPT_SIGNAL_SOURCE_LIB_HEADERS ${OPT_SIGNAL_SOURCE_LIB_HEADERS} ion_gsms_chunk_unpacking_ctx.h) endif() diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc deleted file mode 100644 index 154ad6904..000000000 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.cc +++ /dev/null @@ -1,126 +0,0 @@ -/*! - * \file ion_gsms_metadata_handler.cc - * \brief Build instances of IONGSMSFileSource as needed given a list of stream ids - * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com - * - * ----------------------------------------------------------------------------- - * - * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. - * This file is part of GNSS-SDR. - * - * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) - * SPDX-License-Identifier: GPL-3.0-or-later - * - * ----------------------------------------------------------------------------- - */ - -#include "ion_gsms_metadata_handler.h" -#include -#if USE_GLOG_AND_GFLAGS -#include -#else -#include -#endif - -IONGSMSMetadataHandler::IONGSMSMetadataHandler(const std::string& metadata_filepath) - : metadata_filepath_(metadata_filepath) -{ - load_metadata(); -} - -const std::string& IONGSMSMetadataHandler::metadata_filepath() const -{ - return metadata_filepath_; -} - -void IONGSMSMetadataHandler::load_metadata() -{ - try - { - GnssMetadata::XmlProcessor xml_proc; - if (!xml_proc.Load(metadata_filepath_.c_str(), false, metadata_)) - { - LOG(WARNING) << "Could not load XML metadata file " << metadata_filepath_; - std::cerr << "Could not load XML metadata file " << metadata_filepath_ << std::endl; - std::cout << "GNSS-SDR program ended.\n"; - exit(1); - } - } - catch (GnssMetadata::ApiException& e) - { - LOG(WARNING) << "API Exception while loading XML metadata file: " << std::to_string(e.Error()); - std::cerr << "Could not load XML metadata file " << metadata_filepath_ << " : " << std::to_string(e.Error()) << std::endl; - std::cout << "GNSS-SDR program ended.\n"; - exit(1); - } - catch (std::exception& e) - { - LOG(WARNING) << "Exception while loading XML metadata file: " << e.what(); - std::cerr << "Could not load XML metadata file " << metadata_filepath_ << " : " << e.what() << std::endl; - std::cout << "GNSS-SDR program ended.\n"; - exit(1); - } -} - -std::vector IONGSMSMetadataHandler::make_stream_sources(const std::vector& stream_ids) const -{ - std::vector sources{}; - for (const auto& file : metadata_.Files()) - { - for (const auto& lane : metadata_.Lanes()) - { - if (lane.Id() == file.Lane().Id()) - { - for (const auto& block : lane.Blocks()) - { - bool block_done = false; - for (const auto& chunk : block.Chunks()) - { - for (const auto& lump : chunk.Lumps()) - { - for (const auto& stream : lump.Streams()) - { - bool found = false; - for (const auto& stream_id : stream_ids) - { - if (stream_id == stream.Id()) - { - found = true; - break; - } - } - if (found) - { - auto source = gnss_make_shared( - metadata_filepath_, - file, - block, - stream_ids); - - sources.push_back(source); - - // This file source will take care of any other matching streams in this block - // We can skip the rest of this block - block_done = true; - break; - } - } - - if (block_done) - { - break; - } - } - if (block_done) - { - break; - } - } - } - break; - } - } - } - - return sources; -} diff --git a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h b/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h deleted file mode 100644 index 6d01567c5..000000000 --- a/src/algorithms/signal_source/libs/ion_gsms_metadata_handler.h +++ /dev/null @@ -1,51 +0,0 @@ -/*! - * \file ion_gsms_metadata_handler.h - * \brief Build instances of IONGSMSFileSource as needed given a list of stream ids - * \author Víctor Castillo Agüero, 2024. victorcastilloaguero(at)gmail.com - * - * ----------------------------------------------------------------------------- - * - * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. - * This file is part of GNSS-SDR. - * - * Copyright (C) 2010-2024 (see AUTHORS file for a list of contributors) - * SPDX-License-Identifier: GPL-3.0-or-later - * - * ----------------------------------------------------------------------------- - */ - -#ifndef GNSS_SDR_ION_GSMSS_METADATA_HANDLER_H -#define GNSS_SDR_ION_GSMSS_METADATA_HANDLER_H - -#include "ion_gsms.h" -#include -#include -#include -#include - -/** \addtogroup Signal_Source - * \{ */ -/** \addtogroup Signal_Source_libs - * \{ */ - - -class IONGSMSMetadataHandler -{ -public: - explicit IONGSMSMetadataHandler(const std::string& metadata_filepath); - - std::vector make_stream_sources(const std::vector& stream_ids) const; - const std::string& metadata_filepath() const; - -private: - void load_metadata(); - - // State - std::string metadata_filepath_; - GnssMetadata::Metadata metadata_; -}; - - -/** \} */ -/** \} */ -#endif // GNSS_SDR_ION_GSMSS_METADATA_HANDLER_H From 89d73174a87d243ab88792c49736fbc35120b5ba Mon Sep 17 00:00:00 2001 From: Victor Castillo Date: Mon, 19 Aug 2024 17:44:36 +0200 Subject: [PATCH 34/34] Added valves to properly handle end of samples --- AUTHORS | 2 +- CITATION.cff | 2 +- .../adapters/ion_gsms_signal_source.cc | 16 ++- .../signal_source/gnuradio_blocks/ion_gsms.cc | 108 +++++++++++++----- .../signal_source/gnuradio_blocks/ion_gsms.h | 5 +- 5 files changed, 100 insertions(+), 33 deletions(-) diff --git a/AUTHORS b/AUTHORS index d1251f1fc..7df41ed17 100644 --- a/AUTHORS +++ b/AUTHORS @@ -64,7 +64,7 @@ Marc Sales marcsales92@gmail.com Contributor Piyush Gupta piyush04111999@gmail.com Contributor Rodrigo Muñoz rodrigo.munoz@proteinlab.cl Contributor Stefan van der Linden spvdlinden@gmail.com Contributor -Victor Castillo-Agüero victorcastilloaguero@gmail.com Contributor +Víctor Castillo-Agüero victorcastilloaguero@gmail.com Contributor Will Silberman wsilberm@google.com Contributor Carlos Paniego carpanie@hotmail.com Artwork diff --git a/CITATION.cff b/CITATION.cff index 2be1e1880..4bf27081f 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -38,7 +38,7 @@ authors: affiliation: "Instituto Nacional de Técnica Aeroespacial" email: victorcastilloaguero@gmail.com family-names: "Castillo-Agüero" - given-names: Victor + given-names: Víctor - alias: acebrianjuan email: acebrianjuan@gmail.com family-names: "Cebrián-Juan" diff --git a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc index ba02529b6..b67ec8a3a 100644 --- a/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc +++ b/src/algorithms/signal_source/adapters/ion_gsms_signal_source.cc @@ -17,6 +17,7 @@ #include "ion_gsms_signal_source.h" #include "gnss_sdr_flags.h" #include "gnss_sdr_string_literals.h" +#include "gnss_sdr_valve.h" #include #include #include @@ -54,7 +55,7 @@ IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configura const std::string& role, unsigned int in_streams, unsigned int out_streams, - Concurrent_Queue* queue __attribute__((unused))) + Concurrent_Queue* queue) : SignalSourceBase(configuration, role, "ION_GSMS_Signal_Source"s), stream_ids_(parse_comma_list(configuration->property(role + ".streams"s, ""s))), metadata_filepath_(configuration->property(role + ".metadata_filename"s, "../data/example_capture_metadata.sdrx"s)), @@ -82,6 +83,7 @@ IONGSMSSignalSource::IONGSMSSignalSource(const ConfigurationInterface* configura for (std::size_t i = 0; i < source->output_stream_count(); ++i) { copy_blocks_.push_back(gr::blocks::copy::make(source->output_stream_item_size(i))); + valves_.push_back(gnss_sdr_make_valve(source->output_stream_item_size(i), source->output_stream_total_sample_count(i), queue)); } } } @@ -186,6 +188,7 @@ void IONGSMSSignalSource::connect(gr::top_block_sptr top_block) for (std::size_t i = 0; i < source->output_stream_count(); ++i, ++cumulative_index) { top_block->connect(source, i, copy_blocks_[cumulative_index], 0); + top_block->connect(copy_blocks_[cumulative_index], 0, valves_[cumulative_index], 0); } } } @@ -193,9 +196,14 @@ void IONGSMSSignalSource::connect(gr::top_block_sptr top_block) void IONGSMSSignalSource::disconnect(gr::top_block_sptr top_block) { + std::size_t cumulative_index = 0; for (const auto& source : sources_) { - top_block->disconnect(source); + for (std::size_t i = 0; i < source->output_stream_count(); ++i, ++cumulative_index) + { + top_block->disconnect(source, i, copy_blocks_[cumulative_index], 0); + top_block->disconnect(copy_blocks_[cumulative_index], 0, valves_[cumulative_index], 0); + } } } @@ -219,7 +227,7 @@ gr::basic_block_sptr IONGSMSSignalSource::get_right_block(int RF_channel) if (RF_channel < 0 || RF_channel >= static_cast(copy_blocks_.size())) { LOG(WARNING) << "'RF_channel' out of bounds while trying to get signal source right block."; - return copy_blocks_[0]; + return valves_[0]; } - return copy_blocks_[RF_channel]; + return valves_[RF_channel]; } diff --git a/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.cc b/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.cc index 515bb1cf5..034f43379 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.cc +++ b/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.cc @@ -19,6 +19,12 @@ #include #include +#if USE_GLOG_AND_GFLAGS +#include +#else +#include +#endif + using namespace std::string_literals; IONGSMSFileSource::IONGSMSFileSource( @@ -30,13 +36,20 @@ IONGSMSFileSource::IONGSMSFileSource( "ion_gsms_file_source", gr::io_signature::make(0, 0, 0), make_output_signature(block, stream_ids)), - file_stream_(metadata_filepath.parent_path() / file.Url().Value()), + file_stream_(metadata_filepath.parent_path() / file.Url().Value(), std::ios::in | std::ios::binary), io_buffer_offset_(0), maximum_item_rate_(0), chunk_cycle_length_(0) { fs::path data_filepath = metadata_filepath.parent_path() / file.Url().Value(); std::size_t block_offset = file.Offset(); + + if (!file_stream_.is_open()) + { + LOG(ERROR) << "ion_gsms_file_source: Unable to open the samples file: " << (data_filepath).c_str(); + } + + // Skip offset and block header file_stream_.seekg(file.Offset() + block_offset + block.SizeHeader()); std::size_t output_stream_offset = 0; @@ -49,42 +62,26 @@ IONGSMSFileSource::IONGSMSFileSource( for (std::size_t i = 0; i < out_count; ++i) { output_stream_item_sizes_.push_back(chunk_data_.back()->output_stream_item_size(i)); + output_stream_item_rates_.push_back(chunk_data_.back()->output_stream_item_rate(i)); maximum_item_rate_ = std::max(chunk_data_.back()->output_stream_item_rate(i), maximum_item_rate_); } } output_stream_count_ = output_stream_offset; -} + output_stream_total_sample_counts_.resize(output_stream_count_); -int IONGSMSFileSource::work( - int noutput_items, - gr_vector_const_void_star& input_items __attribute__((unused)), - gr_vector_void_star& output_items) -{ - const std::size_t max_sample_output = std::floor((noutput_items - 1.0) / maximum_item_rate_); - io_buffer_.resize(max_sample_output * chunk_cycle_length_); - io_buffer_offset_ = 0; - file_stream_.read(io_buffer_.data(), sizeof(decltype(io_buffer_)::value_type) * io_buffer_.size()); - - items_produced_.clear(); - items_produced_.resize(output_items.size()); - - while (io_buffer_offset_ < io_buffer_.size()) + std::size_t cycle_count = block.Cycles(); + if (cycle_count == 0) { - for (auto& c : chunk_data_) - { - auto* chunk = c.get(); - io_buffer_offset_ += chunk->read_from_buffer(reinterpret_cast(io_buffer_.data()), io_buffer_offset_); - chunk->write_to_output(output_items, items_produced_); - } + // Read the whole file + const std::size_t file_size = fs::file_size(data_filepath); + cycle_count = std::floor((file_size - block_offset - block.SizeHeader()) / chunk_cycle_length_); } - for (std::size_t i = 0; i < items_produced_.size(); ++i) + for (std::size_t i = 0; i < output_stream_count_; ++i) { - produce(i, items_produced_[i]); + output_stream_total_sample_counts_[i] = cycle_count * output_stream_item_rates_[i]; } - - return WORK_CALLED_PRODUCE; } @@ -99,6 +96,10 @@ std::size_t IONGSMSFileSource::output_stream_item_size(std::size_t stream_index) return output_stream_item_sizes_[stream_index]; } +std::size_t IONGSMSFileSource::output_stream_total_sample_count(std::size_t stream_index) const +{ + return output_stream_total_sample_counts_[stream_index]; +} gr::io_signature::sptr IONGSMSFileSource::make_output_signature(const GnssMetadata::Block& block, const std::vector& stream_ids) { @@ -140,3 +141,58 @@ gr::io_signature::sptr IONGSMSFileSource::make_output_signature(const GnssMetada nstreams, item_sizes); } + +int IONGSMSFileSource::work( + int noutput_items, + gr_vector_const_void_star& input_items __attribute__((unused)), + gr_vector_void_star& output_items) +{ + // Compute the maximum number of samples that will be copied across all output buffer. + // If there are more than one output buffer (multichannel set up), the one with the most samples will be used as the maximum. + // + // Complex samples produce 2 items each (I and Q). In order to account for them, we subtract 1 from `noutput_items` and + // then floor the division. During testing, not doing this caused `max_sample_output` to oscillate between two values, thus + // resizing the `io_buffer_` on each call to `work()`. + const std::size_t max_sample_output = std::floor((noutput_items - 1.0) / maximum_item_rate_); + + // Resize the IO buffer to fit exactly the maximum amount of samples that will be outputted. + io_buffer_.resize(max_sample_output * chunk_cycle_length_); + + // We will be walking the IO buffer with this variable. + io_buffer_offset_ = 0; + + // Read samples from file into IO buffer + const std::size_t bytes_to_read = io_buffer_.size(); + file_stream_.read(io_buffer_.data(), bytes_to_read); + + // Reset `items_produced_` vector. This vector will accumulate the amount of items produced for each output stream. + items_produced_.clear(); + items_produced_.resize(output_items.size()); + + // Walk the IO buffer one chunk cycle at a time. See ION documentation for a definition of chunk and chunk cycle. + while (io_buffer_offset_ < bytes_to_read) + { + // Iterate chunks within a chunk cycle + for (auto& c : chunk_data_) + { + auto* chunk = c.get(); + + // Copy chunk into a separate buffer where the samples will be shifted from. + const std::size_t bytes_copied = chunk->read_from_buffer(reinterpret_cast(io_buffer_.data()), io_buffer_offset_); + + // Advance IO buffer offset + io_buffer_offset_ += bytes_copied; + + // Shift samples into output buffers following the appropriate unpacking strategy for this chunk. + chunk->write_to_output(output_items, items_produced_); + } + } + + // Call `produce(int, int)` with the appropriate item count for each output stream. + for (std::size_t i = 0; i < items_produced_.size(); ++i) + { + produce(i, items_produced_[i]); + } + + return WORK_CALLED_PRODUCE; +} diff --git a/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.h b/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.h index a4f7e2625..a787344bf 100644 --- a/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.h +++ b/src/algorithms/signal_source/gnuradio_blocks/ion_gsms.h @@ -24,10 +24,10 @@ #include #include #include +#include #include #include #include -#include /** \addtogroup Signal_Source * \{ */ @@ -52,6 +52,7 @@ public: std::size_t output_stream_count() const; std::size_t output_stream_item_size(std::size_t stream_index) const; + std::size_t output_stream_total_sample_count(std::size_t stream_index) const; private: static gr::io_signature::sptr make_output_signature(const GnssMetadata::Block& block, const std::vector& stream_ids); @@ -62,6 +63,8 @@ private: std::vector items_produced_; std::size_t output_stream_count_; std::vector output_stream_item_sizes_; + std::vector output_stream_item_rates_; + std::vector output_stream_total_sample_counts_; std::size_t maximum_item_rate_; std::vector> chunk_data_; std::size_t chunk_cycle_length_;