mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-12 11:10:33 +00:00
[TAS-255] [BUG] Assure time synch. is properly done
if d_flag_debug=false, now system clock is used to for the receiver synchronisation. It uses the UTC time and the GST epoch start time (adjusted for local time zone difference) to create a local estimation of GST, then compares with GST_SIS (coming from NavData Words 5 and 6)
This commit is contained in:
parent
2db37f384e
commit
a47cf1187c
@ -112,6 +112,21 @@ 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){
|
||||
// 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?
|
||||
}
|
||||
else{
|
||||
d_GST_Rx = d_helper->compute_gst_now();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -138,6 +153,50 @@ void osnma_msg_receiver::msg_handler_osnma(const pmt::pmt_t& msg)
|
||||
LOG(INFO) << output_message.str();
|
||||
std::cout << output_message.str() << std::endl;
|
||||
|
||||
// Receiver time update
|
||||
d_GST_SIS = d_helper->compute_gst(nma_msg->WN_sf0, nma_msg->TOW_sf0);
|
||||
if (d_last_verified_key_GST == 0){
|
||||
d_last_received_GST = d_GST_SIS;
|
||||
}
|
||||
else if (d_GST_SIS > d_last_received_GST){
|
||||
d_last_received_GST = d_GST_SIS;
|
||||
}
|
||||
if (d_flag_debug){
|
||||
d_GST_Rx = d_last_received_GST;
|
||||
}
|
||||
else{
|
||||
d_GST_Rx = d_helper->compute_gst_now();
|
||||
}
|
||||
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;
|
||||
|
||||
// time constraint verification
|
||||
std::time_t delta_T = std::abs(static_cast<int64_t>(d_GST_Rx - d_GST_SIS));
|
||||
if (delta_T <= d_T_L)
|
||||
{
|
||||
d_tags_to_verify = {0, 4, 12};
|
||||
LOG(INFO) << "Galileo OSNMA: time constraint OK ( delta_T=" << delta_T << " s)";
|
||||
std::cout << "Galileo OSNMA: time constraint OK ( delta_T=" << delta_T << " s)" << std::endl;
|
||||
}
|
||||
else if (delta_T > d_T_L && delta_T <= 10 * d_T_L)
|
||||
{
|
||||
d_tags_to_verify = {12};
|
||||
LOG(WARNING) << "Galileo OSNMA: time constraint allows only slow MACs to be verified";
|
||||
std::cout << "Galileo OSNMA: |local_t - GST_SIS| < T_L [ |" << static_cast<int>(d_GST_Rx - d_GST_SIS) << " | < " << static_cast<int>(d_T_L) << " ]" << std::endl;
|
||||
LOG(WARNING) << "Galileo OSNMA: d_receiver_time: " << d_GST_Rx << " d_GST_SIS: " << d_GST_SIS;
|
||||
LOG(WARNING) << "Galileo OSNMA: |local_t - GST_SIS| < T_L [ |" << static_cast<int>(d_GST_Rx - d_GST_SIS) << " | < " << static_cast<int>(d_T_L) << " ]";
|
||||
}
|
||||
else
|
||||
{
|
||||
d_tags_to_verify = {};
|
||||
LOG(WARNING) << "Galileo OSNMA: time constraint violation";
|
||||
std::cerr << "Galileo OSNMA: time constraint violation" << std::endl;
|
||||
std::cerr << "Galileo OSNMA: | local_t - GST_SIS | < T_L [ | " << static_cast<int>(d_GST_Rx - d_GST_SIS) << " | < " << static_cast<int>(d_T_L) << " ]" << std::endl;
|
||||
LOG(WARNING) << "Galileo OSNMA: d_receiver_time: " << d_GST_Rx << " d_GST_SIS: " << d_GST_SIS;
|
||||
LOG(WARNING) << "Galileo OSNMA: | local_t - GST_SIS | < T_L [ | " << static_cast<int>(d_GST_Rx - d_GST_SIS) << " | < " << static_cast<int>(d_T_L) << " ]";
|
||||
return;
|
||||
}
|
||||
|
||||
process_osnma_message(nma_msg);
|
||||
} // OSNMA frame received
|
||||
else if (msg_type_hash_code == typeid(std::shared_ptr<std::tuple<uint32_t, std::string, uint32_t>>).hash_code()) // Navigation data bits for OSNMA received
|
||||
@ -159,7 +218,7 @@ void osnma_msg_receiver::msg_handler_osnma(const pmt::pmt_t& msg)
|
||||
}
|
||||
|
||||
// Send the resulting decoded NMA data (if available) to PVT
|
||||
if (d_new_data) // TODO where is it set to true?
|
||||
if (d_new_data)
|
||||
{
|
||||
auto osnma_data_ptr = std::make_shared<OSNMA_data>(d_osnma_data);
|
||||
this->message_port_pub(pmt::mp("OSNMA_to_PVT"), pmt::make_any(osnma_data_ptr));
|
||||
@ -177,13 +236,14 @@ void osnma_msg_receiver::process_osnma_message(const std::shared_ptr<OSNMA_msg>&
|
||||
}
|
||||
read_nma_header(osnma_msg->hkroot[0]);
|
||||
|
||||
// Check for corner cases: renewal, revocation
|
||||
// Check for corner cases: renewal, revocation, alert message
|
||||
if (d_osnma_data.d_nma_header.nmas == 0 /* RES */){
|
||||
LOG(WARNING) << "Galileo OSNMA: NMAS invalid (RES), skipping osnma message";
|
||||
return;
|
||||
}
|
||||
// TODO - trusting the NMAS and CPKS shall be done upon PKR verification or Tag verification.
|
||||
// It's ok to activate the flags, but the final decision should happen after verifying it.
|
||||
// For OAM is solved, but NPK and PKREV I think not yet
|
||||
if (d_osnma_data.d_nma_header.nmas == 2 /* OP */ && d_osnma_data.d_nma_header.cpks == 4 /* NPK */ && d_GST_PKR_PKREV_start == 0){
|
||||
d_flag_PK_renewal = true;
|
||||
d_GST_PKR_PKREV_start = d_helper->compute_gst(osnma_msg->WN_sf0, osnma_msg->TOW_sf0);
|
||||
@ -229,9 +289,9 @@ void osnma_msg_receiver::process_osnma_message(const std::shared_ptr<OSNMA_msg>&
|
||||
read_dsm_header(osnma_msg->hkroot[1]);
|
||||
read_dsm_block(osnma_msg);
|
||||
process_dsm_block(osnma_msg); // will process dsm block if received a complete one, then will call mack processing upon re-setting the dsm block to 0
|
||||
if (d_osnma_data.d_dsm_kroot_message.towh_k != 0)
|
||||
{
|
||||
local_time_verification(osnma_msg);
|
||||
if (d_osnma_data.d_dsm_kroot_message.towh_k != 0){
|
||||
d_GST_0 = d_helper->compute_gst(d_osnma_data.d_dsm_kroot_message.wn_k, d_osnma_data.d_dsm_kroot_message.towh_k * 3600);
|
||||
d_GST_Sf = d_GST_0 + 30 * std::floor((d_GST_SIS - d_GST_0) / 30); // Eq. 3 R.G.
|
||||
}
|
||||
read_and_process_mack_block(osnma_msg); // only process them if at least 3 available.
|
||||
}
|
||||
@ -350,63 +410,6 @@ void osnma_msg_receiver::read_dsm_block(const std::shared_ptr<OSNMA_msg>& osnma_
|
||||
std::cout << available_blocks.str() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function to verify the local time based on GST_SIS and GST_0
|
||||
*
|
||||
* @param osnma_msg Shared pointer to OSNMA message structure
|
||||
*/
|
||||
void osnma_msg_receiver::local_time_verification(const std::shared_ptr<OSNMA_msg>& osnma_msg)
|
||||
{
|
||||
// compute local time based on GST_SIS and GST_0
|
||||
d_GST_SIS = (osnma_msg->WN_sf0 & 0x00000FFF) << 20 | (osnma_msg->TOW_sf0 & 0x000FFFFF);
|
||||
// std::cout << "Galileo OSNMA: d_GST_SIS: " << d_GST_SIS << std::endl;
|
||||
// d_GST_0 = d_osnma_data.d_dsm_kroot_message.towh_k + 604800 * d_osnma_data.d_dsm_kroot_message.wn_k + 30;
|
||||
d_GST_0 = ((d_osnma_data.d_dsm_kroot_message.wn_k & 0x00000FFF) << 20 | (d_osnma_data.d_dsm_kroot_message.towh_k * 3600 & 0x000FFFFF)); // applicable time (GST_Kroot + 30)
|
||||
// d_GST_0 = d_osnma_data.d_dsm_kroot_message.towh_k + 604800 * d_osnma_data.d_dsm_kroot_message.wn_k + 30;
|
||||
// TODO store list of SVs sending OSNMA and if received ID matches one stored, then just increment time 30s for that ID.
|
||||
if (d_receiver_time != 0)
|
||||
{
|
||||
d_receiver_time = d_GST_0 + 30 * std::floor((d_GST_SIS - d_GST_0) / 30); // Eq. 3 R.G.
|
||||
// d_receiver_time += 30;
|
||||
// std::cout << "Galileo OSNMA: d_receiver_time: " << d_receiver_time << std::endl;
|
||||
}
|
||||
else
|
||||
{ // local time not initialised -> compute it.
|
||||
d_receiver_time = d_GST_0 + 30 * std::floor((d_GST_SIS - d_GST_0) / 30); // Eq. 3 R.G.
|
||||
// std::cout << "Galileo OSNMA: d_receiver_time: " << d_receiver_time << std::endl;
|
||||
}
|
||||
// verify time constraint
|
||||
std::time_t delta_T = std::abs(static_cast<int64_t>(d_receiver_time - d_GST_SIS));
|
||||
if (delta_T <= d_T_L)
|
||||
{
|
||||
d_tags_allowed = tags_to_verify::all;
|
||||
d_tags_to_verify = {0, 4, 12};
|
||||
LOG(INFO) << "Galileo OSNMA: time constraint OK ( delta_T=" << delta_T << " s)";
|
||||
// LOG(INFO) << "Galileo OSNMA: d_receiver_time: " << d_receiver_time << " d_GST_SIS: " << d_GST_SIS;
|
||||
// std::cout << "( |local_t - GST_SIS| < T_L ) [ |" << static_cast<int>(d_receiver_time - d_GST_SIS)<< " | < " << static_cast<int>(d_T_L) << " ]" << std::endl;
|
||||
|
||||
// TODO set flag to false to avoid processing dsm and MACK messages
|
||||
}
|
||||
else if (delta_T > d_T_L && delta_T <= 10 * d_T_L)
|
||||
{
|
||||
d_tags_allowed = tags_to_verify::slow_eph;
|
||||
d_tags_to_verify = {12};
|
||||
LOG(WARNING) << "Galileo OSNMA: time constraint allows only slow MACs to be verified";
|
||||
LOG(WARNING) << "Galileo OSNMA: d_receiver_time: " << d_receiver_time << " d_GST_SIS: " << d_GST_SIS;
|
||||
LOG(WARNING) << "Galileo OSNMA: ( |local_t - GST_SIS| < T_L ) [ |" << static_cast<int>(d_receiver_time - d_GST_SIS) << " | < " << static_cast<int>(d_T_L) << " ]";
|
||||
}
|
||||
else
|
||||
{
|
||||
d_tags_allowed = tags_to_verify::none;
|
||||
d_tags_to_verify = {};
|
||||
LOG(WARNING) << "Galileo OSNMA: time constraint violation";
|
||||
LOG(WARNING) << "Galileo OSNMA: d_receiver_time: " << d_receiver_time << " d_GST_SIS: " << d_GST_SIS;
|
||||
LOG(WARNING) << "Galileo OSNMA: ( |local_t - GST_SIS| < T_L ) [ |" << static_cast<int>(d_receiver_time - d_GST_SIS) << " | < " << static_cast<int>(d_T_L) << " ]";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Process DSM block of an OSNMA message.
|
||||
*
|
||||
@ -671,7 +674,6 @@ void osnma_msg_receiver::process_dsm_message(const std::vector<uint8_t>& dsm_msg
|
||||
else if (d_flag_alert_message){
|
||||
LOG(WARNING) << "Galileo OSNMA: DSM-PKR verification :: Alert message verification :: SUCCESS. OSNMA disabled. Contact Galileo Service Centre";
|
||||
std::cout << "Galileo OSNMA: DSM-PKR verification :: Alert message verification :: SUCCESS. OSNMA disabled. Contact Galileo Service Centre" << std::endl;
|
||||
|
||||
}
|
||||
else{
|
||||
d_crypto->d_PublicKeyType = PKT;
|
||||
@ -686,7 +688,6 @@ void osnma_msg_receiver::process_dsm_message(const std::vector<uint8_t>& dsm_msg
|
||||
d_count_failed_pubKey ++;
|
||||
if (d_flag_alert_message){
|
||||
d_flag_alert_message = false; // disregard message as its authenticity could not be verified.
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -725,8 +726,7 @@ void osnma_msg_receiver::read_and_process_mack_block(const std::shared_ptr<OSNMA
|
||||
(d_osnma_data.d_nma_header.nmas == 3 && !d_kroot_verified); // NMAS is DU, but must be disregarded
|
||||
bool can_verify_tesla_key = d_kroot_verified || d_tesla_key_verified; // Either of those suffices for verifying the incoming TESLA key
|
||||
bool can_parse_tag_fields = d_osnma_data.d_dsm_kroot_message.ts != 0; // calculating the number of tags is based on the TS of the DSM-KROOT.
|
||||
if (can_verify_tesla_key && can_parse_tag_fields && can_process_mack_block)
|
||||
{ // 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
|
||||
if (can_verify_tesla_key && can_parse_tag_fields && can_process_mack_block){
|
||||
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;
|
||||
@ -1012,14 +1012,8 @@ void osnma_msg_receiver::process_mack_message()
|
||||
{
|
||||
LOG(WARNING) << "Galileo OSNMA: MACK cannot be processed, "
|
||||
<< "no Kroot nor TESLA key available.";
|
||||
if (!d_flag_debug)
|
||||
{
|
||||
return; // early return, cannot proceed further without one of the two verified. this equals to having Kroot but no TESLa key yet.
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << "Galileo OSNMA: But it will be processed for debugging purposes.";
|
||||
}
|
||||
|
||||
}
|
||||
// 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.get_tow_sf0()) == d_tesla_keys.end()) // check if already available => no need to verify
|
||||
@ -1425,14 +1419,14 @@ void osnma_msg_receiver::display_data()
|
||||
bool osnma_msg_receiver::verify_tesla_key(std::vector<uint8_t>& key, uint32_t TOW)
|
||||
{
|
||||
uint32_t num_of_hashes_needed;
|
||||
uint32_t GST_SFi = d_receiver_time - 30; // GST of target key is to be used.
|
||||
uint32_t GST_SFi = d_GST_Sf - 30; // GST of target key is to be used.
|
||||
std::vector<uint8_t> hash;
|
||||
const uint8_t lk_bytes = d_dsm_reader->get_lk_bits(d_osnma_data.d_dsm_kroot_message.ks) / 8;
|
||||
std::vector<uint8_t> validated_key;
|
||||
if (d_tesla_key_verified)
|
||||
{ // have to go up to last verified key
|
||||
validated_key = d_tesla_keys.rbegin()->second;
|
||||
num_of_hashes_needed = (d_receiver_time - d_last_verified_key_GST) / 30; // Eq. 19 ICD modified
|
||||
num_of_hashes_needed = (d_GST_Sf - d_last_verified_key_GST) / 30; // Eq. 19 ICD modified
|
||||
LOG(INFO) << "Galileo OSNMA: TESLA verification (" << num_of_hashes_needed << " hashes) need to be performed up to closest verified TESLA key";
|
||||
|
||||
hash = hash_chain(num_of_hashes_needed, key, GST_SFi, lk_bytes);
|
||||
@ -1440,7 +1434,7 @@ bool osnma_msg_receiver::verify_tesla_key(std::vector<uint8_t>& key, uint32_t TO
|
||||
else
|
||||
{ // have to go until Kroot
|
||||
validated_key = d_osnma_data.d_dsm_kroot_message.kroot;
|
||||
num_of_hashes_needed = (d_receiver_time - d_GST_0) / 30 + 1; // Eq. 19 IC
|
||||
num_of_hashes_needed = (d_GST_Sf - d_GST_0) / 30 + 1; // Eq. 19 IC
|
||||
LOG(INFO) << "Galileo OSNMA: TESLA verification (" << num_of_hashes_needed << " hashes) need to be performed up to Kroot";
|
||||
|
||||
hash = hash_chain(num_of_hashes_needed, key, GST_SFi, lk_bytes);
|
||||
@ -1458,24 +1452,16 @@ bool osnma_msg_receiver::verify_tesla_key(std::vector<uint8_t>& key, uint32_t TO
|
||||
std::cout << "Galileo OSNMA: TESLA key verification :: SUCCESS!" << std::endl;
|
||||
d_tesla_keys.insert(std::pair<uint32_t, std::vector<uint8_t>>(TOW, key));
|
||||
d_tesla_key_verified = true;
|
||||
d_last_verified_key_GST = d_receiver_time;
|
||||
d_last_verified_key_GST = d_GST_Sf;
|
||||
}
|
||||
else if (num_of_hashes_needed > 0)
|
||||
{
|
||||
LOG(WARNING) << "Galileo OSNMA: TESLA key verification :: FAILED";
|
||||
std::cerr << "Galileo OSNMA: TESLA key verification :: FAILED" << std::endl;
|
||||
if (d_flag_debug)
|
||||
{
|
||||
d_tesla_keys.insert(std::pair<uint32_t, std::vector<uint8_t>>(TOW, key));
|
||||
d_last_verified_key_GST = d_receiver_time;
|
||||
d_tesla_key_verified = true;
|
||||
// TODO - if intermediate verification fails, can one still use the former verified tesla key or should go to Kroot or even retrieve new Kroot?
|
||||
}
|
||||
}
|
||||
return d_tesla_key_verified;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Removes the tags that have been verified from the multimap d_tags_awaiting_verify.
|
||||
*
|
||||
@ -1582,7 +1568,7 @@ void osnma_msg_receiver::control_tags_awaiting_verify_size()
|
||||
bool osnma_msg_receiver::verify_macseq(const MACK_message& mack)
|
||||
{
|
||||
// MACSEQ verification
|
||||
d_GST_Sf = d_receiver_time - 30; // time of the start of SF containing MACSEQ // TODO buffer with times? since out of debug not every 30 s a Sf is necessarily received..
|
||||
uint32_t GST_SFi = d_GST_Sf - 30; // time of the start of SF containing MACSEQ
|
||||
std::vector<uint8_t> applicable_key = d_tesla_keys[mack.TOW + 30]; // current tesla key ie transmitted in the next subframe
|
||||
std::vector<std::string> sq1{};
|
||||
std::vector<std::string> sq2{};
|
||||
@ -1594,7 +1580,6 @@ bool osnma_msg_receiver::verify_macseq(const MACK_message& mack)
|
||||
sq1 = it->second.sequence1;
|
||||
sq2 = it->second.sequence2;
|
||||
}
|
||||
|
||||
// Assign relevant sequence based on subframe time
|
||||
if (mack.TOW % 60 < 30) // tried GST_Sf and it does not support the data present.
|
||||
{
|
||||
@ -1635,10 +1620,10 @@ bool osnma_msg_receiver::verify_macseq(const MACK_message& mack)
|
||||
// Fixed as well as FLX Tags share first part - Eq. 22 ICD
|
||||
std::vector<uint8_t> m(5 + 2 * flxTags.size()); // each flx tag brings two bytes
|
||||
m[0] = static_cast<uint8_t>(mack.PRNa); // PRN_A - SVID of the satellite transmiting the tag
|
||||
m[1] = static_cast<uint8_t>((d_GST_Sf & 0xFF000000) >> 24); // TODO d_GST_Sf left useless
|
||||
m[2] = static_cast<uint8_t>((d_GST_Sf & 0x00FF0000) >> 16);
|
||||
m[3] = static_cast<uint8_t>((d_GST_Sf & 0x0000FF00) >> 8);
|
||||
m[4] = static_cast<uint8_t>(d_GST_Sf & 0x000000FF);
|
||||
m[1] = static_cast<uint8_t>((GST_SFi & 0xFF000000) >> 24);
|
||||
m[2] = static_cast<uint8_t>((GST_SFi & 0x00FF0000) >> 16);
|
||||
m[3] = static_cast<uint8_t>((GST_SFi & 0x0000FF00) >> 8);
|
||||
m[4] = static_cast<uint8_t>(GST_SFi & 0x000000FF);
|
||||
// Case tags flexible - Eq. 21 ICD
|
||||
for (size_t i = 0; i < flxTags.size(); i++)
|
||||
{
|
||||
@ -1823,7 +1808,7 @@ std::vector<MACK_tag_and_info> osnma_msg_receiver::verify_macseq_new(const MACK_
|
||||
std::vector<MACK_tag_and_info> verified_tags{};
|
||||
|
||||
// MACSEQ verification
|
||||
d_GST_Sf = d_receiver_time - 30; // time of the start of SF containing MACSEQ // TODO buffer with times? since out of debug not every 30 s a Sf is necessarily received.
|
||||
uint32_t GST_Sfi = d_GST_Sf - 30; // time of the start of SF containing MACSEQ
|
||||
std::vector<uint8_t> applicable_key;
|
||||
const auto key_it = d_tesla_keys.find(mack.TOW + 30); // current tesla key ie transmitted in the next subframe
|
||||
if (key_it != d_tesla_keys.cend())
|
||||
@ -1891,10 +1876,10 @@ std::vector<MACK_tag_and_info> osnma_msg_receiver::verify_macseq_new(const MACK_
|
||||
// Fixed as well as FLX Tags share first part - Eq. 22 ICD
|
||||
std::vector<uint8_t> m(5 + 2 * flxTags.size()); // each flx tag brings two bytes
|
||||
m[0] = static_cast<uint8_t>(mack.PRNa); // PRN_A - SVID of the satellite transmiting the tag
|
||||
m[1] = static_cast<uint8_t>((d_GST_Sf & 0xFF000000) >> 24); // TODO d_GST_Sf left useless
|
||||
m[2] = static_cast<uint8_t>((d_GST_Sf & 0x00FF0000) >> 16);
|
||||
m[3] = static_cast<uint8_t>((d_GST_Sf & 0x0000FF00) >> 8);
|
||||
m[4] = static_cast<uint8_t>(d_GST_Sf & 0x000000FF);
|
||||
m[1] = static_cast<uint8_t>((GST_Sfi & 0xFF000000) >> 24);
|
||||
m[2] = static_cast<uint8_t>((GST_Sfi & 0x00FF0000) >> 16);
|
||||
m[3] = static_cast<uint8_t>((GST_Sfi & 0x0000FF00) >> 8);
|
||||
m[4] = static_cast<uint8_t>(GST_Sfi & 0x000000FF);
|
||||
// Case tags flexible - Eq. 21 ICD
|
||||
for (size_t i = 0; i < flxTags.size(); i++)
|
||||
{
|
||||
|
@ -73,7 +73,6 @@ private:
|
||||
void read_nma_header(uint8_t nma_header);
|
||||
void read_dsm_header(uint8_t dsm_header);
|
||||
void read_dsm_block(const std::shared_ptr<OSNMA_msg>& osnma_msg);
|
||||
void local_time_verification(const std::shared_ptr<OSNMA_msg>& osnma_msg);
|
||||
void process_dsm_block(const std::shared_ptr<OSNMA_msg>& osnma_msg);
|
||||
void process_dsm_message(const std::vector<uint8_t>& dsm_msg, const uint8_t& nma_header);
|
||||
void read_and_process_mack_block(const std::shared_ptr<OSNMA_msg>& osnma_msg);
|
||||
@ -118,35 +117,24 @@ private:
|
||||
|
||||
OSNMA_data d_osnma_data{};
|
||||
|
||||
enum tags_to_verify
|
||||
{
|
||||
all,
|
||||
utc,
|
||||
slow_eph,
|
||||
eph,
|
||||
none
|
||||
};
|
||||
tags_to_verify d_tags_allowed{tags_to_verify::all};
|
||||
std::time_t d_receiver_time{0};
|
||||
|
||||
uint32_t d_GST_Sf{}; // C: used for MACSEQ and Tesla Key verification TODO need really to be global var?
|
||||
uint32_t d_last_verified_key_GST{0};
|
||||
uint32_t d_GST_0{};
|
||||
uint32_t d_GST_SIS{};
|
||||
uint32_t d_last_received_GST{0}; // latest GST received
|
||||
uint32_t d_GST_Sf{}; // Scaled GST time for cryptographic computations
|
||||
uint32_t d_GST_Rx{0}; // local GST receiver time
|
||||
uint32_t d_last_verified_key_GST{0}; // GST for the latest verified TESLA key
|
||||
uint32_t d_GST_0{}; // Time of applicability GST (KROOT + 30 s)
|
||||
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 d_Lt_min{}; // minimum equivalent tag length
|
||||
uint8_t d_Lt_verified_eph{0}; // verified tag bits - ephemeris
|
||||
uint8_t d_Lt_verified_utc{0}; // verified tag bits - timing
|
||||
uint8_t const d_T_L{30}; // s RG Section 2.1
|
||||
uint8_t const d_delta_COP{30}; // s SIS ICD Table 14
|
||||
|
||||
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{false};
|
||||
bool d_flag_debug{true};
|
||||
bool d_flag_hot_start{false};
|
||||
bool d_flag_PK_renewal{false};
|
||||
bool d_flag_PK_revocation{false};
|
||||
|
@ -19,13 +19,37 @@
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <sstream>
|
||||
#include <ctime> // timezone
|
||||
|
||||
uint32_t Osnma_Helper::compute_gst(uint32_t WN, uint32_t TOW) const
|
||||
{
|
||||
uint32_t GST = (WN & 0x00000FFF) << 20 | (TOW & 0x000FFFFF);
|
||||
return GST;
|
||||
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));
|
||||
auto input_time_point = std::chrono::system_clock::from_time_t(mktime(&input));
|
||||
|
||||
// Get the duration from epoch in seconds
|
||||
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;
|
||||
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();
|
||||
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;
|
||||
return compute_gst(week_number, time_of_week);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Osnma_Helper::gst_to_uint8(uint32_t GST) const
|
||||
{
|
||||
@ -121,3 +145,12 @@ 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)
|
||||
{
|
||||
return (GST & 0xFFF00000) >> 20;
|
||||
}
|
||||
uint32_t Osnma_Helper::get_TOW(uint32_t GST)
|
||||
{
|
||||
return GST & 0x000FFFFF;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#define GNSS_SDR_OSNMA_HELPER_H
|
||||
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -27,11 +28,18 @@ public:
|
||||
Osnma_Helper() = default;
|
||||
~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);
|
||||
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};
|
||||
|
||||
};
|
||||
|
||||
#endif // GNSS_SDR_OSNMA_HELPER_H
|
||||
|
@ -252,10 +252,9 @@ TEST_F(OsnmaMsgReceiverTest, TeslaKeyVerification)
|
||||
osnma->d_osnma_data.d_dsm_kroot_message.kroot = {0x5B, 0xF8, 0xC9, 0xCB, 0xFC, 0xF7, 0x04, 0x22, 0x08, 0x14, 0x75, 0xFD, 0x44, 0x5D, 0xF0, 0xFF}; // Kroot, TOW 345570 GST_0 - 30
|
||||
osnma->d_osnma_data.d_dsm_kroot_message.ks = 4; // TABLE 10 --> 128 bits
|
||||
osnma->d_osnma_data.d_dsm_kroot_message.alpha = 0x610BDF26D77B;
|
||||
// local_time_verification would do this operation. TODO - eliminate duplication.
|
||||
osnma->d_GST_SIS = (1248 & 0x00000FFF) << 20 | (345630 & 0x000FFFFF);
|
||||
osnma->d_GST_0 = ((1248 & 0x00000FFF) << 20 | (345600 & 0x000FFFFF)); // applicable time (GST_Kroot + 30)
|
||||
osnma->d_receiver_time = osnma->d_GST_0 + 30 * std::floor((osnma->d_GST_SIS - osnma->d_GST_0) / 30); // Eq. 3 R.G.//345630;
|
||||
osnma->d_GST_Sf = osnma->d_GST_0 + 30 * std::floor((osnma->d_GST_SIS - osnma->d_GST_0) / 30); // Eq. 3 R.G.
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user