mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-12 11:10:33 +00:00
Get time zone offset in a more standard way (#17)
* Clang Tidy fixes * Get time zone offset in a more standard way Account for leap seconds Use GNSS-SDR.osnma_mode=strict to check for local time * Fix for C++20 * Initialize tm in a more portable way * Remove unnecessary data members in osnma_msg_receiver --------- Co-authored-by: cesaaargm <cesare.martinez@proton.me>
This commit is contained in:
parent
6beb92278f
commit
3457b8ed3b
@ -61,15 +61,18 @@ namespace wht = std;
|
||||
#endif
|
||||
|
||||
|
||||
osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath)
|
||||
osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath, bool strict_mode)
|
||||
{
|
||||
return osnma_msg_receiver_sptr(new osnma_msg_receiver(pemFilePath, merkleFilePath));
|
||||
return osnma_msg_receiver_sptr(new osnma_msg_receiver(pemFilePath, merkleFilePath, strict_mode));
|
||||
}
|
||||
|
||||
|
||||
osnma_msg_receiver::osnma_msg_receiver(const std::string& crtFilePath, const std::string& merkleFilePath) : gr::block("osnma_msg_receiver",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0))
|
||||
osnma_msg_receiver::osnma_msg_receiver(const std::string& crtFilePath,
|
||||
const std::string& merkleFilePath,
|
||||
bool strict_mode) : gr::block("osnma_msg_receiver",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
d_strict_mode(strict_mode)
|
||||
{
|
||||
d_dsm_reader = std::make_unique<OSNMA_DSM_Reader>();
|
||||
d_crypto = std::make_unique<Gnss_Crypto>(crtFilePath, merkleFilePath);
|
||||
@ -114,23 +117,20 @@ osnma_msg_receiver::osnma_msg_receiver(const std::string& crtFilePath, const std
|
||||
boost::bind(&osnma_msg_receiver::msg_handler_osnma, this, _1));
|
||||
#endif
|
||||
#endif
|
||||
std::chrono::time_point<std::chrono::system_clock> now;
|
||||
if (d_flag_debug)
|
||||
|
||||
if (d_strict_mode)
|
||||
{
|
||||
// d_GST_Rx = d_helper->compute_gst(d_initial_debug_time);
|
||||
LOG(WARNING) << "Galileo OSNMA: Debug mode, time artificially set up.";
|
||||
std::cout << "Galileo OSNMA: Debug mode, time artificially set up." << std::endl;
|
||||
// TODO - need to synchronize time lapse with Gnss_Synchro?
|
||||
d_GST_Rx = d_helper->compute_gst_now();
|
||||
const auto WN = d_helper->get_WN(d_GST_Rx);
|
||||
const auto TOW = d_helper->get_TOW(d_GST_Rx);
|
||||
LOG(INFO) << "Galileo OSNMA: initial receiver time GST=[" << WN << " " << TOW << "]";
|
||||
std::cout << "Galileo OSNMA: initial receiver time GST=[" << WN << " " << TOW << "]" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_GST_Rx = d_helper->compute_gst_now();
|
||||
LOG(WARNING) << "Galileo OSNMA: in non-strict mode, local system time is not checked.";
|
||||
std::cout << "Galileo OSNMA: in non-strict mode, local system time is not checked." << std::endl;
|
||||
}
|
||||
|
||||
d_WN = d_helper->get_WN(d_GST_Rx);
|
||||
d_TOW = d_helper->get_TOW(d_GST_Rx);
|
||||
LOG(WARNING) << "Galileo OSNMA: initial receiver time GST=[" << d_WN << " " << d_TOW << "]";
|
||||
std::cout << "Galileo OSNMA: initial receiver time GST=[" << d_WN << " " << d_TOW << "]" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@ -167,13 +167,13 @@ void osnma_msg_receiver::msg_handler_osnma(const pmt::pmt_t& msg)
|
||||
{
|
||||
d_last_received_GST = d_GST_SIS;
|
||||
}
|
||||
if (d_flag_debug)
|
||||
if (d_strict_mode)
|
||||
{
|
||||
d_GST_Rx = d_last_received_GST;
|
||||
d_GST_Rx = d_helper->compute_gst_now();
|
||||
}
|
||||
else
|
||||
{
|
||||
d_GST_Rx = d_helper->compute_gst_now();
|
||||
d_GST_Rx = d_last_received_GST;
|
||||
}
|
||||
LOG(INFO) << "Galileo OSNMA: Receiver Time GST=[" << d_helper->get_WN(d_GST_Rx) << " " << d_helper->get_TOW(d_GST_Rx) << "]";
|
||||
std::cout << "Galileo OSNMA: Receiver Time GST=[" << d_helper->get_WN(d_GST_Rx) << " " << d_helper->get_TOW(d_GST_Rx) << "]" << std::endl;
|
||||
@ -1425,6 +1425,7 @@ std::vector<uint8_t> osnma_msg_receiver::build_message(Tag& tag) const
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
void osnma_msg_receiver::display_data()
|
||||
{
|
||||
// if(d_satellite_nav_data.empty())
|
||||
@ -1489,6 +1490,7 @@ bool osnma_msg_receiver::verify_tesla_key(std::vector<uint8_t>& key, uint32_t TO
|
||||
return d_tesla_key_verified;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Removes the tags that have been verified from the multimap d_tags_awaiting_verify.
|
||||
*
|
||||
@ -1560,6 +1562,7 @@ void osnma_msg_receiver::remove_verified_tags()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Control the size of the tags awaiting verification multimap.
|
||||
*
|
||||
@ -1948,6 +1951,7 @@ std::vector<MACK_tag_and_info> osnma_msg_receiver::verify_macseq_new(const MACK_
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void osnma_msg_receiver::send_data_to_pvt(const std::vector<OSNMA_NavData>& data)
|
||||
{
|
||||
if (!data.empty())
|
||||
@ -1960,6 +1964,7 @@ void osnma_msg_receiver::send_data_to_pvt(const std::vector<OSNMA_NavData>& data
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool osnma_msg_receiver::store_dsm_kroot(const std::vector<uint8_t>& dsm, const uint8_t nma_header) const
|
||||
{
|
||||
std::ofstream file(KROOTFILE_DEFAULT, std::ios::binary | std::ios::out);
|
||||
@ -1978,6 +1983,7 @@ bool osnma_msg_receiver::store_dsm_kroot(const std::vector<uint8_t>& dsm, const
|
||||
return file.good();
|
||||
}
|
||||
|
||||
|
||||
std::pair<std::vector<uint8_t>, uint8_t> osnma_msg_receiver::parse_dsm_kroot() const
|
||||
{
|
||||
std::ifstream file(KROOTFILE_DEFAULT, std::ios::binary | std::ios::in);
|
||||
|
@ -28,16 +28,16 @@
|
||||
#include "gnss_sdr_make_unique.h" // for std::make:unique in C++11
|
||||
#include "osnma_data.h" // for OSNMA_data structures
|
||||
#include "osnma_nav_data_manager.h"
|
||||
#include <gnuradio/block.h> // for gr::block
|
||||
#include <pmt/pmt.h> // for pmt::pmt_t
|
||||
#include <array> // for std::array
|
||||
#include <cstdint> // for uint8_t
|
||||
#include <ctime> // for std::time_t
|
||||
#include <map> // for std::map, std::multimap
|
||||
#include <memory> // for std::shared_ptr
|
||||
#include <string> // for std::string
|
||||
#include <vector> // for std::vector
|
||||
#include <utility> // for std::pair
|
||||
#include <gnuradio/block.h> // for gr::block
|
||||
#include <pmt/pmt.h> // for pmt::pmt_t
|
||||
#include <array> // for std::array
|
||||
#include <cstdint> // for uint8_t
|
||||
#include <ctime> // for std::time_t
|
||||
#include <map> // for std::map, std::multimap
|
||||
#include <memory> // for std::shared_ptr
|
||||
#include <string> // for std::string
|
||||
#include <utility> // for std::pair
|
||||
#include <vector> // for std::vector
|
||||
|
||||
/** \addtogroup Core
|
||||
* \{ */
|
||||
@ -51,7 +51,7 @@ class osnma_msg_receiver;
|
||||
|
||||
using osnma_msg_receiver_sptr = gnss_shared_ptr<osnma_msg_receiver>;
|
||||
|
||||
osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath);
|
||||
osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath, bool strict_mode = false);
|
||||
|
||||
/*!
|
||||
* \brief GNU Radio block that receives asynchronous OSNMA messages
|
||||
@ -66,8 +66,8 @@ public:
|
||||
std::unique_ptr<Gnss_Crypto> d_crypto; // access to cryptographic functions
|
||||
void msg_handler_osnma(const pmt::pmt_t& msg); // GnssCrypto and the message handler are needed by public method within TestVectors fixture
|
||||
private:
|
||||
friend osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath);
|
||||
osnma_msg_receiver(const std::string& crtFilePath, const std::string& merkleFilePath);
|
||||
friend osnma_msg_receiver_sptr osnma_msg_receiver_make(const std::string& pemFilePath, const std::string& merkleFilePath, bool strict_mode);
|
||||
osnma_msg_receiver(const std::string& crtFilePath, const std::string& merkleFilePath, bool strict_mode);
|
||||
|
||||
void process_osnma_message(const std::shared_ptr<OSNMA_msg>& osnma_msg);
|
||||
void read_nma_header(uint8_t nma_header);
|
||||
@ -103,6 +103,7 @@ private:
|
||||
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
|
||||
|
||||
std::vector<uint8_t> d_new_public_key;
|
||||
std::vector<uint8_t> d_tags_to_verify{0, 4, 12};
|
||||
std::vector<MACK_message> d_macks_awaiting_MACSEQ_verification;
|
||||
|
||||
@ -111,8 +112,8 @@ private:
|
||||
std::array<uint16_t, 16> d_number_of_blocks{};
|
||||
std::array<uint8_t, 60> d_mack_message{}; // C: 480 b
|
||||
|
||||
std::unique_ptr<OSNMA_DSM_Reader> d_dsm_reader; // osnma parameters parser
|
||||
std::unique_ptr<Osnma_Helper> d_helper; // helper class with auxiliary functions
|
||||
std::unique_ptr<OSNMA_DSM_Reader> d_dsm_reader; // osnma parameters parser
|
||||
std::unique_ptr<Osnma_Helper> d_helper; // helper class with auxiliary functions
|
||||
std::unique_ptr<OSNMA_nav_data_Manager> d_nav_data_manager; // refactor for holding and processing navigation data
|
||||
|
||||
OSNMA_data d_osnma_data{};
|
||||
@ -125,30 +126,28 @@ private:
|
||||
uint32_t d_GST_SIS{}; // GST coming from W6 and W5 of SIS
|
||||
uint32_t d_GST_PKR_PKREV_start{};
|
||||
uint32_t d_GST_PKR_AM_start{};
|
||||
uint32_t d_WN{};
|
||||
uint32_t d_TOW{};
|
||||
|
||||
uint8_t const d_T_L{30}; // s RG Section 2.1
|
||||
|
||||
bool d_new_data{false};
|
||||
bool d_public_key_verified{false};
|
||||
bool d_kroot_verified{false};
|
||||
bool d_tesla_key_verified{false};
|
||||
bool d_flag_debug{true};
|
||||
bool d_flag_hot_start{false};
|
||||
bool d_flag_PK_renewal{false};
|
||||
bool d_flag_PK_revocation{false};
|
||||
uint8_t d_new_public_key_id{};
|
||||
std::vector<uint8_t> d_new_public_key;
|
||||
bool d_flag_NPK_set{false};
|
||||
bool d_flag_alert_message{false};
|
||||
|
||||
// Provide access to inner functions to Gtest
|
||||
uint32_t d_count_successful_tags{0};
|
||||
uint32_t d_count_failed_tags{0};
|
||||
uint32_t d_count_failed_Kroot{0};
|
||||
uint32_t d_count_failed_pubKey{0}; // failed public key verifications against Merkle root
|
||||
uint32_t d_count_failed_macseq{0};
|
||||
|
||||
uint8_t const d_T_L{30}; // s RG Section 2.1
|
||||
uint8_t d_new_public_key_id{};
|
||||
|
||||
bool d_new_data{false};
|
||||
bool d_public_key_verified{false};
|
||||
bool d_kroot_verified{false};
|
||||
bool d_tesla_key_verified{false};
|
||||
bool d_strict_mode{false};
|
||||
bool d_flag_hot_start{false};
|
||||
bool d_flag_PK_renewal{false};
|
||||
bool d_flag_PK_revocation{false};
|
||||
bool d_flag_NPK_set{false};
|
||||
bool d_flag_alert_message{false};
|
||||
|
||||
// Provide access to inner functions to Gtest
|
||||
FRIEND_TEST(OsnmaMsgReceiverTest, TeslaKeyVerification);
|
||||
FRIEND_TEST(OsnmaMsgReceiverTest, TagVerification);
|
||||
FRIEND_TEST(OsnmaMsgReceiverTest, BuildTagMessageM0);
|
||||
|
@ -126,7 +126,13 @@ void GNSSFlowgraph::init()
|
||||
enable_osnma_rx_ = true;
|
||||
const auto certFilePath = configuration_->property("GNSS-SDR.osnma_public_key", CRTFILE_DEFAULT);
|
||||
const auto merKleTreePath = configuration_->property("GNSS-SDR.osnma_merkletree", MERKLEFILE_DEFAULT);
|
||||
osnma_rx_ = osnma_msg_receiver_make(certFilePath, merKleTreePath);
|
||||
std::string osnma_mode = configuration_->property("GNSS-SDR.osnma_mode", std::string(""));
|
||||
bool strict_mode = false;
|
||||
if (osnma_mode == "strict")
|
||||
{
|
||||
strict_mode = true;
|
||||
}
|
||||
osnma_rx_ = osnma_msg_receiver_make(certFilePath, merKleTreePath, strict_mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -16,15 +16,26 @@
|
||||
|
||||
#include "osnma_helper.h"
|
||||
#include <bitset>
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <sstream>
|
||||
#include <ctime> // timezone
|
||||
|
||||
uint32_t Osnma_Helper::compute_gst(uint32_t WN, uint32_t TOW) const{
|
||||
|
||||
Osnma_Helper::Osnma_Helper()
|
||||
{
|
||||
GST_START_EPOCH.tm_mday = 22;
|
||||
GST_START_EPOCH.tm_mon = 7; // August (0-based)
|
||||
GST_START_EPOCH.tm_year = 1999 - 1900;
|
||||
}
|
||||
|
||||
|
||||
uint32_t Osnma_Helper::compute_gst(uint32_t WN, uint32_t TOW) const
|
||||
{
|
||||
return (WN & 0x00000FFF) << 20 | (TOW & 0x000FFFFF);
|
||||
}
|
||||
|
||||
|
||||
uint32_t Osnma_Helper::compute_gst(tm& input)
|
||||
{
|
||||
auto epoch_time_point = std::chrono::system_clock::from_time_t(mktime(&GST_START_EPOCH));
|
||||
@ -34,23 +45,28 @@ uint32_t Osnma_Helper::compute_gst(tm& input)
|
||||
auto duration_sec = std::chrono::duration_cast<std::chrono::seconds>(input_time_point - epoch_time_point);
|
||||
|
||||
// Calculate the week number (WN) and time of week (TOW)
|
||||
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;
|
||||
const uint32_t sec_in_week = 604800;
|
||||
const uint32_t week_number = duration_sec.count() / sec_in_week;
|
||||
const uint32_t time_of_week = duration_sec.count() % sec_in_week;
|
||||
return compute_gst(week_number, time_of_week);
|
||||
}
|
||||
|
||||
|
||||
uint32_t Osnma_Helper::compute_gst_now()
|
||||
{
|
||||
std::chrono::time_point epoch_time_point = std::chrono::system_clock::from_time_t(mktime(&GST_START_EPOCH) - timezone);
|
||||
// auto time_utc = std::chrono::time_point_cast<std::chrono::seconds>(time).time_since_epoch();
|
||||
time_t now = time(nullptr);
|
||||
struct tm local_tm = *std::localtime(&now);
|
||||
struct tm utc_tm = *std::gmtime(&now);
|
||||
auto timezone_offset = std::mktime(&utc_tm) - std::mktime(&local_tm);
|
||||
auto epoch_time_point = std::chrono::system_clock::from_time_t(std::mktime(&GST_START_EPOCH) - timezone_offset) + std::chrono::seconds(13);
|
||||
auto duration_sec = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - epoch_time_point);
|
||||
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;
|
||||
const uint32_t sec_in_week = 604800;
|
||||
const uint32_t week_number = duration_sec.count() / sec_in_week;
|
||||
const uint32_t time_of_week = duration_sec.count() % sec_in_week;
|
||||
return compute_gst(week_number, time_of_week);
|
||||
}
|
||||
|
||||
|
||||
std::vector<uint8_t> Osnma_Helper::gst_to_uint8(uint32_t GST) const
|
||||
{
|
||||
std::vector<uint8_t> res;
|
||||
@ -145,12 +161,15 @@ std::vector<uint8_t> Osnma_Helper::convert_from_hex_string(const std::string& he
|
||||
|
||||
return result;
|
||||
}
|
||||
uint32_t Osnma_Helper::get_WN(uint32_t GST)
|
||||
|
||||
|
||||
uint32_t Osnma_Helper::get_WN(uint32_t GST) const
|
||||
{
|
||||
return (GST & 0xFFF00000) >> 20;
|
||||
}
|
||||
uint32_t Osnma_Helper::get_TOW(uint32_t GST)
|
||||
|
||||
|
||||
uint32_t Osnma_Helper::get_TOW(uint32_t GST) const
|
||||
{
|
||||
return GST & 0x000FFFFF;
|
||||
}
|
||||
|
||||
|
@ -18,27 +18,34 @@
|
||||
#define GNSS_SDR_OSNMA_HELPER_H
|
||||
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/** \addtogroup Core
|
||||
* \{ */
|
||||
/** \addtogroup System_Parameters
|
||||
* \{ */
|
||||
|
||||
class Osnma_Helper
|
||||
{
|
||||
public:
|
||||
Osnma_Helper() = default;
|
||||
Osnma_Helper();
|
||||
~Osnma_Helper() = default;
|
||||
uint32_t compute_gst(uint32_t WN, uint32_t TOW) const;
|
||||
uint32_t compute_gst(std::tm& input);
|
||||
uint32_t compute_gst_now();
|
||||
uint32_t get_WN(uint32_t GST);
|
||||
uint32_t get_TOW(uint32_t GST);
|
||||
uint32_t get_WN(uint32_t GST) const;
|
||||
uint32_t get_TOW(uint32_t GST) const;
|
||||
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::vector<uint8_t> convert_from_hex_string(const std::string& hex_string) const; // TODO remove similar function in gnss_crypto
|
||||
|
||||
std::tm GST_START_EPOCH = {0, 0, 0, 22, 8 - 1, 1999 - 1900, 0, 0, 0, 0, 0};
|
||||
std::tm GST_START_EPOCH{};
|
||||
};
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
#endif // GNSS_SDR_OSNMA_HELPER_H
|
||||
|
Loading…
Reference in New Issue
Block a user