1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-12 11:10:33 +00:00

More fixes (#25)

* Clang Tidy fixes

* Fix some potential defects and be more consistent in class name. Improve const correctness

* Fix formatting

---------

Co-authored-by: cesaaargm <cesare.martinez@proton.me>
This commit is contained in:
Carles Fernandez 2024-08-11 12:44:18 +02:00 committed by GitHub
parent 79da7787ff
commit 5a634f7332
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 118 additions and 123 deletions

View File

@ -77,7 +77,7 @@ osnma_msg_receiver::osnma_msg_receiver(const std::string& crtFilePath,
d_dsm_reader = std::make_unique<OSNMA_DSM_Reader>();
d_crypto = std::make_unique<Gnss_Crypto>(crtFilePath, merkleFilePath);
d_helper = std::make_unique<Osnma_Helper>();
d_nav_data_manager = std::make_unique<OSNMA_nav_data_Manager>();
d_nav_data_manager = std::make_unique<OSNMA_NavDataManager>();
if (d_crypto->have_public_key())
{ // Hot start is enabled
@ -1192,7 +1192,7 @@ void osnma_msg_receiver::process_mack_message()
}
d_nav_data_manager->update_nav_data(d_tags_awaiting_verify, tag_size);
auto data_to_send = d_nav_data_manager->get_verified_data();
d_nav_data_manager->print_status();
d_nav_data_manager->log_status();
send_data_to_pvt(data_to_send);
remove_verified_tags();

View File

@ -26,7 +26,7 @@
#include "galileo_inav_message.h" // for OSNMA_msg
#include "gnss_block_interface.h" // for gnss_shared_ptr
#include "osnma_data.h" // for OSNMA_data structures
#include "osnma_nav_data_manager.h" // for OSNMA_nav_data_Manager
#include "osnma_nav_data_manager.h" // for OSNMA_NavDataManager
#include <gnuradio/block.h> // for gr::block
#include <pmt/pmt.h> // for pmt::pmt_t
#include <array> // for std::array
@ -112,10 +112,10 @@ private:
std::array<uint16_t, 16> d_number_of_blocks{};
std::array<uint8_t, 60> d_mack_message{}; // C: 480 b
std::unique_ptr<Gnss_Crypto> d_crypto; // class for cryptographic functions
std::unique_ptr<OSNMA_DSM_Reader> d_dsm_reader; // osnma parameters parser
std::unique_ptr<Osnma_Helper> d_helper; // helper class with auxiliary functions
std::unique_ptr<OSNMA_nav_data_Manager> d_nav_data_manager; // refactor for holding and processing navigation data
std::unique_ptr<Gnss_Crypto> d_crypto; // class for cryptographic functions
std::unique_ptr<OSNMA_DSM_Reader> d_dsm_reader; // osnma parameters parser
std::unique_ptr<Osnma_Helper> d_helper; // helper class with auxiliary functions
std::unique_ptr<OSNMA_NavDataManager> d_nav_data_manager; // refactor for holding and processing navigation data
OSNMA_data d_osnma_data{};

View File

@ -28,13 +28,13 @@
* @param PRNd The satellite ID.
* @param TOW The TOW of the received data.
*/
void OSNMA_nav_data_Manager::add_navigation_data(const std::string& nav_bits, uint32_t PRNd, uint32_t TOW)
void OSNMA_NavDataManager::add_navigation_data(const std::string& nav_bits, uint32_t PRNd, uint32_t TOW)
{
if (not have_nav_data(nav_bits, PRNd, TOW))
{
_satellite_nav_data[PRNd][TOW].add_nav_data(nav_bits);
_satellite_nav_data[PRNd][TOW].PRNd = PRNd;
_satellite_nav_data[PRNd][TOW].set_tow_sf0(TOW);
d_satellite_nav_data[PRNd][TOW].add_nav_data(nav_bits);
d_satellite_nav_data[PRNd][TOW].PRNd = PRNd;
d_satellite_nav_data[PRNd][TOW].set_tow_sf0(TOW);
}
}
@ -42,33 +42,39 @@ void OSNMA_nav_data_Manager::add_navigation_data(const std::string& nav_bits, ui
/**
* @brief loops over the verified tags and updates the navigation data tag length
*/
void OSNMA_nav_data_Manager::update_nav_data(const std::multimap<uint32_t, Tag>& tags_verified, const uint8_t tag_size)
void OSNMA_NavDataManager::update_nav_data(const std::multimap<uint32_t, Tag>& tags_verified, uint8_t tag_size)
{
if (d_satellite_nav_data.empty())
{
return;
}
// loop through all tags
for (const auto& tag : tags_verified)
{
// if tag status is verified, look for corresponding OSNMA_NavData and add increase verified tag bits.
if (tag.second.status == Tag::e_verification_status::SUCCESS)
{
if (have_PRNd_nav_data(tag.second.PRN_d))
auto sat_it = d_satellite_nav_data.find(tag.second.PRN_d);
if (sat_it == d_satellite_nav_data.end())
{
std::map<uint32_t, OSNMA_NavData> tow_map = _satellite_nav_data.find(tag.second.PRN_d)->second;
for (auto& tow_it : tow_map) // note: starts with smallest (i.e. oldest) navigation dataset
continue;
}
auto& tow_map = sat_it->second;
for (auto& tow_it : tow_map) // note: starts with smallest (i.e. oldest) navigation dataset
{
std::string nav_data;
if (tag.second.ADKD == 0 || tag.second.ADKD == 12)
{
std::string nav_data;
if (tag.second.ADKD == 0 || tag.second.ADKD == 12)
{
nav_data = tow_it.second.get_ephemeris_data();
}
else if (tag.second.ADKD == 4)
{
nav_data = tow_it.second.get_utc_data();
}
// find associated OSNMA_NavData
if (tag.second.nav_data == nav_data)
{
_satellite_nav_data[tag.second.PRN_d][tow_it.first].verified_bits += tag_size;
}
nav_data = tow_it.second.get_ephemeris_data();
}
else if (tag.second.ADKD == 4)
{
nav_data = tow_it.second.get_utc_data();
}
// find associated OSNMA_NavData
if (tag.second.nav_data == nav_data)
{
d_satellite_nav_data[tag.second.PRN_d][tow_it.first].verified_bits += tag_size;
}
}
}
@ -76,24 +82,17 @@ void OSNMA_nav_data_Manager::update_nav_data(const std::multimap<uint32_t, Tag>&
}
bool OSNMA_nav_data_Manager::have_PRNd_nav_data(uint32_t PRNd)
{
// check if have data from PRNd in _satellite_nav_data
return _satellite_nav_data.find(PRNd) != _satellite_nav_data.end();
}
std::vector<OSNMA_NavData> OSNMA_nav_data_Manager::get_verified_data()
std::vector<OSNMA_NavData> OSNMA_NavDataManager::get_verified_data()
{
std::vector<OSNMA_NavData> result;
for (const auto& prna : _satellite_nav_data)
for (const auto& prna : d_satellite_nav_data)
{
for (const auto& tow_navdata : prna.second)
{
if (tow_navdata.second.verified_bits >= L_t_min)
{
result.push_back(tow_navdata.second);
_satellite_nav_data[prna.first][tow_navdata.first].verified = true;
d_satellite_nav_data[prna.first][tow_navdata.first].verified = true;
}
}
}
@ -101,45 +100,37 @@ std::vector<OSNMA_NavData> OSNMA_nav_data_Manager::get_verified_data()
}
bool OSNMA_nav_data_Manager::have_nav_data(uint32_t PRNd, uint32_t TOW, uint8_t ADKD)
bool OSNMA_NavDataManager::have_nav_data(uint32_t PRNd, uint32_t TOW, uint8_t ADKD) const
{
if (ADKD == 0 || ADKD == 12)
const auto sat_it = d_satellite_nav_data.find(PRNd);
if (sat_it == d_satellite_nav_data.cend())
{
const auto it = _satellite_nav_data.find(PRNd);
if (it != _satellite_nav_data.cend())
{
const auto it2 = it->second.find(TOW);
if (it2 != it->second.cend() && !it->second[TOW].get_ephemeris_data().empty())
{
return true;
}
}
return false;
}
else if (ADKD == 4)
const auto tow_it = sat_it->second.find(TOW);
if (tow_it == sat_it->second.cend())
{
const auto it = _satellite_nav_data.find(PRNd);
if (it != _satellite_nav_data.cend())
{
const auto it2 = it->second.find(TOW);
if (it2 != it->second.cend() && !it->second[TOW].get_utc_data().empty())
{
return true;
}
}
return false;
}
switch (ADKD)
{
case 0:
case 12:
return !tow_it->second.get_ephemeris_data().empty();
case 4:
return !tow_it->second.get_utc_data().empty();
default:
return false;
}
return false;
}
/**
* @brief returns OSNMA_NavData object.
* @remarks assumes it exists (called have_nav_data before), otherwise undefined behavior
* TODO - maybe add const promise and use find() instead? this is kinda sensitive topic.
*/
std::string OSNMA_nav_data_Manager::get_navigation_data(const Tag& tag)
std::string OSNMA_NavDataManager::get_navigation_data(const Tag& tag) const
{
auto prn_it = _satellite_nav_data.find(tag.PRN_d);
if (prn_it == _satellite_nav_data.end())
auto prn_it = d_satellite_nav_data.find(tag.PRN_d);
if (prn_it == d_satellite_nav_data.end())
{
return "";
}
@ -178,11 +169,11 @@ std::string OSNMA_nav_data_Manager::get_navigation_data(const Tag& tag)
* @param PRNd
* @return
*/
bool OSNMA_nav_data_Manager::have_nav_data(const std::string& nav_bits, uint32_t PRNd, uint32_t TOW)
bool OSNMA_NavDataManager::have_nav_data(const std::string& nav_bits, uint32_t PRNd, uint32_t TOW)
{
if (_satellite_nav_data.find(PRNd) != _satellite_nav_data.end())
if (d_satellite_nav_data.find(PRNd) != d_satellite_nav_data.end())
{
for (auto& data_timestamp : _satellite_nav_data[PRNd])
for (auto& data_timestamp : d_satellite_nav_data[PRNd])
{
if (nav_bits.size() == EPH_SIZE)
{
@ -211,10 +202,10 @@ bool OSNMA_nav_data_Manager::have_nav_data(const std::string& nav_bits, uint32_t
* @param t Tag object
* @return True if the needed navigation data for the tag is available (oldest possible OSNMA_NavData available)
*/
bool OSNMA_nav_data_Manager::have_nav_data(const Tag& t) const
bool OSNMA_NavDataManager::have_nav_data(const Tag& t) const
{
auto prn_it = _satellite_nav_data.find(t.PRN_d);
if (prn_it == _satellite_nav_data.end())
auto prn_it = d_satellite_nav_data.find(t.PRN_d);
if (prn_it == d_satellite_nav_data.end())
{
return false;
}
@ -245,9 +236,9 @@ bool OSNMA_nav_data_Manager::have_nav_data(const Tag& t) const
}
void OSNMA_nav_data_Manager::print_status()
void OSNMA_NavDataManager::log_status() const
{
for (const auto& satellite : _satellite_nav_data)
for (const auto& satellite : d_satellite_nav_data)
{
LOG(INFO) << "Galileo OSNMA: NavData status :: SVID=" << satellite.first;
const auto& tow_data = satellite.second;
@ -258,7 +249,7 @@ void OSNMA_nav_data_Manager::print_status()
<< ", TOW_start="
<< nav_data.second.get_tow_sf0()
<< ", TOW_last="
<< nav_data.second.last_received_TOW
<< nav_data.second.get_last_received_TOW()
<< ", l_t="
<< nav_data.second.verified_bits
<< ", PRNd="

View File

@ -17,8 +17,8 @@
#ifndef GNSS_SDR_OSNMA_NAV_DATA_MANAGER_H
#define GNSS_SDR_OSNMA_NAV_DATA_MANAGER_H
#include "osnma_data.h" // NavData
#include <cstdint> // uint32_t
#include "osnma_data.h" // for OSNMA_NavData, Tag
#include <cstdint> // for uint32_t
#include <map>
#include <string>
#include <vector>
@ -29,33 +29,29 @@
* \{ */
/**
* @class OSNMA_nav_data_Manager
* @class OSNMA_NavDataManager
* @brief Class for managing OSNMA navigation data
* @details It does good stuff
* @remarks throw it whatever, it will improve it. Does good stuff
*/
class OSNMA_nav_data_Manager
class OSNMA_NavDataManager
{
public:
OSNMA_nav_data_Manager() = default;
bool have_nav_data(const std::string& nav_bits, uint32_t PRNd, uint32_t TOW);
bool have_nav_data(uint32_t PRNd, uint32_t TOW, uint8_t ADKD);
bool have_nav_data(const Tag& t) const;
void add_navigation_data(const std::string& nav_bits, uint32_t PRNd, uint32_t TOW); // gets the bits and adds them to the list
std::string get_navigation_data(const Tag& t);
OSNMA_NavDataManager() = default;
void update_nav_data(const std::multimap<uint32_t, Tag>& tags_verified, const uint8_t tag_size);
void log_status() const;
bool have_nav_data(const Tag& t) const;
bool have_nav_data(uint32_t PRNd, uint32_t TOW, uint8_t ADKD) const;
std::string get_navigation_data(const Tag& t) const;
void add_navigation_data(const std::string& nav_bits, uint32_t PRNd, uint32_t TOW);
void update_nav_data(const std::multimap<uint32_t, Tag>& tags_verified, uint8_t tag_size);
bool have_nav_data(const std::string& nav_bits, uint32_t PRNd, uint32_t TOW);
std::vector<OSNMA_NavData> get_verified_data();
void print_status();
private:
bool have_PRNd_nav_data(uint32_t PRNd);
std::map<uint32_t, std::map<uint32_t, OSNMA_NavData>> _satellite_nav_data{}; // NavData sorted by [PRNd][TOW_start]
std::map<uint32_t, std::map<uint32_t, OSNMA_NavData>> d_satellite_nav_data{}; // NavData sorted by [PRNd][TOW_start]
const uint32_t L_t_min{40};
const uint16_t EPH_SIZE{549};
const uint16_t UTC_SIZE{141};
const uint16_t MAX_ALLOWED_SIZE{150}; // arbitrary maximum for the navigation data container
};
/** \} */

View File

@ -35,19 +35,25 @@ bool OSNMA_NavData::add_nav_data(const std::string& nav_data)
}
return false;
}
std::string OSNMA_NavData::get_utc_data() const
{
return d_utc;
}
std::string OSNMA_NavData::get_ephemeris_data() const
{
return d_ephemeris_iono;
}
/**
* Updates the last TOW the NavData bits were received.
* @param TOW
*/
void OSNMA_NavData::update_last_received_timestamp(uint32_t TOW)
{
last_received_TOW = TOW;
d_last_received_TOW = TOW;
}

View File

@ -136,35 +136,34 @@ class OSNMA_NavData
{
public:
OSNMA_NavData() : nav_data_id(id_counter++) {}
const uint32_t nav_data_id;
std::string get_utc_data() const;
std::string get_ephemeris_data() const;
uint32_t get_tow_sf0() const { return TOW_sf0; }
uint32_t get_last_received_TOW() const { return d_last_received_TOW; }
uint32_t get_tow_sf0() const { return d_TOW_sf0; }
const uint32_t nav_data_id;
bool have_this_bits(std::string nav_data);
bool add_nav_data(const std::string& nav_data);
bool verified{false};
void update_last_received_timestamp(uint32_t TOW);
void set_tow_sf0(int value) { TOW_sf0 = value; }
void set_tow_sf0(int value) { d_TOW_sf0 = value; }
void set_ephemeris_data(std::string value) { d_ephemeris_iono = value; }
void set_utc_data(std::string value) { d_utc = value; }
void update_last_received_timestamp(uint32_t TOW);
uint32_t verified_bits{0};
uint32_t last_received_TOW{0};
uint32_t IOD_nav{0};
uint32_t PRNd{0};
uint32_t ADKD{};
bool verified{false};
private:
std::string d_ephemeris_iono{""};
std::string d_utc{""};
uint32_t TOW_sf0{0};
uint32_t d_TOW_sf0{0};
uint32_t d_last_received_TOW{0};
static uint32_t id_counter;
};
/*!
* \brief This class handles ONSMA data
* See https://www.gsc-europa.eu/sites/default/files/sites/all/files/Galileo_OSNMA_User_ICD_for_Test_Phase_v1.0.pdf

View File

@ -16,15 +16,15 @@
* -----------------------------------------------------------------------------
*/
#include "Galileo_OSNMA.h"
#include "gnss_crypto.h"
#include "osnma_helper.h"
#include "osnma_msg_receiver.h"
#include <gtest/gtest.h>
#include <bitset>
#include <chrono>
#include <fstream>
#include <vector>
#include "Galileo_OSNMA.h"
#include "gnss_crypto.h"
#include "osnma_helper.h"
#include "osnma_msg_receiver.h"
#if USE_GLOG_AND_GFLAGS
#include <glog/logging.h> // for LOG
@ -43,7 +43,7 @@ protected:
uint32_t TOW{};
uint32_t WN{};
std::tm GST_START_EPOCH = {0, 0, 0, 22, 8 - 1, 1999 - 1900, 0, 0, 0, 0, 0}; // months start with 0 and years since 1900 in std::tm
const uint32_t LEAP_SECONDS = 0; // tried with 13 + 5, which is the official count, but won't parse correctly
const uint32_t LEAP_SECONDS = 0; // tried with 13 + 5, which is the official count, but won't parse correctly
void set_time(std::tm& input);
void SetUp() override
@ -253,7 +253,7 @@ TEST_F(OsnmaMsgReceiverTest, TeslaKeyVerification)
osnma->d_osnma_data.d_dsm_kroot_message.ks = 4; // TABLE 10 --> 128 bits
osnma->d_osnma_data.d_dsm_kroot_message.alpha = 0x610BDF26D77B;
osnma->d_GST_SIS = (1248 & 0x00000FFF) << 20 | (345630 & 0x000FFFFF);
osnma->d_GST_0 = ((1248 & 0x00000FFF) << 20 | (345600 & 0x000FFFFF)); // applicable time (GST_Kroot + 30)
osnma->d_GST_0 = ((1248 & 0x00000FFF) << 20 | (345600 & 0x000FFFFF)); // applicable time (GST_Kroot + 30)
osnma->d_GST_Sf = osnma->d_GST_0 + 30 * std::floor((osnma->d_GST_SIS - osnma->d_GST_0) / 30); // Eq. 3 R.G.
osnma->d_tesla_keys.insert((std::pair<uint32_t, std::vector<uint8_t>>(345600, {0xEF, 0xF9, 0x99, 0x04, 0x0E, 0x19, 0xB5, 0x70, 0x83, 0x50, 0x60, 0xBE, 0xBD, 0x23, 0xED, 0x92}))); // K1, not needed, just for reference.

View File

@ -161,7 +161,7 @@ TEST_F(OsnmaTestVectors, PublicKeyRevocation)
std::tm input_time_step1 = {0, 45, 7, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0};
std::tm input_time_step2 = {0, 30, 9, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0};
std::tm input_time_step3 = {0, 30, 10, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0};
std::vector<std::tm> input_times = { input_time_step1, input_time_step2, input_time_step3 };
std::vector<std::tm> input_times = {input_time_step1, input_time_step2, input_time_step3};
std::vector<TestVector> testVectors_step1 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/pkrev_step1/07_OCT_2023_GST_07_45_01.csv");
std::vector<TestVector> testVectors_step2 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/pkrev_step2/07_OCT_2023_GST_09_30_01.csv");
@ -170,7 +170,7 @@ TEST_F(OsnmaTestVectors, PublicKeyRevocation)
{
ASSERT_TRUE(false);
}
std::vector<std::vector<TestVector>> testVectors = { testVectors_step1, testVectors_step2, testVectors_step3};
std::vector<std::vector<TestVector>> testVectors = {testVectors_step1, testVectors_step2, testVectors_step3};
bool result = feedOsnmaWithTestVectors(osnma, testVectors, input_times);
ASSERT_TRUE(result);
@ -182,7 +182,8 @@ TEST_F(OsnmaTestVectors, PublicKeyRevocation)
ASSERT_EQ(osnma->d_count_failed_macseq, 0);
}
TEST_F(OsnmaTestVectors, AlertMessage){
TEST_F(OsnmaTestVectors, AlertMessage)
{
// Arrange
std::string crtFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_3/PublicKey/OSNMA_PublicKey_20231007201500_PKID_1.crt";
std::string merkleFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_3/MerkleTree/OSNMA_MerkleTree_20231007201500_PKID_1.xml";
@ -190,7 +191,7 @@ TEST_F(OsnmaTestVectors, AlertMessage){
std::tm input_time_step1 = {0, 45, 18, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0};
std::tm input_time_step2 = {0, 45, 19, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0};
std::vector<std::tm> input_times = { input_time_step1, input_time_step2 };
std::vector<std::tm> input_times = {input_time_step1, input_time_step2};
std::vector<TestVector> testVectors_step1 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/oam_step1/07_OCT_2023_GST_18_45_01.csv");
std::vector<TestVector> testVectors_step2 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/oam_step2/07_OCT_2023_GST_19_45_01.csv");
@ -198,7 +199,7 @@ TEST_F(OsnmaTestVectors, AlertMessage){
{
ASSERT_TRUE(false);
}
std::vector<std::vector<TestVector>> testVectors = { testVectors_step1, testVectors_step2};
std::vector<std::vector<TestVector>> testVectors = {testVectors_step1, testVectors_step2};
// Act
bool result = feedOsnmaWithTestVectors(osnma, testVectors, input_times);
@ -219,17 +220,18 @@ TEST_F(OsnmaTestVectors, AlertMessage){
// Auxiliary functions for the OsnmaTestVectorsSimulation test fixture.
// Essentially, they perform same work as the telemetry decoder block, but adapted to the osnma-test-vector files.
bool OsnmaTestVectors::feedOsnmaWithTestVectors(osnma_msg_receiver_sptr osnma_object, std::vector<std::vector<TestVector>> testVectors, std::vector<std::tm> startTimesFiles){
bool OsnmaTestVectors::feedOsnmaWithTestVectors(osnma_msg_receiver_sptr osnma_object, std::vector<std::vector<TestVector>> testVectors, std::vector<std::tm> startTimesFiles)
{
bool end_of_hex_stream;
int offset_byte{0};
int byte_index{0}; // index containing the last byte position of the hex stream that was retrieved. Takes advantage that all TVs have same size
int byte_index{0}; // index containing the last byte position of the hex stream that was retrieved. Takes advantage that all TVs have same size
const int DUMMY_PAGE{63};
bool flag_dummy_page{false};
// Act
// loop over all bytes of data. Note: all TestVectors have same amount of data.
// if needed, add global flags so that particular logic may be done at certain points in between files
for (size_t test_step = 0; test_step < testVectors.size() ; test_step++)
for (size_t test_step = 0; test_step < testVectors.size(); test_step++)
{
// set variables for each file
end_of_hex_stream = false;
@ -241,7 +243,8 @@ bool OsnmaTestVectors::feedOsnmaWithTestVectors(osnma_msg_receiver_sptr osnma_ob
<< ", TOW=" << TOW
<< ", WN=" << WN << std::endl;
if (test_step == 1 && d_flag_NPK == true ){
if (test_step == 1 && d_flag_NPK == true)
{
// step 2: this simulates the osnma connecting to the GSC server and downloading the Merkle tree of the next public key
osnma_object->read_merkle_xml(
std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/MerkleTree/OSNMA_MerkleTree_20231007081500_PKID_8.xml");
@ -436,7 +439,7 @@ bool OsnmaTestVectors::feedOsnmaWithTestVectors(osnma_msg_receiver_sptr osnma_ob
if (end_of_hex_stream)
continue;
}
return true;
return true;
}
std::vector<TestVector> OsnmaTestVectors::readTestVectorsFromFile(const std::string& filename)