diff --git a/src/core/libs/osnma_msg_receiver.cc b/src/core/libs/osnma_msg_receiver.cc index dfc067796..6e0b161c4 100644 --- a/src/core/libs/osnma_msg_receiver.cc +++ b/src/core/libs/osnma_msg_receiver.cc @@ -1082,12 +1082,24 @@ std::vector osnma_msg_receiver::build_message(const Tag& tag) two_bits_nmas = two_bits_nmas << 6; m.push_back(two_bits_nmas); + // Add applicable NavData bits to message + std::string applicable_nav_data; + std::vector applicable_nav_data_bytes; + if (tag.ADKD == 0 || tag.ADKD == 12) + { + applicable_nav_data = d_satellite_nav_data[tag.PRN_d][tag.TOW - 30].ephemeris_iono_vector_2; + } + else if (tag.ADKD == 4) + { + applicable_nav_data = d_satellite_nav_data[tag.PRN_d][tag.TOW - 30].utc_vector_2; + } + else + std::cerr<<"Galileo OSNMA :: Tag verification :: unknown ADKD" <<"\n"; // convert std::string to vector - std::string ephemeris_iono_vector_2 = d_satellite_nav_data[tag.PRN_d][tag.TOW - 30].ephemeris_iono_vector_2; - std::vector ephemeris_iono_vector_2_bytes = d_helper->bytes(ephemeris_iono_vector_2); + applicable_nav_data_bytes = d_helper->bytes(applicable_nav_data); - // Convert and add ephemeris_iono_vector_2 into the vector - for (uint8_t byte : ephemeris_iono_vector_2_bytes) { + // Convert and add NavData bytes into the message, taking care of that NMAS has only 2 bits + for (uint8_t byte : applicable_nav_data_bytes) { m.back() |= (byte >> 2); // First take the 6 MSB bits of byte and add to m m.push_back(byte << 6); // Then take the last 2 bits of byte, shift them to MSB position and insert the new element into m } diff --git a/src/core/system_parameters/galileo_inav_message.h b/src/core/system_parameters/galileo_inav_message.h index 0e9c15b25..bc5d5f780 100644 --- a/src/core/system_parameters/galileo_inav_message.h +++ b/src/core/system_parameters/galileo_inav_message.h @@ -54,6 +54,7 @@ public: std::vector EphemerisClockAndStatusData {}; // TODO _2 rename and substitute this std::string EphemerisClockAndStatusData_2{}; std::vector TimingData {}; + std::string TimingData_2{}; Galileo_Ephemeris EphemerisData {}; Galileo_Iono IonoData {}; Galileo_Utc_Model UtcModelData {}; diff --git a/src/core/system_parameters/osnma_data.cc b/src/core/system_parameters/osnma_data.cc index 25124bb81..4424c55ba 100644 --- a/src/core/system_parameters/osnma_data.cc +++ b/src/core/system_parameters/osnma_data.cc @@ -38,6 +38,7 @@ void NavData::init(const std::shared_ptr &osnma_msg) // new parsing, directly parsing bits ephemeris_iono_vector_2 = osnma_msg->EphemerisClockAndStatusData_2; + utc_vector_2 = osnma_msg->TimingData_2; }; void NavData::generate_eph_iono_vector() { diff --git a/src/core/system_parameters/osnma_data.h b/src/core/system_parameters/osnma_data.h index 6e3439a4c..cf9bcb7d9 100644 --- a/src/core/system_parameters/osnma_data.h +++ b/src/core/system_parameters/osnma_data.h @@ -134,6 +134,7 @@ public: std::vector ephemeris_iono_vector{}; std::string ephemeris_iono_vector_2{}; std::vector utc_vector{}; + std::string utc_vector_2{}; uint32_t PRNa{}; uint32_t WN_sf0{}; uint32_t TOW_sf0{}; diff --git a/src/tests/unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc b/src/tests/unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc index 2c6eca790..1c4b1c7b9 100644 --- a/src/tests/unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/osnma/osnma_msg_receiver_test.cc @@ -90,6 +90,7 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) { initializeGoogleLog(); // Arrange + // ---------- std::vector testVectors = readTestVectorsFromFile("/home/cgm/CLionProjects/osnma/data/16_AUG_2023_GST_05_00_01.csv"); if (testVectors.empty()){ ASSERT_TRUE(false); @@ -98,10 +99,10 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) 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}; - const int SIZE_SUBFRAME_PAGES{15}; - const int SIZE_SUBFRAME_BYTES{SIZE_PAGE_BYTES*SIZE_SUBFRAME_PAGES}; - const int DURATION_SUBFRAME{30}; + 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 SIZE_SUBFRAME_BYTES{SIZE_PAGE_BYTES*SIZE_SUBFRAME_PAGES}; // total bytes of a subframe + const int DURATION_SUBFRAME{30}; // duration of a subframe, in seconds const int DUMMY_PAGE{63}; bool flag_dummy_page{false}; @@ -110,7 +111,11 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) << ", WN=" << WN << std::endl; + + + // Act + // ---------- while (end_of_hex_stream == false){ // loop over all bytes of data. Note all TestVectors have same amount of data. for(const TestVector& tv : testVectors) { // loop over all SVs, extract a subframe std::cout << "OsnmaTestVectorsSimulation: SVID (PRN_a) "<< tv.svId << std::endl; @@ -118,7 +123,7 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) std::array hkroot{}; std::array 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> words; + std::map> words; // structure containing and for (int idx = 0; idx < SIZE_SUBFRAME_PAGES; ++idx) // extract all pages of a subframe { @@ -179,6 +184,7 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) byte_index += SIZE_PAGE_BYTES; } + std::cout<< "----------" << std::endl; if(end_of_hex_stream) break; @@ -193,17 +199,21 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) osnmaMsg_sptr->WN_sf0 = (d_GST_SIS & 0xFFF00000) >> 20 ; osnmaMsg_sptr->PRN = tv.svId; // PRNa - bool allWordsReceived = true; + // TODO - refactor this logic, currently it is split + + // check if words 1--> 5 words are received + bool ephClockStatusWordsReceived = true; for (int i = 1; i <= 5; ++i) { - if (words.find(i) == words.end() && flag_dummy_page == false) + if (words.find(i) == words.end()) { - allWordsReceived = false; + ephClockStatusWordsReceived = false; std::cerr<< "OsnmaTestVectorsSimulation: error parsing words 1->5. " "Word "<< i << " should be received for each subframe but was not." << std::endl; } } - if(allWordsReceived) + // extract bits as needed by osnma block + if(ephClockStatusWordsReceived) { // Define the starting position and length of bits to extract for each word @@ -222,32 +232,38 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) uint8_t start = param.second.first; uint8_t length = param.second.second; - // Extract the required bits + // Extract the required bits and fill osnma block osnmaMsg_sptr->EphemerisClockAndStatusData_2 += words[wordKey]. to_string().substr( start, length); - -// std::bitset<8> byte; -// int byteIndex = 0; -// for (uint8_t i = start; i < start + length; ++i) { -// byte[byteIndex] = word[i]; -// byteIndex++; -// -// // Once we have collected 8 bits, we can add them as an uint8_t to the vector -// if (byteIndex == 8) { -// osnmaMsg_sptr->EphemerisClockAndStatusData.push_back(static_cast(byte.to_ulong())); -// byte.reset(); -// byteIndex = 0; -// } -// } -// -// // Push remaining bits if it didn't reach 8 bits -// if (byteIndex > 0) { -// osnmaMsg_sptr->EphemerisClockAndStatusData.push_back(static_cast(byte.to_ulong())); -// } } } + // check w6 && w10 is received + bool timingWordsReceived = words.find(6) != words.end() && + words.find(10) != words.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> extractionParams = { + {6, {6, 99}}, + {10, {86, 42}} + }; + + // 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 + osnmaMsg_sptr->TimingData_2 += words[wordKey].to_string().substr( + start, length); + } + + } auto temp_obj = pmt::make_any(osnmaMsg_sptr); osnma->msg_handler_osnma(temp_obj); // osnma entry point @@ -266,8 +282,12 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) } + + // Assert - // TODO + // ---------- + + // TODO - create global vars with failed tags and compare to total tags (Tag Id for example) } std::vector OsnmaMsgReceiverTest::readTestVectorsFromFile(const std::string& filename) @@ -527,7 +547,7 @@ TEST_F(OsnmaMsgReceiverTest, TagVerification) { osnma->d_osnma_data.d_dsm_kroot_message.ts = 9; // 40 bit osnma->d_tesla_keys[TOW_Key_Tag3] = {0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73}; // K4 osnma->d_osnma_data.d_dsm_kroot_message.mf = 0; - osnma->d_satellite_nav_data[PRNa][TOW_NavData].ephemeris_iono_vector_2 = + osnma->d_satellite_nav_data[PRNa][TOW_NavData].utc_vector_2 = "111111111111111111111111111111110000000000000000000000010001001001001000" "111000001000100111100010010111111111011110111111111001001100000100000000"; osnma->d_osnma_data.d_nma_header.nmas = 0b10;