Skip to content

Commit 742bb32

Browse files
committed
- fixed adkd0 and adkd4 on OSNMA
1 parent 0f64956 commit 742bb32

File tree

1 file changed

+81
-41
lines changed

1 file changed

+81
-41
lines changed

src/cssrlib/osnma.py

Lines changed: 81 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from enum import IntEnum
2323
import xml.etree.ElementTree as et
2424
from cssrlib.gnss import gpst2time, time2gst
25+
import copy
2526

2627

2728
class uOSNMA(IntEnum):
@@ -145,14 +146,17 @@ class osnma():
145146
tag = bytearray(42)
146147
mack_p = bytearray(60*GALMAX) # previous MACK
147148
mack_c = bytearray(60*GALMAX) # current MACK
148-
subfrm = bytearray(16*10*GALMAX)
149149
tag_list = []
150150

151151
vcnt_min = 2
152152
iodnav = np.zeros(GALMAX+1, dtype=int)
153153
vcnt = np.zeros(GALMAX+1, dtype=int)
154154
vstatus = np.zeros(GALMAX+1, dtype=bool)
155155

156+
subfrm_n = None
157+
subfrm_p = None
158+
subfrm = None
159+
156160
# Public Key in PEM received from GSC OSNMA server
157161
# note : EC_PARAMETER section should be removed.
158162
# pubk_path = '../data/OSNMA_PublicKey_20210920133026_s.pem'
@@ -162,6 +166,8 @@ class osnma():
162166
mt_path = '../data/pubkey/osnma/OSNMA_MerkleTree_20240115100000_newPKID_1.xml'
163167
pk_list = []
164168

169+
flg_slowmac = False
170+
165171
def raw2der(self, ds):
166172
""" convert digital signature from raw format to der format """
167173
lds = len(ds)
@@ -234,6 +240,14 @@ def __init__(self):
234240
self.pk_list.append(pubkey(k))
235241
self.load_mt(self.mt_path)
236242

243+
self.flg_dsm = {}
244+
245+
self.subfrm_n = bytearray(16*10*self.GALMAX)
246+
self.subfrm_p = bytearray(16*10*self.GALMAX)
247+
self.subfrm = bytearray(16*10*self.GALMAX)
248+
249+
self.prn_ref = -1
250+
237251
def process_hash(self, msg):
238252
""" calculate hash """
239253
digest = hashes.Hash(self.hash_table[self.hf]())
@@ -394,7 +408,7 @@ def decode_dsm_pkr(self, did):
394408
self.status |= uOSNMA.PKR_UPDATED # PKR updated
395409
return result
396410

397-
def decode_hk(self, hk):
411+
def decode_hk(self, hk, prn):
398412
""" decode HKROOT message """
399413
self.nma_header = hk[0]
400414
nmas, cid, cpks, _ = bs.unpack_from('u2u2u3u1', hk, 0)
@@ -424,6 +438,9 @@ def decode_hk(self, hk):
424438
self.nb[did] = nb_ + 6 # number of blocks
425439

426440
result = False
441+
if self.monlevel > 1:
442+
print(f"flg_dsm[did={did}]={self.flg_dsm[did]:2x} "
443+
f"nb={self.nb[did]:2d} bid={bid} prn={prn}")
427444
if did in self.nb.keys() and \
428445
self.flg_dsm[did] == (1 << self.nb[did])-1:
429446
if did <= 11: # DSM-KROOT
@@ -532,9 +549,10 @@ def decode_mack(self, prn):
532549
lk = self.klen_t[self.ks]
533550
self.nt = (480-lk)//(lt+16) # number of tags
534551
ltag_b = (lt+16)//8
535-
i0 = 60*(prn-1)
536-
mack_p = self.mack_p[i0:i0+60] # previous MACK
537-
mack_c = self.mack_c[i0:i0+60] # current MACK
552+
lm_b = 60
553+
i0 = (prn-1)*lm_b
554+
mack_p = self.mack_p[i0:i0+lm_b] # previous MACK
555+
mack_c = self.mack_c[i0:i0+lm_b] # current MACK
538556
i0 = ltag_b*self.nt
539557
self.tag = mack_p[0:i0]
540558
self.key_p = mack_p[i0:i0+lk//8]
@@ -590,12 +608,33 @@ def load_inav(self, msg):
590608

591609
return nav, nma_b
592610

593-
def load_nav(self, nav, prn):
611+
def load_nav(self, nav, prn, tow):
594612
""" load navigation message into subframe buffer """
595613
mt = bs.unpack_from('u6', nav, 0)[0]
614+
j0 = (prn-1)*160
615+
616+
if tow % 30 == 1:
617+
self.subfrm[j0:j0+160] = self.subfrm_p[j0:j0+160]
618+
self.subfrm_p[j0:j0+160] = self.subfrm_n[j0:j0+160]
619+
# self.subfrm_n[j0:j0+160] = [0]*160
620+
596621
if mt > 0 and mt <= 10:
597-
j = (prn-1)*160+(mt-1)*16
598-
self.subfrm[j:j+16] = nav
622+
j = j0+(mt-1)*16
623+
self.subfrm_n[j:j+16] = nav
624+
625+
if self.monlevel > 0 and prn == self.prn_ref:
626+
if mt >= 1 and mt <= 4:
627+
iodnav = bs.unpack_from('u10', nav, 6)[0]
628+
print(f"tow={tow} prn={prn:2d} mt={mt:2d} iodnav={iodnav}")
629+
elif mt == 5:
630+
tow_ = bs.unpack_from('u20', nav, 85)[0]
631+
print(f"tow={tow} prn={prn:2d} mt={mt:2d} tow={tow_}")
632+
elif mt == 6:
633+
tow_ = bs.unpack_from('u20', nav, 105)[0]
634+
print(f"tow={tow} prn={prn:2d} mt={mt:2d} tow={tow_}")
635+
else:
636+
print(f"tow={tow} prn={prn:2d} mt={mt:2d}")
637+
599638
return True
600639

601640
def gen_navmsg(self, prn):
@@ -656,7 +695,6 @@ def gen_utcmsg(self):
656695
return None
657696
if self.monlevel > 0:
658697
tow = bs.unpack_from('u20', mt6, 105)[0]
659-
# bs.pack_into('u20', mt6, 105, tow+self.tofst) # <- tow-=60
660698
print(" utc gst_tow=%6d" % (tow))
661699

662700
# 141b MT6 99b, MT10 42b
@@ -667,20 +705,16 @@ def gen_utcmsg(self):
667705
bs.pack_into('u8', msg, j, b)
668706
j += 8
669707
j = 99
670-
for k in range(5):
671-
b = bs.unpack_from('u8', mt10, k*8+86)[0]
672-
bs.pack_into('u8', msg, j, b)
673-
j += 8
674708

675-
b = bs.unpack_from('u2', mt10, 40+86)[0]
676-
bs.pack_into('u2', msg, j, b)
677-
j += 2
709+
a0g, a1g, t0g, wn0g = bs.unpack_from('s16s12u8u6', mt10, 86)
710+
bs.pack_into('s16s12u8u6', msg, j, a0g, a1g, t0g, wn0g)
678711

679712
return msg
680713

681714
def gen_msg(self, adkd, prn_d, gst_sf, ctr, msg):
682715
""" generate message for verification of NMA """
683716
mlen = 141 if adkd == 4 else 549
717+
rem_ = mlen-mlen//8*8 # number of remaining bit
684718
j = 0
685719
if adkd == 0 and self.prn_a == prn_d:
686720
mlen += 8+42
@@ -700,13 +734,9 @@ def gen_msg(self, adkd, prn_d, gst_sf, ctr, msg):
700734
j += 42
701735
for k in range(len(msg)):
702736
b = msg[k]
703-
if k == len(msg)-1:
704-
if adkd == 4:
705-
bs.pack_into('u3', m, j, b >> 5)
706-
j += 3
707-
else:
708-
bs.pack_into('u5', m, j, b >> 3)
709-
j += 5
737+
if rem_ != 0 and k == len(msg)-1:
738+
bs.pack_into('u'+str(rem_), m, j, b >> (8-rem_))
739+
j += rem_
710740
else:
711741
bs.pack_into('u8', m, j, b)
712742
j += 8
@@ -765,26 +795,26 @@ def decode(self, nma_b, wn, tow, prn):
765795
PRN number
766796
"""
767797
status = False
768-
k = (tow % 30)//2
769-
if k == 0: # reset counter
798+
ki = (tow % 30)//2
799+
if ki == 0: # reset counter
770800
self.cnt[prn-1] = 0
771801
self.hk[prn-1] = bytearray(15)
772802
self.mack[prn-1][0] = 0
773-
elif k < 0:
803+
elif ki < 0:
774804
return
775805

776806
# convert GPS time to Galileo standard time (GST)
777807
gst_wn, gst_tow = time2gst(gpst2time(wn, tow))
778808

779809
self.gst_tow = (gst_tow//30)*30 # current subframe-time
780810
# store sub-frame for NMA
781-
self.hk[prn-1][k] = nma_b[0] # HK-ROOT message
782-
self.mack[prn-1][k*4:k*4+4] = nma_b[1:5] # MACK message
783-
self.cnt[prn-1] |= (1 << k)
811+
self.hk[prn-1][ki] = nma_b[0] # HK-ROOT message
812+
self.mack[prn-1][ki*4:ki*4+4] = nma_b[1:5] # MACK message
813+
self.cnt[prn-1] |= (1 << ki)
784814
if self.cnt[prn-1] == 0x7fff: # all(0-14) message loaded
785815
self.save_mack(self.mack[prn-1], prn) # store MACK
786816
# decode HK-ROOT messages
787-
result = self.decode_hk(self.hk[prn-1])
817+
result = self.decode_hk(self.hk[prn-1], prn)
788818
if self.monlevel > 0:
789819
s = "wn=%4d tow=%d gst_tow=%6d prn=%d did=%d" % \
790820
(wn, tow, self.gst_tow, prn, self.did0)
@@ -865,20 +895,29 @@ def decode(self, nma_b, wn, tow, prn):
865895
tag, macseq, cop = self.decode_tags_info(0)
866896
else:
867897
tag, prn_d, adkd, cop = self.decode_tags_info(k)
868-
if adkd == 12: # delayed tag loading
898+
if adkd == 12 and self.flg_slowmac:
899+
# delayed tag loading
869900
navmsg = self.gen_navmsg(prn_d)
870-
tag_ = taginfo(self.gst_sf, prn_d, adkd, cop,
901+
tag_ = taginfo(self.gst_sf_p, prn_d, adkd, cop,
871902
tag, ctr, navmsg)
872903
self.tag_list.append(tag_)
873904

874905
if adkd == 12:
906+
print(f"{ctr} prn_d={prn_d} adkd={adkd} slow-MAC "
907+
"is skipped")
875908
continue
876909
elif adkd == 0:
877910
navmsg = self.gen_navmsg(prn_d)
878911
elif adkd == 4:
879912
navmsg = self.gen_utcmsg()
880913
else:
881914
navmsg = None
915+
916+
if navmsg is None:
917+
print(f"{ctr} prn_d={prn_d} adkd={adkd} navmsg is "
918+
"not available.")
919+
continue
920+
882921
tag_ = taginfo(self.gst_sf_p, prn_d,
883922
adkd, cop, tag, ctr, navmsg)
884923
result = self.verify_navmsg(tag_)
@@ -893,15 +932,16 @@ def decode(self, nma_b, wn, tow, prn):
893932
print(f"{ctr} prn_d={prn_d} adkd={
894933
adkd} tag not verified")
895934
# slow MAC
896-
for tag_ in self.tag_list:
897-
dt = self.difftime(self.gst_sf, tag_.gst_sf)
898-
if dt == 300:
899-
result = self.verify_navmsg(tag_)
900-
if self.monlevel > 0 and result:
901-
print("SLOW-MAC# %d prn_d=%2d adkd=%2d tag verified"
902-
% (tag_.cnt, tag_.prn, tag_.adkd))
903-
elif dt > 300:
904-
tag_ = None
935+
if self.flg_slowmac:
936+
for tag_ in self.tag_list:
937+
dt = self.difftime(self.gst_sf, tag_.gst_sf)
938+
if dt == 300:
939+
result = self.verify_navmsg(tag_)
940+
if self.monlevel > 0 and result:
941+
print("SLOW-MAC# %d prn_d=%2d adkd=%2d tag verified"
942+
% (tag_.cnt, tag_.prn, tag_.adkd))
943+
elif dt > 300:
944+
tag_ = None
905945

906946
self.cnt[prn-1] = 0
907947
return status

0 commit comments

Comments
 (0)