1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-10-29 22:26:22 +00:00

[TEST][OsnmaTestVector] refactor parsing code into feedOsnmaWithTestVectors method.

* could not find a way to access osnma private methods, so had to make d_crypto and msg_handler_osnma public. Looking for a way to avoid that.
This commit is contained in:
cesaaargm 2024-07-29 15:21:35 +02:00
parent fc1541ef10
commit 440dc582b5
3 changed files with 111 additions and 258 deletions

View File

@ -535,12 +535,14 @@ void osnma_msg_receiver::process_dsm_message(const std::vector<uint8_t>& dsm_msg
{
LOG(WARNING) << "Galileo OSNMA: KROOT authentication failed.";
std::cerr << "Galileo OSNMA: KROOT authentication failed." << std::endl;
d_count_failed_Kroot ++;
}
}
else
{
LOG(WARNING) << "Galileo OSNMA: Error computing padding bits.";
// TODO - here will have to decide if perform the verification or not. Since this step is not mandatory, one could as well have skipped it.
d_count_failed_Kroot++;
}
}
}
@ -608,7 +610,7 @@ void osnma_msg_receiver::process_dsm_message(const std::vector<uint8_t>& dsm_msg
bool verification = verify_dsm_pkr(d_osnma_data.d_dsm_pkr_message);
if (verification)
{
LOG(INFO) << "Galileo OSNMA: DSM-PKR verified successfully";
LOG(INFO) << "Galileo OSNMA: DSM-PKR verification :: SUCCESS";
d_public_key_verified = true;
if (d_flag_PK_renewal){
d_new_public_key = d_osnma_data.d_dsm_pkr_message.npk;
@ -618,6 +620,12 @@ void osnma_msg_receiver::process_dsm_message(const std::vector<uint8_t>& dsm_msg
d_crypto->store_public_key(PEMFILE_DEFAULT);
}
}
else
{
LOG(ERROR) << "Galileo OSNMA: DSM-PKR verification :: FAILURE";
d_public_key_verified = false;
d_count_failed_pubKey ++;
}
}
}
else
@ -1005,6 +1013,7 @@ void osnma_msg_receiver::process_mack_message()
* */
if (ret)
{
d_count_successful_tags++;
it.second.status = Tag::SUCCESS;
LOG(INFO) << "Galileo OSNMA: Tag verification :: SUCCESS for tag Id="
<< it.second.tag_id
@ -1031,6 +1040,7 @@ void osnma_msg_receiver::process_mack_message()
* communicate to PVT*/
else
{
d_count_failed_tags++;
it.second.status = Tag::FAIL;
LOG(WARNING) << "Galileo OSNMA: Tag verification :: FAILURE for tag Id="
<< it.second.tag_id
@ -1770,6 +1780,7 @@ std::vector<MACK_tag_and_info> osnma_msg_receiver::verify_macseq_new(const MACK_
if (mack.tag_and_info.size() != applicable_sequence.size() - 1)
{
LOG(WARNING) << "Galileo OSNMA: Number of retrieved tags does not match MACLT sequence size!";
d_count_failed_macseq += mack.tag_and_info.size();
return verified_tags;
}
std::vector<uint8_t> flxTags{};
@ -1796,6 +1807,7 @@ std::vector<MACK_tag_and_info> osnma_msg_receiver::verify_macseq_new(const MACK_
LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: FAILURE :: ADKD mismatch against MAC Look-up table for Tag=0x"
<< std::setfill('0') << std::setw(10) << std::hex << std::uppercase
<< mack.tag_and_info[i].tag << std::dec;
d_count_failed_macseq ++;
}
}
@ -1844,10 +1856,10 @@ std::vector<MACK_tag_and_info> osnma_msg_receiver::verify_macseq_new(const MACK_
}
return verified_tags;
}
else
{
LOG(WARNING) << "Galileo OSNMA: MACSEQ verification :: FAILURE :: FLX tags verification failed";
d_count_failed_macseq += flxTags.size();
return verified_tags;
}
}

View File

@ -63,11 +63,12 @@ class osnma_msg_receiver : public gr::block
{
public:
~osnma_msg_receiver() = default; //!< Default destructor
std::unique_ptr<Gnss_Crypto> d_crypto; // access to cryptographic functions
void msg_handler_osnma(const pmt::pmt_t& msg); // GnssCrypto and the message handler are needed by public method within TestVectors fixture
private:
friend osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath);
osnma_msg_receiver(const std::string& crtFilePath, const std::string& merkleFilePath);
void msg_handler_osnma(const pmt::pmt_t& msg);
void process_osnma_message(const std::shared_ptr<OSNMA_msg>& osnma_msg);
void read_nma_header(uint8_t nma_header);
void read_dsm_header(uint8_t dsm_header);
@ -112,7 +113,6 @@ private:
std::array<uint8_t, 60> d_mack_message{}; // C: 480 b
std::unique_ptr<OSNMA_DSM_Reader> d_dsm_reader; // osnma parameters parser
std::unique_ptr<Gnss_Crypto> d_crypto; // access to cryptographic functions
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
@ -154,13 +154,19 @@ private:
bool d_flag_NPK_set{false};
// Provide access to inner functions to Gtest
uint32_t d_count_successful_tags{0};
uint32_t d_count_failed_tags{0};
uint32_t d_count_failed_Kroot{0};
uint32_t d_count_failed_pubKey{0}; // failed public key verifications against Merkle root
uint32_t d_count_failed_macseq{0};
FRIEND_TEST(OsnmaMsgReceiverTest, TeslaKeyVerification);
FRIEND_TEST(OsnmaMsgReceiverTest, TagVerification);
FRIEND_TEST(OsnmaMsgReceiverTest, BuildTagMessageM0);
FRIEND_TEST(OsnmaMsgReceiverTest, VerifyPublicKey);
FRIEND_TEST(OsnmaMsgReceiverTest, ComputeBaseLeaf);
FRIEND_TEST(OsnmaMsgReceiverTest, ComputeMerkleRoot);
FRIEND_TEST(OsnmaTestVectors, OsnmaTestVectorsSimulation);
FRIEND_TEST(OsnmaTestVectors, NominalTestConf1);
FRIEND_TEST(OsnmaTestVectors, NominalTestConf2);
FRIEND_TEST(OsnmaTestVectors, PublicKeyRenewal);
};

View File

@ -17,7 +17,6 @@
*/
#include "gnss_crypto.h"
#include "osnma_helper.h"
#include "osnma_msg_receiver.h"
#include <gtest/gtest.h>
#include <bitset>
@ -41,302 +40,143 @@ struct TestVector
class OsnmaTestVectors : public ::testing::Test
{
public:
static std::vector<uint8_t> parseNavBits(const std::string& hex);
static std::vector<TestVector> readTestVectorsFromFile(const std::string& filename);
protected:
std::vector<uint8_t> parseNavBits(const std::string& hex);
std::vector<TestVector> readTestVectorsFromFile(const std::string& filename);
std::string bytes_to_str(const std::vector<uint8_t>& bytes);
std::vector<uint8_t> extract_page_bytes(const TestVector& tv, int byte_index, int num_bytes);
bool feedOsnmaWithTestVectors(osnma_msg_receiver_sptr osnma_object, std::vector<std::vector<TestVector>> testVectors, std::vector<std::tm> startTimesFiles);
void set_time(std::tm& input);
void SetUp() override
{
}
protected:
Osnma_Helper helper;
osnma_msg_receiver_sptr osnma;
OSNMA_msg osnma_msg{};
std::array<int8_t, 15> nma_position_filled;
uint32_t d_GST_SIS{};
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; // 13 + 5;
void set_time(std::tm& input);
void SetUp() override
{
}
const uint32_t LEAP_SECONDS = 0;
const int SIZE_PAGE_BYTES{240 / 8}; // total bytes of a page
const int SIZE_SUBFRAME_PAGES{15}; // number of pages of a subframe
const int DURATION_SUBFRAME{30}; // duration of a subframe, in seconds// 13 + 5;
bool d_flag_NPK{false}; // flag for NPK, new MT will be set when the new Kroot is received.
};
// TODO - split this into configuration 1 and configuration 2
TEST_F(OsnmaTestVectors, OsnmaTestVectorsSimulation)
TEST_F(OsnmaTestVectors, NominalTestConf1)
{
// Arrange
// std::tm input_time = {0, 0, 5, 16, 8 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; // conf. 1
std::tm input_time = {0, 0, 0, 27, 7 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; // conf. 2
set_time(input_time);
std::string crtFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/PublicKey/OSNMA_PublicKey_20230720113300_newPKID_2.crt"; // conf. 2
std::string merkleFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/MerkleTree/OSNMA_MerkleTree_20230720113300_newPKID_2.xml";
osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath);
std::vector<TestVector> testVectors = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/configuration_2/27_JUL_2023_GST_00_00_01.csv"); // conf. 2
if (testVectors.empty())
std::string crtFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_1/PublicKey/OSNMA_PublicKey_20230803105952_newPKID_1.crt";
std::string merkleFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_1/MerkleTree/OSNMA_MerkleTree_20230803105953_newPKID_1.xml";
osnma_msg_receiver_sptr osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath);
std::tm input_time = {0, 0, 5, 16, 8 - 1, 2023 - 1900, 0, 0, 0, 0, 0};
std::vector<std::tm> input_times = {input_time};
std::vector<TestVector> testVector = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/configuration_1/16_AUG_2023_GST_05_00_01.csv");
if (testVector.empty())
{
ASSERT_TRUE(false);
}
bool end_of_hex_stream{false};
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
const int SIZE_PAGE_BYTES{240 / 8}; // total bytes of a page
const int SIZE_SUBFRAME_PAGES{15}; // number of pages of a subframe
const int DURATION_SUBFRAME{30}; // duration of a subframe, in seconds
const int DUMMY_PAGE{63};
bool flag_dummy_page{false};
std::cout << "OsnmaTestVectorsSimulation:"
<< " d_GST_SIS= " << d_GST_SIS
<< ", TOW=" << TOW
<< ", WN=" << WN << std::endl;
std::vector<std::vector<TestVector>> testVectors = {testVector};
// Act
// loop over all bytes of data. Note: all TestVectors have same amount of data.
while (!end_of_hex_stream)
{
// loop over all SVs, extract a subframe
for (const TestVector& tv : testVectors)
{ // loop over all SVs, extract a subframe
std::cout << "OsnmaTestVectorsSimulation: SVID (PRN_a) " << tv.svId << std::endl;
auto osnmaMsg_sptr = std::make_shared<OSNMA_msg>();
std::array<uint8_t, 15> hkroot{};
std::array<uint32_t, 15> mack{};
byte_index = offset_byte; // reset byte_index to the offset position for the next test vector. Offset is updated at the end of each Subframe (every 30 s or 450 Bytes)
std::map<uint8_t, std::bitset<128>> words_for_OSNMA; // structure containing <WORD_NUMBER> and <EXTRACTED_BITS>
bool result = feedOsnmaWithTestVectors(osnma, testVectors, input_times);
ASSERT_TRUE(result);
for (int idx = 0; idx < SIZE_SUBFRAME_PAGES; ++idx) // extract all pages of a subframe
{
// extract bytes of complete page (odd+even) -- extract SIZE_PAGE from tv.navBits, starting from byte_index
std::vector<uint8_t> page_bytes = extract_page_bytes(tv, byte_index, SIZE_PAGE_BYTES);
if (page_bytes.empty())
{
std::cout << "OsnmaTestVectorsSimulation: end of TestVectors \n"
<< "byte_index=" << byte_index << " expected= " << 432000 / 8 << std::endl;
end_of_hex_stream = true;
break;
}
// convert them to bitset representation using bytes_to_string
std::string page_bits = bytes_to_str(page_bytes);
// Extract the 40 OSNMA bits starting from the 18th bit
std::string even_page = page_bits.substr(0, page_bits.size() / 2);
std::string odd_page = page_bits.substr(page_bits.size() / 2);
if (even_page.size() < 120 || odd_page.size() < 120)
{
std::cout << "OsnmaTestVectorsSimulation: error parsing pages" << std::endl;
}
bool even_odd_OK = even_page[0] == '0' && odd_page[0] == '1';
bool page_type_OK = even_page[1] == '0' && odd_page[1] == '0';
bool tail_bits_OK = even_page.substr(even_page.size() - 6) == "000000" && odd_page.substr(odd_page.size() - 6) == "000000";
if (!even_odd_OK || !page_type_OK || !tail_bits_OK)
std::cerr << "OsnmaTestVectorsSimulation: error parsing pages." << std::endl;
std::bitset<112> data_k(even_page.substr(2, 112));
std::bitset<16> data_j(odd_page.substr(2, 16));
std::bitset<112> shifted_data_k = data_k;
uint8_t word_type = static_cast<uint8_t>((shifted_data_k >>= 106).to_ulong()); // word type is the first 6 bits of the word
std::cout << "OsnmaTestVectorsSimulation: received Word " << static_cast<int>(word_type) << std::endl;
if ((word_type >= 1 && word_type <= 5) || word_type == 6 || word_type == 10)
{
// store raw word
std::bitset<128> data_combined(data_k.to_string() + data_j.to_string());
words_for_OSNMA[word_type] = data_combined;
}
if (word_type == DUMMY_PAGE)
flag_dummy_page = true;
// place it into osnma object.
std::bitset<40> osnmaBits(odd_page.substr(18, 40));
// Extract bits for hkroot and mack
std::bitset<8> hkrootBits(osnmaBits.to_string().substr(0, 8));
std::bitset<32> mackBits(osnmaBits.to_string().substr(8, 32));
hkroot[idx] = static_cast<uint8_t>(hkrootBits.to_ulong());
mack[idx] = static_cast<uint32_t>(mackBits.to_ulong());
byte_index += SIZE_PAGE_BYTES;
}
std::cout << "----------" << std::endl;
if (end_of_hex_stream)
break;
if (flag_dummy_page)
{
flag_dummy_page = false;
continue; // skip this SV
}
// Fill osnma object
osnmaMsg_sptr->hkroot = hkroot;
osnmaMsg_sptr->mack = mack;
osnmaMsg_sptr->TOW_sf0 = d_GST_SIS & 0x000FFFFF;
osnmaMsg_sptr->WN_sf0 = (d_GST_SIS & 0xFFF00000) >> 20;
osnmaMsg_sptr->PRN = tv.svId; // PRNa
// TODO - refactor this logic, currently it is split
// check if words_for_OSNMA 1--> 5 words_for_OSNMA are received => fill EphClockStatus data vector
bool ephClockStatusWordsReceived = true;
for (int i = 1; i <= 5; ++i)
{
if (words_for_OSNMA.find(i) == words_for_OSNMA.end())
{
ephClockStatusWordsReceived = false;
std::cerr << "OsnmaTestVectorsSimulation: error parsing words_for_OSNMA 1->5. "
"Word "
<< i << " should be received for each subframe but was not." << std::endl;
}
}
// extract bits as needed by osnma block
if (ephClockStatusWordsReceived)
{
// Define the starting position and length of bits to extract for each word
std::map<uint8_t, std::pair<uint8_t, uint8_t>> extractionParams = {
{1, {6, 120}},
{2, {6, 120}},
{3, {6, 122}},
{4, {6, 120}},
{5, {6, 67}},
};
// Fill NavData bits -- Iterate over the extraction parameters
std::string nav_data_ADKD_0_12 = "";
for (const auto& param : extractionParams)
{
uint8_t wordKey = param.first;
uint8_t start = param.second.first;
uint8_t length = param.second.second;
// Extract the required bits and fill osnma block
nav_data_ADKD_0_12 += words_for_OSNMA[wordKey].to_string().substr(start, length);
}
// send to osnma block
bool check_size_is_ok = nav_data_ADKD_0_12.size() == 549;
if (check_size_is_ok)
{
std::cout << "Galileo OSNMA: sending ADKD=0/12 navData, PRN_d (" << tv.svId << ") "
<< "TOW_sf=" << osnmaMsg_sptr->TOW_sf0 << std::endl;
const auto tmp_obj_osnma = std::make_shared<std::tuple<uint32_t, std::string, uint32_t>>( // < PRNd , navDataBits, TOW_Sosf>
tv.svId,
nav_data_ADKD_0_12,
osnmaMsg_sptr->TOW_sf0);
LOG(INFO) << "|---> Galileo OSNMA :: Telemetry Decoder NavData (PRN_d=" << static_cast<int>(tv.svId) << ", TOW=" << static_cast<int>(osnmaMsg_sptr->TOW_sf0) << "): 0b" << nav_data_ADKD_0_12;
osnma->msg_handler_osnma(pmt::make_any(tmp_obj_osnma));
}
}
// check w6 && w10 is received => fill TimingData data vector
bool timingWordsReceived = words_for_OSNMA.find(6) != words_for_OSNMA.end() &&
words_for_OSNMA.find(10) != words_for_OSNMA.end();
// extract bits as needed by osnma block
if (timingWordsReceived)
{
// Define the starting position and length of bits to extract for each word
std::map<uint8_t, std::pair<uint8_t, uint8_t>> extractionParams = {
{6, {6, 99}},
{10, {86, 42}}};
std::string nav_data_ADKD_4 = "";
// Fill NavData bits -- Iterate over the extraction parameters
for (const auto& param : extractionParams)
{
uint8_t wordKey = param.first;
uint8_t start = param.second.first;
uint8_t length = param.second.second;
// Extract the required bits and fill osnma block
nav_data_ADKD_4 += words_for_OSNMA[wordKey].to_string().substr(start, length);
}
// send to osnma block
bool check_size_is_ok = nav_data_ADKD_4.size() == 141;
if (check_size_is_ok)
{
std::cout << "Galileo OSNMA: sending ADKD=04 navData, PRN_d (" << tv.svId << ") "
<< "TOW_sf=" << osnmaMsg_sptr->TOW_sf0 << std::endl;
const auto tmp_obj_osnma = std::make_shared<std::tuple<uint32_t, std::string, uint32_t>>( // < PRNd , navDataBits, TOW_Sosf>
tv.svId,
nav_data_ADKD_4,
osnmaMsg_sptr->TOW_sf0);
LOG(INFO) << "|---> Galileo OSNMA :: Telemetry Decoder NavData (PRN_d=" << static_cast<int>(tv.svId) << ", TOW=" << static_cast<int>(osnmaMsg_sptr->TOW_sf0) << "): 0b" << nav_data_ADKD_4;
osnma->msg_handler_osnma(pmt::make_any(tmp_obj_osnma));
}
}
// Call the handler, as if it came from telemetry decoder block
auto temp_obj = pmt::make_any(osnmaMsg_sptr);
osnma->msg_handler_osnma(temp_obj); // osnma entry point
}
if (!end_of_hex_stream)
{
offset_byte = byte_index; // update offset for the next subframe
d_GST_SIS += DURATION_SUBFRAME;
TOW = d_GST_SIS & 0x000FFFFF;
WN = (d_GST_SIS & 0xFFF00000) >> 20;
std::cout << "OsnmaTestVectorsSimulation:"
<< " d_GST_SIS= " << d_GST_SIS
<< ", TOW=" << TOW
<< ", WN=" << WN << std::endl;
}
}
// Assert
ASSERT_EQ(osnma->d_count_failed_tags, 0);
ASSERT_EQ(osnma->d_count_failed_Kroot, 0);
ASSERT_EQ(osnma->d_count_failed_pubKey, 0);
ASSERT_EQ(osnma->d_count_failed_macseq, 0);
}
// TODO - create global vars with failed tags and compare to total tags (Tag Id for example)
TEST_F(OsnmaTestVectors, NominalTestConf2)
{
// Arrange
std::string crtFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/PublicKey/OSNMA_PublicKey_20230720113300_newPKID_2.crt"; // conf. 2
std::string merkleFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/MerkleTree/OSNMA_MerkleTree_20230720113300_newPKID_2.xml";
osnma_msg_receiver_sptr osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath);
std::tm input_time = {0, 0, 0, 27, 7 - 1, 2023 - 1900, 0, 0, 0, 0, 0}; // conf. 2
std::vector<std::tm> input_times = {input_time};
std::vector<TestVector> testVector = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/configuration_2/27_JUL_2023_GST_00_00_01.csv");
if (testVector.empty())
{
ASSERT_TRUE(false);
}
std::vector<std::vector<TestVector>> testVectors = {testVector};
// Act
bool result = feedOsnmaWithTestVectors(osnma, testVectors, input_times);
ASSERT_TRUE(result);
// Assert
ASSERT_EQ(osnma->d_count_failed_tags, 0);
ASSERT_EQ(osnma->d_count_failed_Kroot, 0);
ASSERT_EQ(osnma->d_count_failed_pubKey, 0);
ASSERT_EQ(osnma->d_count_failed_macseq, 0);
}
TEST_F(OsnmaTestVectors, PublicKeyRenewal)
{
// Arrange
std::string crtFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/PublicKey/OSNMA_PublicKey_20231007041500_PKID_7.crt";
std::string merkleFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/MerkleTree/OSNMA_MerkleTree_20231007041500_PKID_7.xml";
osnma_msg_receiver_sptr osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath);
std::tm input_time_step1 = {0, 45, 2, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0};
std::tm input_time_step2 = {0, 45, 3, 7, 10 - 1, 2023 - 1900, 0, 0, 0, 0, 0};
std::tm input_time_step3 = {0, 45, 4, 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::string crtFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/PublicKey/OSNMA_PublicKey_20231007041500_PKID_7.crt";
std::string merkleFilePath = std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/MerkleTree/OSNMA_MerkleTree_20231007041500_PKID_7.xml";
osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath);
std::vector<TestVector> testVectors_step1 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/npk_step1/07_OCT_2023_GST_02_45_01.csv");
std::vector<TestVector> testVectors_step2 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/npk_step2/07_OCT_2023_GST_03_45_01.csv");
std::vector<TestVector> testVectors_step3 = readTestVectorsFromFile(std::string(BASE_OSNMA_TEST_VECTORS) + "osnma_test_vectors/npk_step3/07_OCT_2023_GST_04_45_01.csv");
std::vector<std::vector<TestVector>> testVectors = {testVectors_step1, testVectors_step2, testVectors_step3};
if (testVectors_step1.empty() || testVectors_step2.empty() || testVectors_step3.empty())
{
ASSERT_TRUE(false);
}
std::vector<std::vector<TestVector>> testVectors = {testVectors_step1, testVectors_step2, testVectors_step3};
d_flag_NPK = true;
bool result = feedOsnmaWithTestVectors(osnma, testVectors, input_times);
ASSERT_TRUE(result);
// Assert
ASSERT_EQ(osnma->d_count_failed_tags, 0);
ASSERT_EQ(osnma->d_count_failed_Kroot, 0);
ASSERT_EQ(osnma->d_count_failed_pubKey, 0);
ASSERT_EQ(osnma->d_count_failed_macseq, 0);
}
// 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 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
const int SIZE_PAGE_BYTES{240 / 8}; // total bytes of a page
const int SIZE_SUBFRAME_PAGES{15}; // number of pages of a subframe
const int DURATION_SUBFRAME{30}; // duration of a subframe, in seconds
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.
for (int test_step = 0; test_step < 3 ; test_step++)
// 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++)
{
// set variables for each file
end_of_hex_stream = false;
offset_byte = 0;
byte_index = 0;
set_time(input_times[test_step]);
set_time(startTimesFiles[test_step]);
std::cout << "OsnmaTestVectorsSimulation:"
<< " d_GST_SIS= " << d_GST_SIS
<< ", TOW=" << TOW
<< ", WN=" << WN << std::endl;
if (test_step == 1 ){
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->d_crypto->read_merkle_xml(
osnma_object->d_crypto->read_merkle_xml(
std::string(BASE_OSNMA_TEST_VECTORS) + "cryptographic_material/Merkle_tree_2/MerkleTree/OSNMA_MerkleTree_20231007081500_PKID_8.xml");
}
@ -468,7 +308,7 @@ TEST_F(OsnmaTestVectors, PublicKeyRenewal)
nav_data_ADKD_0_12,
osnmaMsg_sptr->TOW_sf0);
LOG(INFO) << "|---> Galileo OSNMA :: Telemetry Decoder NavData (PRN_d=" << static_cast<int>(tv.svId) << ", TOW=" << static_cast<int>(osnmaMsg_sptr->TOW_sf0) << "): 0b" << nav_data_ADKD_0_12;
osnma->msg_handler_osnma(pmt::make_any(tmp_obj_osnma));
osnma_object->msg_handler_osnma(pmt::make_any(tmp_obj_osnma));
}
}
@ -505,16 +345,15 @@ TEST_F(OsnmaTestVectors, PublicKeyRenewal)
nav_data_ADKD_4,
osnmaMsg_sptr->TOW_sf0);
LOG(INFO) << "|---> Galileo OSNMA :: Telemetry Decoder NavData (PRN_d=" << static_cast<int>(tv.svId) << ", TOW=" << static_cast<int>(osnmaMsg_sptr->TOW_sf0) << "): 0b" << nav_data_ADKD_4;
osnma->msg_handler_osnma(pmt::make_any(tmp_obj_osnma));
osnma_object->msg_handler_osnma(pmt::make_any(tmp_obj_osnma));
}
}
// Call the handler, as if it came from telemetry decoder block
auto temp_obj = pmt::make_any(osnmaMsg_sptr);
osnma->msg_handler_osnma(temp_obj); // osnma entry point
osnma_object->msg_handler_osnma(temp_obj); // osnma entry point
}
if (!end_of_hex_stream)
{
offset_byte = byte_index; // update offset for the next subframe
@ -527,16 +366,12 @@ TEST_F(OsnmaTestVectors, PublicKeyRenewal)
<< ", WN=" << WN << std::endl;
}
}
if (end_of_hex_stream)
break;
}
// Assert
// TODO - create global vars with failed tags and compare to total tags (Tag Id for example)
// Assert
return true;
}
// 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.
std::vector<TestVector> OsnmaTestVectors::readTestVectorsFromFile(const std::string& filename)
{
std::ifstream file(filename);