algafix / osnma Goto Github PK
View Code? Open in Web Editor NEWA python implementation of the Galileo OSNMA protocol.
License: European Union Public License 1.2
A python implementation of the Galileo OSNMA protocol.
License: European Union Public License 1.2
Currently, the number of "past_keys" parameter in the "calculate_index" method of mack_structure.py is computed as follows:
past_keys = (self.gst_sf.uint - gst_0.uint) // 30
and, if the gst_sf and gst0, belong to two different week numbers this formula generates very strange values for the past_keys field and consequently for the tesla_key index.
My advice is to handle the computation of past_keys by converting the two time stamp into absolute galileo time stamps, e.g.:
past_keys = ((self.wn.uint864007 + self.tow.uint) - (gst_0[:12].uint864007 + gst_0[12:].uint)) // 30
Accordingly, additional modifications are suggested also for the following modules:
- tesla_chain.py
-- init method of TESLAChain class (line 90):
Integrate constructor as follows:
def init(self, nav_data_structure, dsm_kroot: DSMKroot, param_dict):
self.dsm_kroot = dsm_kroot
self.chain_id = dsm_kroot.get_value('CIDKR').uint
self.alpha = dsm_kroot.get_value('ALPHA')
self.nmack = dsm_kroot.get_value('NMACK').uint
self.key_size = KS_lt[dsm_kroot.get_value('KS').uint]
self.tag_size = TS_lt[dsm_kroot.get_value('TS').uint]
self.maclt = dsm_kroot.get_value('MACLT').uint
gst0_wn = dsm_kroot.get_value('WN_K')
gst0_tow = dsm_kroot.get_value('TOWH_K').uint * 3600
self.GST0 = gst0_wn + BitArray(uint=gst0_tow, length=20)
# Define the hash function to be used during this chain
hash_index = dsm_kroot.get_value('HF').uint
if hash_index == HF.SHA_256:
self.hash_function = hashlib.sha256
elif hash_index == HF.SHA3_224:
self.hash_function = hashlib.sha3_224
elif hash_index == HF.SHA3_256:
self.hash_function = hashlib.sha3_256
else:
raise FieldValueNotRecognized(f"DMSKroot field HF value {hash_index} not recognised")
# Define the mac function to be used during this chain
mac_f_index = dsm_kroot.get_value('MF').uint
if mac_f_index == MF.HMAC_SHA_256:
self.mac_function = self._hmac256
elif mac_f_index == MF.CMAC_AES:
self.mac_function = self._cmac_aes
logger.warning('cmac_aes not tested')
else:
raise FieldValueNotRecognized(f"DMSKroot field MF value {mac_f_index} not recognised")
#gst0_tow = 604770 if gst0_tow == 0 else gst0_tow # TODO: solucionar amb anell a gst
# Define the two keys that the chain will be storing at any time: kroot and last verified tesla key
if gst0_tow == 0:
gst0_wn_tmp = gst0_wn.uint - 1
gst0_wn = BitArray(uint=gst0_wn_tmp, length=12)
gst0_tow = 604800
root_key = TESLAKey(gst0_wn, gst0_tow - 30, dsm_kroot.get_value('KROOT'), 0, 0, 0)
root_key.set_verified(dsm_kroot.is_verified())
self.root_tesla_key = root_key
self.last_tesla_key = root_key
# Instantiate the auxiliary object for the tag management and parsing of messages
self.nav_data_structure = nav_data_structure
self.mac_msg_parser = MACKMessageParser(self)
self.tags_structure = TagStateStructure(self, self.nav_data_structure)
self.mack_df = pd.DataFrame()
self.tesla_key_df = pd.DataFrame()
self.param_dict = param_dict
- tesla_chain.py
_- -compute_gst_subframe method (line 108):
Change method implementation as follows:
def _compute_gst_subframe(self, index: int) -> BitArray:
wn_base = self.GST0[:12].uint
tow_base = self.GST0[12:].uint
if index == 0:
#gst_subframe = self.GST0.uint - 30
if(tow_base == 0):
wn_base = wn_base - 1
tow_base = 604770
else:
tow_base = tow_base - 30
else:
tow_base = (tow_base - 30) + 30 * -(index // -self.nmack)
wn_base = wn_base + tow_base // 604800
tow_base = tow_base % 604800
gst_subframe = BitArray(uint=wn_base, length=12) + BitArray(uint=tow_base, length=20)
return gst_subframe
- tesla_chain.py
- -get_key_index method (line 177):
Change method implementation as follows:
def get_key_index(self, gst_sf: BitArray) -> int:
past_keys = ( (gst_sf[:12].uint*86400*7 + gst_sf[12:].uint ) - (self.GST0[:12].uint*86400*7 + self.GST0[12:].uint) )// 30
index = past_keys * self.nmack + 1
return index
-nav_data_manager.py
--method get_nav_data of ADKD4DataStructure class (line 223)
Change method implementation as follows:
def get_nav_data(self, gst_tag):
nav_data = {6: False, 10: False}
# Search for the newest word6 and word10 when the tag was received
for word_type, word_list in self.word_lists.items():
for word in word_list:
if word.gst_start.uint < gst_tag.uint:
nav_data[word_type] = BitArray(word.data)
# Set the TOW to the previous subframe
if nav_data[6] and nav_data[10]:
tow_data = gst_tag[12:].uint - 25
if (tow_data < 0):
tow_data = tow_data + 604800
nav_data[6].append(BitArray(uint=tow_data, length=20))
return ADKD4DataBlock(gst_tag, nav_data[6] + nav_data[10])
else:
return None
In the module "receiver_state.py", the method process_mack_subframe accumulates new mack_subfames in the self.kroot_waiting_mack list if the self.tesla_chain_force is None.
If one of the accumulated mack subframe causes an exception (e.g.: MackParsingError and/or TeslaKeyVerificationFailed), it will be kept in the self.kroot_waiting_mack causing a continuous loop over the same wrong/invalid mack subfame
It is suggested to modify the method according to what follows:
def process_mack_subframe(self, mack_subframe, gst_subframe, svid, sf_nma_status):
if self.nma_status == NMAS.DONT_USE:
logger.warning(f"NMA Status: Don't Use. Subframe tags not processed.")
self.kroot_waiting_mack = []
return
if self.tesla_chain_force is None:
self.kroot_waiting_mack.append((mack_subframe, gst_subframe, svid, sf_nma_status))
else:
try:
if self.kroot_waiting_mack:
for w_mack in self.kroot_waiting_mack:
self.tesla_chain_force.parse_mack_message(w_mack[0], w_mack[1], w_mack[2], w_mack[3])
self.kroot_waiting_mack = []
self.tesla_chain_force.parse_mack_message(mack_subframe, gst_subframe, svid, sf_nma_status)
self.tesla_chain_force.update_tag_lists()
except MackParsingError as e:
# Unable to parse the message correctly
logger.error(f"ERROR: Unable to parse the MACK message correctly.\n{e}")
if self.start_status == StartStates.HOT_START:
self._fallback_to_warm_start()
**else:
logger.warning(f"WARNING: Deleting mack message from waiting list")
self.kroot_waiting_mack = self.kroot_waiting_mack[1:]**
except TeslaKeyVerificationFailed as e:
# Unable to verify the TESLA key
logger.error(f"Failed authenticating a TESLA key.\n{e}")
if self.start_status == StartStates.HOT_START:
self._fallback_to_warm_start()
**else:
logger.warning(f"WARNING: Deleting mack message from waiting list")
self.kroot_waiting_mack = self.kroot_waiting_mack[1:]**
else:
if self.start_status == StartStates.HOT_START:
self.start_status = StartStates.STARTED
logger.info(f"One TESLA key verified. Start Status: {self.start_status.name}")
I have an osnma certified SBF file. Can I import it directly into osnmalib for parsing? Because I see that the public key and other files are used in the project.
Hello, it is known that the Septentrio receiver can save the data in the entire OSNMA authentication process, and the SBF data can be analyzed by OSNMALib.
My confusion is whether the authentication algorithm implemented by OSNMALib and septentrio's internal chip is the same? In the authentication process, the receiver is authenticated in real time, and OSNMALib first uses the SBF file for parsing and authentication. Will their mechanisms be different?
Looking forward to your reply, I wish you a happy life!
Best,
Faye
Hello, your tool currently supports SBF and Galmon input.
Have you considered combining it with GNSS-SDR tools? This tool can receive and decode Galileo navigation messages.
Looking forward to your reply and wish you a happy life!
I cant find anything usable. I will try read
SFRBX messages from Ublox but i cant separate E1B INAV messages from another one and this message not tontain seconds for frame sync
can anybody help me ?
Hi,
I've been using this repository for this last month and it's been really helpful, thanks!
I'm afraid to tell you that I'm having the following issue with this last release when using the runner for Galmon data. After authenticating ADKDs the first time, the code breaks at:
File "run.py", line 24, in live_galmon_config
osnma_r.start()
File "~./osnma/receiver/receiver.py", line 122, in start
self.receiver_state.process_mack_subframe(mack_sf, gst_sf, satellite.svid, nma_status)
File "~./osnma/osnma_core/receiver_state.py", line 413, in process_mack_subframe
self.tesla_chain_force.parse_mack_message(w_mack[0], w_mack[1], w_mack[2], w_mack[3])
File "~./osnma/osnma_core/tesla_chain.py", line 172, in parse_mack_message
self.tags_structure.update_tag_lists(gst_sf)
File "~./osnma/osnma_core/tag_verification.py", line 160, in update_tag_lists
tag.nav_data = self.nav_data_m.get_data(tag)
File "~./osnma/osnma_core/nav_data_manager.py", line 387, in get_data
nav_data = self.adkd0_data_managers[svid].get_nav_data(tag)
File "~./osnma/osnma_core/nav_data_manager.py", line 243, in get_nav_data
if data.gst_completed and data.gst_completed > gst_start_tesla_key - Config.TL:
AttributeError: 'NoneType' object has no attribute 'gst_completed'
Can you replicate the error?
I've added an Ublox parser to the library and I'm not getting this error, if that helps.
Dear colleague,
I am trying to run your OSNMA code using the following SW:
_```
_H:\osnma\OSNMA-master\live_galmon_run>python run.py
Running using GALMON live data.
INFO -
Start status COLD_START
WARNING - Cannot compute Padding length: Missing attribute NB_DP
INFO - Public Key 2 read. Start status WARM_START_
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.