From fc135eacef7793491cc26b6256aa7ca930209c31 Mon Sep 17 00:00:00 2001 From: Flyer350 <57186034+Flyer350@users.noreply.github.com> Date: Wed, 11 Nov 2020 00:08:30 +0100 Subject: [PATCH] Update uplink.py additional decoded fields added --- pyModeS/decoder/uplink.py | 204 +++++++++++++++++++++++++++++++++++++- 1 file changed, 202 insertions(+), 2 deletions(-) diff --git a/pyModeS/decoder/uplink.py b/pyModeS/decoder/uplink.py index 586ee56..d1a6f70 100644 --- a/pyModeS/decoder/uplink.py +++ b/pyModeS/decoder/uplink.py @@ -1,4 +1,5 @@ from pyModeS import common +from textwrap import wrap def uplink_icao(msg): @@ -21,5 +22,204 @@ def uplink_icao(msg): def uf(msg): """Decode Uplink Format value, bits 1 to 5.""" - ufbin = common.hex2bin(msg[:2]) - return min(common.bin2int(ufbin[0:5]), 24) + dfbin = common.hex2bin(msg[:2]) + return min(common.bin2int(dfbin[0:5]), 24) + + +def bds(msg): + """Decode requested BDS register from selective (Roll Call) interrogation.""" + UF = uf(msg) + msgbin = common.hex2bin(msg) + msgbin_split = wrap(msgbin, 8) + mbytes = list(map(common.bin2int, msgbin_split)) + + if uf(msg) in {4, 5, 20, 21}: + # Decode the SI or II interrogator code + # Decode the DI and get the lockout information + # conveniently (LSS or LOS) + + # DI - Designator Identification + di = mbytes[1] & 0x7 + RR = mbytes[1] >> 3 & 0x1F + if RR > 15: + BDS1 = RR - 16 + if di == 7: + RRS = mbytes[2] & 0x0F + BDS2 = RRS + elif di == 3: + RRS = ((mbytes[2] & 0x1) << 4) | ((mbytes[3] & 0xE0) >> 5) + BDS2 = RRS + else: + BDS2 = 0 + + return str(BDS1) + str(BDS2) + else: + return None + else: + return None + + +def pr(msg): + """Decode PR (probability of reply) field from All Call interrogation. + Interpretation: + 0 signifies reply with probability of 1 + 1 signifies reply with probability of 1/2 + 2 signifies reply with probability of 1/4 + 3 signifies reply with probability of 1/8 + 4 signifies reply with probability of 1/16 + 5, 6, 7 not assigned + 8 signifies disregard lockout, reply with probability of 1 + 9 signifies disregard lockout, reply with probability of 1/2 + 10 signifies disregard lockout, reply with probability of 1/4 + 11 signifies disregard lockout, reply with probability of 1/8 + 12 signifies disregard lockout, reply with probability of 1/16 + 13, 14, 15 not assigned. + """ + msgbin = common.hex2bin(msg) + msgbin_split = wrap(msgbin, 8) + mbytes = list(map(common.bin2int, msgbin_split)) + if uf(msg) == 11: + return ((mbytes[0] & 0x7) << 1) | ((mbytes[1] & 0x80) >> 7) + else: + return None + + +def ic(msg): + """Decode IC (interrogator code) from a ground-based interrogation.""" + + UF = uf(msg) + msgbin = common.hex2bin(msg) + msgbin_split = wrap(msgbin, 8) + mbytes = list(map(common.bin2int, msgbin_split)) + IC = None + BDS2 = "" + if uf(msg) == 11: + + codeLabel = mbytes[1] & 0x7 + icField = (mbytes[1] >> 3) & 0xF + + # Store the Interogator Code + ic_switcher = { + 0: "II" + str(icField), + 1: "SI" + str(icField), + 2: "SI" + str(icField + 16), + 3: "SI" + str(icField + 32), + 4: "SI" + str(icField + 48), + } + IC = ic_switcher.get(codeLabel, "") + + if uf(msg) in {4, 5, 20, 21}: + di = mbytes[1] & 0x7 + RR = mbytes[1] >> 3 & 0x1F + if RR > 15: + BDS1 = RR - 16 + if di == 0 or di == 1 or di == 7: + # II + II = (mbytes[2] >> 4) & 0xF + IC = "II" + str(II) + elif di == 3: + # SI + SI = (mbytes[2] >> 2) & 0x3F + IC = "SI" + str(SI) + return IC + + +def lockout(msg): + """Decode the lockout command from selective (Roll Call) interrogation.""" + msgbin = common.hex2bin(msg) + msgbin_split = wrap(msgbin, 8) + mbytes = list(map(common.bin2int, msgbin_split)) + + if uf(msg) in {4, 5, 20, 21}: + lockout = False + di = mbytes[1] & 0x7 + if di == 7: + # LOS + if ((mbytes[3] & 0x40) >> 6) == 1: + lockout = True + elif di == 3: + # LSS + if ((mbytes[2] & 0x2) >> 1) == 1: + lockout = True + return lockout + else: + return None + + +def uplink_fields(msg): + """Decode individual fields of a ground-based interrogation.""" + msgbin = common.hex2bin(msg) + msgbin_split = wrap(msgbin, 8) + mbytes = list(map(common.bin2int, msgbin_split)) + PR = "" + LOS = "" + IC = "" + lockout = False + di = "" + RR = "" + RRS = "" + BDS1 = "" + BDS2 = "" + if uf(msg) == 11: + # Decode the SI or II interrogator code + # Get cl and ic bit fields from the data + + # Probability of Reply decoding + + PR = ((mbytes[0] & 0x7) << 1) | ((mbytes[1] & 0x80) >> 7) + + codeLabel = mbytes[1] & 0x7 + icField = (mbytes[1] >> 3) & 0xF + + # Store the Interogator Code + ic_switcher = { + 0: "II" + str(icField), + 1: "SI" + str(icField), + 2: "SI" + str(icField + 16), + 3: "SI" + str(icField + 32), + 4: "SI" + str(icField + 48), + } + IC = ic_switcher.get(codeLabel, "") + + if uf(msg) in {4, 5, 20, 21}: + # Decode the SI or II interrogator code + # Decode the DI and get the lockout information + # conveniently (LSS or LOS) + + # DI - Designator Identification + di = mbytes[1] & 0x7 + RR = mbytes[1] >> 3 & 0x1F + if RR > 15: + BDS1 = RR - 16 + BDS2 = 0 + if di == 0 or di == 1: + # II + II = (mbytes[2] >> 4) & 0xF + IC = "II" + str(II) + elif di == 7: + # LOS + if ((mbytes[3] & 0x40) >> 6) == 1: + lockout = True + # II + II = (mbytes[2] >> 4) & 0xF + IC = "II" + str(II) + RRS = mbytes[2] & 0x0F + BDS2 = RRS + elif di == 3: + # LSS + if ((mbytes[2] & 0x2) >> 1) == 1: + lockout = True + # SI + SI = (mbytes[2] >> 2) & 0x3F + IC = "SI" + str(SI) + RRS = ((mbytes[2] & 0x1) << 4) | ((mbytes[3] & 0xE0) >> 5) + BDS2 = RRS + return { + "DI": di, + "IC": IC, + "LOS": lockout, + "PR": PR, + "RR": RR, + "RRS": RRS, + "BDS": str(BDS1) + str(BDS2), + }