From 37b343391c13db4ad062f891f497c520479139e9 Mon Sep 17 00:00:00 2001
From: cesaaargm
Date: Sat, 16 Mar 2024 19:05:01 +0100
Subject: [PATCH 1/4] Refactor tag verification logic WIP
---
src/core/libs/osnma_msg_receiver.cc | 614 ++++++++++++++---------
src/core/libs/osnma_msg_receiver.h | 17 +-
src/core/system_parameters/osnma_data.cc | 1 +
src/core/system_parameters/osnma_data.h | 41 ++
4 files changed, 439 insertions(+), 234 deletions(-)
diff --git a/src/core/libs/osnma_msg_receiver.cc b/src/core/libs/osnma_msg_receiver.cc
index f439b97b8..21fe08b1e 100644
--- a/src/core/libs/osnma_msg_receiver.cc
+++ b/src/core/libs/osnma_msg_receiver.cc
@@ -38,6 +38,7 @@
#if PMT_USES_BOOST_ANY
#include
+#include
namespace wht = boost;
#else
#include
@@ -169,7 +170,7 @@ void osnma_msg_receiver::read_dsm_header(uint8_t dsm_header)
}
/*
- * accumulates dsm messages until completeness, then calls process_dsm_message
+ * accumulates dsm messages
* */
void osnma_msg_receiver::read_dsm_block(const std::shared_ptr& osnma_msg)
{
@@ -559,9 +560,12 @@ void osnma_msg_receiver::read_and_process_mack_block(const std::shared_ptr& osnma_msg)
{
d_flag_debug = true;
- // populate d_nav_data with needed data from subframe
- d_osnma_data.d_nav_data.init(osnma_msg);
- // store MACK, KROOT and NavData needed.
- d_old_OSNMA_buffer.push_back(d_osnma_data);
- if(d_old_OSNMA_buffer.size() < 3)
- {
- std::cerr << "Galileo OSNMA: MACK cannot be processed. "<< ", "
- << "Not enough OSNMA messages available"
- << "buffer size: "<< d_old_OSNMA_buffer.size() << std::endl;
- return;
- }
+
if(d_kroot_verified == false && d_tesla_key_verified == false)
{
std::cerr << "Galileo OSNMA: MACK cannot be processed. "<< ", "
- << "No Kroot nor TESLA key available" << std::endl;
+ << "No Kroot nor TESLA key available" << std::endl;
if(!d_flag_debug)
return; // early return, cannot proceed further without one of the two verified.
}
-
- // Verify tesla key
- if(d_tesla_key_verified || d_flag_debug)
- {
- // TODO - find out I bt. both tesla keys, then hash until then, then compare.
- // retrieve latest tesla key
- // compute hashes needed
- // hash current key until num_hashes and compare
+ // verify tesla key and add it to the container of verified keys if successful
+ bool retV = verify_tesla_key(d_osnma_data.d_mack_message.key);
+ if(retV){
+ d_tesla_keys.insert(std::pair(d_osnma_data.d_nav_data.TOW_sf0, d_osnma_data.d_mack_message.key));
}
- else
- {// have to go until Kroot
- uint32_t num_of_hashes_needed = (d_receiver_time - d_GST_0) / 30 + 1; // Eq. 19 ICD
- std::cout << "Galileo OSNMA: TESLA verification ("<< num_of_hashes_needed << " hashes) need to be performed. " << std::endl;
- auto start = std::chrono::high_resolution_clock::now();
- uint32_t GST_SFi = d_receiver_time;
- std::vector K_II = d_osnma_data.d_mack_message.key;
- std::vector K_I; // result of the recursive hash operations
- const uint8_t lk_bytes = d_dsm_reader->get_lk_bits(d_osnma_data.d_dsm_kroot_message.ks)/8;
- // compute the tesla key for current SF (GST_SFi and K_II change in each iteration)
- for (uint32_t i = 1; i < num_of_hashes_needed ; i++)
- {
- // build message digest m = (K_I+1 || GST_SFi || alpha)
- // TODO sizeof() wrong.
- std::vector msg(sizeof(K_II) + sizeof(GST_SFi) + sizeof(d_osnma_data.d_dsm_kroot_message.alpha));
- std::copy(K_II.begin(),K_II.end(),msg.begin());
- msg.push_back((d_GST_Sf & 0xFF000000) >> 24);
- msg.push_back((d_GST_Sf & 0x00FF0000) >> 16);
- msg.push_back((d_GST_Sf & 0x0000FF00) >> 8);
- msg.push_back(d_GST_Sf & 0x000000FF);
- // extract alpha
- for (int k = 5; k >= 0;k--)
- {
- // TODO: static extracts the MSB in case from larger to shorter int?
- msg.push_back(static_cast((d_osnma_data.d_dsm_kroot_message.alpha >> (i * 8)) & 0xFF)); // extract first 6 bytes of alpha.
- }
- // compute hash
- std::vector hash;
- if (d_osnma_data.d_dsm_kroot_message.hf == 0) // Table 8.
- {
- hash = d_crypto->computeSHA256(msg);
- }
- else if (d_osnma_data.d_dsm_kroot_message.hf == 2)
- {
- hash = d_crypto->computeSHA3_256(msg);
- }
+ // MACSEQ - verify current macks, then add current retrieved mack to the end.
+ for (auto& mack : d_macks_awating_MACSEQ_verification){
+ if(d_tesla_keys.find(mack.TOW) != d_tesla_keys.end()){
+ bool ret = verify_macseq(mack);
+
+ }
+
+ }
+ // TODO verify MACSEQ of FLX tags
+ // add newly retrieved tags to the container
+ for (const auto& MTI: d_osnma_data.d_mack_message.tag_and_info){
+ Tag tag(MTI, d_osnma_data.d_nav_data.TOW_sf0, d_osnma_data.d_nav_data.PRNa);
+ d_tags_awaiting_verify.insert({tag.TOW, tag});
+ }
+
+ // d_satellite_data already updated from a msg_handler coming from TD. TODO
+
+// d_old_OSNMA_buffer.push_back(d_osnma_data); // TODO deprecate
+// if(d_keys.size() < 2)
+// {
+// std::cerr << "Galileo OSNMA: MACK cannot be processed. "<< ", "
+// << "Not enough OSNMA messages available"
+// << "buffer size: "<< d_old_OSNMA_buffer.size() << std::endl;
+// return;
+// }
+
+ // verify tags
+ for (auto it = d_tags_awaiting_verify.begin(); it != d_tags_awaiting_verify.end(); ++it){
+ bool ret;
+ if(d_tesla_keys.find(it->first) != d_tesla_keys.end() && nav_data_available(it->second)){
+ ret = verify_tag(it->second);
+ if(ret)
+ int a;
+ // TODO notify PVT via pmt
else
- {
- hash = std::vector(32);
- }
- // truncate hash
- K_I.reserve(lk_bytes); // TODO - case hash function has 512 bits
- for (uint16_t i = 0; i < lk_bytes; i++)
- {
- K_I.push_back(hash[i]);
- }
-
- // set parameters for next iteration
- GST_SFi -= 30; // next SF time is the actual minus 30 seconds
- K_II = K_I; // next key is the actual one
- K_I.clear(); // empty the actual one for a new computation
- }
- // compare computed current key against received key
- auto end = std::chrono::high_resolution_clock::now();
- std::chrono::duration elapsed = end - start;
- std::cout << "Galileo OSNMA: TESLA verification ("<< num_of_hashes_needed << " hashes) took " << elapsed.count() << " seconds.\n";
-
- if(K_II.size() != d_osnma_data.d_mack_message.key.size())
- {
- std::cout << "Galileo OSNMA: Error during tesla key verification. " << std::endl;
- return;
- }
- if (K_II == d_osnma_data.d_mack_message.key)
- {
- std::cout << "Galileo OSNMA: tesla key verified successfully " << std::endl;
- d_tesla_key_verified = true;
- // TODO - propagate result
- // TODO - save current tesla key as latest one? propose a map with
- // TODO - Tags Sequence Verification: check ADKD[i] follows MACLT sequence
- }
- else
-
- {
- std::cerr << "Galileo OSNMA: Error during tesla key verification. " << std::endl;
- if(!d_flag_debug)
- return;
+ int a;
+ // also
}
}
+ remove_verified_tags();
+
+ control_tags_awaiting_verify_size(); // remove oldest tags if size is too big.
+
+
+
+
+
+
+
+
+
+
+
+
// verify MACK tags - MACSEQ
OSNMA_data applicable_OSNMA = d_old_OSNMA_buffer[d_old_OSNMA_buffer.size() - 2]; // former subframe
- d_GST_Sf = d_GST_SIS - 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..
+
+ //d_GST_Sf = d_GST_SIS - 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..
std::vector applicable_key = d_old_OSNMA_buffer.back().d_mack_message.key; // current tesla key ie transmitted in the next subframe
std::vector sq1{};
std::vector sq2{};
@@ -968,7 +935,6 @@ void osnma_msg_receiver::process_mack_message(const std::shared_ptr&
{
std::cout << "Galileo OSNMA: Mismatch in the GST verification. " << std::endl;
}
- // compare ADKD of Mack tags with MACLT defined ADKDs
if(applicable_OSNMA.d_mack_message.tag_and_info.size() != applicable_sequence.size()-1)
{
std::cout << "Galileo OSNMA: Number of retrieved tags does not match MACLT sequence size!" << std::endl;
@@ -976,6 +942,7 @@ void osnma_msg_receiver::process_mack_message(const std::shared_ptr&
}
std::vector flxTags {};
std::string tempADKD;
+ // MACLT verification
for (uint8_t i = 0; i < applicable_OSNMA.d_mack_message.tag_and_info.size(); i++)
{
tempADKD = applicable_sequence[i+1];
@@ -989,121 +956,96 @@ void osnma_msg_receiver::process_mack_message(const std::shared_ptr&
}
}
- // MACSEQ verification
- // Fixed as well as FLX Tags share first part - Eq. 22 ICD
- std::vector m(5 + 2 * flxTags.size()); // each flx tag brings two bytes
- m[0] = static_cast(applicable_OSNMA.d_nav_data.PRNa); // PRN_A - SVID of the satellite transmiting the tag
- m[1] = static_cast((d_GST_Sf & 0xFF000000) >> 24);
- m[2] = static_cast((d_GST_Sf & 0x00FF0000) >> 16);
- m[3] = static_cast((d_GST_Sf & 0x0000FF00) >> 8);
- m[4] = static_cast(d_GST_Sf & 0x000000FF);
-
- // Case tags flexible - Eq. 21 ICD
- for (uint8_t i = 0; i < flxTags.size() ; i++)
- {
- m[2*i + 5] = applicable_OSNMA.d_mack_message.tag_and_info[flxTags[i]].tag_info.PRN_d;
- m[2*i + 6] = applicable_OSNMA.d_mack_message.tag_and_info[flxTags[i]].tag_info.ADKD << 4 |
- applicable_OSNMA.d_mack_message.tag_and_info[flxTags[i]].tag_info.cop;
- }
-// m = {0x18, 0x4f, 0x93, 0x53, 0x04, 0x05, 0x0f, 0x1f, 0x0f};
-// applicable_key = {0x11, 0x26, 0x47, 0x3b, 0x0e, 0x05, 0x05, 0x35,
-// 0xb0, 0xf2, 0xa7, 0x24, 0x00, 0x22, 0xba, 0x8f};
-// applicable_OSNMA.d_mack_message.header.macseq = 0xbb8;
- // compute mac
- std::vector mac;
- if (applicable_OSNMA.d_dsm_kroot_message.mf == 0) // C: HMAC-SHA-256
- {
- mac = d_crypto->computeHMAC_SHA_256(applicable_key, m);
- }
- else if (applicable_OSNMA.d_dsm_kroot_message.mf == 1) // C: CMAC-AES
- {
- mac = d_crypto->computeCMAC_AES(applicable_key, m);
- }
- // Truncate the twelve MSBits and compare with received MACSEQ
- uint16_t mac_msb = 0;
- if (!mac.empty())
- {
- mac_msb = (mac[0] << 8) + mac[1];
- }
- uint16_t computed_macseq = (mac_msb & 0xFFF0) >> 4;
// Verify tags if MACSEQ is authenticated
- if (computed_macseq == applicable_OSNMA.d_mack_message.header.macseq)
- { // TODO this shall affect only flx tags verification - and currently all tags of a MACK are affected which is undesired
- std::cout << "OSNMA: MACSEQ authenticated for PRN_A "
+ bool flxTagsV = false;
+ if (computed_macseq == applicable_OSNMA.d_mack_message.header.macseq && flxTags.size() > 0)
+ {
+ std::cout << "Galileo OSNMA: FLX tags authenticated for PRN_A "
<< osnma_msg->PRN << " with WN="
<< osnma_msg->WN_sf0 << ", TOW="
<< osnma_msg->TOW_sf0 << ". Verifying tags. "
<< std::endl;
- uint8_t lt_bits = 0;
- const auto it2 = OSNMA_TABLE_11.find(d_osnma_data.d_dsm_kroot_message.ts);
- if (it2 != OSNMA_TABLE_11.cend())
- {
- lt_bits = it2->second;
- }
- if (lt_bits == 0)
- {
- return; // C: TODO if Tag length is 0, what is the action? no verification possible of NavData for sure.
+ flxTagsV = true;
+ }
+
+ uint8_t lt_bits = 0;
+ const auto it2 = OSNMA_TABLE_11.find(d_osnma_data.d_dsm_kroot_message.ts);
+ if (it2 != OSNMA_TABLE_11.cend())
+ {
+ lt_bits = it2->second;
+ }
+ if (lt_bits == 0)
+ {
+ return; // C: TODO if Tag length is 0, what is the action? no verification possible of NavData for sure.
+ }
+
+ // Tag verification
+ // tag[i-1]:
+ // adkd = 4/0 : use TK[i], NavData[i-2] to validate Tag[i-1]
+ // adkd = 12 : ignore it -> not possible to verify yet
+ // tag[i-10]
+ // adkd = 4/0 : use TK[i-9], NavData[i-11] to validate Tag[i-10] would already be done by tag[i-1]
+ // adkd = 12 : use TK[i], NavData[i-11] to validate Tag[i-10] TODO - pending better logic for not repeating this while twice.
+ int t = d_old_OSNMA_buffer.size() - 2;
+ applicable_OSNMA = d_old_OSNMA_buffer[t]; // former subframe
+ d_GST_Sf = d_receiver_time - 30; // time of the start of SF containing MACSEQ
+
+ size_t i = 0;
+ while (i < applicable_OSNMA.d_mack_message.tag_and_info.size() && // loop over all tags in MACK message
+ std::find(d_tags_to_verify.begin(),d_tags_to_verify.end(), // ADKD[i] is within allowed ADKDs
+ applicable_OSNMA.d_mack_message.tag_and_info[i].tag_info.ADKD)
+ != d_tags_to_verify.end())
+ {
+ // TODO - if a subsequent tag was already part of the verification (inner loop), this while is going to ignore that and try to validate it anyway.
+
+ // check if tag is flx
+ bool is_flexible_tag = std::find(flxTags.begin(),flxTags.end(), i) != flxTags.end();
+ if(is_flexible_tag && flxTagsV == false){
+ //std::cout << "Galileo OSNMA: cannot verify flx tag. " << std::endl;
+ continue;
}
- // Tag verification
- // tag[i-1]:
- // adkd = 4/0 : use TK[i], NavData[i-2] to validate Tag[i-1]
- // adkd = 12 : ignore it -> not possible to verify yet
- // tag[i-10]
- // adkd = 4/0 : use TK[i-9], NavData[i-11] to validate Tag[i-10] would already be done by tag[i-1]
- // adkd = 12 : use TK[i], NavData[i-11] to validate Tag[i-10] TODO - pending better logic for not repeating this while twice.
- int t = d_old_OSNMA_buffer.size() - 2;
- applicable_OSNMA = d_old_OSNMA_buffer[t]; // former subframe
- d_GST_Sf = d_receiver_time - 30; // time of the start of SF containing MACSEQ
- size_t i = 0;
- while (i < applicable_OSNMA.d_mack_message.tag_and_info.size() && // loop over all tags in MACK message
- std::find(d_tags_to_verify.begin(),d_tags_to_verify.end(), // ADKD[i] is within allowed ADKDs
- applicable_OSNMA.d_mack_message.tag_and_info[i].tag_info.ADKD)
- != d_tags_to_verify.end())
+ // Take tag_k and check its ADKD, COP, PRN_d, this will be the reference for the iteration and search of other Tags
+ uint8_t Nt = d_Lt_min / applicable_OSNMA.d_dsm_kroot_message.ts; // Tags needed to be verified
+ uint8_t applicable_ADKD = applicable_OSNMA.d_mack_message.tag_and_info[i].tag_info.ADKD;
+ uint8_t applicable_COP = applicable_OSNMA.d_mack_message.tag_and_info[i].tag_info.cop; // * d_delta_COP;
+ uint8_t counter_COP = 1;
+ uint8_t applicable_PRNd = applicable_OSNMA.d_mack_message.tag_and_info[i].tag_info.PRN_d;
+ // ADKD=12 or ADKD = 4/0 => pick d_old_OSNMA_buffer.back() or [size-1]
+ applicable_key = d_old_OSNMA_buffer[t+1].d_mack_message.key; // current subframe
+ NavData applicable_NavData{};
+ if((applicable_ADKD == 0 || applicable_ADKD == 4) && d_old_OSNMA_buffer.size() > 3)
{
- // TODO - if a subsequent tag was already part of the verification (inner loop), this while is going to ignore that and try to validate it anyway.
-
- // Take tag_k and check its ADKD, COP, PRN_d, this will be the reference for the iteration and search of other Tags
- uint8_t Nt = d_Lt_min / applicable_OSNMA.d_dsm_kroot_message.ts; // Tags needed to be verified
- uint8_t applicable_ADKD = applicable_OSNMA.d_mack_message.tag_and_info[i].tag_info.ADKD;
- uint8_t applicable_COP = applicable_OSNMA.d_mack_message.tag_and_info[i].tag_info.cop; // * d_delta_COP;
- uint8_t counter_COP = 1;
- uint8_t applicable_PRNd = applicable_OSNMA.d_mack_message.tag_and_info[i].tag_info.PRN_d;
- // ADKD=12 or ADKD = 4/0 => pick d_old_OSNMA_buffer.back() or [size-1]
- applicable_key = d_old_OSNMA_buffer[t+1].d_mack_message.key; // current subframe
- NavData applicable_NavData{};
- if((applicable_ADKD == 0 || applicable_ADKD == 4) && d_old_OSNMA_buffer.size() > 3)
- {
- applicable_NavData = d_old_OSNMA_buffer[t-1].d_nav_data;
- }
- else if(applicable_ADKD == 12 && d_old_OSNMA_buffer.size() > 11)
- {
- applicable_NavData = d_old_OSNMA_buffer[t - 11].d_nav_data;
- }
- else
- {
- std::cout << "Galileo OSNMA: MACK message buffer elements not enough. Cannot verify tags. " << std::endl;
- }
+ applicable_NavData = d_old_OSNMA_buffer[t-1].d_nav_data;
+ }
+ else if(applicable_ADKD == 12 && d_old_OSNMA_buffer.size() > 11)
+ {
+ applicable_NavData = d_old_OSNMA_buffer[t - 11].d_nav_data;
+ }
+ else
+ {
+ std::cout << "Galileo OSNMA: MACK message buffer elements not enough. Cannot verify tags. " << std::endl;
+ }
- int k = i + 1;
- uint8_t nt = 0;
- bool flag_cancel_tag_verification = false; // if a tag fails, cancel whole NavData verification set
- // Look for tags relative to reference NavData until Nt achieved,
- // this may require going back in time, as long as COP is valid
- while (nt <= Nt && counter_COP <= applicable_COP && !flag_cancel_tag_verification)
- {
- auto start_it = std::next(applicable_OSNMA.d_mack_message.tag_and_info.begin(), k);
+ int k = i + 1;
+ uint8_t nt = 0;
+ bool flag_cancel_tag_verification = false; // if a tag fails, cancel whole NavData verification set
+ // Look for tags relative to reference NavData until Nt achieved,
+ // this may require going back in time, as long as COP is valid
+ while (nt <= Nt && counter_COP <= applicable_COP && !flag_cancel_tag_verification)
+ {
+ auto start_it = std::next(applicable_OSNMA.d_mack_message.tag_and_info.begin(), k);
- // check the vector of tags of aplicable OSNMA for a match against the chosen
- for (auto it = start_it; it != applicable_OSNMA.d_mack_message.tag_and_info.end() && nt <= Nt; ++it)
+ // check the vector of tags of aplicable OSNMA for a match against the chosen
+ for (auto it = start_it; it != applicable_OSNMA.d_mack_message.tag_and_info.end() && nt <= Nt; ++it)
{
- // Check if ADKD, COP, and PRN_d match
- if(it->tag_info.ADKD == applicable_ADKD
- // && it->tag_info.cop == applicable_COP // TODO - I think this may be skipped as the relevant is the COP distance.
- && it->tag_info.PRN_d == applicable_PRNd)
+ // Check if ADKD, COP, and PRN_d match
+ if(it->tag_info.ADKD == applicable_ADKD
+ // && it->tag_info.cop == applicable_COP // TODO - I think this may be skipped as the relevant is the COP distance.
+ && it->tag_info.PRN_d == applicable_PRNd)
{
if(verify_tag(it.operator*(), applicable_OSNMA, k,applicable_key,applicable_NavData))
{
@@ -1111,46 +1053,44 @@ void osnma_msg_receiver::process_mack_message(const std::shared_ptr&
}
else
{
- // failure, discard this k-th tag
- flag_cancel_tag_verification = true;
- std::cout << "Galileo OSNMA: tag verification failed for PRN_a "
- << applicable_OSNMA.d_nav_data.PRNa << " with WN="
- << applicable_OSNMA.d_nav_data.WN_sf0 << ", TOW="
- << applicable_OSNMA.d_nav_data.TOW_sf0 << ". "
- << std::endl;
+ // failure, discard this k-th tag
+ flag_cancel_tag_verification = true;
+ std::cout << "Galileo OSNMA: tag verification failed for PRN_a "
+ << applicable_OSNMA.d_nav_data.PRNa << " with WN="
+ << applicable_OSNMA.d_nav_data.WN_sf0 << ", TOW="
+ << applicable_OSNMA.d_nav_data.TOW_sf0 << ". "
+ << std::endl;
}
}
- if(flag_cancel_tag_verification)
- break;
+ if(flag_cancel_tag_verification)
+ break;
}
- // Check if Nt is achieved, if not, switch to older frame
- if(nt < Nt && t > 0 /*not end of buffer*/ && counter_COP <= applicable_COP && !flag_cancel_tag_verification)
- {
- t--;
- applicable_OSNMA = d_old_OSNMA_buffer[t];
- applicable_key = d_old_OSNMA_buffer[t+1].d_mack_message.key;
- applicable_NavData = d_old_OSNMA_buffer[t-1].d_nav_data;
- d_GST_Sf -= 30;
- counter_COP++;
- k = 0;
- }
- }
-
- if (nt >= Nt)
+ // Check if Nt is achieved, if not, switch to older frame
+ if(nt < Nt && t > 0 /*not end of buffer*/ && counter_COP <= applicable_COP && !flag_cancel_tag_verification)
{
- nt = 0;
- std::cout << "Galileo OSNMA: tag verification accumulation succesful for PRN_a "
- << applicable_OSNMA.d_nav_data.PRNa << " with WN="
- << applicable_OSNMA.d_nav_data.WN_sf0 << ", TOW="
- << applicable_OSNMA.d_nav_data.TOW_sf0 << ". "
- << std::endl;
+ t--;
+ applicable_OSNMA = d_old_OSNMA_buffer[t];
+ applicable_key = d_old_OSNMA_buffer[t+1].d_mack_message.key;
+ applicable_NavData = d_old_OSNMA_buffer[t-1].d_nav_data;
+ d_GST_Sf -= 30;
+ counter_COP++;
+ k = 0;
}
-
}
+ if (nt >= Nt)
+ {
+ nt = 0;
+ std::cout << "Galileo OSNMA: tag verification accumulation succesful for PRN_a "
+ << applicable_OSNMA.d_nav_data.PRNa << " with WN="
+ << applicable_OSNMA.d_nav_data.WN_sf0 << ", TOW="
+ << applicable_OSNMA.d_nav_data.TOW_sf0 << ". "
+ << std::endl;
+ }
}
+
}
bool osnma_msg_receiver::verify_dsm_pkr(DSM_PKR_message message)
@@ -1348,6 +1288,27 @@ bool osnma_msg_receiver::verify_tag(MACK_tag_and_info tag_and_info,
}
return verified;
}
+bool osnma_msg_receiver::verify_tag(Tag& tag)
+{
+ // TODO
+// m = t.build_message(t) // **needs d_nav_data[t.PRNd][t.TOW-30]**
+//
+// t.hasKey()?: k = t.**getKey**()
+//
+// computed_tag = d_crypto→hmac(m,k)
+//
+// if t.tag == computed_tag
+//
+// t.verified::true;
+//
+// return true
+//
+// else
+//
+// t.verified::false
+//
+// return false;
+}
/**
* @brief Checks if the current subframe time is bigger than last one received.
*
@@ -1367,3 +1328,194 @@ bool osnma_msg_receiver::is_next_subframe()
return is_bigger;
}
+void osnma_msg_receiver::add_satellite_data(uint32_t SV_ID, uint32_t TOW, const NavData& data)
+{
+ while (d_satellite_data[SV_ID].size() >= 25) {
+ d_satellite_data[SV_ID].erase(d_satellite_data[SV_ID].begin());
+ }
+ d_osnma_data[TOW] = crypto; // crypto
+ d_satellite_data[SV_ID][TOW] = data; // nav
+ std::cout << "Galileo OSNMA: added element, size is " << d_satellite_data[SV_ID].size() << std::endl;
+}
+void osnma_msg_receiver::display_data()
+{
+ if(d_satellite_data.empty())
+ return;
+
+ for(const auto& satellite : d_satellite_data) {
+ std::cout << "SV_ID: " << satellite.first << std::endl;
+ for(const auto& towData : satellite.second) {
+ std::cout << "\tTOW: " << towData.first << " key: ";
+ for(size_t i = 0; i < towData.second.d_mack_message.key.size(); i++) {
+ std::cout << std::hex << std::setfill('0') << std::setw(2)
+ << static_cast(towData.second.d_mack_message.key[i]) << " ";
+ }
+ }
+ }
+}
+bool osnma_msg_receiver::verify_tesla_key(std::vector& key)
+{
+ if(d_tesla_key_verified || d_flag_debug)
+ {
+ // TODO - find out I bt. both tesla keys, then hash until then, then compare.
+ // retrieve latest tesla key
+ // compute hashes needed
+ // hash current key until num_hashes and compare
+ }
+ else
+ {// have to go until Kroot
+ uint32_t num_of_hashes_needed = (d_GST_SIS - d_GST_0) / 30 + 1; // Eq. 19 ICD
+ std::cout << "Galileo OSNMA: TESLA verification ("<< num_of_hashes_needed << " hashes) need to be performed. " << std::endl;
+ auto start = std::chrono::high_resolution_clock::now();
+ uint32_t GST_SFi = d_GST_SIS;
+ std::vector K_II = applicable_MACK.key;
+ std::vector K_I; // result of the recursive hash operations
+ const uint8_t lk_bytes = d_dsm_reader->get_lk_bits(d_osnma_data.d_dsm_kroot_message.ks)/8;
+ // compute the tesla key for current SF (GST_SFi and K_II change in each iteration)
+ for (uint32_t i = 1; i < num_of_hashes_needed ; i++)
+ {
+ // build message digest m = (K_I+1 || GST_SFi || alpha)
+ std::vector msg(K_II.size() + sizeof(GST_SFi) + sizeof(d_osnma_data.d_dsm_kroot_message.alpha));
+ std::copy(K_II.begin(),K_II.end(),msg.begin());
+
+ msg.push_back((d_GST_Sf & 0xFF000000) >> 24);
+ msg.push_back((d_GST_Sf & 0x00FF0000) >> 16);
+ msg.push_back((d_GST_Sf & 0x0000FF00) >> 8);
+ msg.push_back(d_GST_Sf & 0x000000FF);
+ // extract alpha
+ for (int k = 5; k >= 0;k--)
+ {
+ // TODO: static extracts the MSB in case from larger to shorter int?
+ msg.push_back(static_cast((d_osnma_data.d_dsm_kroot_message.alpha >> (i * 8)) & 0xFF)); // extract first 6 bytes of alpha.
+ }
+ // compute hash
+ std::vector hash;
+ if (d_osnma_data.d_dsm_kroot_message.hf == 0) // Table 8.
+ {
+ hash = d_crypto->computeSHA256(msg);
+ }
+ else if (d_osnma_data.d_dsm_kroot_message.hf == 2)
+ {
+ hash = d_crypto->computeSHA3_256(msg);
+ }
+ else
+ {
+ hash = std::vector(32);
+ }
+ // truncate hash
+ K_I.reserve(lk_bytes); // TODO - case hash function has 512 bits
+ for (uint16_t i = 0; i < lk_bytes; i++)
+ {
+ K_I.push_back(hash[i]);
+ }
+
+ // set parameters for next iteration
+ GST_SFi -= 30; // next SF time is the actual minus 30 seconds
+ K_II = K_I; // next key is the actual one
+ K_I.clear(); // empty the actual one for a new computation
+ }
+ // compare computed current key against received key
+ auto end = std::chrono::high_resolution_clock::now();
+ std::chrono::duration elapsed = end - start;
+ std::cout << "Galileo OSNMA: TESLA verification ("<< num_of_hashes_needed << " hashes) took " << elapsed.count() << " seconds.\n";
+
+ if(K_II.size() != applicable_MACK.key.size())
+ {
+ std::cout << "Galileo OSNMA: Error during tesla key verification. " << std::endl;
+ return;
+ }
+ if (K_II == applicable_MACK.key)
+ {
+ std::cout << "Galileo OSNMA: tesla key verified successfully " << std::endl;
+ d_keys.insert(std::pair(applicable_MACK.TOW,applicable_MACK.key));
+ d_tesla_key_verified = true;
+ // TODO - propagate result
+ // TODO - save current tesla key as latest one? propose a map with
+ // TODO - Tags Sequence Verification: check ADKD[i] follows MACLT sequence
+ }
+ else
+
+ {
+ std::cerr << "Galileo OSNMA: Error during tesla key verification. " << std::endl;
+ if(!d_flag_debug)
+ return;
+ }
+ }
+
+}
+void osnma_msg_receiver::remove_verified_tags()
+{
+ for (auto it = d_tags_awaiting_verify.begin(); it != d_tags_awaiting_verify.end() ; ){
+ if (it->second.status == Tag::SUCCESS || it->second.status == Tag::FAIL)
+ it = d_tags_awaiting_verify.erase(it);
+ else
+ ++it;
+ }
+}
+void osnma_msg_receiver::control_tags_awaiting_verify_size()
+{
+ // TODO
+}
+bool osnma_msg_receiver::verify_macseq(MACK_message& message)
+{
+ // MACSEQ verification
+
+ // Fixed as well as FLX Tags share first part - Eq. 22 ICD
+ std::vector m(5 + 2 * flxTags.size()); // each flx tag brings two bytes
+ m[0] = static_cast(applicable_OSNMA.d_nav_data.PRNa); // PRN_A - SVID of the satellite transmiting the tag
+ m[1] = static_cast((d_GST_Sf & 0xFF000000) >> 24);
+ m[2] = static_cast((d_GST_Sf & 0x00FF0000) >> 16);
+ m[3] = static_cast((d_GST_Sf & 0x0000FF00) >> 8);
+ m[4] = static_cast(d_GST_Sf & 0x000000FF);
+ // Case tags flexible - Eq. 21 ICD
+ for (uint8_t i = 0; i < flxTags.size() ; i++)
+ {
+ m[2*i + 5] = applicable_OSNMA.d_mack_message.tag_and_info[flxTags[i]].tag_info.PRN_d;
+ m[2*i + 6] = applicable_OSNMA.d_mack_message.tag_and_info[flxTags[i]].tag_info.ADKD << 4 |
+ applicable_OSNMA.d_mack_message.tag_and_info[flxTags[i]].tag_info.cop;
+ }
+ // m = {0x18, 0x4f, 0x93, 0x53, 0x04, 0x05, 0x0f, 0x1f, 0x0f};
+ // applicable_key = {0x11, 0x26, 0x47, 0x3b, 0x0e, 0x05, 0x05, 0x35,
+ // 0xb0, 0xf2, 0xa7, 0x24, 0x00, 0x22, 0xba, 0x8f};
+ // applicable_OSNMA.d_mack_message.header.macseq = 0xbb8;
+ // compute mac
+ std::vector mac;
+ if (applicable_OSNMA.d_dsm_kroot_message.mf == 0) // C: HMAC-SHA-256
+ {
+ mac = d_crypto->computeHMAC_SHA_256(applicable_key, m);
+ }
+ else if (applicable_OSNMA.d_dsm_kroot_message.mf == 1) // C: CMAC-AES
+ {
+ mac = d_crypto->computeCMAC_AES(applicable_key, m);
+ }
+ // Truncate the twelve MSBits and compare with received MACSEQ
+ uint16_t mac_msb = 0;
+ if (!mac.empty())
+ {
+ mac_msb = (mac[0] << 8) + mac[1];
+ }
+ uint16_t computed_macseq = (mac_msb & 0xFFF0) >> 4;
+ if (computed_macseq == applicable_OSNMA.d_mack_message.header.macseq && flxTags.size() > 0)
+ return true;
+ else
+ return false;
+}
+bool osnma_msg_receiver::nav_data_available(Tag t)
+{
+ auto prn_it = d_satellite_nav_data.find(t.PRNa);
+ if (prn_it != d_satellite_nav_data.end()) {
+ // PRN was found, check if TOW exists in inner map
+ std::map& tow_map = prn_it->second;
+ auto tow_it = tow_map.find(t.TOW);
+ if (tow_it != tow_map.end()) {
+ return true;
+ } else {
+ // TOW not found
+ return false;
+ }
+ } else {
+ // PRN was not found
+ return false;
+ }
+ return false;
+}
diff --git a/src/core/libs/osnma_msg_receiver.h b/src/core/libs/osnma_msg_receiver.h
index b6a7bb812..1a2703bcd 100644
--- a/src/core/libs/osnma_msg_receiver.h
+++ b/src/core/libs/osnma_msg_receiver.h
@@ -72,14 +72,23 @@ private:
void read_mack_header();
void read_mack_body();
void process_mack_message(const std::shared_ptr& osnma_msg);
+ void add_satellite_data(uint32_t SV_ID, uint32_t TOW, const NavData &data);
+ bool verify_tesla_key(std::vector& key);
+ void const display_data();
bool verify_tag(MACK_tag_and_info tag_and_info, OSNMA_data applicable_OSNMA, uint8_t tag_position, const std::vector& applicable_key, NavData applicable_NavData);
+ bool verify_tag(Tag& tag);
+ bool is_next_subframe();
+ bool nav_data_available(Tag& t);
- //boost::circular_buffer d_old_mack_message;
+ std::map> d_satellite_nav_data; // map holding NavData sorted by SVID and TOW.
boost::circular_buffer d_old_OSNMA_buffer; // buffer that holds last 12 received OSNMA messages, including current one at back()
+ std::map> d_tesla_keys; // tesla keys over time, sorted by TOW
+ std::vector d_macks_awating_MACSEQ_verification;
+ std::multimap d_tags_awaiting_verify; // container with tags to verify from arbitrary SVIDs, sorted by TOW
std::unique_ptr d_dsm_reader;
std::unique_ptr d_crypto;
- std::array, 16> d_dsm_message{}; // C: each dsm[0-15] has 2048 bits
+ std::array, 16> d_dsm_message{}; // structure for recording DSM blocks, when filled it sends them to parse and resets itself.
std::array, 16> d_dsm_id_received{};
std::array d_number_of_blocks{};
std::array d_mack_message{}; // C: 480 b
@@ -103,7 +112,9 @@ private:
enum tags_to_verify{all,utc,slow_eph, eph, none}; // TODO is this safe? I hope so
tags_to_verify d_tags_allowed{tags_to_verify::all};
std::vector d_tags_to_verify{0,4,12};
- bool is_next_subframe();
+ void remove_verified_tags();
+ void control_tags_awaiting_verify_size();
+ bool verify_macseq(MACK_message& message);
};
diff --git a/src/core/system_parameters/osnma_data.cc b/src/core/system_parameters/osnma_data.cc
index 9a291330d..44f343286 100644
--- a/src/core/system_parameters/osnma_data.cc
+++ b/src/core/system_parameters/osnma_data.cc
@@ -163,3 +163,4 @@ void NavData::generate_utc_vector()
utc_vector.push_back(static_cast(bit_buffer));
}
}
+
diff --git a/src/core/system_parameters/osnma_data.h b/src/core/system_parameters/osnma_data.h
index 4bc78ebbb..4a05ddabb 100644
--- a/src/core/system_parameters/osnma_data.h
+++ b/src/core/system_parameters/osnma_data.h
@@ -121,6 +121,7 @@ public:
MACK_header header;
std::vector tag_and_info;
std::vector key;
+ uint32_t TOW; // TODO duplicated variable
};
class NavData
@@ -157,9 +158,49 @@ public:
DSM_KROOT_message d_dsm_kroot_message;
MACK_message d_mack_message;
NavData d_nav_data;
+
};
+class Tag
+{
+public:
+ enum e_verification_status{
+ SUCCESS,
+ FAIL,
+ UNVERIFIED};
+ Tag(const MACK_tag_and_info& MTI, uint32_t TOW, uint32_t PRNa)
+ : tag_id(id_counter++),
+ received_tag(MTI.tag),
+ computed_tag(0),
+ PRN_d(MTI.tag_info.PRN_d),
+ ADKD(MTI.tag_info.ADKD),
+ cop(MTI.tag_info.cop),
+ TOW(TOW),
+ PRNa(PRNa),
+ status(UNVERIFIED)
+ {
+ }
+ const uint32_t tag_id;
+ uint32_t TOW;
+ uint32_t PRNa;
+ std::vector build_message();
+ e_verification_status status;
+
+private:
+ uint32_t static id_counter;
+ uint64_t received_tag;
+ uint64_t computed_tag;
+
+
+ uint8_t PRN_d;
+ uint8_t ADKD;
+ uint8_t cop;
+
+
+
+;
+};
/** \} */
/** \} */
#endif // GNSS_SDR_OSNMA_DATA_H
From f03608ac827b0b3eac471bbc6af9c47131ad2573 Mon Sep 17 00:00:00 2001
From: Carles Fernandez
Date: Fri, 29 Mar 2024 14:39:32 +0100
Subject: [PATCH 2/4] Update links
---
CMakeLists.txt | 6 +++---
README.md | 31 +++++++++++++++------------
cmake/Modules/FindLOG4CPP.cmake | 2 +-
cmake/Modules/FindPCAP.cmake | 2 +-
docs/CHANGELOG.md | 5 ++---
docs/doxygen/other/main_page.dox | 6 +++---
docs/doxygen/other/reference_docs.dox | 14 ++++++------
docs/protobuf/README.md | 5 ++---
src/utils/nav-listener/README.md | 2 +-
src/utils/rinex-tools/README.md | 2 +-
10 files changed, 38 insertions(+), 37 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7c3bf7d38..324e118fb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1927,7 +1927,7 @@ endif()
################################################################################
-# Armadillo - http://arma.sourceforge.net/
+# Armadillo - https://arma.sourceforge.net/
################################################################################
if(ENABLE_OWN_ARMADILLO)
unset(Armadillo::armadillo CACHE)
@@ -1939,7 +1939,7 @@ else()
endif()
set_package_properties(Armadillo PROPERTIES
- URL "http://arma.sourceforge.net/"
+ URL "https://arma.sourceforge.net/"
PURPOSE "Used for matrix computations."
TYPE REQUIRED
)
@@ -2538,7 +2538,7 @@ endif()
################################################################################
find_package(Protobuf)
set_package_properties(Protobuf PROPERTIES
- URL "https://developers.google.com/protocol-buffers/"
+ URL "https://protobuf.dev/"
PURPOSE "Used to serialize output data in a way that can be read by other applications."
TYPE REQUIRED
)
diff --git a/README.md b/README.md
index edac6e4af..bba7566a3 100644
--- a/README.md
+++ b/README.md
@@ -396,7 +396,7 @@ or manually as explained below, and then please follow instructions on how to
### Manual installation of other required dependencies
-#### Install [Armadillo](http://arma.sourceforge.net/ "Armadillo's Homepage"), a C++ linear algebra library
+#### Install [Armadillo](https://arma.sourceforge.net/ "Armadillo's Homepage"), a C++ linear algebra library
```
$ sudo apt-get install libblas-dev liblapack-dev # For Debian/Ubuntu/LinuxMint
@@ -469,7 +469,7 @@ $ sudo make install
$ sudo ldconfig
```
-#### Install [Protocol Buffers](https://developers.google.com/protocol-buffers/ "Protocol Buffers' Homepage"), a portable mechanism for serialization of structured data
+#### Install [Protocol Buffers](https://protobuf.dev/ "Protocol Buffers' Homepage"), a portable mechanism for serialization of structured data
GNSS-SDR requires Protocol Buffers v3.0.0 or later. If the packages that come
with your distribution are older than that (_e.g._, Ubuntu 16.04 Xenial came
@@ -886,7 +886,7 @@ $ brew install lapack
### Other package managers
GNU Radio and other dependencies can also be installed using other package
-managers than Macports, such as [Fink](http://www.finkproject.org/ "Fink").
+managers than Macports, such as [Fink](https://www.finkproject.org/ "Fink").
Since the version of Python that ships with OS X is great for learning but it is
not good for development, you could have another Python executable in a
non-standard location. If that is the case, you need to inform GNSS-SDR's
@@ -976,7 +976,7 @@ do so.
- **GNSS-SDR in embedded platforms**: we provide a Software Development Kit
- (SDK) based on [OpenEmbedded](http://www.openembedded.org/wiki/Main_Page) for
+ (SDK) based on [OpenEmbedded](https://www.openembedded.org/wiki/Main_Page) for
cross-compiling GNSS-SDR in your desktop computer and for producing
executables that can run in embedded platforms, such as Xilinx's Zynq and
ZynqMP architectures, Raspberry Pi, and many others. Please check
@@ -1991,11 +1991,11 @@ PVT.rtcm_MT1077_rate_ms=1000
Notation (JSON) supported by numerous mapping and GIS software packages,
including [OpenLayers](https://openlayers.org),
[Leaflet](https://leafletjs.com), [MapServer](https://mapserver.org/),
- [GeoServer](http://geoserver.org), [GeoDjango](https://www.djangoproject.com),
- [GDAL](https://gdal.org/), and [CartoDB](https://cartodb.com). It is also
- possible to use GeoJSON with [PostGIS](https://postgis.net/) and
- [Mapnik](https://mapnik.org/), both of which handle the format via the GDAL
- OGR conversion library. The
+ [GeoServer](https://geoserver.org/),
+ [GeoDjango](https://www.djangoproject.com), [GDAL](https://gdal.org/), and
+ [CartoDB](https://cartodb.com). It is also possible to use GeoJSON with
+ [PostGIS](https://postgis.net/) and [Mapnik](https://mapnik.org/), both of
+ which handle the format via the GDAL OGR conversion library. The
[Google Maps Javascript API](https://developers.google.com/maps/documentation/javascript/)
v3 directly supports the
[integration of GeoJSON data layers](https://developers.google.com/maps/documentation/javascript/examples/layer-data-simple),
@@ -2008,8 +2008,9 @@ PVT.rtcm_MT1077_rate_ms=1000
(OGC KML), and it is maintained by the Open Geospatial Consortium, Inc. (OGC).
KML files can be displayed in geobrowsers such as
[Google Earth](https://www.google.com/earth/),
- [Marble](https://marble.kde.org), [osgEarth](http://osgearth.org), or used
- with the [NASA World Wind SDK for Java](https://worldwind.arc.nasa.gov/java/).
+ [Marble](https://marble.kde.org),
+ [osgEarth](https://github.com/gwaldron/osgearth), or used with the
+ [NASA World Wind SDK for Java](https://worldwind.arc.nasa.gov/java/).
- **GPX** (the GPS Exchange Format) is a lightweight XML data format for the
interchange of GPS data (waypoints, routes, and tracks) between applications
@@ -2044,9 +2045,11 @@ PVT.rtcm_MT1077_rate_ms=1000
(usually with other data unknown to the original receiver, such as better
models of the atmospheric conditions at time of measurement). RINEX files can
be used by software packages such as
- [GNSSTK](https://github.com/SGL-UT/gnsstk), [RTKLIB](http://www.rtklib.com/),
- and [gLAB](https://gage.upc.edu/gLAB/). GNSS-SDR by default generates RINEX
- version [3.02](ftp://igs.org/pub/data/format/rinex302.pdf). If
+ [GNSSTK](https://github.com/SGL-UT/gnsstk), [RTKLIB](https://www.rtklib.com/),
+ and
+ [gLAB](https://gage.upc.edu/en/learning-materials/software-tools/glab-tool-suite).
+ GNSS-SDR by default generates RINEX version
+ [3.02](ftp://igs.org/pub/data/format/rinex302.pdf). If
[2.11](ftp://igs.org/pub/data/format/rinex211.txt) is needed, it can be
requested through the `rinex_version` parameter in the configuration file:
diff --git a/cmake/Modules/FindLOG4CPP.cmake b/cmake/Modules/FindLOG4CPP.cmake
index 73876d1da..95a14cf62 100644
--- a/cmake/Modules/FindLOG4CPP.cmake
+++ b/cmake/Modules/FindLOG4CPP.cmake
@@ -121,7 +121,7 @@ include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LOG4CPP DEFAULT_MSG LOG4CPP_INCLUDE_DIRS LOG4CPP_LIBRARIES)
set_package_properties(LOG4CPP PROPERTIES
- URL "http://log4cpp.sourceforge.net/"
+ URL "https://log4cpp.sourceforge.net/"
)
if(LOG4CPP_FOUND AND PC_LOG4CPP_VERSION)
diff --git a/cmake/Modules/FindPCAP.cmake b/cmake/Modules/FindPCAP.cmake
index b72b5f5d1..ae4b049f6 100644
--- a/cmake/Modules/FindPCAP.cmake
+++ b/cmake/Modules/FindPCAP.cmake
@@ -6,7 +6,7 @@
# - Find pcap
# Find the PCAP includes and library
-# http://www.tcpdump.org/
+# https://www.tcpdump.org/
#
# The environment variable PCAPDIR allows to specify where to find
# libpcap in non standard location.
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index c453414f6..3d797d433 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -328,7 +328,7 @@ https://gnss-sdr.org/design-forces/
- Fixed building against GNU Radio v3.10.X.Y, which does not support the C++20
standard.
- Fixed building against GNU Radio v3.10.X.Y, which replaced
- [log4cpp](http://log4cpp.sourceforge.net/) by the
+ [log4cpp](https://log4cpp.sourceforge.net/) by the
[spdlog](https://github.com/gabime/spdlog) and
[fmt](https://github.com/fmtlib/fmt) libraries.
- Updated `cpu_features` library for improved processor detection.
@@ -475,8 +475,7 @@ https://gnss-sdr.org/design-forces/
inconsistencies in the configuration file.
- Fix segmentation fault if the RINEX output was disabled.
- Added a feature that optionally enables the remote monitoring of GPS and
- Galileo ephemeris using UDP and
- [Protocol Buffers](https://developers.google.com/protocol-buffers).
+ Galileo ephemeris using UDP and [Protocol Buffers](https://protobuf.dev/).
- Now building the software passing the `-DENABLE_FPGA=ON` to CMake does not
make the receiver unusable when running on non-FPGA-enabled platforms. On
FPGA-enabled platforms, now it is possible to run non-FPGA-enabled
diff --git a/docs/doxygen/other/main_page.dox b/docs/doxygen/other/main_page.dox
index 0968c3eb9..5545c2bae 100644
--- a/docs/doxygen/other/main_page.dox
+++ b/docs/doxygen/other/main_page.dox
@@ -77,19 +77,19 @@ As outputs, it provides:
In principle, GNSS-SDR can be built in any Unix-like system. In practice, it depends on being able to install all the required dependencies. See the building guide page for details about the project's
dependencies and build process. Mainly, it consists on installing GNU Radio plus some few more libraries:
-\li Armadillo, a C++ linear algebra library,
+\li Armadillo, a C++ linear algebra library,
\li Boost, a set of free peer-reviewed portable C++ source libraries,
\li Gflags, a library that implements commandline flags processing,
\li Glog, a library that implements application-level logging,
\li Googletest, Google's framework for writing C++ tests,
\li Mako, a template library written in Python,
\li Matio, a MATLAB MAT File I/O Library,
-\li Protocol Buffers, a language-neutral, platform-neutral extensible mechanism for serializing structured data,
+\li Protocol Buffers, a language-neutral, platform-neutral extensible mechanism for serializing structured data,
\li PugiXML, a light-weight, simple and fast XML parser for C++ with XPath support,
\li Volk, a Vector-Optimized Library of Kernels which provides an abstraction of optimized math routines targeting several SIMD processors,
and, optionally,
-\li GNU Radio modules for hardware interface (gr-uhd, gr-osmosdr, gr-iio),
+\li GNU Radio modules for hardware interface (gr-uhd, gr-osmosdr, gr-iio),
\li Benchmark, a library to benchmark code snippets,
\li Gperftools, which provides fast, multi-threaded malloc() and performance analysis tools.
diff --git a/docs/doxygen/other/reference_docs.dox b/docs/doxygen/other/reference_docs.dox
index 00af2e1a2..5871776d5 100644
--- a/docs/doxygen/other/reference_docs.dox
+++ b/docs/doxygen/other/reference_docs.dox
@@ -153,7 +153,7 @@ automatically selected by the CMake script):
You can get it from ISO, IEC
- or ANSI. The closest free working document available is
ISO, IEC
- or ANSI. The closest free working document available is
N4659.
C++14: A former ISO C++ standard was officially known as ISO International Standard ISO/IEC 14882:2014 – Programming languages – C++.
You can get it from ISO or ANSI. The closest free working document available is
N4296.
C++11: An older ISO C++ standard was ISO/IEC 14882:2011.
You can get it from ISO. The closest free working document available is N3337.
@@ -207,7 +207,7 @@ User plane protocols:
\li Open Mobile Alliance (OMA), Secure User Plane Location Architecture Version 2 (SUPL 2.0), April 2012.
LTE Release 9 introduced extension hooks in LPP messages, so that the bodies external to 3GPP could extend the LPP feature set. OMA LPP extensions (LPPe), supported in SUPL 3.0, build on top of the 3GPP LPP reusing its procedures and data types.
-Check the OMA Specifications webpage for updated information about LPP Extensions (LPPe) Specification.
+Check the OMA Specifications webpage for updated information about LPP Extensions (LPPe) Specification.
\li The OMA Mobile Location Protocol (MLP) V3.5
is an application-level protocol for getting the position of mobile stations
diff --git a/docs/protobuf/README.md b/docs/protobuf/README.md
index a555ae44c..438a9d66d 100644
--- a/docs/protobuf/README.md
+++ b/docs/protobuf/README.md
@@ -11,9 +11,8 @@ SPDX-FileCopyrightText: 2011-2020 Carles Fernandez-Prades
Files in this folder describe structured data formats that are generated by
-GNSS-SDR. They use
-[Protocol Buffers](https://developers.google.com/protocol-buffers/)'
-[proto3](https://developers.google.com/protocol-buffers/docs/proto3) syntax.
+GNSS-SDR. They use [Protocol Buffers](https://protobuf.dev/)'
+[proto3](https://protobuf.dev/programming-guides/proto3/) syntax.
From those files, the protocol buffer compiler creates classes that implement
automatic encoding and parsing of the protocol buffer data with an efficient
diff --git a/src/utils/nav-listener/README.md b/src/utils/nav-listener/README.md
index 147e9717f..76b2aedaf 100644
--- a/src/utils/nav-listener/README.md
+++ b/src/utils/nav-listener/README.md
@@ -17,7 +17,7 @@ as a example on how to retrieve data using the `nav_message.proto` file.
# Build the software
This software requires [Boost](https://www.boost.org/) and
-[Protocol Buffers](https://developers.google.com/protocol-buffers).
+[Protocol Buffers](https://protobuf.dev/).
In a terminal, type:
diff --git a/src/utils/rinex-tools/README.md b/src/utils/rinex-tools/README.md
index 58a1bd259..453ccd7a9 100644
--- a/src/utils/rinex-tools/README.md
+++ b/src/utils/rinex-tools/README.md
@@ -17,7 +17,7 @@ observation files.
Requirements:
-- [Armadillo](http://arma.sourceforge.net/): A C++ library for linear algebra
+- [Armadillo](https://arma.sourceforge.net/): A C++ library for linear algebra
and scientific computing. This program requires version 9.800 or higher. If
your installed Armadillo version is older, see below.
- [Gflags](https://github.com/gflags/gflags): A C++ library that implements
From 4d934017c6f9b0e9f9d07f5992d0ddc0d958ddd4 Mon Sep 17 00:00:00 2001
From: Carles Fernandez
Date: Fri, 29 Mar 2024 22:57:49 +0100
Subject: [PATCH 3/4] CI: Fix macos-based jobs
---
.github/workflows/main.yml | 27 +++++++++++++++++++++------
README.md | 3 ++-
2 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 56e631df8..ad507ba20 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -40,6 +40,9 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
+ with:
+ python-version: '3.12'
- name: install dependencies
run: |
brew update
@@ -53,8 +56,10 @@ jobs:
rm /usr/local/bin/pydoc3.1* || true
rm /usr/local/bin/python3.1* || true
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
+ brew link --overwrite python@3.12
brew install ninja hdf5 automake armadillo lapack libmatio \
- gflags glog gnuradio log4cpp openssl pugixml protobuf python-mako
+ gflags glog gnuradio log4cpp openssl pugixml protobuf
+ pip3 install mako
- name: configure
run: cd build && cmake -GNinja ..
- name: build
@@ -68,6 +73,9 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
+ with:
+ python-version: '3.12'
- name: install dependencies
run: |
brew update
@@ -81,8 +89,10 @@ jobs:
rm /usr/local/bin/pydoc3.1* || true
rm /usr/local/bin/python3.1* || true
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
+ brew link --overwrite python@3.12
brew install ninja pkg-config hdf5 automake armadillo lapack libmatio \
- gflags glog gnuradio log4cpp openssl pugixml protobuf python-mako
+ gflags glog gnuradio log4cpp openssl pugixml protobuf
+ pip3 install mako
- name: configure
run: cd build && cmake -GXcode ..
- name: build
@@ -115,6 +125,9 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
+ with:
+ python-version: '3.12'
- name: install dependencies
run: |
brew update
@@ -128,15 +141,17 @@ jobs:
rm /usr/local/bin/pydoc3.1* || true
rm /usr/local/bin/python3.1* || true
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
- brew install llvm pkg-config hdf5 armadillo lapack gflags glog gnuradio libmatio \
- log4cpp openssl pugixml protobuf python-mako
+ brew link --overwrite python@3.12
+ brew install ninja pkg-config hdf5 automake armadillo lapack libmatio \
+ gflags glog gnuradio log4cpp openssl pugixml protobuf llvm
+ pip3 install mako
ln -s $(brew --prefix llvm)/bin/clang-tidy /usr/local/bin
ln -s $(brew --prefix llvm)/bin/clang-apply-replacements /usr/local/bin
- ln -s $(brew --prefix llvm)/bin/run-clang-tidy /usr/local/bin
+ ln -s $(brew --prefix llvm)/bin/run-clang-tidy.py /usr/local/bin
- name: Prepare run
run: cd build && cmake .. && make volk_gnsssdr_module gtest-1.14.0 core_monitor core_libs pvt_libs
- name: run clang-tidy
- run: cd build && run-clang-tidy -fix
+ run: cd build && /usr/local/opt/llvm/bin/run-clang-tidy -fix
- name: check
run: |
git diff > clang_tidy.patch
diff --git a/README.md b/README.md
index bba7566a3..02bc80df7 100644
--- a/README.md
+++ b/README.md
@@ -872,9 +872,10 @@ Install the required dependencies:
```
$ brew update && brew upgrade
$ brew install armadillo cmake hdf5 gflags glog gnuradio libmatio log4cpp \
- openssl pkg-config protobuf pugixml python-mako
+ openssl pkg-config protobuf pugixml
$ brew install --cask mactex # when completed, restart Terminal
$ brew install graphviz doxygen
+¢ pip3 install mako
```
For macOS versions older than Sonoma, you will also need LAPACK:
From d0b170547470da859fe08b86682cd27c6d7d1170 Mon Sep 17 00:00:00 2001
From: Carles Fernandez
Date: Sat, 30 Mar 2024 00:10:55 +0100
Subject: [PATCH 4/4] Bump local version of Protocol Buffers to 26.1 and GNSSTk
to 14.3.0
---
CMakeLists.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 324e118fb..a20109162 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -339,11 +339,11 @@ set(GNSSSDR_ARMADILLO_LOCAL_VERSION "12.8.x")
set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2")
set(GNSSSDR_GLOG_LOCAL_VERSION "0.7.0")
set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.26")
-set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "25.0")
+set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "26.1")
set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.14")
set(GNSSSDR_GTEST_LOCAL_VERSION "1.14.0")
set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master")
-set(GNSSSDR_GNSSTK_LOCAL_VERSION "14.0.0")
+set(GNSSSDR_GNSSTK_LOCAL_VERSION "14.3.0")
set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.8.3")
set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7")