From 39f94dcbe69559fb235d161b90467ee292a864e5 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 23 Jul 2024 11:16:45 +0200 Subject: [PATCH 1/6] Code cleaning --- .../galileo_telemetry_decoder_gs.cc | 28 +- .../galileo_telemetry_decoder_gs.h | 3 - src/core/libs/osnma_msg_receiver.cc | 111 +++-- src/core/libs/osnma_msg_receiver.h | 4 +- .../system_parameters/galileo_inav_message.cc | 30 +- .../system_parameters/galileo_inav_message.h | 14 +- src/core/system_parameters/osnma_data.cc | 207 +++------- src/core/system_parameters/osnma_data.h | 62 ++- src/core/system_parameters/osnma_helper.h | 4 +- .../osnma/osnma_msg_receiver_test.cc | 379 +++++++++--------- 10 files changed, 360 insertions(+), 482 deletions(-) diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc index a84db6946..4fe185501 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc @@ -369,6 +369,8 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in // 1. De-interleave std::vector page_part_symbols_soft_value(frame_length); deinterleaver(GALILEO_INAV_INTERLEAVER_ROWS, GALILEO_INAV_INTERLEAVER_COLS, page_part_symbols, page_part_symbols_soft_value.data()); + bool flag_osnma_adkd_4_gst = false; + bool flag_osnma_adkd_4_utc = false; // 2. Viterbi decoder // 2.1 Take into account the NOT gate in G2 polynomial (Galileo ICD Figure 13, FEC encoder) @@ -441,33 +443,31 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in // 4. Push the new navigation data to the queues // extract OSNMA bits, reset container. bool check_size_is_ok = d_inav_nav.get_osnma_adkd_0_12_nav_bits().size() == 549; - if(check_size_is_ok) + if (check_size_is_ok) { - std::cout << "Galileo OSNMA: new ADKD=0/12 navData from " << d_satellite << " at TOW_sf=" << d_inav_nav.get_TOW5() - 25 <>( // < PRNd , navDataBits, TOW_Sosf> + DLOG(INFO) << "Galileo OSNMA: new ADKD=0/12 navData from " << d_satellite << " at TOW_sf=" << d_inav_nav.get_TOW5() - 25; + const auto tmp_obj_osnma = std::make_shared>( // < PRNd , navDataBits, TOW_Sosf> d_satellite.get_PRN(), d_inav_nav.get_osnma_adkd_0_12_nav_bits(), d_inav_nav.get_TOW5() - 25); this->message_port_pub(pmt::mp("OSNMA_from_TLM"), pmt::make_any(tmp_obj_osnma)); - LOG(INFO) << "|---> Galileo OSNMA :: Sending Telemetry Decoder NavData (PRN_d="<< static_cast(d_satellite.get_PRN()) << ", TOW=" << static_cast(d_inav_nav.get_TOW5() - 25) <<")";//: 0b" << d_inav_nav.get_osnma_adkd_0_12_nav_bits(); + DLOG(INFO) << "|---> Galileo OSNMA :: Sending Telemetry Decoder NavData (PRN_d=" << static_cast(d_satellite.get_PRN()) << ", TOW=" << static_cast(d_inav_nav.get_TOW5() - 25) << ")"; //: 0b" << d_inav_nav.get_osnma_adkd_0_12_nav_bits(); d_inav_nav.reset_osnma_nav_bits_adkd0_12(); } check_size_is_ok = d_inav_nav.get_osnma_adkd_4_nav_bits().size() == 141; - if(check_size_is_ok) + if (check_size_is_ok) { - std::cout << "Galileo OSNMA: new ADKD=4 navData from " << d_satellite <<" at TOW_sf=" << d_inav_nav.get_TOW6() - 5 <>( // < PRNd , navDataBits, TOW_Sosf> // TODO conversion from W6 to W_Start_of_subframe + DLOG(INFO) << "Galileo OSNMA: new ADKD=4 navData from " << d_satellite << " at TOW_sf=" << d_inav_nav.get_TOW6() - 5; + const auto tmp_obj = std::make_shared>( // < PRNd , navDataBits, TOW_Sosf> // TODO conversion from W6 to W_Start_of_subframe d_satellite.get_PRN(), d_inav_nav.get_osnma_adkd_4_nav_bits(), d_inav_nav.get_TOW6() - 5); this->message_port_pub(pmt::mp("OSNMA_from_TLM"), pmt::make_any(tmp_obj)); - LOG(INFO) << "|---> Galileo OSNMA :: Sending Telemetry Decoder NavData (PRN_d="<< static_cast(d_satellite.get_PRN()) << ", TOW=" << static_cast(d_inav_nav.get_TOW6() - 5) <<")";//: 0b" << d_inav_nav.get_osnma_adkd_4_nav_bits(); + DLOG(INFO) << "|---> Galileo OSNMA :: Sending Telemetry Decoder NavData (PRN_d=" << static_cast(d_satellite.get_PRN()) << ", TOW=" << static_cast(d_inav_nav.get_TOW6() - 5) << ")"; //: 0b" << d_inav_nav.get_osnma_adkd_4_nav_bits(); d_inav_nav.reset_osnma_nav_bits_adkd4(); } - if (d_inav_nav.have_new_ephemeris() == true) // C: tells if W1-->W4 available from same blcok (and W5!) { // get object for this SV (mandatory) @@ -499,8 +499,6 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in } this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); d_first_eph_sent = true; // do not send reduced CED anymore, since we have the full ephemeris set - -// d_flag_osnma_adkd_0_12 = true; // W1-> W5 available } else { @@ -586,7 +584,7 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in d_delta_t = tmp_obj->A_0G + tmp_obj->A_1G * (static_cast(d_TOW_at_current_symbol_ms) / 1000.0 - tmp_obj->t_0G + 604800 * (std::fmod(static_cast(d_inav_nav.get_Galileo_week() - tmp_obj->WN_0G), 64.0))); DLOG(INFO) << "delta_t=" << d_delta_t << "[s]"; - d_flag_osnma_adkd_4_utc = true; + flag_osnma_adkd_4_utc = true; } if (d_inav_nav.have_new_almanac() == true) // flag_almanac_4 tells if W10 available. @@ -621,11 +619,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in DLOG(INFO) << "d_TOW_at_current_symbol_ms=" << d_TOW_at_current_symbol_ms; DLOG(INFO) << "d_nav.WN_0=" << d_inav_nav.get_Galileo_week(); - d_flag_osnma_adkd_4_gst = true; + flag_osnma_adkd_4_gst = true; } // get osnma message if the needed nav data is available - bool adkd_4_nav_data_available = d_flag_osnma_adkd_4_utc && d_flag_osnma_adkd_4_gst; // supposition: data did not change bt. flags reset and now. + bool adkd_4_nav_data_available = flag_osnma_adkd_4_utc && flag_osnma_adkd_4_gst; // supposition: data did not change bt. flags reset and now. // bool adkd_4_nav_data_available = d_inav_nav.get_osnma_adkd_4_nav_bits().size() == 141; // newApproach: let decoder decide when block starts and let it fill the data, and just check for length if(adkd_4_nav_data_available /*&& d_inav_nav.is_TOW5_set() not needed cause W6 has TOW also.*/) diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h index 4b1725e8a..a6391a2e0 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h @@ -155,9 +155,6 @@ private: bool d_there_are_e1_channels; bool d_there_are_e6_channels; bool d_use_ced; - bool d_flag_osnma_adkd_0_12; // flag to indicate if the ephemeris is complete for OSNMA processing - bool d_flag_osnma_adkd_4_gst; // flag to indicate if the GST conversion parameters are complete for OSNMA processing - bool d_flag_osnma_adkd_4_utc; // flag to indicate if the iono correction and time is complete for OSNMA processing }; diff --git a/src/core/libs/osnma_msg_receiver.cc b/src/core/libs/osnma_msg_receiver.cc index 0688af6e9..701f358c9 100644 --- a/src/core/libs/osnma_msg_receiver.cc +++ b/src/core/libs/osnma_msg_receiver.cc @@ -25,13 +25,15 @@ #include "osnma_dsm_reader.h" // for OSNMA_DSM_Reader #include "osnma_helper.h" #include // for gr::io_signature::make +#include #include #include #include // for std::setfill #include // for std::hex, std::uppercase #include -#include // for std::accumulate -#include // std::stringstream +#include // for std::accumulate +#include // std::stringstream +#include #include // for typeid #include @@ -104,12 +106,12 @@ void osnma_msg_receiver::msg_handler_osnma(const pmt::pmt_t& msg) std::ostringstream output_message; output_message << "Galileo OSNMA: data received starting at " - << "WN=" - << nma_msg->WN_sf0 - << ", TOW=" - << nma_msg->TOW_sf0 - << ", from satellite " - << sat; + << "WN=" + << nma_msg->WN_sf0 + << ", TOW=" + << nma_msg->TOW_sf0 + << ", from satellite " + << sat; LOG(INFO) << output_message.str(); std::cout << output_message.str() << std::endl; @@ -126,15 +128,15 @@ void osnma_msg_receiver::msg_handler_osnma(const pmt::pmt_t& msg) // iono data => 549 bits, utc data, 141 bits. if (nav_data.size() == 549) { - // LOG(INFO) << "Galileo OSNMA: received ADKD=0/12 navData, PRN_d (" << PRNa << ") " + // LOG(INFO) << "Galileo OSNMA: received ADKD=0/12 OSNMA_NavData, PRN_d (" << PRNa << ") " // << "TOW_sf=" << TOW; - d_satellite_nav_data[PRNa][TOW].ephemeris_iono_vector_2 = nav_data; + d_satellite_nav_data[PRNa][TOW].set_ephemeris_iono_data(nav_data); } else if (nav_data.size() == 141) { - // LOG(INFO) << "Galileo OSNMA: received ADKD=4 navData, PRN_d (" << PRNa << ") " + // LOG(INFO) << "Galileo OSNMA: received ADKD=4 OSNMA_NavData, PRN_d (" << PRNa << ") " // << "TOW_sf=" << TOW; - d_satellite_nav_data[PRNa][TOW].utc_vector_2 = nav_data; + d_satellite_nav_data[PRNa][TOW].set_utc_data(nav_data); } else { @@ -488,11 +490,11 @@ void osnma_msg_receiver::process_dsm_message(const std::vector& dsm_msg << ", WN=" << static_cast(d_osnma_data.d_dsm_kroot_message.wn_k) << ", TOW=" << static_cast(d_osnma_data.d_dsm_kroot_message.towh_k) * 3600; local_time_verification(osnma_msg); - if(l_ds_bits == 512) + if (l_ds_bits == 512) { d_kroot_verified = d_crypto->verify_signature_ecdsa_p256(message, d_osnma_data.d_dsm_kroot_message.ds); } - else if(l_ds_bits == 1056) + else if (l_ds_bits == 1056) { d_kroot_verified = d_crypto->verify_signature_ecdsa_p521(message, d_osnma_data.d_dsm_kroot_message.ds); } @@ -614,11 +616,11 @@ void osnma_msg_receiver::read_and_process_mack_block(const std::shared_ptrPRN; // FIXME this is ugly. d_osnma_data.d_mack_message.TOW = osnma_msg->TOW_sf0; @@ -626,7 +628,7 @@ void osnma_msg_receiver::read_and_process_mack_block(const std::shared_ptr no need to verify + if (d_tesla_keys.find(d_osnma_data.d_nav_data.get_tow_sf0()) == d_tesla_keys.end()) // check if already available => no need to verify { - bool retV = verify_tesla_key(d_osnma_data.d_mack_message.key, d_osnma_data.d_nav_data.TOW_sf0); + bool retV = verify_tesla_key(d_osnma_data.d_mack_message.key, d_osnma_data.d_nav_data.get_tow_sf0()); if (retV) { - d_tesla_keys.insert(std::pair>(d_osnma_data.d_nav_data.TOW_sf0, d_osnma_data.d_mack_message.key)); + d_tesla_keys.insert(std::pair>(d_osnma_data.d_nav_data.get_tow_sf0(), d_osnma_data.d_mack_message.key)); } } @@ -924,11 +926,11 @@ void osnma_msg_receiver::process_mack_message() if (d_tesla_keys.find(mack->TOW + 30) != d_tesla_keys.end()) { // add tag0 first - Tag tag0 (*mack); + Tag tag0(*mack); d_tags_awaiting_verify.insert(std::pair(mack->TOW, tag0)); -// bool ret = verify_macseq(*mack); + // bool ret = verify_macseq(*mack); std::vector macseq_verified_tags = verify_macseq_new(*mack); - for (auto & tag_and_info : macseq_verified_tags) + for (auto& tag_and_info : macseq_verified_tags) { // add tags of current mack to the verification queue Tag t(tag_and_info, mack->TOW, mack->WN, mack->PRNa, tag_and_info.counter); @@ -948,7 +950,6 @@ void osnma_msg_receiver::process_mack_message() } LOG(INFO) << "Galileo OSNMA: d_tags_awaiting_verify :: size: " << d_tags_awaiting_verify.size(); mack = d_macks_awaiting_MACSEQ_verification.erase(mack); - } else { @@ -969,7 +970,7 @@ void osnma_msg_receiver::process_mack_message() /* TODO - take into account: * - COP: if * - ADKD type - * - NavData the tag verifies (min. number of bits verified to consider NavData OK) + * - OSNMA_NavData the tag verifies (min. number of bits verified to consider OSNMA_NavData OK) * */ if (ret) { @@ -1020,7 +1021,7 @@ void osnma_msg_receiver::process_mack_message() << static_cast(it.second.PRN_d) << std::endl; } } - else if (it.second.TOW > d_osnma_data.d_nav_data.TOW_sf0) + else if (it.second.TOW > d_osnma_data.d_nav_data.get_tow_sf0()) { // TODO - I dont understand logic. This needs to be reviewed. // case 1: adkd=12 and t.Tow + 300 < current TOW @@ -1059,7 +1060,7 @@ void osnma_msg_receiver::process_mack_message() */ bool osnma_msg_receiver::verify_dsm_pkr(const DSM_PKR_message& message) const { - const auto base_leaf = get_merkle_tree_leaves(message); // m_i + const auto base_leaf = get_merkle_tree_leaves(message); // m_i const auto computed_merkle_root = compute_merkle_root(message, base_leaf); // x_4_0 const auto msg_id = static_cast(message.mid); LOG(INFO) << "Galileo OSNMA: DSM-PKR verification :: leaf provided for Message ID " << msg_id; @@ -1110,7 +1111,7 @@ std::vector osnma_msg_receiver::compute_merkle_root(const DSM_PKR_messa std::vector osnma_msg_receiver::get_merkle_tree_leaves(const DSM_PKR_message& dsm_pkr_message) const { - // build base leaf m_i according to OSNMA SIS ICD v1.1, section 6.2 DSM-PKR Verification + // build base leaf m_i according to OSNMA SIS ICD v1.1, section 6.2 DSM-PKR Verification std::vector m_i; const size_t size_npk = dsm_pkr_message.npk.size(); m_i.reserve(1 + size_npk); @@ -1138,7 +1139,7 @@ bool osnma_msg_receiver::verify_tag(const Tag& tag) const if (tag.ADKD == 0 || tag.ADKD == 4) { const auto it = d_tesla_keys.find(tag.TOW + 30); - if(it != d_tesla_keys.cend()) + if (it != d_tesla_keys.cend()) { applicable_key = it->second; } @@ -1151,7 +1152,7 @@ bool osnma_msg_receiver::verify_tag(const Tag& tag) const else // ADKD 12 { const auto it = d_tesla_keys.find(tag.TOW + 330); - if(it != d_tesla_keys.cend()) + if (it != d_tesla_keys.cend()) { applicable_key = it->second; } @@ -1212,26 +1213,6 @@ bool osnma_msg_receiver::verify_tag(const Tag& tag) const // Compare computed tag with received one truncated if (tag.received_tag == computed_mac) { - LOG(INFO) << "Galileo OSNMA: Tag verification :: SUCCESS for tag Id=" - << tag.tag_id - << ", value=0x" << std::setfill('0') << std::setw(10) << std::hex << std::uppercase - << tag.received_tag << std::dec - << ", TOW=" - << tag.TOW - << ", ADKD=" - << static_cast(tag.ADKD) - << ", PRNa=" - << static_cast(tag.PRNa) - << ", PRNd=" - << static_cast(tag.PRN_d); - std::cout << "Galileo OSNMA: Tag verification :: SUCCESS for tag Id=" - << tag.tag_id - << ", ADKD=" - << static_cast(tag.ADKD) - << ", PRNa=" - << static_cast(tag.PRNa) - << ", PRNd=" - << static_cast(tag.PRN_d) << std::endl; return true; } return false; @@ -1267,7 +1248,7 @@ std::vector osnma_msg_receiver::build_message(const Tag& tag) const const auto it2 = it->second.find(tag.TOW - 30); if (it2 != it->second.cend()) { - applicable_nav_data = it2->second.ephemeris_iono_vector_2; + applicable_nav_data = it2->second.get_ephemeris_iono_data(); } } // LOG(INFO) << "|---> Galileo OSNMA :: applicable NavData (PRN_d="<< static_cast(tag.PRN_d) << ", TOW=" << tag.TOW - 30 <<"): 0b" << applicable_nav_data; @@ -1280,10 +1261,10 @@ std::vector osnma_msg_receiver::build_message(const Tag& tag) const const auto it2 = it->second.find(tag.TOW - 30); if (it2 != it->second.cend()) { - applicable_nav_data = it2->second.utc_vector_2; + applicable_nav_data = it2->second.get_utc_data(); } } - // LOG(INFO) << "|---> Galileo OSNMA :: applicable NavData (PRN_d="<< static_cast(tag.PRN_d) << ", TOW=" << tag.TOW - 30 <<"): 0b" << applicable_nav_data; + // LOG(INFO) << "|---> Galileo OSNMA :: applicable OSNMA_NavData (PRN_d="<< static_cast(tag.PRN_d) << ", TOW=" << tag.TOW - 30 <<"): 0b" << applicable_nav_data; } else { @@ -1292,7 +1273,7 @@ std::vector osnma_msg_receiver::build_message(const Tag& tag) const // convert std::string to vector applicable_nav_data_bytes = d_helper->bytes(applicable_nav_data); - // Convert and add NavData bytes into the message, taking care of that NMAS has only 2 bits + // Convert and add OSNMA_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 @@ -1322,7 +1303,7 @@ std::vector osnma_msg_receiver::build_message(const Tag& tag) const } -void osnma_msg_receiver::add_satellite_data(uint32_t SV_ID, uint32_t TOW, const NavData& data) +void osnma_msg_receiver::add_satellite_data(uint32_t SV_ID, uint32_t TOW, const OSNMA_NavData& data) { // control size of container while (d_satellite_nav_data[SV_ID].size() >= 25) @@ -1596,8 +1577,8 @@ bool osnma_msg_receiver::tag_has_nav_data_available(const Tag& t) const if (prn_it != d_satellite_nav_data.end()) { // 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; + // LOG(INFO) << "Galileo OSNMA: hasData = true " << std::endl; + std::map tow_map = prn_it->second; auto tow_it = tow_map.find(t.TOW - 30); if (tow_it != tow_map.end()) { @@ -1612,7 +1593,7 @@ bool osnma_msg_receiver::tag_has_nav_data_available(const Tag& t) const else { // PRN was not found - //LOG(INFO) << "Galileo OSNMA: hasData = false " << std::endl; + // LOG(INFO) << "Galileo OSNMA: hasData = false " << std::endl; return false; } return false; @@ -1631,7 +1612,7 @@ bool osnma_msg_receiver::tag_has_key_available(const Tag& t) const auto it = d_tesla_keys.find(t.TOW + 30); if (it != d_tesla_keys.end()) { - //LOG(INFO) << "Galileo OSNMA: hasKey = true " << std::endl; + // LOG(INFO) << "Galileo OSNMA: hasKey = true " << std::endl; return true; } } @@ -1640,11 +1621,11 @@ bool osnma_msg_receiver::tag_has_key_available(const Tag& t) const auto it = d_tesla_keys.find(t.TOW + 330); if (it != d_tesla_keys.end()) { - //LOG(INFO) << "Galileo OSNMA: hasKey = true " << std::endl; + // LOG(INFO) << "Galileo OSNMA: hasKey = true " << std::endl; return true; } } - //LOG(INFO) << "Galileo OSNMA: hasKey = false "; + // LOG(INFO) << "Galileo OSNMA: hasKey = false "; return false; } diff --git a/src/core/libs/osnma_msg_receiver.h b/src/core/libs/osnma_msg_receiver.h index 7ecbe7428..40ac73e78 100644 --- a/src/core/libs/osnma_msg_receiver.h +++ b/src/core/libs/osnma_msg_receiver.h @@ -77,7 +77,7 @@ private: void read_mack_header(); void read_mack_body(); void process_mack_message(); - void add_satellite_data(uint32_t SV_ID, uint32_t TOW, const NavData& data); + void add_satellite_data(uint32_t SV_ID, uint32_t TOW, const OSNMA_NavData& data); void remove_verified_tags(); void control_tags_awaiting_verify_size(); void display_data(); @@ -95,7 +95,7 @@ private: std::vector hash_chain(uint32_t num_of_hashes_needed, const std::vector& key, uint32_t GST_SFi, const uint8_t lk_bytes) const; std::vector verify_macseq_new(const MACK_message& mack); - std::map> d_satellite_nav_data; // map holding NavData sorted by SVID (first key) and TOW (second key). + std::map> d_satellite_nav_data; // map holding OSNMA_NavData sorted by SVID (first key) and TOW (second key). std::map> d_tesla_keys; // tesla keys over time, sorted by TOW std::multimap d_tags_awaiting_verify; // container with tags to verify from arbitrary SVIDs, sorted by TOW diff --git a/src/core/system_parameters/galileo_inav_message.cc b/src/core/system_parameters/galileo_inav_message.cc index a8509db23..c5ddcbfaa 100644 --- a/src/core/system_parameters/galileo_inav_message.cc +++ b/src/core/system_parameters/galileo_inav_message.cc @@ -185,7 +185,7 @@ void Galileo_Inav_Message::split_page(std::string page_string, int32_t flag_even if (page_position_in_inav_subframe != 255) { if (page_position_in_inav_subframe == 0) - { // TODO - is it redundant? receiving Word 2 already resets this + { // TODO - is it redundant? receiving Word 2 already resets this nma_position_filled = std::array{}; nma_msg.mack = std::array{}; nma_msg.hkroot = std::array{}; @@ -215,6 +215,7 @@ void Galileo_Inav_Message::split_page(std::string page_string, int32_t flag_even } } + // C: tells if W1-->W4 available from same blcok bool Galileo_Inav_Message::have_new_ephemeris() // Check if we have a new ephemeris stored in the galileo navigation class { @@ -349,6 +350,7 @@ bool Galileo_Inav_Message::have_new_ephemeris() // Check if we have a new ephem return false; } + // C: tells if W5 is available bool Galileo_Inav_Message::have_new_iono_and_GST() // Check if we have a new iono data set stored in the galileo navigation class { @@ -361,6 +363,7 @@ bool Galileo_Inav_Message::have_new_iono_and_GST() // Check if we have a new io return false; } + // C: tells if W6 is available bool Galileo_Inav_Message::have_new_utc_model() // Check if we have a new utc data set stored in the galileo navigation class { @@ -373,13 +376,14 @@ bool Galileo_Inav_Message::have_new_utc_model() // Check if we have a new utc d return false; } + // flag_almanac_4 tells if W10 available. bool Galileo_Inav_Message::have_new_almanac() // Check if we have a new almanac data set stored in the galileo navigation class { -// if(flag_almanac_4) -// { -// flag_adkd_4_complete = true; -// } + // if(flag_almanac_4) + // { + // flag_adkd_4_complete = true; + // } if ((flag_almanac_1 == true) and (flag_almanac_2 == true) and (flag_almanac_3 == true) and (flag_almanac_4 == true)) { // All Almanac data have been received @@ -618,7 +622,7 @@ void Galileo_Inav_Message::read_page_1(const std::bitset& DLOG(INFO) << "A_1= " << A_1; flag_ephemeris_1 = true; DLOG(INFO) << "flag_tow_set" << flag_TOW_set; - nav_bits_word_1 = data_bits.to_string().substr(6,120); + nav_bits_word_1 = data_bits.to_string().substr(6, 120); } @@ -640,7 +644,7 @@ void Galileo_Inav_Message::read_page_2(const std::bitset& DLOG(INFO) << "iDot_2= " << iDot_2; flag_ephemeris_2 = true; DLOG(INFO) << "flag_tow_set" << flag_TOW_set; - nav_bits_word_2 = data_bits.to_string().substr(6,120); + nav_bits_word_2 = data_bits.to_string().substr(6, 120); } @@ -1058,7 +1062,7 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) flag_utc_model = true; // set to false externally flag_TOW_set = true; // set to false externally DLOG(INFO) << "flag_tow_set" << flag_TOW_set; - nav_bits_word_6 = data_jk_bits.to_string().substr(6, 99); + nav_bits_word_6 = data_jk_bits.to_string().substr(6, 99); break; case 7: // Word type 7: Almanac for SVID1 (1/2), almanac reference time and almanac reference week number @@ -1417,7 +1421,7 @@ OSNMA_msg Galileo_Inav_Message::get_osnma_msg() nma_position_filled = std::array{}; // Fill TOW and WN nma_msg.WN_sf0 = WN_0; - int32_t TOW_sf0 = TOW_5 - 25;//- 24; // according to OS SIS ICD, TOW of word 5 is 25 seconds after Sf start TODO review + int32_t TOW_sf0 = TOW_5 - 25; //- 24; // according to OS SIS ICD, TOW of word 5 is 25 seconds after Sf start TODO review if (TOW_sf0 < 0) { TOW_sf0 += 604800; @@ -1442,17 +1446,23 @@ bool Galileo_Inav_Message::have_new_nma() return false; } } + + std::string Galileo_Inav_Message::get_osnma_adkd_4_nav_bits() { nav_bits_adkd_4 = nav_bits_word_6 + nav_bits_word_10; return nav_bits_adkd_4; } + + std::string Galileo_Inav_Message::get_osnma_adkd_0_12_nav_bits() { nav_bits_adkd_0_12 = nav_bits_word_1 + nav_bits_word_2 + nav_bits_word_3 + nav_bits_word_4 + nav_bits_word_5; return nav_bits_adkd_0_12; } + + void Galileo_Inav_Message::reset_osnma_nav_bits_adkd0_12() { nav_bits_word_1 = ""; @@ -1461,6 +1471,8 @@ void Galileo_Inav_Message::reset_osnma_nav_bits_adkd0_12() nav_bits_word_4 = ""; nav_bits_word_5 = ""; } + + void Galileo_Inav_Message::reset_osnma_nav_bits_adkd4() { nav_bits_word_6 = ""; diff --git a/src/core/system_parameters/galileo_inav_message.h b/src/core/system_parameters/galileo_inav_message.h index a4cc6a31a..2ecb8aa53 100644 --- a/src/core/system_parameters/galileo_inav_message.h +++ b/src/core/system_parameters/galileo_inav_message.h @@ -49,17 +49,15 @@ public: std::array mack{}; std::array hkroot{}; uint32_t PRN{}; - uint32_t WN_sf0{}; // TODO - this is present in UtcModelData already + uint32_t WN_sf0{}; // TODO - this is present in UtcModelData already uint32_t TOW_sf0{}; - std::vector EphemerisClockAndStatusData {}; // TODO _2 rename and substitute this + std::vector EphemerisClockAndStatusData{}; // TODO _2 rename and substitute this std::string EphemerisClockAndStatusData_2{}; - std::vector TimingData {}; + std::vector TimingData{}; std::string TimingData_2{}; - Galileo_Ephemeris EphemerisData {}; - Galileo_Iono IonoData {}; - Galileo_Utc_Model UtcModelData {}; - - + 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 49051b7be..91a32a1f3 100644 --- a/src/core/system_parameters/osnma_data.cc +++ b/src/core/system_parameters/osnma_data.cc @@ -1,172 +1,55 @@ /*! -* \file osnma_data.cc -* \brief Class for Galileo OSNMA data storage -* \author Carles Fernandez-Prades, 2020-2023 cfernandez(at)cttc.es -* -* ----------------------------------------------------------------------------- -* -* GNSS-SDR is a Global Navigation Satellite System software-defined receiver. -* This file is part of GNSS-SDR. -* -* Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors) -* SPDX-License-Identifier: GPL-3.0-or-later -* -* ----------------------------------------------------------------------------- -*/ - -#include "osnma_data.h" -#include -#include - -/** - * @brief Constructs a NavData object with the given osnma_msg. - * \details Packs the ephemeris, iono and utc data from the current subframe into the NavData structure. It also gets the PRNa and the GST. - * @param osnma_msg The shared pointer to the OSNMA_msg object. + * \file osnma_data.cc + * \brief Class for Galileo OSNMA data storage + * \author Carles Fernandez-Prades, 2020-2023 cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- */ +#include "osnma_data.h" + uint32_t Tag::id_counter = 0; -void NavData::init(const std::shared_ptr &osnma_msg) + + +void OSNMA_NavData::init(const std::shared_ptr& osnma_msg) { - EphemerisData = osnma_msg->EphemerisData; - IonoData = osnma_msg->IonoData; - UtcData = osnma_msg->UtcModelData; - generate_eph_iono_vector(); - generate_utc_vector(); - PRNa = osnma_msg->PRN; - WN_sf0 = osnma_msg->WN_sf0; - TOW_sf0 = osnma_msg->TOW_sf0; - - // 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() -{ - ephemeris_iono_vector.clear(); - uint64_t bit_buffer = 0; // variable to store the bits to be extracted, it can contain bits from different variables - int bit_count = 0; // Number of bits in the buffer, i.e. to be extracted - - // create structure to hold the variables to store into the vector along with their bit size - std::vector> variables = { - // data from word type 1 - {static_cast(&EphemerisData.IOD_nav), sizeof(EphemerisData.IOD_nav) * 8}, - {static_cast(&EphemerisData.toe), sizeof(EphemerisData.toe) * 8}, - {static_cast(&EphemerisData.M_0), sizeof(EphemerisData.M_0) * 8}, - {static_cast(&EphemerisData.ecc), sizeof(EphemerisData.ecc) * 8}, - {static_cast(&EphemerisData.sqrtA), sizeof(EphemerisData.sqrtA) * 8}, - // data from word type 2 - {static_cast(&EphemerisData.IOD_nav), sizeof(EphemerisData.IOD_nav) * 8}, - {static_cast(&EphemerisData.OMEGA_0), sizeof(EphemerisData.OMEGA_0) * 8}, - {static_cast(&EphemerisData.i_0), sizeof(EphemerisData.i_0) * 8}, - {static_cast(&EphemerisData.omega), sizeof(EphemerisData.omega) * 8}, - {static_cast(&EphemerisData.idot), sizeof(EphemerisData.idot) * 8}, - {static_cast(&EphemerisData.IOD_nav), sizeof(EphemerisData.IOD_nav) * 8}, - // data from word type 3 - {static_cast(&EphemerisData.OMEGAdot), sizeof(EphemerisData.OMEGAdot) * 8}, - {static_cast(&EphemerisData.delta_n), sizeof(EphemerisData.delta_n) * 8}, - {static_cast(&EphemerisData.Cuc), sizeof(EphemerisData.Cuc) * 8}, - {static_cast(&EphemerisData.Cus), sizeof(EphemerisData.Cus) * 8}, - {static_cast(&EphemerisData.Crc), sizeof(EphemerisData.Crc) * 8}, - {static_cast(&EphemerisData.Crs), sizeof(EphemerisData.Crs) * 8}, - {static_cast(&EphemerisData.SISA), sizeof(EphemerisData.SISA) * 8}, - // data from word type 4 - {static_cast(&EphemerisData.IOD_nav), sizeof(EphemerisData.IOD_nav) * 8}, - {static_cast(&EphemerisData.PRN), sizeof(EphemerisData.PRN) * 8}, - {static_cast(&EphemerisData.Cic), sizeof(EphemerisData.Cic) * 8}, - {static_cast(&EphemerisData.Cis), sizeof(EphemerisData.Cis) * 8}, - {static_cast(&EphemerisData.toe), sizeof(EphemerisData.toe) * 8}, - {static_cast(&EphemerisData.af0), sizeof(EphemerisData.af0) * 8}, - {static_cast(&EphemerisData.af1), sizeof(EphemerisData.af1) * 8}, - {static_cast(&EphemerisData.af2), sizeof(EphemerisData.af2) * 8}, - // data from word type 5 - {static_cast(&IonoData.ai0), sizeof(IonoData.ai0) * 8}, - {static_cast(&IonoData.ai1), sizeof(IonoData.ai1) * 8}, - {static_cast(&IonoData.ai2), sizeof(IonoData.ai2) * 8}, - {static_cast(&IonoData.Region1_flag), sizeof(IonoData.Region1_flag) * 8}, - {static_cast(&IonoData.Region2_flag), sizeof(IonoData.Region2_flag) * 8}, - {static_cast(&IonoData.Region3_flag), sizeof(IonoData.Region3_flag) * 8}, - {static_cast(&IonoData.Region4_flag), sizeof(IonoData.Region4_flag) * 8}, - {static_cast(&IonoData.Region5_flag), sizeof(IonoData.Region5_flag) * 8}, - {static_cast(&EphemerisData.BGD_E1E5a), sizeof(EphemerisData.BGD_E1E5a) * 8}, - {static_cast(&EphemerisData.BGD_E1E5b), sizeof(EphemerisData.BGD_E1E5b) * 8}, - {static_cast(&EphemerisData.E5b_HS), sizeof(EphemerisData.E5b_HS) * 8}, - {static_cast(&EphemerisData.E1B_HS), sizeof(EphemerisData.E1B_HS) * 8}, - {static_cast(&EphemerisData.E5b_DVS), sizeof(EphemerisData.E5b_DVS) * 8}, - {static_cast(&EphemerisData.E1B_DVS), sizeof(EphemerisData.E1B_DVS) * 8}, - }; - - for (auto& var : variables) - { - // extract the bits from the variable - uint64_t binary_representation; - memcpy(&binary_representation, var.first, var.second / 8); - - // Append the bits to the buffer and update the bit count - bit_buffer = (bit_buffer << var.second) | binary_representation; - bit_count += var.second; - // While there are 8 or more bits in the buffer - while (bit_count >= 8) - { - // Extract the 8 bits starting from last bit position and add them to the vector - uint8_t extracted_bits = (bit_buffer >> (bit_count - 8)) & 0xFF; - ephemeris_iono_vector.push_back(extracted_bits); - - // Remove the extracted bits from the buffer - bit_count -= 8; - bit_buffer = bit_buffer & ~(0xFF << bit_count); - } - - } - - // If there are any bits left in the buffer, add them to the vector - if (bit_count > 0) - { - ephemeris_iono_vector.push_back(static_cast(bit_buffer)); - } + d_TOW_sf0 = osnma_msg->TOW_sf0; } -void NavData::generate_utc_vector() + +std::string OSNMA_NavData::get_ephemeris_iono_data() const { - utc_vector.clear(); - uint64_t bit_buffer = 0; - int bit_count = 0; - - std::vector> variables = { - {static_cast(&UtcData.A0), sizeof(UtcData.A0) * 8}, - {static_cast(&UtcData.A1), sizeof(UtcData.A1) * 8}, - {static_cast(&UtcData.Delta_tLS), sizeof(UtcData.Delta_tLS) * 8}, - {static_cast(&UtcData.tot), sizeof(UtcData.tot) * 8}, - {static_cast(&UtcData.WNot), sizeof(UtcData.WNot) * 8}, - {static_cast(&UtcData.WN_LSF), sizeof(UtcData.WN_LSF) * 8}, - {static_cast(&UtcData.DN), sizeof(UtcData.DN) * 8}, - {static_cast(&UtcData.Delta_tLSF), sizeof(UtcData.Delta_tLSF) * 8}, - {static_cast(&UtcData.A_0G), sizeof(UtcData.A_0G) * 8}, - {static_cast(&UtcData.A_1G), sizeof(UtcData.A_1G) * 8}, - {static_cast(&UtcData.t_0G), sizeof(UtcData.t_0G) * 8}, - {static_cast(&UtcData.WN_0G), sizeof(UtcData.WN_0G) * 8}, - }; - - for (auto& var : variables) - { - uint64_t binary_representation; - memcpy(&binary_representation, var.first, var.second / 8); - - bit_buffer = (bit_buffer << var.second) | binary_representation; - bit_count += var.second; - - while (bit_count >= 8) - { - uint8_t extracted_bits = (bit_buffer >> (bit_count - 8)) & 0xFF; - utc_vector.push_back(extracted_bits); - - bit_count -= 8; - bit_buffer = bit_buffer & ~(0xFF << bit_count); - } - } - - if (bit_count > 0) - { - utc_vector.push_back(static_cast(bit_buffer)); - } + return d_ephemeris_iono; } + +std::string OSNMA_NavData::get_utc_data() const +{ + return d_utc; +} + + +uint32_t OSNMA_NavData::get_tow_sf0() const +{ + return d_TOW_sf0; +} + + +void OSNMA_NavData::set_ephemeris_iono_data(const std::string& iono_data) +{ + d_ephemeris_iono = iono_data; +} + + +void OSNMA_NavData::set_utc_data(const std::string& utc_data) +{ + d_utc = utc_data; +} diff --git a/src/core/system_parameters/osnma_data.h b/src/core/system_parameters/osnma_data.h index 484fa0162..910ee3e2d 100644 --- a/src/core/system_parameters/osnma_data.h +++ b/src/core/system_parameters/osnma_data.h @@ -18,12 +18,10 @@ #ifndef GNSS_SDR_OSNMA_DATA_H #define GNSS_SDR_OSNMA_DATA_H -#include "galileo_ephemeris.h" -#include "galileo_inav_message.h" -#include "galileo_iono.h" -#include "galileo_utc_model.h" +#include "galileo_inav_message.h" // for OSNMA_msg #include #include +#include #include #include @@ -72,9 +70,9 @@ class MACK_tag_and_info { public: MACK_tag_and_info() = default; - uint64_t tag; // C: 20-40 bits + uint64_t tag; // C: 20-40 bits MACK_tag_info tag_info; - uint32_t counter; // CTR + uint32_t counter; // CTR }; class DSM_PKR_message @@ -107,7 +105,7 @@ public: uint8_t reserved1{}; uint8_t hf{}; uint8_t mf{}; - uint8_t ks{}; // key size, in bits + uint8_t ks{}; // key size, in bits uint8_t ts{}; uint8_t maclt{}; uint8_t reserved{}; @@ -121,31 +119,26 @@ public: MACK_header header; std::vector tag_and_info; std::vector key; - uint32_t TOW; // TODO duplicated variable, also in NavData + uint32_t TOW; // TODO duplicated variable, also in OSNMA_NavData uint32_t WN; uint32_t PRNa; }; -class NavData +class OSNMA_NavData { public: - NavData()=default; - void init(const std::shared_ptr &osnma_msg); - 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{}; + OSNMA_NavData() = default; + void init(const std::shared_ptr& osnma_msg); + std::string get_ephemeris_iono_data() const; + std::string get_utc_data() const; + uint32_t get_tow_sf0() const; + void set_ephemeris_iono_data(const std::string& iono_data); + void set_utc_data(const std::string& utc_data); + private: - Galileo_Ephemeris EphemerisData; - Galileo_Iono IonoData; - Galileo_Utc_Model UtcData; - void generate_eph_iono_vector(); // TODO pass data directly fro Telemetry Decoder (if bits are in the needed order) - void generate_utc_vector(); // TODO - - + std::string d_ephemeris_iono; + std::string d_utc; + uint32_t d_TOW_sf0{}; }; /*! @@ -161,19 +154,22 @@ public: DSM_PKR_message d_dsm_pkr_message; DSM_KROOT_message d_dsm_kroot_message; MACK_message d_mack_message; - NavData d_nav_data; + OSNMA_NavData d_nav_data; }; + class Tag { public: - enum e_verification_status{ + enum e_verification_status + { SUCCESS, FAIL, - UNVERIFIED}; - Tag(const MACK_tag_and_info& MTI, uint32_t TOW,uint32_t WN, uint32_t PRNa,uint8_t CTR) // standard tag constructor, for tags within Tag&Info field + UNVERIFIED + }; + Tag(const MACK_tag_and_info& MTI, uint32_t TOW, uint32_t WN, uint32_t PRNa, uint8_t CTR) // standard tag constructor, for tags within Tag&Info field : tag_id(id_counter++), - TOW(TOW), // TODO missing for build_message WN for GST computation, CTR, NMAS, NavData missing + TOW(TOW), // TODO missing for build_message WN for GST computation, CTR, NMAS, OSNMA_NavData missing WN(WN), PRNa(PRNa), CTR(CTR), @@ -186,16 +182,16 @@ public: skipped(0) { } - Tag(const MACK_message& mack) // constructor for Tag0 + Tag(const MACK_message& mack) // constructor for Tag0 : tag_id(id_counter++), - TOW(mack.TOW), // TODO missing for build_message WN for GST computation, CTR, NMAS, NavData missing + TOW(mack.TOW), // TODO missing for build_message WN for GST computation, CTR, NMAS, OSNMA_NavData missing WN(mack.WN), PRNa(mack.PRNa), CTR(1), status(UNVERIFIED), received_tag(mack.header.tag0), computed_tag(0), - PRN_d(mack.PRNa), // Tag0 are self-authenticating + PRN_d(mack.PRNa), // Tag0 are self-authenticating ADKD(0), cop(mack.header.cop), skipped(0) diff --git a/src/core/system_parameters/osnma_helper.h b/src/core/system_parameters/osnma_helper.h index 686ef5e99..07a3c457f 100644 --- a/src/core/system_parameters/osnma_helper.h +++ b/src/core/system_parameters/osnma_helper.h @@ -30,8 +30,8 @@ public: std::vector gst_to_uint8(uint32_t GST) const; std::vector bytes(const std::string& binaryString) const; std::string verification_status_str(int status) const; - std::string convert_to_hex_string(const std::vector& vector) const ; - std::vector convert_from_hex_string(const std::string& hex_string) const; // TODO remove similar function in gnss_crypto + std::string convert_to_hex_string(const std::vector& vector) const; + std::vector convert_from_hex_string(const std::string& hex_string) const; // TODO remove similar function in gnss_crypto }; #endif // GNSS_SDR_OSNMA_HELPER_H 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 d0df27a3b..5f1efcee3 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 @@ -1,13 +1,31 @@ +/*! + * \file osmna_msg_receiver_testt.cc + * \brief Tests for the osnma_msg_receiver class. + * \author Carles Fernandez, 2023-2024. cfernandez(at)cttc.es + * Cesare Ghionoiu Martinez, 2023-2024. c.ghionoiu-martinez@tu-braunschweig.de + * + * + * ----------------------------------------------------------------------------- + * + * 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 "gnss_crypto.h" +#include "osnma_helper.h" +#include "osnma_msg_receiver.h" #include #include #include #include -#include #include #if USE_GLOG_AND_GFLAGS -#include "osnma_helper.h" -#include "gnss_crypto.h" #include // for LOG #include #else @@ -21,11 +39,18 @@ struct TestVector std::vector navBits; }; + // TODO - parametrize class for different configurations (config_1, config_2, etc.. potentially 5 or 6 more) an make sure wont affect current TEST_F // note: until the test is parametrized for configuration 1 and 2, in order to change between them you have to comment/uncomment the respective calls in this test, identified with comments // conf. 1/2 // log_name, input_time, crtFilePath, merkleFilePath, testVectors class OsnmaMsgReceiverTest : public ::testing::Test { +public: + static std::vector parseNavBits(const std::string& hex); + static std::vector readTestVectorsFromFile(const std::string& filename); + std::string bytes_to_str(const std::vector& bytes); + std::vector extract_page_bytes(const TestVector& tv, const int byte_index, const int num_bytes); + protected: Osnma_Helper helper; osnma_msg_receiver_sptr osnma; @@ -34,38 +59,31 @@ protected: 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}; // months start with 0 and years since 1900 in std::tm - const uint32_t LEAP_SECONDS = 0; //13 + 5; + std::tm GST_START_EPOCH = {0, 0, 0, 22, 8 - 1, 1999 - 1900, 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); -// std::string log_name {"CONFIG1-2023-08-16-PKID1-OSNMA"}; - std::string log_name {"CONFIG2-2023-07-27-PKID2-MT2-OSNMA"}; + // std::string log_name {"CONFIG1-2023-08-16-PKID1-OSNMA"}; + std::string log_name{"CONFIG2-2023-07-27-PKID2-MT2-OSNMA"}; void initializeGoogleLog(); void SetUp() override { initializeGoogleLog(); -// std::tm input_time = {0, 0, 5, 16, 8 - 1, 2023 - 1900, 0}; // conf. 1 - std::tm input_time = {0, 0, 0, 27, 7 - 1, 2023 - 1900, 0}; // conf. 2 + // std::tm input_time = {0, 0, 5, 16, 8 - 1, 2023 - 1900, 0}; // conf. 1 + std::tm input_time = {0, 0, 0, 27, 7 - 1, 2023 - 1900, 0}; // conf. 2 set_time(input_time); -// std::string crtFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_PublicKey_20230803105952_newPKID_1.crt"; // conf. 1 -// std::string merkleFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_MerkleTree_20230803105953_newPKID_1.xml"; - std::string crtFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_PublicKey_20230720113300_newPKID_2.crt"; // conf. 2 + // std::string crtFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_PublicKey_20230803105952_newPKID_1.crt"; // conf. 1 + // std::string merkleFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_MerkleTree_20230803105953_newPKID_1.xml"; + std::string crtFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_PublicKey_20230720113300_newPKID_2.crt"; // conf. 2 std::string merkleFilePath = "/home/cgm/CLionProjects/osnma/data/OSNMA_MerkleTree_20230720113300_newPKID_2.xml"; osnma = osnma_msg_receiver_make(crtFilePath, merkleFilePath); } - -public: - - static std::vector parseNavBits(const std::string& hex); - static std::vector readTestVectorsFromFile(const std::string& filename); - std::string bytes_to_str(const std::vector& bytes); - std::vector extract_page_bytes(const TestVector& tv, const int byte_index, const int num_bytes); }; + TEST_F(OsnmaMsgReceiverTest, ComputeMerkleRoot) { // Arrange - // ---------- std::vector computed_merkle_root; std::vector expected_merkle_root = helper.convert_from_hex_string("A10C440F3AA62453526DB4AF76DF8D9410D35D8277397D7053C700D192702B0D"); DSM_PKR_message dsm_pkr_message; @@ -73,8 +91,8 @@ TEST_F(OsnmaMsgReceiverTest, ComputeMerkleRoot) dsm_pkr_message.npktid = 0x2; dsm_pkr_message.mid = 0x01; std::vector base_leaf = helper.convert_from_hex_string("120303B2CE64BC207BDD8BC4DF859187FCB686320D63FFA091410FC158FBB77980EA"); - - std::vector vec = helper.convert_from_hex_string("7CBE05D9970CFC9E22D0A43A340EF557624453A2E821AADEAC989C405D78BA06" + std::vector vec = helper.convert_from_hex_string( + "7CBE05D9970CFC9E22D0A43A340EF557624453A2E821AADEAC989C405D78BA06" "956380BAB0D2C939EC6208151040CCFFCF1FB7156178FD1255BA0AECAAA253F7" "407B6C5DD4DF059FF8789474061301E1C34881DB7A367A913A3674300E21EAB1" "24EF508389B7D446C3E2ECE8D459FBBD3239A794906F5B1F92469C640164FD87"); @@ -82,18 +100,16 @@ TEST_F(OsnmaMsgReceiverTest, ComputeMerkleRoot) dsm_pkr_message.npk = helper.convert_from_hex_string("0303B2CE64BC207BDD8BC4DF859187FCB686320D63FFA091410FC158FBB77980EA"); // Act - // ---------- computed_merkle_root = osnma->compute_merkle_root(dsm_pkr_message, base_leaf); // Assert - // ---------- ASSERT_EQ(computed_merkle_root, expected_merkle_root); } + TEST_F(OsnmaMsgReceiverTest, ComputeBaseLeaf) { // Arrange - // ---------- std::vector expected_base_leaf = helper.convert_from_hex_string("120303B2CE64BC207BDD8BC4DF859187FCB686320D63FFA091410FC158FBB77980EA"); DSM_PKR_message dsm_pkr_message; dsm_pkr_message.npkt = 0x01; @@ -101,63 +117,68 @@ TEST_F(OsnmaMsgReceiverTest, ComputeBaseLeaf) dsm_pkr_message.npk = helper.convert_from_hex_string("0303B2CE64BC207BDD8BC4DF859187FCB686320D63FFA091410FC158FBB77980EA"); // Act - // ---------- std::vector computed_base_leaf = osnma->get_merkle_tree_leaves(dsm_pkr_message); // Assert - // ---------- - ASSERT_EQ(computed_base_leaf,expected_base_leaf); + ASSERT_EQ(computed_base_leaf, expected_base_leaf); } -TEST_F(OsnmaMsgReceiverTest, VerifyPublicKey){ // values taken from RG A.7 + +TEST_F(OsnmaMsgReceiverTest, VerifyPublicKey) +{ + // values taken from RG A.7 // Arrange - // ---------- osnma->d_crypto->set_merkle_root(helper.convert_from_hex_string("A10C440F3AA62453526DB4AF76DF8D9410D35D8277397D7053C700D192702B0D")); DSM_PKR_message dsm_pkr_message; dsm_pkr_message.npkt = 0x01; dsm_pkr_message.npktid = 0x2; dsm_pkr_message.mid = 0x01; - std::vector vec = helper.convert_from_hex_string("7CBE05D9970CFC9E22D0A43A340EF557624453A2E821AADEAC989C405D78BA06" - "956380BAB0D2C939EC6208151040CCFFCF1FB7156178FD1255BA0AECAAA253F7" - "407B6C5DD4DF059FF8789474061301E1C34881DB7A367A913A3674300E21EAB1" - "24EF508389B7D446C3E2ECE8D459FBBD3239A794906F5B1F92469C640164FD87"); + std::vector vec = helper.convert_from_hex_string( + "7CBE05D9970CFC9E22D0A43A340EF557624453A2E821AADEAC989C405D78BA06" + "956380BAB0D2C939EC6208151040CCFFCF1FB7156178FD1255BA0AECAAA253F7" + "407B6C5DD4DF059FF8789474061301E1C34881DB7A367A913A3674300E21EAB1" + "24EF508389B7D446C3E2ECE8D459FBBD3239A794906F5B1F92469C640164FD87"); std::copy(vec.begin(), vec.end(), dsm_pkr_message.itn.begin()); dsm_pkr_message.npk = helper.convert_from_hex_string("0303B2CE64BC207BDD8BC4DF859187FCB686320D63FFA091410FC158FBB77980EA"); // Act - // ---------- bool result = osnma->verify_dsm_pkr(dsm_pkr_message); // Assert - // ---------- ASSERT_TRUE(result); - } + TEST_F(OsnmaMsgReceiverTest, BuildTagMessageM0) { // Arrange - // ---------- - // m0 - std::vector expected_message = { + std::vector expected_message = { 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 - }; + 0x02, 0x68, 0x05, 0x4A, 0x02, 0xC2, 0x26, 0x07, 0xF7, 0xFC, 0x00}; uint32_t TOW_Tag0 = 345660; uint32_t TOW_NavData = TOW_Tag0 - 30; - uint32_t TOW_Key_Tag0 = 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.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 = "000011101001011001000100000101000111010110100100100101100000000000011101101011001111101110101010000001010000011011111100000011101011011100101101011010101011011011001001110111101011110110111111001111001000011111101110011000111111110111111010000011101011111111110000110111000000100000001110110000110110001110000100001110101100010100110100010001000110001110011010110000111010000010000000000001101000000000000011100101100100010000000000000110110100110001111100000000000000100110100000000101010010100000001011000010001001100000011111110111111111000000000"; + osnma->d_satellite_nav_data[PRNa][TOW_NavData].set_ephemeris_iono_data( + "000011101001011001000100000101000111010110100100100101100000000000" + "011101101011001111101110101010000001010000011011111100000011101011" + "011100101101011010101011011011001001110111101011110110111111001111" + "001000011111101110011000111111110111111010000011101011111111110000" + "110111000000100000001110110000110110001110000100001110101100010100" + "110100010001000110001110011010110000111010000010000000000001101000" + "000000000011100101100100010000000000000110110100110001111100000000" + "000000100110100000000101010010100000001011000010001001100000011111" + "110111111111000000000"); osnma->d_osnma_data.d_nma_header.nmas = 0b10; MACK_tag_and_info MTI; @@ -167,34 +188,39 @@ TEST_F(OsnmaMsgReceiverTest, BuildTagMessageM0) MTI.tag_info.cop = 0x0F; Tag t0(MTI, TOW_Tag0, WN, PRNa, CTR); - - // Act - // ---------- auto computed_message = osnma->build_message(t0); - // Assert - // ---------- ASSERT_TRUE(computed_message == expected_message); - } -TEST_F(OsnmaMsgReceiverTest, TagVerification) { + +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 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, 0xDD, 0xBC, 0x73}; // K4 + 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, 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 = "000011101001011001000100000101000111010110100100100101100000000000011101101011001111101110101010000001010000011011111100000011101011011100101101011010101011011011001001110111101011110110111111001111001000011111101110011000111111110111111010000011101011111111110000110111000000100000001110110000110110001110000100001110101100010100110100010001000110001110011010110000111010000010000000000001101000000000000011100101100100010000000000000110110100110001111100000000000000100110100000000101010010100000001011000010001001100000011111110111111111000000000"; + osnma->d_satellite_nav_data[PRNa][TOW_NavData].set_ephemeris_iono_data(""); + osnma->d_satellite_nav_data[PRNa][TOW_NavData].set_ephemeris_iono_data( + "000011101001011001000100000101000111010110100100100101100000000000" + "011101101011001111101110101010000001010000011011111100000011101011" + "011100101101011010101011011011001001110111101011110110111111001111" + "001000011111101110011000111111110111111010000011101011111111110000" + "110111000000100000001110110000110110001110000100001110101100010100" + "110100010001000110001110011010110000111010000010000000000001101000" + "000000000011100101100100010000000000000110110100110001111100000000" + "000000100110100000000101010010100000001011000010001001100000011111" + "110111111111000000000"); osnma->d_osnma_data.d_nma_header.nmas = 0b10; MACK_tag_and_info MTI; @@ -204,34 +230,25 @@ TEST_F(OsnmaMsgReceiverTest, TagVerification) { 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 ; + 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, 0xDD, 0xBC, 0x73}; // K4 + 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].utc_vector_2 = + osnma->d_satellite_nav_data[PRNa][TOW_NavData].set_utc_data( "111111111111111111111111111111110000000000000000000000010001001001001000" - "111000001000100111100010010111111111011110111111111001001100000100000000"; + "111000001000100111100010010111111111011110111111111001001100000100000000"); osnma->d_osnma_data.d_nma_header.nmas = 0b10; MTI.tag = static_cast(0x7BB238C883); @@ -243,90 +260,78 @@ TEST_F(OsnmaMsgReceiverTest, TagVerification) { bool result_tag3 = osnma->verify_tag(t3); ASSERT_TRUE(result_tag0 && result_tag3); - } -TEST_F(OsnmaMsgReceiverTest, TeslaKeyVerification) { + +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 + 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 osnma->d_osnma_data.d_dsm_kroot_message.alpha = 0x610BDF26D77B; // local_time_verification would do this operation. TODO - eliminate duplication. 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_receiver_time = osnma->d_GST_0 + 30 * std::floor((osnma->d_GST_SIS - osnma->d_GST_0) / 30); // Eq. 3 R.G.//345630; + osnma->d_GST_0 = ((1248 & 0x00000FFF) << 20 | (345600 & 0x000FFFFF)); // applicable time (GST_Kroot + 30) + osnma->d_receiver_time = osnma->d_GST_0 + 30 * std::floor((osnma->d_GST_SIS - osnma->d_GST_0) / 30); // Eq. 3 R.G.//345630; - osnma->d_tesla_keys.insert((std::pair>(345600,{0xEF, 0xF9, 0x99, 0x04, 0x0E, 0x19, 0xB5, 0x70, 0x83, 0x50, 0x60, 0xBE, 0xBD, 0x23, 0xED, 0x92}))); // K1, not needed, just for reference. - std::vector key = {0x2D, 0xC3, 0xA3, 0xCD, 0xB1, 0x17, 0xFA, 0xAD, 0xB8, 0x3B, 0x5F, 0x0B, 0x6F, 0xEA, 0x88, 0xEB}; // K2 + osnma->d_tesla_keys.insert((std::pair>(345600, {0xEF, 0xF9, 0x99, 0x04, 0x0E, 0x19, 0xB5, 0x70, 0x83, 0x50, 0x60, 0xBE, 0xBD, 0x23, 0xED, 0x92}))); // K1, not needed, just for reference. + std::vector key = {0x2D, 0xC3, 0xA3, 0xCD, 0xB1, 0x17, 0xFA, 0xAD, 0xB8, 0x3B, 0x5F, 0x0B, 0x6F, 0xEA, 0x88, 0xEB}; // K2 uint32_t TOW = 345630; - - - // Act - // ---------- bool result = osnma->verify_tesla_key(key, TOW); - - - - // Assert - // ---------- ASSERT_TRUE(result); - } + TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) { // Arrange - // ---------- -// std::vector testVectors = readTestVectorsFromFile("/home/cgm/CLionProjects/osnma/data/16_AUG_2023_GST_05_00_01.csv"); // conf. 1 - std::vector testVectors = readTestVectorsFromFile("/home/cgm/CLionProjects/osnma/data/27_JUL_2023_GST_00_00_01.csv"); // conf. 2 - if (testVectors.empty()){ + std::vector testVectors = readTestVectorsFromFile("/home/cgm/CLionProjects/osnma/data/27_JUL_2023_GST_00_00_01.csv"); // conf. 2 + if (testVectors.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 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 + 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::cout << "OsnmaTestVectorsSimulation:" + << " d_GST_SIS= " << d_GST_SIS + << ", TOW=" << TOW + << ", WN=" << WN << std::endl; // Act - // ---------- - // loop over all bytes of data. Note: all TestVectors have same amount of data. - while (end_of_hex_stream == false){ + while (end_of_hex_stream == false) + { // 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; + 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(); 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_for_OSNMA; // structure containing and + 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_for_OSNMA; // structure containing and - for (int idx = 0; idx < SIZE_SUBFRAME_PAGES; ++idx) // extract all pages of a subframe + 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 page_bytes = extract_page_bytes(tv,byte_index,SIZE_PAGE_BYTES); - if(page_bytes.empty()){ - std::cout<< "OsnmaTestVectorsSimulation: end of TestVectors \n" << "byte_index="< data_k(even_page.substr(2,112)); - std::bitset<16> data_j(odd_page.substr(2,16)); + 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((shifted_data_k >>= 106).to_ulong()); // word type is the first 6 bits of the word - std::cout<< "OsnmaTestVectorsSimulation: received Word "<< static_cast(word_type) << std::endl; - if( (word_type >= 1 && word_type <=5) || word_type == 6 || word_type == 10) + uint8_t word_type = static_cast((shifted_data_k >>= 106).to_ulong()); // word type is the first 6 bits of the word + std::cout << "OsnmaTestVectorsSimulation: received Word " << static_cast(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) + if (word_type == DUMMY_PAGE) flag_dummy_page = true; // place it into osnma object. @@ -370,12 +376,13 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) byte_index += SIZE_PAGE_BYTES; } - std::cout<< "----------" << std::endl; - if(end_of_hex_stream) + std::cout << "----------" << std::endl; + if (end_of_hex_stream) break; - if(flag_dummy_page){ + if (flag_dummy_page) + { flag_dummy_page = false; - continue; // skip this SV + continue; // skip this SV } // Fill osnma object @@ -383,8 +390,8 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) 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 + osnmaMsg_sptr->WN_sf0 = (d_GST_SIS & 0xFFF00000) >> 20; + osnmaMsg_sptr->PRN = tv.svId; // PRNa // TODO - refactor this logic, currently it is split @@ -395,14 +402,14 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) 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; + 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) + if (ephClockStatusWordsReceived) { - // Define the starting position and length of bits to extract for each word std::map> extractionParams = { {1, {6, 120}}, @@ -414,7 +421,8 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) // Fill NavData bits -- Iterate over the extraction parameters std::string nav_data_ADKD_0_12 = ""; - for (const auto& param : extractionParams) { + for (const auto& param : extractionParams) + { uint8_t wordKey = param.first; uint8_t start = param.second.first; uint8_t length = param.second.second; @@ -424,16 +432,16 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) } // send to osnma block bool check_size_is_ok = nav_data_ADKD_0_12.size() == 549; - if(check_size_is_ok) + if (check_size_is_ok) { - std::cout << "Galileo OSNMA: sending ADKD=0/12 navData, PRN_d (" << tv.svId << ") " << "TOW_sf=" << osnmaMsg_sptr->TOW_sf0 <>( // < PRNd , navDataBits, TOW_Sosf> + 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>( // < 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(tv.svId) << ", TOW=" << static_cast(osnmaMsg_sptr->TOW_sf0) <<"): 0b" << nav_data_ADKD_0_12; + LOG(INFO) << "|---> Galileo OSNMA :: Telemetry Decoder NavData (PRN_d=" << static_cast(tv.svId) << ", TOW=" << static_cast(osnmaMsg_sptr->TOW_sf0) << "): 0b" << nav_data_ADKD_0_12; osnma->msg_handler_osnma(pmt::make_any(tmp_obj_osnma)); - } } @@ -441,12 +449,12 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) 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){ + if (timingWordsReceived) + { // Define the starting position and length of bits to extract for each word std::map> extractionParams = { {6, {6, 99}}, - {10, {86, 42}} - }; + {10, {86, 42}}}; std::string nav_data_ADKD_4 = ""; // Fill NavData bits -- Iterate over the extraction parameters @@ -461,63 +469,62 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) } // send to osnma block bool check_size_is_ok = nav_data_ADKD_4.size() == 141; - if(check_size_is_ok) + if (check_size_is_ok) { - std::cout << "Galileo OSNMA: sending ADKD=04 navData, PRN_d (" << tv.svId << ") " << "TOW_sf=" << osnmaMsg_sptr->TOW_sf0 <>( // < PRNd , navDataBits, TOW_Sosf> + 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>( // < 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(tv.svId) << ", TOW=" << static_cast(osnmaMsg_sptr->TOW_sf0) <<"): 0b" << nav_data_ADKD_4; + LOG(INFO) << "|---> Galileo OSNMA :: Telemetry Decoder NavData (PRN_d=" << static_cast(tv.svId) << ", TOW=" << static_cast(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 + osnma->msg_handler_osnma(temp_obj); // osnma entry point } - - if(!end_of_hex_stream){ - offset_byte = byte_index; // update offset for the next subframe + 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 + WN = (d_GST_SIS & 0xFFF00000) >> 20; + std::cout << "OsnmaTestVectorsSimulation:" + << " d_GST_SIS= " << d_GST_SIS << ", TOW=" << TOW << ", WN=" << WN << std::endl; } - - } - - // Assert - // ---------- // TODO - create global vars with failed tags and compare to total tags (Tag Id for example) } + // 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 OsnmaMsgReceiverTest::readTestVectorsFromFile(const std::string& filename) { std::ifstream file(filename); std::vector testVectors; - if (!file.is_open()) { - std::cerr<<"Error reading the file \"" << filename <<"\" \n"; + if (!file.is_open()) + { + std::cerr << "Error reading the file \"" << filename << "\" \n"; return testVectors; } std::string line; std::getline(file, line); - if (line != "SVID,NumNavBits,NavBitsHEX\r" ){ - std::cerr<<"Error parsing first line" <<"\n"; - } + if (line != "SVID,NumNavBits,NavBitsHEX\r") + { + std::cerr << "Error parsing first line" + << "\n"; + } while (std::getline(file, line)) { @@ -540,29 +547,35 @@ std::vector OsnmaMsgReceiverTest::readTestVectorsFromFile(const std: return testVectors; } + + std::vector OsnmaMsgReceiverTest::parseNavBits(const std::string& hex) { std::vector bytes; - for (unsigned int i = 0; i < hex.length()-1; i += 2) + for (unsigned int i = 0; i < hex.length() - 1; i += 2) { std::string byteString = hex.substr(i, 2); - uint8_t byte = (uint8_t) strtol(byteString.c_str(), NULL, 16); + uint8_t byte = (uint8_t)strtol(byteString.c_str(), NULL, 16); bytes.push_back(byte); } return bytes; } + + std::string OsnmaMsgReceiverTest::bytes_to_str(const std::vector& bytes) { std::string bit_string; bit_string.reserve(bytes.size() * 8); - for(const auto& byte : bytes) + for (const auto& byte : bytes) { std::bitset<8> bits(byte); bit_string += bits.to_string(); } return bit_string; } + + /** * @brief Extracts a range of bytes from a TestVector's navBits vector. * @@ -591,6 +604,8 @@ std::vector OsnmaMsgReceiverTest::extract_page_bytes(const TestVector& return extracted_bytes; } + + /** * @brief Sets the time based on the given input. * @@ -614,25 +629,24 @@ void OsnmaMsgReceiverTest::set_time(std::tm& input) uint32_t sec_in_week = 7 * 24 * 60 * 60; uint32_t week_number = duration_sec.count() / sec_in_week; uint32_t time_of_week = duration_sec.count() % sec_in_week; - this->WN = week_number; - this->TOW = time_of_week + LEAP_SECONDS; + this->WN = week_number; + this->TOW = time_of_week + LEAP_SECONDS; // Return the week number and time of week as a pair // TODO: d_GST_SIS or d_receiver_time? doubt // I am assuming that local realisation of receiver is identical to SIS GST time coming from W5 or W0 - this->d_GST_SIS = (this->WN & 0x00000FFF) << 20 | (this->TOW & 0x000FFFFF); - - + this->d_GST_SIS = (this->WN & 0x00000FFF) << 20 | (this->TOW & 0x000FFFFF); } + + void OsnmaMsgReceiverTest::initializeGoogleLog() { - google::InitGoogleLogging(log_name.c_str()); // TODO - running all tests causes conflict due to being called twice - FLAGS_minloglevel = 0; // INFO - FLAGS_logtostderr = 0; // add this line + google::InitGoogleLogging(log_name.c_str()); // TODO - running all tests causes conflict due to being called twice + FLAGS_minloglevel = 0; // INFO + FLAGS_logtostderr = 0; // add this line FLAGS_log_dir = "/home/cgm/CLionProjects/osnma/data/build/src/tests/logs"; if (FLAGS_log_dir.empty()) { - std::cout << "Logging will be written at " << std::filesystem::temp_directory_path() << '\n' @@ -667,4 +681,3 @@ void OsnmaMsgReceiverTest::initializeGoogleLog() } } } - From 49eb854b162f9a3f9406d2ccd32fb0ee2401eac6 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 23 Jul 2024 16:51:59 +0200 Subject: [PATCH 2/6] Fix formatting --- cmake/Modules/GnssSdrCrypto.cmake | 2 +- .../galileo_telemetry_decoder_gs.cc | 17 ++++++----- src/core/libs/osnma_msg_receiver.h | 4 +-- src/core/system_parameters/Galileo_OSNMA.h | 3 +- src/core/system_parameters/osnma_data.cc | 2 +- src/core/system_parameters/osnma_data.h | 2 +- src/core/system_parameters/osnma_helper.h | 28 +++++++++---------- 7 files changed, 28 insertions(+), 30 deletions(-) diff --git a/cmake/Modules/GnssSdrCrypto.cmake b/cmake/Modules/GnssSdrCrypto.cmake index b1edb5982..5286c6d01 100644 --- a/cmake/Modules/GnssSdrCrypto.cmake +++ b/cmake/Modules/GnssSdrCrypto.cmake @@ -127,7 +127,7 @@ else() set(GNUTLS_HMAC_INIT_WITH_DIGEST TRUE) endif() if("${gnutls_gnutls_file_contents}" MATCHES "GNUTLS_MAC_AES_CMAC_128") - set(GNUTLS_MAC_AES_CMAC_128 TRUE) + set(GNUTLS_MAC_AES_CMAC_128 TRUE) endif() file(READ "${GNUTLS_INCLUDE_DIR}/gnutls/abstract.h" gnutls_abstract_file_contents) if("${gnutls_abstract_file_contents}" MATCHES "gnutls_pubkey_export2") diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc index 4fe185501..156194544 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc @@ -45,6 +45,7 @@ #include // for std::numeric_limits #include // for std::map #include // for std::out_of_range +#include // for std::tuple #include // for typeid #include // for std::pair @@ -468,7 +469,7 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in d_inav_nav.reset_osnma_nav_bits_adkd4(); } - if (d_inav_nav.have_new_ephemeris() == true) // C: tells if W1-->W4 available from same blcok (and W5!) + if (d_inav_nav.have_new_ephemeris() == true) // C: tells if W1-->W4 available from same blcok (and W5!) { // get object for this SV (mandatory) const std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_ephemeris()); @@ -503,7 +504,7 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in else { // If we still do not have ephemeris, check if we have a reduced CED - if ((d_band == '1') && d_use_ced && !d_first_eph_sent && (d_inav_nav.have_new_reduced_ced() == true)) // C: W16 has some Eph. params, uneeded for OSNMa I guess + if ((d_band == '1') && d_use_ced && !d_first_eph_sent && (d_inav_nav.have_new_reduced_ced() == true)) // C: W16 has some Eph. params, uneeded for OSNMa I guess { const std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_reduced_ced()); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); @@ -519,7 +520,7 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in } } - if (d_inav_nav.have_new_iono_and_GST() == true) // C: W5 + if (d_inav_nav.have_new_iono_and_GST() == true) // C: W5 { // get object for this SV (mandatory) const std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_iono()); @@ -550,7 +551,7 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in } } - if (d_inav_nav.have_new_utc_model() == true) // C: tells if W6 is available + if (d_inav_nav.have_new_utc_model() == true) // C: tells if W6 is available { // get object for this SV (mandatory) const std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_utc_model()); @@ -587,7 +588,7 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in flag_osnma_adkd_4_utc = true; } - if (d_inav_nav.have_new_almanac() == true) // flag_almanac_4 tells if W10 available. + if (d_inav_nav.have_new_almanac() == true) // flag_almanac_4 tells if W10 available. { const std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_almanac()); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); @@ -623,19 +624,17 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in } // get osnma message if the needed nav data is available - bool adkd_4_nav_data_available = flag_osnma_adkd_4_utc && flag_osnma_adkd_4_gst; // supposition: data did not change bt. flags reset and now. + bool adkd_4_nav_data_available = flag_osnma_adkd_4_utc && flag_osnma_adkd_4_gst; // supposition: data did not change bt. flags reset and now. // bool adkd_4_nav_data_available = d_inav_nav.get_osnma_adkd_4_nav_bits().size() == 141; // newApproach: let decoder decide when block starts and let it fill the data, and just check for length - if(adkd_4_nav_data_available /*&& d_inav_nav.is_TOW5_set() not needed cause W6 has TOW also.*/) + if (adkd_4_nav_data_available /*&& d_inav_nav.is_TOW5_set() not needed cause W6 has TOW also.*/) { } auto newOSNMA = d_inav_nav.have_new_nma(); if (d_band == '1' && newOSNMA) { const std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_osnma_msg()); - this->message_port_pub(pmt::mp("OSNMA_from_TLM"), pmt::make_any(tmp_obj)); - } } diff --git a/src/core/libs/osnma_msg_receiver.h b/src/core/libs/osnma_msg_receiver.h index 40ac73e78..c554f861a 100644 --- a/src/core/libs/osnma_msg_receiver.h +++ b/src/core/libs/osnma_msg_receiver.h @@ -96,8 +96,8 @@ private: std::vector verify_macseq_new(const MACK_message& mack); std::map> d_satellite_nav_data; // map holding OSNMA_NavData sorted by SVID (first key) and TOW (second key). - std::map> d_tesla_keys; // tesla keys over time, sorted by TOW - std::multimap d_tags_awaiting_verify; // container with tags to verify from arbitrary SVIDs, sorted by TOW + std::map> d_tesla_keys; // tesla keys over time, sorted by TOW + std::multimap d_tags_awaiting_verify; // container with tags to verify from arbitrary SVIDs, sorted by TOW std::vector d_tags_to_verify{0, 4, 12}; std::vector d_macks_awaiting_MACSEQ_verification; diff --git a/src/core/system_parameters/Galileo_OSNMA.h b/src/core/system_parameters/Galileo_OSNMA.h index 6032be061..09f615e08 100644 --- a/src/core/system_parameters/Galileo_OSNMA.h +++ b/src/core/system_parameters/Galileo_OSNMA.h @@ -193,8 +193,7 @@ const std::unordered_map OSNMA_TABLE_16 = { {38, {2, 5, {"00S", "FLX", "04S", "FLX", "12S"}, {"00S", "FLX", "FLX", "12S", "FLX"}}}, {39, {2, 4, {"00S", "FLX", "04S", "FLX"}, {"00S", "FLX", "00E", "12S"}}}, {40, {2, 4, {"00S", "00E", "04S", "12S"}, {"00S", "00E", "00E", "12E"}}}, - {41, {2, 4, {"00S", "FLX", "04S", "FLX"}, {"00S", "FLX", "FLX", "12S"}}} -}; + {41, {2, 4, {"00S", "FLX", "04S", "FLX"}, {"00S", "FLX", "FLX", "12S"}}}}; /** \} */ /** \} */ diff --git a/src/core/system_parameters/osnma_data.cc b/src/core/system_parameters/osnma_data.cc index 91a32a1f3..1e37ed26f 100644 --- a/src/core/system_parameters/osnma_data.cc +++ b/src/core/system_parameters/osnma_data.cc @@ -39,7 +39,7 @@ std::string OSNMA_NavData::get_utc_data() const uint32_t OSNMA_NavData::get_tow_sf0() const { - return d_TOW_sf0; + return d_TOW_sf0; } diff --git a/src/core/system_parameters/osnma_data.h b/src/core/system_parameters/osnma_data.h index 910ee3e2d..cbdaa9c9a 100644 --- a/src/core/system_parameters/osnma_data.h +++ b/src/core/system_parameters/osnma_data.h @@ -182,7 +182,7 @@ public: skipped(0) { } - Tag(const MACK_message& mack) // constructor for Tag0 + explicit Tag(const MACK_message& mack) // constructor for Tag0 : tag_id(id_counter++), TOW(mack.TOW), // TODO missing for build_message WN for GST computation, CTR, NMAS, OSNMA_NavData missing WN(mack.WN), diff --git a/src/core/system_parameters/osnma_helper.h b/src/core/system_parameters/osnma_helper.h index 07a3c457f..1e0eae235 100644 --- a/src/core/system_parameters/osnma_helper.h +++ b/src/core/system_parameters/osnma_helper.h @@ -1,18 +1,18 @@ /*! -* \file osnma_helper.h -* \brief Class for auxiliary osnma functions -* \author Carles Fernandez-Prades, 2024 cfernandez(at)cttc.es -* -* ----------------------------------------------------------------------------- -* -* GNSS-SDR is a Global Navigation Satellite System software-defined receiver. -* This file is part of GNSS-SDR. -* -* Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors) -* SPDX-License-Identifier: GPL-3.0-or-later -* -* ----------------------------------------------------------------------------- -*/ + * \file osnma_helper.h + * \brief Class for auxiliary osnma functions + * \author Carles Fernandez-Prades, 2024 cfernandez(at)cttc.es + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2023 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ #ifndef GNSS_SDR_OSNMA_HELPER_H #define GNSS_SDR_OSNMA_HELPER_H From 70315ecfae59373402d997aefb40ae8d0014427b Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Tue, 23 Jul 2024 17:32:47 +0200 Subject: [PATCH 3/6] Fix formatting --- src/tests/single_test_main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/single_test_main.cc b/src/tests/single_test_main.cc index c0a6e1dee..27dc60c17 100644 --- a/src/tests/single_test_main.cc +++ b/src/tests/single_test_main.cc @@ -18,8 +18,8 @@ #include "concurrent_map.h" #include "concurrent_queue.h" -#include "gps_acq_assist.h" #include "gnss_sdr_flags.h" +#include "gps_acq_assist.h" #include #include #include From fe9ebb70f1cc8ce60d339a9a9acc8135b9fa0524 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jul 2024 19:05:31 +0200 Subject: [PATCH 4/6] Fix building local Armadillo with old CMake --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 120505397..638a5e08d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -361,6 +361,10 @@ set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7") set(GNSSSDR_ABSL_LOCAL_VERSION "origin/master") # live at head (see https://abseil.io/about/releases) # Downgrade versions if requirements are not met +if(CMAKE_VERSION VERSION_LESS "3.5") + set(GNSSSDR_ARMADILLO_LOCAL_VERSION "12.8.x") +endif() + if(CMAKE_VERSION VERSION_LESS "3.22") set(GNSSSDR_GLOG_LOCAL_VERSION "0.6.0") endif() From 8ff339671b26e00df1b7304a24b1a5e8d5b44c17 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jul 2024 20:39:40 +0200 Subject: [PATCH 5/6] Code cleaning --- .../galileo_telemetry_decoder_gs.cc | 8 ++++++-- src/core/system_parameters/galileo_inav_message.cc | 5 ----- src/core/system_parameters/galileo_inav_message.h | 10 ++++++++-- src/core/system_parameters/gnss_crypto.cc | 14 +++++++------- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc index 156194544..e83bfb05c 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc @@ -452,7 +452,9 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in d_inav_nav.get_osnma_adkd_0_12_nav_bits(), d_inav_nav.get_TOW5() - 25); this->message_port_pub(pmt::mp("OSNMA_from_TLM"), pmt::make_any(tmp_obj_osnma)); - DLOG(INFO) << "|---> Galileo OSNMA :: Sending Telemetry Decoder NavData (PRN_d=" << static_cast(d_satellite.get_PRN()) << ", TOW=" << static_cast(d_inav_nav.get_TOW5() - 25) << ")"; //: 0b" << d_inav_nav.get_osnma_adkd_0_12_nav_bits(); + DLOG(INFO) << "|---> Galileo OSNMA :: Sending Telemetry Decoder NavData (PRN_d=" + << static_cast(d_satellite.get_PRN()) + << ", TOW=" << static_cast(d_inav_nav.get_TOW5() - 25) << ")"; //: 0b" << d_inav_nav.get_osnma_adkd_0_12_nav_bits(); d_inav_nav.reset_osnma_nav_bits_adkd0_12(); } @@ -465,7 +467,9 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in d_inav_nav.get_osnma_adkd_4_nav_bits(), d_inav_nav.get_TOW6() - 5); this->message_port_pub(pmt::mp("OSNMA_from_TLM"), pmt::make_any(tmp_obj)); - DLOG(INFO) << "|---> Galileo OSNMA :: Sending Telemetry Decoder NavData (PRN_d=" << static_cast(d_satellite.get_PRN()) << ", TOW=" << static_cast(d_inav_nav.get_TOW6() - 5) << ")"; //: 0b" << d_inav_nav.get_osnma_adkd_4_nav_bits(); + DLOG(INFO) << "|---> Galileo OSNMA :: Sending Telemetry Decoder NavData (PRN_d=" + << static_cast(d_satellite.get_PRN()) + << ", TOW=" << static_cast(d_inav_nav.get_TOW6() - 5) << ")"; //: 0b" << d_inav_nav.get_osnma_adkd_4_nav_bits(); d_inav_nav.reset_osnma_nav_bits_adkd4(); } diff --git a/src/core/system_parameters/galileo_inav_message.cc b/src/core/system_parameters/galileo_inav_message.cc index c5ddcbfaa..ab62b684c 100644 --- a/src/core/system_parameters/galileo_inav_message.cc +++ b/src/core/system_parameters/galileo_inav_message.cc @@ -380,10 +380,6 @@ bool Galileo_Inav_Message::have_new_utc_model() // Check if we have a new utc d // flag_almanac_4 tells if W10 available. bool Galileo_Inav_Message::have_new_almanac() // Check if we have a new almanac data set stored in the galileo navigation class { - // if(flag_almanac_4) - // { - // flag_adkd_4_complete = true; - // } if ((flag_almanac_1 == true) and (flag_almanac_2 == true) and (flag_almanac_3 == true) and (flag_almanac_4 == true)) { // All Almanac data have been received @@ -1451,7 +1447,6 @@ bool Galileo_Inav_Message::have_new_nma() std::string Galileo_Inav_Message::get_osnma_adkd_4_nav_bits() { nav_bits_adkd_4 = nav_bits_word_6 + nav_bits_word_10; - return nav_bits_adkd_4; } diff --git a/src/core/system_parameters/galileo_inav_message.h b/src/core/system_parameters/galileo_inav_message.h index 2ecb8aa53..820478c77 100644 --- a/src/core/system_parameters/galileo_inav_message.h +++ b/src/core/system_parameters/galileo_inav_message.h @@ -141,15 +141,21 @@ public: * @brief Retrieves the OSNMA ADKD 4 NAV bits. Resets the string. */ std::string get_osnma_adkd_4_nav_bits(); + + /* + * @brief Resets the OSNMA ADKD 4 NAV bits. + */ void reset_osnma_nav_bits_adkd4(); - bool flag_adkd_4_complete{false}; /* * @brief Retrieves the OSNMA ADKD 0/12 NAV bits. Resets the string. */ std::string get_osnma_adkd_0_12_nav_bits(); + + /* + * @brief Resets the OSNMA ADKD 0/12 NAV bits. + */ void reset_osnma_nav_bits_adkd0_12(); - bool flag_adkd_0_12_complete{false}; inline bool get_flag_CRC_test() const { diff --git a/src/core/system_parameters/gnss_crypto.cc b/src/core/system_parameters/gnss_crypto.cc index 9ff183ed3..fa47720b1 100644 --- a/src/core/system_parameters/gnss_crypto.cc +++ b/src/core/system_parameters/gnss_crypto.cc @@ -225,7 +225,7 @@ bool Gnss_Crypto::verify_signature_ecdsa_p256(const std::vector& messag success = (ret >= 0); if (success) { - LOG(INFO) << "GnuTLS: OSNMA signature authenticated successfully"; + DLOG(INFO) << "GnuTLS: OSNMA signature authenticated successfully"; } else { @@ -301,7 +301,7 @@ bool Gnss_Crypto::verify_signature_ecdsa_p256(const std::vector& messag if (verification == 1) { success = true; - LOG(INFO) << "OpenSSL: OSNMA signature authenticated successfully"; + DLOG(INFO) << "OpenSSL: OSNMA signature authenticated successfully"; } else { @@ -320,7 +320,7 @@ bool Gnss_Crypto::verify_signature_ecdsa_p256(const std::vector& messag if (verification == 1) { success = true; - LOG(INFO) << "OpenSSL: OSNMA signature authenticated successfully"; + DLOG(INFO) << "OpenSSL: OSNMA signature authenticated successfully"; } else if (verification == 0) { @@ -379,7 +379,7 @@ bool Gnss_Crypto::verify_signature_ecdsa_p521(const std::vector& messag if (ret >= 0) { - LOG(INFO) << "GnuTLS: OSNMA signature authenticated successfully"; + DLOG(INFO) << "GnuTLS: OSNMA signature authenticated successfully"; success = true; } else @@ -428,7 +428,7 @@ bool Gnss_Crypto::verify_signature_ecdsa_p521(const std::vector& messag if (verification == 1) { - LOG(INFO) << "OpenSSL: OSNMA signature authenticated successfully"; + DLOG(INFO) << "OpenSSL: OSNMA signature authenticated successfully"; success = true; } else if (verification == 0) @@ -451,7 +451,7 @@ bool Gnss_Crypto::verify_signature_ecdsa_p521(const std::vector& messag ECDSA_SIG_free(ecdsa_sig); if (verification == 1) { - LOG(INFO) << "OpenSSL: OSNMA signature authenticated successfully"; + DLOG(INFO) << "OpenSSL: OSNMA signature authenticated successfully"; success = true; } else if (verification == 0) @@ -896,7 +896,7 @@ void Gnss_Crypto::set_public_key(const std::vector& publicKey) #endif // OpenSSL 1.x EVP_PKEY_free(pkey); #endif - LOG(INFO) << "OSNMA Public Key successfully set up."; + DLOG(INFO) << "OSNMA Public Key successfully set up."; } From 8a208d57d8132a93e4e7d08a5d02645fb6ad1f4d Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 24 Jul 2024 21:02:39 +0200 Subject: [PATCH 6/6] Add benchmarks for cryptographic functions --- src/tests/benchmarks/CMakeLists.txt | 9 +- src/tests/benchmarks/benchmark_crypto.cc | 213 +++++++++++++++++++++++ 2 files changed, 218 insertions(+), 4 deletions(-) create mode 100644 src/tests/benchmarks/benchmark_crypto.cc diff --git a/src/tests/benchmarks/CMakeLists.txt b/src/tests/benchmarks/CMakeLists.txt index 28bddd050..74607d1a1 100644 --- a/src/tests/benchmarks/CMakeLists.txt +++ b/src/tests/benchmarks/CMakeLists.txt @@ -109,11 +109,12 @@ if(ENABLE_GLOG_AND_GFLAGS) set(EXTRA_BENCHMARK_DEPENDENCIES "Gflags::gflags;Glog::glog") endif() -add_benchmark(benchmark_copy) -add_benchmark(benchmark_preamble core_system_parameters ${EXTRA_BENCHMARK_DEPENDENCIES}) -add_benchmark(benchmark_detector core_system_parameters ${EXTRA_BENCHMARK_DEPENDENCIES}) -add_benchmark(benchmark_reed_solomon core_system_parameters ${EXTRA_BENCHMARK_DEPENDENCIES}) add_benchmark(benchmark_atan2 Gnuradio::runtime) +add_benchmark(benchmark_copy) +add_benchmark(benchmark_crypto core_system_parameters ${EXTRA_BENCHMARK_DEPENDENCIES}) +add_benchmark(benchmark_detector core_system_parameters ${EXTRA_BENCHMARK_DEPENDENCIES}) +add_benchmark(benchmark_preamble core_system_parameters ${EXTRA_BENCHMARK_DEPENDENCIES}) +add_benchmark(benchmark_reed_solomon core_system_parameters ${EXTRA_BENCHMARK_DEPENDENCIES}) if(has_std_plus_void) target_compile_definitions(benchmark_detector PRIVATE -DCOMPILER_HAS_STD_PLUS_VOID=1) diff --git a/src/tests/benchmarks/benchmark_crypto.cc b/src/tests/benchmarks/benchmark_crypto.cc new file mode 100644 index 000000000..43d5f1035 --- /dev/null +++ b/src/tests/benchmarks/benchmark_crypto.cc @@ -0,0 +1,213 @@ +/*! + * \file benchmark_crypto.cc + * \brief Benchmarks for cryptographic functions + * \author Carles Fernandez-Prades, 2024. cfernandez(at)cttc.es + * + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2024 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "gnss_crypto.h" +#include + +void bm_SHA_256(benchmark::State& state) +{ + auto d_crypto = std::make_unique(); + + std::vector message{ + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; + + while (state.KeepRunning()) + { + std::vector output = d_crypto->compute_SHA_256(message); + } +} + + +void bm_SHA3_256(benchmark::State& state) +{ + auto d_crypto = std::make_unique(); + + std::vector message{ + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; + + while (state.KeepRunning()) + { + std::vector output = d_crypto->compute_SHA3_256(message); + } +} + + +void bm_HMAC_SHA_256(benchmark::State& state) +{ + auto d_crypto = std::make_unique(); + + std::vector key = { + 0x24, 0x24, 0x3B, 0x76, 0xF9, 0x14, 0xB1, 0xA7, + 0x7D, 0x48, 0xE7, 0xF1, 0x48, 0x0C, 0xC2, 0x98, + 0xEB, 0x62, 0x3E, 0x95, 0x6B, 0x2B, 0xCE, 0xA3, + 0xB4, 0xD4, 0xDB, 0x31, 0xEE, 0x96, 0xAB, 0xFA}; + + std::vector message{ + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x0A}; + + while (state.KeepRunning()) + { + std::vector output = d_crypto->compute_HMAC_SHA_256(key, message); + } +} + + +void bm_CMAC_AES(benchmark::State& state) +{ + auto d_crypto = std::make_unique(); + + std::vector key = { + 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C}; + + std::vector message{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A}; + + while (state.KeepRunning()) + { + std::vector output = d_crypto->compute_CMAC_AES(key, message); + } +} + + +void bm_verify_ecdsa_p256(benchmark::State& state) +{ + auto d_crypto = std::make_unique(); + + // RG example - import crt certificate + std::vector message = { + 0x82, 0x10, 0x49, 0x22, 0x04, 0xE0, 0x60, 0x61, 0x0B, 0xDF, + 0x26, 0xD7, 0x7B, 0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04, + 0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF}; + + // ECDSA P-256 signature, raw format + std::vector signature = { + 0xF8, 0xCD, 0x88, 0x29, 0x9F, 0xA4, 0x60, 0x58, 0x00, 0x20, + 0x7B, 0xFE, 0xBE, 0xAC, 0x55, 0x02, 0x40, 0x53, 0xF3, 0x0F, + 0x7C, 0x69, 0xB3, 0x5C, 0x15, 0xE6, 0x08, 0x00, 0xAC, 0x3B, + 0x6F, 0xE3, 0xED, 0x06, 0x39, 0x95, 0x2F, 0x7B, 0x02, 0x8D, + 0x86, 0x86, 0x74, 0x45, 0x96, 0x1F, 0xFE, 0x94, 0xFB, 0x22, + 0x6B, 0xFF, 0x70, 0x06, 0xE0, 0xC4, 0x51, 0xEE, 0x3F, 0x87, + 0x28, 0xC1, 0x77, 0xFB}; + + // PEM format + std::vector publicKey = { + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, + 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, + 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, + 0x77, 0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49, 0x7A, + 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, + 0x49, 0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, + 0x67, 0x41, 0x45, 0x41, 0x37, 0x4C, 0x4F, 0x5A, 0x4C, 0x77, + 0x67, 0x65, 0x39, 0x32, 0x4C, 0x78, 0x4E, 0x2B, 0x46, 0x6B, + 0x59, 0x66, 0x38, 0x74, 0x6F, 0x59, 0x79, 0x44, 0x57, 0x50, + 0x2F, 0x0A, 0x6F, 0x4A, 0x46, 0x42, 0x44, 0x38, 0x46, 0x59, + 0x2B, 0x37, 0x64, 0x35, 0x67, 0x4F, 0x71, 0x49, 0x61, 0x45, + 0x32, 0x52, 0x6A, 0x50, 0x41, 0x6E, 0x4B, 0x49, 0x36, 0x38, + 0x73, 0x2F, 0x4F, 0x4B, 0x2F, 0x48, 0x50, 0x67, 0x6F, 0x4C, + 0x6B, 0x4F, 0x32, 0x69, 0x6A, 0x51, 0x38, 0x78, 0x41, 0x5A, + 0x79, 0x44, 0x64, 0x50, 0x42, 0x31, 0x64, 0x48, 0x53, 0x51, + 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, + 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, + 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A}; + + d_crypto->set_public_key(publicKey); + + while (state.KeepRunning()) + { + bool output = d_crypto->verify_signature_ecdsa_p256(message, signature); + if (output) + { + // Avoid unused-but-set-variable warning + } + } +} + + +void bm_verify_ecdsa_p521(benchmark::State& state) +{ + std::unique_ptr d_crypto = std::make_unique(); + + // Message to be verified + std::vector message = { + 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64}; + + // Public key in PEM format + std::vector publicKey = { + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, + 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, + 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x47, 0x62, 0x4D, 0x42, 0x41, 0x47, 0x42, + 0x79, 0x71, 0x47, 0x53, 0x4D, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x42, + 0x53, 0x75, 0x42, 0x42, 0x41, 0x41, 0x6A, 0x41, 0x34, 0x47, 0x47, 0x41, + 0x41, 0x51, 0x41, 0x6F, 0x35, 0x76, 0x77, 0x66, 0x6E, 0x47, 0x57, 0x47, + 0x33, 0x44, 0x63, 0x59, 0x75, 0x2B, 0x2F, 0x61, 0x58, 0x47, 0x32, 0x7A, + 0x74, 0x65, 0x41, 0x46, 0x50, 0x54, 0x33, 0x0A, 0x48, 0x36, 0x4C, 0x76, + 0x4F, 0x4C, 0x76, 0x49, 0x51, 0x6A, 0x61, 0x2B, 0x6A, 0x74, 0x57, 0x73, + 0x70, 0x4F, 0x38, 0x37, 0x6F, 0x50, 0x32, 0x4E, 0x6D, 0x72, 0x34, 0x6E, + 0x50, 0x68, 0x76, 0x62, 0x53, 0x58, 0x52, 0x4D, 0x37, 0x6A, 0x49, 0x69, + 0x46, 0x38, 0x47, 0x70, 0x6B, 0x75, 0x58, 0x6A, 0x75, 0x4E, 0x7A, 0x34, + 0x72, 0x61, 0x56, 0x4F, 0x65, 0x49, 0x4D, 0x42, 0x77, 0x45, 0x2B, 0x61, + 0x0A, 0x30, 0x4C, 0x76, 0x7A, 0x37, 0x69, 0x54, 0x4D, 0x5A, 0x46, 0x41, + 0x41, 0x51, 0x64, 0x2B, 0x70, 0x47, 0x72, 0x56, 0x54, 0x47, 0x77, 0x66, + 0x53, 0x48, 0x49, 0x72, 0x49, 0x49, 0x45, 0x78, 0x74, 0x5A, 0x35, 0x77, + 0x30, 0x38, 0x51, 0x4F, 0x43, 0x58, 0x2F, 0x75, 0x46, 0x65, 0x2B, 0x30, + 0x78, 0x52, 0x78, 0x4C, 0x64, 0x2F, 0x33, 0x36, 0x42, 0x4E, 0x74, 0x63, + 0x74, 0x69, 0x2F, 0x45, 0x4C, 0x0A, 0x4B, 0x31, 0x35, 0x67, 0x2B, 0x4B, + 0x32, 0x71, 0x67, 0x2F, 0x6C, 0x39, 0x46, 0x42, 0x47, 0x67, 0x4D, 0x2B, + 0x51, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, + 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x0A}; + + // ECDSA P-521 signature, raw format + std::vector signature = { + 0x01, 0x7B, 0x59, 0xAC, 0x3A, 0x03, 0x5C, 0xB4, 0x07, 0xCD, + 0xC1, 0xEB, 0xBE, 0xE5, 0xA6, 0xCB, 0xDA, 0x0A, 0xFF, 0x4D, + 0x38, 0x61, 0x16, 0x0F, 0xB3, 0x77, 0xE5, 0x8A, 0xDC, 0xF3, + 0xFD, 0x79, 0x38, 0x1E, 0xE8, 0x08, 0x3D, 0x5D, 0xBC, 0xC2, + 0x80, 0x6E, 0xE9, 0x2B, 0xC3, 0xEF, 0x07, 0x3D, 0x0C, 0x82, + 0x4C, 0x9B, 0x7A, 0x5C, 0x2E, 0xD5, 0x46, 0xBD, 0x22, 0x21, + 0x13, 0x8A, 0xB2, 0xCA, 0x96, 0x3D, 0x01, 0xBA, 0x2A, 0xC4, + 0x3F, 0xDB, 0x66, 0x3C, 0x40, 0x26, 0xD9, 0xBC, 0x26, 0xD5, + 0x57, 0xD4, 0xBD, 0x15, 0x16, 0x88, 0x21, 0x3B, 0xAA, 0x07, + 0x89, 0xEF, 0x29, 0x8F, 0x2F, 0x85, 0x76, 0x58, 0x9D, 0xCA, + 0x00, 0xCC, 0xC8, 0x30, 0x88, 0x31, 0x99, 0xC1, 0x94, 0xB9, + 0xAF, 0x91, 0xDC, 0xC4, 0x6F, 0x19, 0x2B, 0x12, 0xA2, 0x82, + 0xA5, 0x66, 0x5E, 0x4B, 0xBB, 0xDF, 0x65, 0x81, 0x52, 0x14, + 0x01, 0xD7}; + + d_crypto->set_public_key(publicKey); + + while (state.KeepRunning()) + { + bool output = d_crypto->verify_signature_ecdsa_p521(message, signature); + if (output) + { + // Avoid unused-but-set-variable warning + } + } +} + + +BENCHMARK(bm_SHA_256); +BENCHMARK(bm_SHA3_256); +BENCHMARK(bm_HMAC_SHA_256); +BENCHMARK(bm_CMAC_AES); +BENCHMARK(bm_verify_ecdsa_p256); +BENCHMARK(bm_verify_ecdsa_p521); + +BENCHMARK_MAIN();