diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..709e9c5 --- /dev/null +++ b/__init__.py @@ -0,0 +1 @@ +import iridium_toolkit.bitsparser as bitsparser \ No newline at end of file diff --git a/bch.py b/bch.py index dd293f7..15cb70d 100755 --- a/bch.py +++ b/bch.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # vim: set ts=4 sw=4 tw=0 et pm=: -from fec import stringify, listify +from .fec import stringify, listify def nndivide(poly,num): # both args as int if(num==0): diff --git a/bitsparser.py b/bitsparser.py index b8df2cc..eaa97c7 100755 --- a/bitsparser.py +++ b/bitsparser.py @@ -5,17 +5,17 @@ import sys import re import struct -from bch import ndivide, nrepair, bch_repair, bch_repair1 +from .bch import ndivide, nrepair, bch_repair, bch_repair1 import crcmod -import rs -import rs6 +from . import rs +from . import rs6 import fileinput import datetime from inspect import stack -from util import * +from .util import * from math import sqrt,atan2,pi,log -import itl +from . import itl iridium_access="001100000011000011110011" # Actually 0x789h in BPSK uplink_access= "110011000011110011111100" # BPSK: 0xc4b @@ -39,8 +39,8 @@ verbose = False perfect = False -uwec = False -harder = False +uwec = True +harder = True linefilter={ 'type': 'All', 'attr': None, 'check': None } errorfile=None forcetype=None @@ -56,6 +56,93 @@ def __init__(self, message): tsoffset=0 maxts=0 +class MessageInterface(object): + parse_error = False + error = False + + def __init__(self, timestamp, timestamp_global, frequency, snr, noise, id, confidence, level, bitsream_raw, swapped=True): + """Initialize a new message object. + + Args: + timestamp (float): Timestamp of the message in ms from the start of data collection. + timestamp_global (int): Timestamp of the message in ns (global). + frequency (int): Frequency of the message in Hz. + snr (float): Signal-to-noise ratio of the message. + noise (float): Noise level of the message. + id (int): ID of the message. + confidence (int): Confidence of the message. + level (int): Level of the message. + bitsream_raw (str): Raw bitstream of the message. + swapped (bool): Whether the bitstream is swapped. + + Returns: + MessageInterface: A new message object. + """ + self.error = False + self.error_msg = [] + self.parse_error = False + + self.lineno = 0 + self.filename = "i-0-t1" + + self.swapped = swapped + self.timestamp = float(timestamp) + if self.timestamp < 0 or self.timestamp > 1000 * 60 * 60 * 24 * 999: # 999 days + self._new_error("Timestamp out of range") + self.frequency = int(frequency) + self.freq_print="%010d" % (self.frequency) + self.snr = float(snr) + self.noise = float(noise) + self.id = str(id) + self.confidence = int(confidence) + self.level = float(level) + self.leveldb = 20 * log(self.level, 10) + self.bitstream_raw = re.sub(r"[\[\]<> ]", "", bitsream_raw) + if self.swapped: + self.bitstream_raw = symbol_reverse(self.bitstream_raw) + self.symbols = len(self.bitstream_raw) // 2 + + self.fileinfo = "p-{:d}".format(timestamp_global) + self.globalns = timestamp_global + + def upgrade(self): + """Upgrade the message to a more specific message type.""" + if self.error: + return self + if self.bitstream_raw.startswith(iridium_access): + self.uplink = 0 + elif self.bitstream_raw.startswith(uplink_access): + self.uplink = 1 + else: + if uwec and len(self.bitstream_raw) >= len(iridium_access): + access = de_dqpsk(self.bitstream_raw[:len(iridium_access)]) + + if bitdiff(access, UW_DOWNLINK) < 4: + self.uplink = 0 + self.ec_uw = bitdiff(access, UW_DOWNLINK) + elif bitdiff(access, UW_UPLINK) < 4: + self.uplink = 1 + self.ec_uw = bitdiff(access, UW_UPLINK) + else: + self._new_error("Access code distance too big: {:d}/{:d} ".format(bitdiff(access, UW_DOWNLINK), bitdiff(access, UW_UPLINK))) + if "uplink" not in self.__dict__: + self._new_error("Access code missing") + return self + try: + return IridiumMessage(self).upgrade() + except ParserError as e: + self._new_error(str(e), e.cls) + return self + + def _new_error(self,msg, cls=None): + self.error = True + if cls is None: + msg = str(type(self).__name__) + ": " + msg + else: + msg = cls + ": " + msg + if not self.error_msg or self.error_msg[-1] != msg: + self.error_msg.append(msg) + class Message(object): p=re.compile(r'(RAW|RWA): ([^ ]*) (-?[\d.]+) (\d+) (?:N:([+-]?\d+(?:\.\d+)?)([+-]\d+(?:\.\d+)?)|A:(\w+)) [IL]:(\w+) +(\d+)% ([\d.]+|inf|nan) +(\d+) ([\[\]<> 01]+)(.*)') parse_error=False diff --git a/iridium.txt b/iridium.txt deleted file mode 120000 index b7cef92..0000000 --- a/iridium.txt +++ /dev/null @@ -1 +0,0 @@ -tracking/iridium.txt \ No newline at end of file diff --git a/itl.py b/itl.py index 7028dc7..1a06e99 100644 --- a/itl.py +++ b/itl.py @@ -1,4 +1,4 @@ -from util import bitdiff, hex2bin +from .util import bitdiff, hex2bin PRS_HDR=[ "00000000000000000000000000000000", diff --git a/rs.py b/rs.py index 0e9efd9..8ad985f 100644 --- a/rs.py +++ b/rs.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # vim: set ts=4 sw=4 tw=0 et pm=: -import reedsolo +from . import reedsolo # IIQ/LCW3: Message: 31B, checksum: 8B, erasure: 8B - RS(47,31) [total: 312b] diff --git a/rs6.py b/rs6.py index b118584..edcfb50 100644 --- a/rs6.py +++ b/rs6.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # vim: set ts=4 sw=4 tw=0 et pm=: -import reedsolo6 +from . import reedsolo6 # VO6/LCW3: Message: 42*6b=31.5B, checksum: 10*6b=7.5B - RS_6(52,10) [total: 312b]