diff --git a/pyModeS/decoder/allcall.py b/pyModeS/decoder/allcall.py index 9ecd194..5f352f4 100644 --- a/pyModeS/decoder/allcall.py +++ b/pyModeS/decoder/allcall.py @@ -1,87 +1,75 @@ +""" +Decode all-call reply messages, with dowlink format 11 +""" + from pyModeS import common -""" -Decoding all call replies DF=11 -""" -def interrogator_code(msg): - if common.df(msg) == 11: # check that the msg is DF11 - '''Returns the IP code of the Mode S all-call reply (DF11)''' - binaryraw=common.hex2bin(msg) - PI=binaryraw[-24:] - DATA=binaryraw[:-24] - Gx='1111111111111010000001001000' - Mx=DATA[::-1].zfill(len(DATA)+24)[::-1] - initialdifference=len(Mx)-len(Gx) - Gx = Gx[::-1].zfill(len(Mx))[::-1] - while len(Mx)>initialdifference: - MSB=Mx[0] - if MSB=='1': - result=int(Mx,2)^int(Gx,2) - Mx = str(bin(result)[2:]) - Gx = Gx.rstrip('0')[::-1].zfill(len(Mx))[::-1] +def _checkdf(func): + """Ensure downlink format is 11.""" - else: #If the Mx starts with a 0 - Mx=Mx[1:] - Gx=Gx[:-1] + def wrapper(msg): + df = common.df(msg) + if df != 11: + raise RuntimeError( + "Incorrect downlink format, expect 11, got {}".format(df) + ) + return func(msg) - SIcode=bin(int(Mx,2)^int(PI,2)).zfill(7) #Mx is the parity sequence and PI is the last field of the DF11. - if int(SIcode[0:3],2)>0: - return str("SI" + str(int(SIcode[3:],2))) - else: - return str("II" + str(int(SIcode,2))) - else: - raise RuntimeError("Incorrect or inconsistent message types") + return wrapper -def flight_status(msg): - '''returns the flight status''' - if common.df(msg) == 11: # check that the msg is DF11 - binaryraw=common.hex2bin(msg) - CA = (int(binaryraw[5:8],2)) - if CA in [0, 1, 2, 3, 6, 7]: #reserved - return None - if CA == 4:#level 2 transponder, ability to set CA to 7 and on ground - return "on ground" - if CA == 5:#level 2 transponder, ability to set CA to 7 and airborn - return "airborne" - else: - raise RuntimeError("Incorrect or inconsistent message types") -def transponder_level(msg): - '''returns the transponder level''' - if common.df(msg) == 11:#check that the msg is DF11 - binaryraw=common.hex2bin(msg) - CA = (int(binaryraw[5:8],2)) - if CA in [1, 2, 3, 4, 5, 6, 7]: #reserved - return 2 - if CA == 0: - return 1 - else: - raise RuntimeError("Incorrect or inconsistent message types") +@_checkdf +def icao(msg): + """Decode transponder code (ICAO address). + Args: + msg (str): 14 hexdigits string + Returns: + string: ICAO address + + """ + return common.icao(msg) + + +@_checkdf +def interrogator(msg): + """Decode interrogator identifier code. + + Args: + msg (str): 14 hexdigits string + Returns: + int: interrogator identifier code + + """ + # simply the CRC reminder + return common.crc(msg) + + +@_checkdf def capability(msg): - '''return the capability code''' - if common.df(msg) == 11:#check that the msg is DF11 - binaryraw=common.hex2bin(msg) - CA = (int(binaryraw[5:8],2)) - if CA == 0: #level 1 transponder - return 0 - if CA in [1, 2, 3]: #reserved - return None - if CA == 4:#level 2 transponder, ability to set CA to 7 and on ground - return 4 - if CA == 5:#level 2 transponder, ability to set CA to 7 and airborn - return 5 - if CA == 6:#level 2 transponder, ability to set CA to 7 and either airborn on ground - return 6 - if CA == 7:# (either DR field is 0 or FS field is 2,3,4 or 5), and either airborn on ground - return 7 - else: - raise RuntimeError("Incorrect or inconsistent message types") + """Decode transponder capability. -def AA(msg): - '''returns the icao code of the aircraft''' - if common.df(msg) == 11: # check that the msg is DF11 - return (msg[2:8]) + Args: + msg (str): 14 hexdigits string + Returns: + int, str: transponder capability, description + + """ + msgbin = common.hex2bin(msg) + ca = common.bin2int(msgbin[5:8]) + + if ca == 0: + text = "level 1 transponder" + elif ca == 4: + text = "level 2 transponder, ability to set CA to 7, on ground" + elif ca == 5: + text = "level 2 transponder, ability to set CA to 7, airborne" + elif ca == 6: + text = "evel 2 transponder, ability to set CA to 7, either airborne or ground" + elif ca == 7: + text = "Downlink Request value is 0,or the Flight Status is 2, 3, 4 or 5, either airborne or on the ground" else: - raise RuntimeError("Incorrect or inconsistent message types") + text = None + + return ca, text