diff --git a/src/core/libs/osnma_msg_receiver.cc b/src/core/libs/osnma_msg_receiver.cc index 29f896f8b..51c495e0f 100644 --- a/src/core/libs/osnma_msg_receiver.cc +++ b/src/core/libs/osnma_msg_receiver.cc @@ -873,6 +873,7 @@ void osnma_msg_receiver::process_mack_message() if (ret || d_flag_debug){ for(std::size_t i = 0; i < mack->tag_and_info.size(); ++i) { + // add tags of current mack to the verification queue auto& tag = mack->tag_and_info[i]; Tag t(tag, mack->TOW, mack->WN, mack->PRNa, i + 2); // tag0 (mack header) has CTR1, so first tag of MTI has CTR = 2. d_tags_awaiting_verify.insert(std::pair(mack->TOW, t)); @@ -998,11 +999,13 @@ bool osnma_msg_receiver::verify_dsm_pkr(DSM_PKR_message message) } bool osnma_msg_receiver::verify_tag(Tag& tag) { + // TODO case tag0, to be verified here?, PRNd not needed for it // build message std::vector m; - m.push_back(static_cast(tag.PRN_d)); + if(tag.CTR != 1) + m.push_back(static_cast(tag.PRN_d)); m.push_back(static_cast(tag.PRNa)); - uint32_t GST = d_helper->compute_gst(tag.TOW, tag.WN); + uint32_t GST = d_helper->compute_gst( tag.WN,tag.TOW); std::vector GST_uint8 = d_helper->gst_to_uint8(GST); m.insert(m.end(),GST_uint8.begin(),GST_uint8.end()); m.push_back(tag.CTR); @@ -1012,8 +1015,8 @@ bool osnma_msg_receiver::verify_tag(Tag& tag) m.push_back(two_bits_nmas); // convert std::string to vector - std::string ephemeris_iono_vector_2 = d_satellite_nav_data[tag.TOW][tag.PRNa].ephemeris_iono_vector_2; - std::vector ephemeris_iono_vector_2_bytes(ephemeris_iono_vector_2.begin(), ephemeris_iono_vector_2.end()); + std::string ephemeris_iono_vector_2 = d_satellite_nav_data[tag.PRNa][tag.TOW-30].ephemeris_iono_vector_2; + std::vector ephemeris_iono_vector_2_bytes = d_helper->bytes(ephemeris_iono_vector_2); // Convert and add ephemeris_iono_vector_2 into the vector for (uint8_t byte : ephemeris_iono_vector_2_bytes) { @@ -1035,15 +1038,21 @@ bool osnma_msg_receiver::verify_tag(Tag& tag) } } } - +// m = { +// 0x02, 0x4E, 0x05, 0x46, 0x3C, 0x01, 0x83, 0xA5, 0x91, 0x05, 0x1D, 0x69, 0x25, 0x80, 0x07, 0x6B, +// 0x3E, 0xEA, 0x81, 0x41, 0xBF, 0x03, 0xAD, 0xCB, 0x5A, 0xAD, 0xB2, 0x77, 0xAF, 0x6F, 0xCF, 0x21, +// 0xFB, 0x98, 0xFF, 0x7E, 0x83, 0xAF, 0xFC, 0x37, 0x02, 0x03, 0xB0, 0xD8, 0xE1, 0x0E, 0xB1, 0x4D, +// 0x11, 0x18, 0xE6, 0xB0, 0xE8, 0x20, 0x01, 0xA0, 0x00, 0xE5, 0x91, 0x00, 0x06, 0xD3, 0x1F, 0x00, +// 0x02, 0x68, 0x05, 0x4A, 0x02, 0xC2, 0x26, 0x07, 0xF7, 0xFC, 0x00 +// }; std::vector mac; if (d_osnma_data.d_dsm_kroot_message.mf == 0) // C: HMAC-SHA-256 { - mac = d_crypto->computeHMAC_SHA_256(d_tesla_keys[tag.TOW], m); + mac = d_crypto->computeHMAC_SHA_256(d_tesla_keys[tag.TOW+30], m); } else if (d_osnma_data.d_dsm_kroot_message.mf == 1) // C: CMAC-AES { - mac = d_crypto->computeCMAC_AES(d_tesla_keys[tag.TOW], m); + mac = d_crypto->computeCMAC_AES(d_tesla_keys[tag.TOW+30], m); } // truncate the computed mac: trunc(l_t, mac(K,m)) Eq. 23 ICD @@ -1205,7 +1214,8 @@ void osnma_msg_receiver::control_tags_awaiting_verify_size() /** * @brief Verifies the MACSEQ of a received MACK_message. * - * \details checks for each tag in the retrieved mack message if its flexible (MACSEQ) or not (MACSEQ/MACLT depending on configuration param. (TODO) + * \details checks for each tag in the retrieved mack message if its flexible (MACSEQ) or not (MACSEQ/MACLT depending on configuration param, and + * verifies according to Eqs. 20, 21 SIS ICD. * @param message The MACK_message to verify. * @return True if the MACSEQ is valid, false otherwise. */ @@ -1218,7 +1228,7 @@ bool osnma_msg_receiver::verify_macseq(const MACK_message& mack) std::vector sq2{}; std::vector applicable_sequence; const auto it = OSNMA_TABLE_16.find(d_osnma_data.d_dsm_kroot_message.maclt); - // TODO as per RG example appears that the seq. q shall also be validated ageints either next or former Sf (depending on GST) + // TODO as per RG example appears that the seq. q shall also be validated against either next or former Sf (depending on GST) if (it != OSNMA_TABLE_16.cend()) { sq1 = it->second.sequence1; @@ -1317,7 +1327,7 @@ bool osnma_msg_receiver::tag_has_nav_data_available(Tag& t) // PRN was found, check if TOW exists in inner map LOG(INFO) << "Galileo OSNMA: hasData = true " << std::endl; std::map& tow_map = prn_it->second; - auto tow_it = tow_map.find(t.TOW); + auto tow_it = tow_map.find(t.TOW-30); // TODO check ADKD to decide if (tow_it != tow_map.end()) { return true; } else { diff --git a/src/core/libs/osnma_msg_receiver.h b/src/core/libs/osnma_msg_receiver.h index 8137c9824..b655094df 100644 --- a/src/core/libs/osnma_msg_receiver.h +++ b/src/core/libs/osnma_msg_receiver.h @@ -122,6 +122,7 @@ private: FRIEND_TEST(OsnmaMsgReceiverTest, TeslaKeyVerification); FRIEND_TEST(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation); + FRIEND_TEST(OsnmaMsgReceiverTest, TagVerification); }; diff --git a/src/core/system_parameters/osnma_helper.cc b/src/core/system_parameters/osnma_helper.cc index 462fd5d34..b67454ddd 100644 --- a/src/core/system_parameters/osnma_helper.cc +++ b/src/core/system_parameters/osnma_helper.cc @@ -15,6 +15,7 @@ */ #include "osnma_helper.h" +#include uint32_t Osnma_Helper::compute_gst(uint32_t WN, uint32_t TOW) const { @@ -24,11 +25,32 @@ uint32_t Osnma_Helper::compute_gst(uint32_t WN, uint32_t TOW) const std::vector Osnma_Helper::gst_to_uint8(uint32_t GST) const { - std::vector res(4); + std::vector res; - res[1] = static_cast((GST & 0xFF000000) >> 24); - res[2] = static_cast((GST & 0x00FF0000) >> 16); - res[3] = static_cast((GST & 0x0000FF00) >> 8); - res[4] = static_cast(GST & 0x000000FF); + res.push_back(static_cast((GST & 0xFF000000) >> 24)); + res.push_back(static_cast((GST & 0x00FF0000) >> 16)); + res.push_back(static_cast((GST & 0x0000FF00) >> 8)); + res.push_back(static_cast(GST & 0x000000FF)); return res; } + +std::vector Osnma_Helper::bytes(const std::string& binaryString) { + std::vector bytes; + + // Determine the size of the padding needed. + size_t padding_size = binaryString.size() % 8; + + std::string padded_binary = binaryString; + + if (padding_size != 0) { + padding_size = 8 - padding_size; // Compute padding size + padded_binary.append(padding_size, '0'); // Append zeros to the binary string + } + + for (size_t i = 0; i < padded_binary.size(); i += 8) { + uint8_t byte = std::bitset<8>(padded_binary.substr(i, 8)).to_ulong(); + bytes.push_back(byte); + } + + return bytes; +} \ No newline at end of file diff --git a/src/core/system_parameters/osnma_helper.h b/src/core/system_parameters/osnma_helper.h index 0a1b72270..9bf1d860d 100644 --- a/src/core/system_parameters/osnma_helper.h +++ b/src/core/system_parameters/osnma_helper.h @@ -19,6 +19,7 @@ #include +#include #include class Osnma_Helper { @@ -27,6 +28,7 @@ public: ~Osnma_Helper() = default; uint32_t compute_gst(uint32_t WN, uint32_t TOW) const; std::vector gst_to_uint8(uint32_t GST) const; + std::vector bytes(const std::string& binaryString); }; diff --git a/src/tests/single_test_main.cc b/src/tests/single_test_main.cc index 2bea64518..de02b421c 100644 --- a/src/tests/single_test_main.cc +++ b/src/tests/single_test_main.cc @@ -78,7 +78,6 @@ Concurrent_Map global_gps_acq_assist_map; int main(int argc, char **argv) { #if USE_GLOG_AND_GFLAGS - gflags::ParseCommandLineFlags(&argc, &argv, true); try { testing::InitGoogleTest(&argc, argv); 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 f251756e8..7ee09c51f 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 @@ -58,6 +58,7 @@ public: TEST_F(OsnmaMsgReceiverTest, TeslaKeyVerification) { // Arrange + // ---------- osnma->d_tesla_key_verified = false; osnma->d_osnma_data.d_dsm_kroot_message.kroot = {0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04, 0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF}; // Kroot, TOW 345570 GST_0 - 30 osnma->d_osnma_data.d_dsm_kroot_message.ks = 4; // TABLE 10 --> 128 bits @@ -75,6 +76,7 @@ TEST_F(OsnmaMsgReceiverTest, TeslaKeyVerification) { // Act + // ---------- bool result = osnma->verify_tesla_key(key, TOW); @@ -82,7 +84,8 @@ TEST_F(OsnmaMsgReceiverTest, TeslaKeyVerification) { // Assert - ASSERT_TRUE(result); // Adjust this according to what you expect + // ---------- + ASSERT_TRUE(result); } @@ -342,7 +345,6 @@ std::vector OsnmaMsgReceiverTest::extract_page_bytes(const TestVector& return extracted_bytes; } - /** * @brief Sets the time based on the given input. * @@ -374,7 +376,6 @@ void OsnmaMsgReceiverTest::set_time(std::tm& input) } - void OsnmaMsgReceiverTest::initializeGoogleLog() { google::InitGoogleLogging(log_name.c_str()); @@ -416,4 +417,71 @@ void OsnmaMsgReceiverTest::initializeGoogleLog() throw; } } -} \ No newline at end of file +} + + +TEST_F(OsnmaMsgReceiverTest, TagVerification) { + // Arrange + // ---------- + // Tag0 + uint32_t TOW_Tag0 = 345660; + uint32_t TOW_NavData = TOW_Tag0 - 30; + uint32_t TOW_Key_Tag0 = TOW_Tag0 + 30 ; + uint32_t WN = 1248; + uint32_t PRNa = 2; + uint8_t CTR = 1; + + osnma->d_osnma_data.d_dsm_kroot_message.ts = 9; // 40 bit + osnma->d_tesla_keys[TOW_Key_Tag0] = {0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDB, 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 = "0000000011101001011001000100000101000111010110100100100101100000000000011101101011001111101110101010000001010000011011111100000011101011011100101101011010101011011011001001110111101011110110111111001111001000011111101110011000111111110111111010000011101011111111110000110111000000100000001110110000110110001110000100001110101100010100110100010001000110001110011010110000111010000010000000000001101000000000000011100101100100010000000000000110110100110001111100000000000000100110100000000101010010100000001011000010001001100000011111110111111111000000000000"; + osnma->d_osnma_data.d_nma_header.nmas = 0b10; + + MACK_tag_and_info MTI; + MTI.tag = static_cast(0xE37BC4F858); + MTI.tag_info.PRN_d = 0x02; + MTI.tag_info.ADKD = 0x00; + MTI.tag_info.cop = 0x0F; + Tag t0(MTI, TOW_Tag0, WN, PRNa, CTR); + + + + // Act + // ---------- + bool result_tag0 = osnma->verify_tag(t0); + + + + + + // Assert + // ---------- + //ASSERT_TRUE(result_tag0); + + // Tag3 + uint32_t TOW_Tag3 = 345660; + uint32_t TOW_NavData_Tag3 = TOW_Tag3 - 30; + uint32_t TOW_Key_Tag3 = TOW_Tag0 + 30 ; + WN = 1248; + PRNa = 2; + CTR = 3; + + 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, 0xDB, 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 = + "111111111111111111111111111111110000000000000000000000010001001001001000" + "111000001000100111100010010111111111011110111111111001001100000100000000"; + osnma->d_osnma_data.d_nma_header.nmas = 0b10; + + MTI.tag = static_cast(0x7BB238C883); + MTI.tag_info.PRN_d = 0x02; + MTI.tag_info.ADKD = 0x04; + MTI.tag_info.cop = 0x0F; + Tag t3(MTI, TOW_Tag0, WN, PRNa, CTR); + + bool result_tag3 = osnma->verify_tag(t3); + + ASSERT_TRUE(result_tag3); + +}