mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-31 15:23:04 +00:00 
			
		
		
		
	Code cleaning
This commit is contained in:
		| @@ -369,6 +369,8 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in | ||||
|     // 1. De-interleave | ||||
|     std::vector<float> 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 <<std::endl; | ||||
|             const auto tmp_obj_osnma = std::make_shared<std::tuple<uint32_t, std::string,uint32_t>>( // < 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<std::tuple<uint32_t, std::string, uint32_t>>(  // < 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<int>(d_satellite.get_PRN()) << ", TOW=" << static_cast<int>(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<int>(d_satellite.get_PRN()) << ", TOW=" << static_cast<int>(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 <<std::endl; | ||||
|  | ||||
|             const auto tmp_obj = std::make_shared<std::tuple<uint32_t, std::string,uint32_t>>( // < 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<std::tuple<uint32_t, std::string, uint32_t>>(  // < 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<int>(d_satellite.get_PRN()) << ", TOW=" << static_cast<int>(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<int>(d_satellite.get_PRN()) << ", TOW=" << static_cast<int>(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<double>(d_TOW_at_current_symbol_ms) / 1000.0 - tmp_obj->t_0G + 604800 * (std::fmod(static_cast<float>(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.*/) | ||||
|   | ||||
| @@ -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 | ||||
| }; | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -25,6 +25,7 @@ | ||||
| #include "osnma_dsm_reader.h"  // for OSNMA_DSM_Reader | ||||
| #include "osnma_helper.h" | ||||
| #include <gnuradio/io_signature.h>  // for gr::io_signature::make | ||||
| #include <algorithm> | ||||
| #include <cmath> | ||||
| #include <cstddef> | ||||
| #include <iomanip>  // for std::setfill | ||||
| @@ -32,6 +33,7 @@ | ||||
| #include <iostream> | ||||
| #include <numeric>  // for std::accumulate | ||||
| #include <sstream>  // std::stringstream | ||||
| #include <tuple> | ||||
| #include <typeinfo>  // for typeid | ||||
| #include <utility> | ||||
|  | ||||
| @@ -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<uint8_t>& dsm_msg | ||||
|                                       << ", WN=" << static_cast<uint32_t>(d_osnma_data.d_dsm_kroot_message.wn_k) | ||||
|                                       << ", TOW=" << static_cast<uint32_t>(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_ptr<OSNMA | ||||
|             index = index + 4; | ||||
|         } | ||||
|  | ||||
|     // update the structure with newly coming NavData | ||||
|     // update the structure with newly coming OSNMA_NavData | ||||
|     d_osnma_data.d_nav_data.init(osnma_msg); | ||||
|  | ||||
|     if (d_kroot_verified || d_tesla_key_verified || d_osnma_data.d_dsm_kroot_message.ts != 0 /*mack parser needs to know the tag size, otherwise cannot parse mack messages*/)  // C: 4 ts <  ts < 10 | ||||
|         {// TODO - correct? with this, MACK would not be processed unless a Kroot is available -- no, if TK available MACK sould go on, this has to change in future | ||||
|         {                                                                                                                                                                       // TODO - correct? with this, MACK would not be processed unless a Kroot is available -- no, if TK available MACK sould go on, this has to change in future | ||||
|             read_mack_header(); | ||||
|             d_osnma_data.d_mack_message.PRNa = osnma_msg->PRN;  // 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<OSNMA | ||||
|             read_mack_body(); | ||||
|             process_mack_message(); | ||||
|             // TODO - shorten the MACK processing for the cases where no TK verified or no Kroot verified (warm and cold start) | ||||
|             // still, for instance the NAvData and Mack storage (within process_mack_message) makes sense. | ||||
|             // still, for instance the OSNMA_NavData and Mack storage (within process_mack_message) makes sense. | ||||
|         } | ||||
| } | ||||
|  | ||||
| @@ -651,7 +653,7 @@ void osnma_msg_receiver::read_mack_header() | ||||
|         } | ||||
|     if (lt_bits == 0) | ||||
|         { | ||||
|             return;  // C: TODO if Tag length is 0, what is the action? no verification possible of NavData for sure. | ||||
|             return;  // C: TODO if Tag length is 0, what is the action? no verification possible of OSNMA_NavData for sure. | ||||
|         } | ||||
|     uint16_t macseq = 0; | ||||
|     uint8_t cop = 0; | ||||
| @@ -882,13 +884,13 @@ void osnma_msg_receiver::read_mack_body() | ||||
|  * @brief Verifies the tags transmitted in the past. | ||||
|  * | ||||
|  * \details This function is responsible for processing the MACK message received (480 bits) at time SF(i). | ||||
|  * It stores the last 10 MACK messages and the last 11 NavData messages. | ||||
|  * It stores the last 10 MACK messages and the last 11 OSNMA_NavData messages. | ||||
|  * Then attempts to verify the Tesla Key by computing the number of hashes of distance between the key-to-verify and the | ||||
|  * Kroot and iteratively hashing the result, until the required number of hashes is achieved. | ||||
|  * The result is then compared with the Kroot. If the two values match, the Tesla key is verified. | ||||
|  *  It also performs MACSEQ validation and compares the ADKD of Mack tags with MACLT defined ADKDs. | ||||
|  *  Finally, it verifies the tags. | ||||
|  * \pre Kroot or already a TESLA key shall be available. Depending on the ADKD of the tag, NavData of SF(i-2)...SF(i-11) | ||||
|  * \pre Kroot or already a TESLA key shall be available. Depending on the ADKD of the tag, OSNMA_NavData of SF(i-2)...SF(i-11) | ||||
|  * \post Number of tags bits verified for each ADKD. MACSEQ verification success | ||||
|  * @param osnma_msg A reference to OSNMA_msg containing the MACK message to be processed. | ||||
|  */ | ||||
| @@ -908,12 +910,12 @@ void osnma_msg_receiver::process_mack_message() | ||||
|                 } | ||||
|         } | ||||
|     // verify tesla key and add it to the container of verified keys if successful | ||||
|     if (d_tesla_keys.find(d_osnma_data.d_nav_data.TOW_sf0) == d_tesla_keys.end())  // check if already available => 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<uint32_t, std::vector<uint8_t>>(d_osnma_data.d_nav_data.TOW_sf0, d_osnma_data.d_mack_message.key)); | ||||
|                     d_tesla_keys.insert(std::pair<uint32_t, std::vector<uint8_t>>(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<uint32_t, Tag>(mack->TOW, tag0)); | ||||
| //                    bool ret = verify_macseq(*mack); | ||||
|                     //                    bool ret = verify_macseq(*mack); | ||||
|                     std::vector<MACK_tag_and_info> 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<unsigned>(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 | ||||
| @@ -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<unsigned>(tag.ADKD) | ||||
|                       << ", PRNa=" | ||||
|                       << static_cast<unsigned>(tag.PRNa) | ||||
|                       << ", PRNd=" | ||||
|                       << static_cast<unsigned>(tag.PRN_d); | ||||
|             std::cout << "Galileo OSNMA: Tag verification :: SUCCESS for tag Id=" | ||||
|                       << tag.tag_id | ||||
|                       << ", ADKD=" | ||||
|                       << static_cast<unsigned>(tag.ADKD) | ||||
|                       << ", PRNa=" | ||||
|                       << static_cast<unsigned>(tag.PRNa) | ||||
|                       << ", PRNd=" | ||||
|                       << static_cast<unsigned>(tag.PRN_d) << std::endl; | ||||
|             return true; | ||||
|         } | ||||
|     return false; | ||||
| @@ -1267,7 +1248,7 @@ std::vector<uint8_t> 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<int>(tag.PRN_d) << ", TOW=" << tag.TOW - 30 <<"): 0b" << applicable_nav_data; | ||||
| @@ -1280,10 +1261,10 @@ std::vector<uint8_t> 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<int>(tag.PRN_d)  << ", TOW=" << tag.TOW - 30 <<"): 0b" << applicable_nav_data; | ||||
|             // LOG(INFO) << "|---> Galileo OSNMA :: applicable OSNMA_NavData (PRN_d="<< static_cast<int>(tag.PRN_d)  << ", TOW=" << tag.TOW - 30 <<"): 0b" << applicable_nav_data; | ||||
|         } | ||||
|     else | ||||
|         { | ||||
| @@ -1292,7 +1273,7 @@ std::vector<uint8_t> osnma_msg_receiver::build_message(const Tag& tag) const | ||||
|     // convert std::string to vector<uint8_t> | ||||
|     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<uint8_t> 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<uint32_t, NavData> tow_map = prn_it->second; | ||||
|             // LOG(INFO) << "Galileo OSNMA: hasData = true " << std::endl; | ||||
|             std::map<uint32_t, OSNMA_NavData> 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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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<uint8_t> hash_chain(uint32_t num_of_hashes_needed, const std::vector<uint8_t>& key, uint32_t GST_SFi, const uint8_t lk_bytes) const; | ||||
|     std::vector<MACK_tag_and_info> verify_macseq_new(const MACK_message& mack); | ||||
|  | ||||
|     std::map<uint32_t, std::map<uint32_t, NavData>> d_satellite_nav_data;  // map holding NavData sorted by SVID (first key) and TOW (second key). | ||||
|     std::map<uint32_t, std::map<uint32_t, OSNMA_NavData>> d_satellite_nav_data;  // map holding OSNMA_NavData sorted by SVID (first key) and TOW (second key). | ||||
|     std::map<uint32_t, std::vector<uint8_t>> d_tesla_keys;                 // tesla keys over time, sorted by TOW | ||||
|     std::multimap<uint32_t, Tag> d_tags_awaiting_verify;                   // container with tags to verify from arbitrary SVIDs, sorted by TOW | ||||
|  | ||||
|   | ||||
| @@ -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<GALILEO_DATA_JK_BITS>& | ||||
|     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<GALILEO_DATA_JK_BITS>& | ||||
|     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); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -1417,7 +1421,7 @@ OSNMA_msg Galileo_Inav_Message::get_osnma_msg() | ||||
|     nma_position_filled = std::array<int8_t, 15>{}; | ||||
|     // 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 = ""; | ||||
|   | ||||
| @@ -51,15 +51,13 @@ public: | ||||
|     uint32_t PRN{}; | ||||
|     uint32_t WN_sf0{};  // TODO - this is present in UtcModelData already | ||||
|     uint32_t TOW_sf0{}; | ||||
|     std::vector<uint8_t> EphemerisClockAndStatusData {}; // TODO _2 rename and substitute this | ||||
|     std::vector<uint8_t> EphemerisClockAndStatusData{};  // TODO _2 rename and substitute this | ||||
|     std::string EphemerisClockAndStatusData_2{}; | ||||
|     std::vector<uint8_t> TimingData {}; | ||||
|     std::vector<uint8_t> 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{}; | ||||
| }; | ||||
|  | ||||
| /*! | ||||
|   | ||||
| @@ -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 <cstring> | ||||
| #include <iostream> | ||||
|  | ||||
| /** | ||||
|  * @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> &osnma_msg) | ||||
|  | ||||
|  | ||||
| void OSNMA_NavData::init(const std::shared_ptr<OSNMA_msg>& 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<std::pair<void*, int>> variables = { | ||||
|         // data from word type 1 | ||||
|         {static_cast<void*>(&EphemerisData.IOD_nav), sizeof(EphemerisData.IOD_nav) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.toe), sizeof(EphemerisData.toe) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.M_0), sizeof(EphemerisData.M_0) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.ecc), sizeof(EphemerisData.ecc) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.sqrtA), sizeof(EphemerisData.sqrtA) * 8}, | ||||
|         // data from word type 2 | ||||
|         {static_cast<void*>(&EphemerisData.IOD_nav), sizeof(EphemerisData.IOD_nav) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.OMEGA_0), sizeof(EphemerisData.OMEGA_0) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.i_0), sizeof(EphemerisData.i_0) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.omega), sizeof(EphemerisData.omega) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.idot), sizeof(EphemerisData.idot) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.IOD_nav), sizeof(EphemerisData.IOD_nav) * 8}, | ||||
|         // data from word type 3 | ||||
|         {static_cast<void*>(&EphemerisData.OMEGAdot), sizeof(EphemerisData.OMEGAdot) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.delta_n), sizeof(EphemerisData.delta_n) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.Cuc), sizeof(EphemerisData.Cuc) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.Cus), sizeof(EphemerisData.Cus) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.Crc), sizeof(EphemerisData.Crc) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.Crs), sizeof(EphemerisData.Crs) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.SISA), sizeof(EphemerisData.SISA) * 8}, | ||||
|         // data from word type 4 | ||||
|         {static_cast<void*>(&EphemerisData.IOD_nav), sizeof(EphemerisData.IOD_nav) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.PRN), sizeof(EphemerisData.PRN) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.Cic), sizeof(EphemerisData.Cic) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.Cis), sizeof(EphemerisData.Cis) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.toe), sizeof(EphemerisData.toe) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.af0), sizeof(EphemerisData.af0) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.af1), sizeof(EphemerisData.af1) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.af2), sizeof(EphemerisData.af2) * 8}, | ||||
|         // data from word type 5 | ||||
|         {static_cast<void*>(&IonoData.ai0), sizeof(IonoData.ai0) * 8}, | ||||
|         {static_cast<void*>(&IonoData.ai1), sizeof(IonoData.ai1) * 8}, | ||||
|         {static_cast<void*>(&IonoData.ai2), sizeof(IonoData.ai2) * 8}, | ||||
|         {static_cast<void*>(&IonoData.Region1_flag), sizeof(IonoData.Region1_flag) * 8}, | ||||
|         {static_cast<void*>(&IonoData.Region2_flag), sizeof(IonoData.Region2_flag) * 8}, | ||||
|         {static_cast<void*>(&IonoData.Region3_flag), sizeof(IonoData.Region3_flag) * 8}, | ||||
|         {static_cast<void*>(&IonoData.Region4_flag), sizeof(IonoData.Region4_flag) * 8}, | ||||
|         {static_cast<void*>(&IonoData.Region5_flag), sizeof(IonoData.Region5_flag) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.BGD_E1E5a), sizeof(EphemerisData.BGD_E1E5a) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.BGD_E1E5b), sizeof(EphemerisData.BGD_E1E5b) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.E5b_HS), sizeof(EphemerisData.E5b_HS) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.E1B_HS), sizeof(EphemerisData.E1B_HS) * 8}, | ||||
|         {static_cast<void*>(&EphemerisData.E5b_DVS), sizeof(EphemerisData.E5b_DVS) * 8}, | ||||
|         {static_cast<void*>(&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<uint8_t>(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<std::pair<void*, int>> variables = { | ||||
|         {static_cast<void*>(&UtcData.A0), sizeof(UtcData.A0) * 8}, | ||||
|         {static_cast<void*>(&UtcData.A1), sizeof(UtcData.A1) * 8}, | ||||
|         {static_cast<void*>(&UtcData.Delta_tLS), sizeof(UtcData.Delta_tLS) * 8}, | ||||
|         {static_cast<void*>(&UtcData.tot), sizeof(UtcData.tot) * 8}, | ||||
|         {static_cast<void*>(&UtcData.WNot), sizeof(UtcData.WNot) * 8}, | ||||
|         {static_cast<void*>(&UtcData.WN_LSF), sizeof(UtcData.WN_LSF) * 8}, | ||||
|         {static_cast<void*>(&UtcData.DN), sizeof(UtcData.DN) * 8}, | ||||
|         {static_cast<void*>(&UtcData.Delta_tLSF), sizeof(UtcData.Delta_tLSF) * 8}, | ||||
|         {static_cast<void*>(&UtcData.A_0G), sizeof(UtcData.A_0G) * 8}, | ||||
|         {static_cast<void*>(&UtcData.A_1G), sizeof(UtcData.A_1G) * 8}, | ||||
|         {static_cast<void*>(&UtcData.t_0G), sizeof(UtcData.t_0G) * 8}, | ||||
|         {static_cast<void*>(&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<uint8_t>(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; | ||||
| } | ||||
|   | ||||
| @@ -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 <array> | ||||
| #include <cstdint> | ||||
| #include <memory> | ||||
| #include <string> | ||||
| #include <vector> | ||||
|  | ||||
| @@ -121,31 +119,26 @@ public: | ||||
|     MACK_header header; | ||||
|     std::vector<MACK_tag_and_info> tag_and_info; | ||||
|     std::vector<uint8_t> 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> &osnma_msg); | ||||
|     std::vector<uint8_t> ephemeris_iono_vector{}; | ||||
|     std::string ephemeris_iono_vector_2{}; | ||||
|     std::vector<uint8_t> 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>& 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), | ||||
| @@ -188,7 +184,7 @@ public: | ||||
|     } | ||||
|     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), | ||||
|   | ||||
| @@ -30,7 +30,7 @@ public: | ||||
|     std::vector<uint8_t> gst_to_uint8(uint32_t GST) const; | ||||
|     std::vector<uint8_t> bytes(const std::string& binaryString) const; | ||||
|     std::string verification_status_str(int status) const; | ||||
|     std::string convert_to_hex_string(const std::vector<uint8_t>& vector) const ; | ||||
|     std::string convert_to_hex_string(const std::vector<uint8_t>& vector) const; | ||||
|     std::vector<uint8_t> convert_from_hex_string(const std::string& hex_string) const;  // TODO remove similar function in gnss_crypto | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -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 <gtest/gtest.h> | ||||
| #include <bitset> | ||||
| #include <chrono> | ||||
| #include <fstream> | ||||
| #include <osnma_msg_receiver.h> | ||||
| #include <vector> | ||||
|  | ||||
| #if USE_GLOG_AND_GFLAGS | ||||
| #include "osnma_helper.h" | ||||
| #include "gnss_crypto.h" | ||||
| #include <glog/logging.h>  // for LOG | ||||
| #include <filesystem> | ||||
| #else | ||||
| @@ -21,11 +39,18 @@ struct TestVector | ||||
|     std::vector<uint8_t> 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<uint8_t> parseNavBits(const std::string& hex); | ||||
|     static std::vector<TestVector> readTestVectorsFromFile(const std::string& filename); | ||||
|     std::string bytes_to_str(const std::vector<uint8_t>& bytes); | ||||
|     std::vector<uint8_t> extract_page_bytes(const TestVector& tv, const int byte_index, const int num_bytes); | ||||
|  | ||||
| protected: | ||||
|     Osnma_Helper helper; | ||||
|     osnma_msg_receiver_sptr osnma; | ||||
| @@ -35,37 +60,30 @@ protected: | ||||
|     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; | ||||
|     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, 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_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<uint8_t> parseNavBits(const std::string& hex); | ||||
|     static std::vector<TestVector> readTestVectorsFromFile(const std::string& filename); | ||||
|     std::string bytes_to_str(const std::vector<uint8_t>& bytes); | ||||
|     std::vector<uint8_t> extract_page_bytes(const TestVector& tv, const int byte_index, const int num_bytes); | ||||
| }; | ||||
|  | ||||
|  | ||||
| TEST_F(OsnmaMsgReceiverTest, ComputeMerkleRoot) | ||||
| { | ||||
|     // Arrange | ||||
|     // ---------- | ||||
|     std::vector<uint8_t> computed_merkle_root; | ||||
|     std::vector<uint8_t> 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<uint8_t> base_leaf = helper.convert_from_hex_string("120303B2CE64BC207BDD8BC4DF859187FCB686320D63FFA091410FC158FBB77980EA"); | ||||
|  | ||||
|     std::vector<uint8_t> vec = helper.convert_from_hex_string("7CBE05D9970CFC9E22D0A43A340EF557624453A2E821AADEAC989C405D78BA06" | ||||
|     std::vector<uint8_t> 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<uint8_t> expected_base_leaf = helper.convert_from_hex_string("120303B2CE64BC207BDD8BC4DF859187FCB686320D63FFA091410FC158FBB77980EA"); | ||||
|     DSM_PKR_message dsm_pkr_message; | ||||
|     dsm_pkr_message.npkt = 0x01; | ||||
| @@ -101,23 +117,24 @@ TEST_F(OsnmaMsgReceiverTest, ComputeBaseLeaf) | ||||
|     dsm_pkr_message.npk = helper.convert_from_hex_string("0303B2CE64BC207BDD8BC4DF859187FCB686320D63FFA091410FC158FBB77980EA"); | ||||
|  | ||||
|     // Act | ||||
|     // ---------- | ||||
|     std::vector<uint8_t> 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<uint8_t> vec = helper.convert_from_hex_string("7CBE05D9970CFC9E22D0A43A340EF557624453A2E821AADEAC989C405D78BA06" | ||||
|     std::vector<uint8_t> vec = helper.convert_from_hex_string( | ||||
|         "7CBE05D9970CFC9E22D0A43A340EF557624453A2E821AADEAC989C405D78BA06" | ||||
|         "956380BAB0D2C939EC6208151040CCFFCF1FB7156178FD1255BA0AECAAA253F7" | ||||
|         "407B6C5DD4DF059FF8789474061301E1C34881DB7A367A913A3674300E21EAB1" | ||||
|         "24EF508389B7D446C3E2ECE8D459FBBD3239A794906F5B1F92469C640164FD87"); | ||||
| @@ -125,31 +142,26 @@ TEST_F(OsnmaMsgReceiverTest, VerifyPublicKey){ // values taken from RG A.7 | ||||
|     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<uint8_t> 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; | ||||
| @@ -157,7 +169,16 @@ TEST_F(OsnmaMsgReceiverTest, BuildTagMessageM0) | ||||
|     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,26 +188,21 @@ 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; | ||||
| @@ -194,7 +210,17 @@ TEST_F(OsnmaMsgReceiverTest, TagVerification) { | ||||
|     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,24 +230,15 @@ 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; | ||||
| @@ -229,9 +246,9 @@ TEST_F(OsnmaMsgReceiverTest, TagVerification) { | ||||
|     osnma->d_osnma_data.d_dsm_kroot_message.ts = 9;                                                                                        // 40 bit | ||||
|     osnma->d_tesla_keys[TOW_Key_Tag3] = {0x69, 0xC0, 0x0A, 0xA7, 0x36, 0x42, 0x37, 0xA6, 0x5E, 0xBF, 0x00, 0x6A, 0xD8, 0xDD, 0xBC, 0x73};  // K4 | ||||
|     osnma->d_osnma_data.d_dsm_kroot_message.mf = 0; | ||||
|     osnma->d_satellite_nav_data[PRNa][TOW_NavData].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<uint64_t>(0x7BB238C883); | ||||
| @@ -243,12 +260,12 @@ 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 | ||||
| @@ -258,63 +275,49 @@ TEST_F(OsnmaMsgReceiverTest, TeslaKeyVerification) { | ||||
|     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<uint32_t, std::vector<uint8_t>>(345600,{0xEF, 0xF9, 0x99, 0x04, 0x0E, 0x19, 0xB5, 0x70, 0x83, 0x50, 0x60, 0xBE, 0xBD, 0x23, 0xED, 0x92}))); // K1, not needed, just for reference. | ||||
|     osnma->d_tesla_keys.insert((std::pair<uint32_t, std::vector<uint8_t>>(345600, {0xEF, 0xF9, 0x99, 0x04, 0x0E, 0x19, 0xB5, 0x70, 0x83, 0x50, 0x60, 0xBE, 0xBD, 0x23, 0xED, 0x92})));  // K1, not needed, just for reference. | ||||
|     std::vector<uint8_t> 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<TestVector> testVectors = readTestVectorsFromFile("/home/cgm/CLionProjects/osnma/data/16_AUG_2023_GST_05_00_01.csv"); // conf. 1 | ||||
|     std::vector<TestVector> testVectors = readTestVectorsFromFile("/home/cgm/CLionProjects/osnma/data/27_JUL_2023_GST_00_00_01.csv");  // conf. 2 | ||||
|     if (testVectors.empty()){ | ||||
|     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_PAGE_BYTES{240 / 8};  // total bytes of a page | ||||
|     const int SIZE_SUBFRAME_PAGES{15};   // number of pages of a subframe | ||||
|     const int SIZE_SUBFRAME_BYTES{SIZE_PAGE_BYTES*SIZE_SUBFRAME_PAGES}; // total bytes of a subframe | ||||
|     const int DURATION_SUBFRAME{30};     // duration of a subframe, in seconds | ||||
|  | ||||
|     const int DUMMY_PAGE{63}; | ||||
|     bool flag_dummy_page{false}; | ||||
|     std::cout << "OsnmaTestVectorsSimulation:" << " d_GST_SIS= " << d_GST_SIS | ||||
|     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<OSNMA_msg>(); | ||||
|                     std::array<uint8_t, 15> hkroot{}; | ||||
|                     std::array<uint32_t, 15> mack{}; | ||||
| @@ -324,9 +327,11 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) | ||||
|                     for (int idx = 0; idx < SIZE_SUBFRAME_PAGES; ++idx)  // extract all pages of a subframe | ||||
|                         { | ||||
|                             // extract bytes of complete page (odd+even) -- extract SIZE_PAGE from tv.navBits, starting from byte_index | ||||
|                             std::vector<uint8_t> page_bytes = extract_page_bytes(tv,byte_index,SIZE_PAGE_BYTES); | ||||
|                             if(page_bytes.empty()){ | ||||
|                                     std::cout<< "OsnmaTestVectorsSimulation: end of TestVectors \n" << "byte_index="<<byte_index<< " expected= " << 432000/8 << std::endl; | ||||
|                             std::vector<uint8_t> page_bytes = extract_page_bytes(tv, byte_index, SIZE_PAGE_BYTES); | ||||
|                             if (page_bytes.empty()) | ||||
|                                 { | ||||
|                                     std::cout << "OsnmaTestVectorsSimulation: end of TestVectors \n" | ||||
|                                               << "byte_index=" << byte_index << " expected= " << 432000 / 8 << std::endl; | ||||
|                                     end_of_hex_stream = true; | ||||
|                                     break; | ||||
|                                 } | ||||
| @@ -334,28 +339,29 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) | ||||
|                             std::string page_bits = bytes_to_str(page_bytes); | ||||
|                             // Extract the 40 OSNMA bits starting from the 18th bit | ||||
|                             std::string even_page = page_bits.substr(0, page_bits.size() / 2); | ||||
|                             std::string odd_page = page_bits.substr( page_bits.size() / 2); | ||||
|                             if(even_page.size() < 120 || odd_page.size() < 120 ){ | ||||
|                                     std::cout<< "OsnmaTestVectorsSimulation: error parsing pages" << std::endl; | ||||
|                             std::string odd_page = page_bits.substr(page_bits.size() / 2); | ||||
|                             if (even_page.size() < 120 || odd_page.size() < 120) | ||||
|                                 { | ||||
|                                     std::cout << "OsnmaTestVectorsSimulation: error parsing pages" << std::endl; | ||||
|                                 } | ||||
|                             bool even_odd_OK = even_page[0] == '0' && odd_page[0] == '1'; | ||||
|                             bool page_type_OK = even_page[1] == '0' && odd_page[1] == '0'; | ||||
|                             bool tail_bits_OK = even_page.substr(even_page.size() - 6) == "000000" && odd_page.substr(odd_page.size() - 6) == "000000"; | ||||
|                             if(!even_odd_OK || !page_type_OK || !tail_bits_OK) | ||||
|                                 std::cerr<< "OsnmaTestVectorsSimulation: error parsing pages." << std::endl; | ||||
|                             if (!even_odd_OK || !page_type_OK || !tail_bits_OK) | ||||
|                                 std::cerr << "OsnmaTestVectorsSimulation: error parsing pages." << std::endl; | ||||
|  | ||||
|                             std::bitset<112> data_k(even_page.substr(2,112)); | ||||
|                             std::bitset<16> data_j(odd_page.substr(2,16)); | ||||
|                             std::bitset<112> data_k(even_page.substr(2, 112)); | ||||
|                             std::bitset<16> data_j(odd_page.substr(2, 16)); | ||||
|                             std::bitset<112> shifted_data_k = data_k; | ||||
|                             uint8_t word_type = static_cast<uint8_t>((shifted_data_k >>= 106).to_ulong());  // word type is the first 6 bits of the word | ||||
|                             std::cout<< "OsnmaTestVectorsSimulation: received Word "<< static_cast<int>(word_type) << std::endl; | ||||
|                             if( (word_type >= 1 && word_type <=5) || word_type == 6 || word_type == 10) | ||||
|                             std::cout << "OsnmaTestVectorsSimulation: received Word " << static_cast<int>(word_type) << std::endl; | ||||
|                             if ((word_type >= 1 && word_type <= 5) || word_type == 6 || word_type == 10) | ||||
|                                 { | ||||
|                                     // store raw word | ||||
|                                     std::bitset<128> data_combined(data_k.to_string() + data_j.to_string()); | ||||
|                                     words_for_OSNMA[word_type] = data_combined; | ||||
|                                 } | ||||
|                             if(word_type == DUMMY_PAGE) | ||||
|                             if (word_type == DUMMY_PAGE) | ||||
|                                 flag_dummy_page = true; | ||||
|  | ||||
|                             // place it into osnma object. | ||||
| @@ -370,10 +376,11 @@ 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 | ||||
|                         } | ||||
| @@ -383,7 +390,7 @@ 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->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<uint8_t, std::pair<uint8_t, uint8_t>> 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 <<std::endl; | ||||
|                                     const auto tmp_obj_osnma = std::make_shared<std::tuple<uint32_t, std::string,uint32_t>>( // < 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<std::tuple<uint32_t, std::string, uint32_t>>(  // < PRNd , navDataBits, TOW_Sosf> | ||||
|                                         tv.svId, | ||||
|                                         nav_data_ADKD_0_12, | ||||
|                                         osnmaMsg_sptr->TOW_sf0); | ||||
|                                     LOG(INFO) << "|---> Galileo OSNMA :: Telemetry Decoder NavData (PRN_d="<< static_cast<int>(tv.svId) << ", TOW=" << static_cast<int>(osnmaMsg_sptr->TOW_sf0) <<"): 0b" << nav_data_ADKD_0_12; | ||||
|                                     LOG(INFO) << "|---> Galileo OSNMA :: Telemetry Decoder NavData (PRN_d=" << static_cast<int>(tv.svId) << ", TOW=" << static_cast<int>(osnmaMsg_sptr->TOW_sf0) << "): 0b" << nav_data_ADKD_0_12; | ||||
|                                     osnma->msg_handler_osnma(pmt::make_any(tmp_obj_osnma)); | ||||
|  | ||||
|                                 } | ||||
|                         } | ||||
|  | ||||
| @@ -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<uint8_t, std::pair<uint8_t, uint8_t>> 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,18 +469,17 @@ 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 <<std::endl; | ||||
|                                     const auto tmp_obj_osnma = std::make_shared<std::tuple<uint32_t, std::string,uint32_t>>( // < 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<std::tuple<uint32_t, std::string, uint32_t>>(  // < PRNd , navDataBits, TOW_Sosf> | ||||
|                                         tv.svId, | ||||
|                                         nav_data_ADKD_4, | ||||
|                                         osnmaMsg_sptr->TOW_sf0); | ||||
|                                     LOG(INFO) << "|---> Galileo OSNMA :: Telemetry Decoder NavData (PRN_d="<< static_cast<int>(tv.svId) << ", TOW=" << static_cast<int>(osnmaMsg_sptr->TOW_sf0) <<"): 0b" << nav_data_ADKD_4; | ||||
|                                     LOG(INFO) << "|---> Galileo OSNMA :: Telemetry Decoder NavData (PRN_d=" << static_cast<int>(tv.svId) << ", TOW=" << static_cast<int>(osnmaMsg_sptr->TOW_sf0) << "): 0b" << nav_data_ADKD_4; | ||||
|                                     osnma->msg_handler_osnma(pmt::make_any(tmp_obj_osnma)); | ||||
|  | ||||
|                                 } | ||||
|  | ||||
|                         } | ||||
|  | ||||
|                     // Call the handler, as if it came from telemetry decoder block | ||||
| @@ -481,42 +488,42 @@ TEST_F(OsnmaMsgReceiverTest, OsnmaTestVectorsSimulation) | ||||
|                     osnma->msg_handler_osnma(temp_obj);  // osnma entry point | ||||
|                 } | ||||
|  | ||||
|  | ||||
|             if(!end_of_hex_stream){ | ||||
|             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<TestVector> OsnmaMsgReceiverTest::readTestVectorsFromFile(const std::string& filename) | ||||
| { | ||||
|     std::ifstream file(filename); | ||||
|     std::vector<TestVector> 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<TestVector> OsnmaMsgReceiverTest::readTestVectorsFromFile(const std: | ||||
|  | ||||
|     return testVectors; | ||||
| } | ||||
|  | ||||
|  | ||||
| std::vector<uint8_t> OsnmaMsgReceiverTest::parseNavBits(const std::string& hex) | ||||
| { | ||||
|     std::vector<uint8_t> 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<uint8_t>& 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<uint8_t> OsnmaMsgReceiverTest::extract_page_bytes(const TestVector& | ||||
|  | ||||
|     return extracted_bytes; | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * @brief Sets the time based on the given input. | ||||
|  * | ||||
| @@ -621,9 +636,9 @@ void OsnmaMsgReceiverTest::set_time(std::tm& input) | ||||
|     // 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); | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| void OsnmaMsgReceiverTest::initializeGoogleLog() | ||||
| { | ||||
|     google::InitGoogleLogging(log_name.c_str());  // TODO - running all tests causes conflict due to being called twice | ||||
| @@ -632,7 +647,6 @@ void OsnmaMsgReceiverTest::initializeGoogleLog() | ||||
|     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() | ||||
|                 } | ||||
|         } | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Carles Fernandez
					Carles Fernandez