diff --git a/lib/air_modes_slicer.cc b/lib/air_modes_slicer.cc index d4fb6e7..9c0bb7f 100644 --- a/lib/air_modes_slicer.cc +++ b/lib/air_modes_slicer.cc @@ -134,7 +134,7 @@ int air_modes_slicer::work(int noutput_items, slice_result_t slice_result = slicer(in[i+j*2], in[i+j*2+1], rx_packet.reference_level); if(slice_result.decision) pkt_hdr += 1 << (4-j); } - if(pkt_hdr == 17 or pkt_hdr == 20 or pkt_hdr == 21) rx_packet.type = Long_Packet; + if(pkt_hdr == 16 or pkt_hdr == 17 or pkt_hdr == 20 or pkt_hdr == 21) rx_packet.type = Long_Packet; else rx_packet.type = Short_Packet; int packet_length = (rx_packet.type == framer_packet_type(Short_Packet)) ? 56 : 112; diff --git a/python/msprint.py b/python/msprint.py index c69e3db..1f38fdb 100644 --- a/python/msprint.py +++ b/python/msprint.py @@ -55,8 +55,8 @@ class output_print(air_modes.parse): output += self.print11(data, ecc) elif msgtype == 17: output += self.print17(data) - elif msgtype == 20 or msgtype == 21: - output += self.print20(data, ecc) + elif msgtype == 20 or msgtype == 21 or msgtype == 16: + output += self.printTCAS(data, ecc) else: output += "No handler for message type %i from %x (but it's in modes_parse)" % (msgtype, ecc) return output @@ -184,14 +184,20 @@ class output_print(air_modes.parse): return retstr - def print20(self, data, ecc): + def printTCAS(self, data, ecc): msgtype = data["df"] - if(msgtype == 20): + if msgtype == 20 or msgtype == 16: + #type 16 does not have fs, dr, um but we get alt here [fs, dr, um, alt] = self.parse4(data) - else: + elif msgtype == 21: [fs, dr, um, ident] = self.parse5(data) - bds1 = data["bds1"] - bds2 = data["bds2"] + + if msgtype == 16: + bds1 = data["vds1"] + bds2 = data["vds2"] + else: + bds1 = data["bds1"] + bds2 = data["bds2"] if bds2 != 0: retstr = "No handler in type %i for BDS2 == %i from %x" % (msgtype, bds2, ecc) @@ -206,14 +212,18 @@ class output_print(air_modes.parse): elif bds1 == 3: retstr = "Type %i TCAS report from %x: " % (msgtype, ecc) tti = data["tti"] - if tti == 1: - (resolutions, complements, rat, mte, threat_id) = self.parseMB_TCAS_threatid(data) - retstr += "threat ID: %x advised: %s complement: %s" % (threat_id, resolutions, complements) - elif tti == 2: - (resolutions, complements, rat, mte, threat_alt, threat_range, threat_bearing) = self.parseMB_TCAS_threatloc(data) - retstr += "range: %i bearing: %i alt: %i advised: %s complement: %s" % (threat_range, threat_bearing, threat_alt, resolutions, complements) + if msgtype == 16: + (resolutions, complements, rat, mte) = self.parse_TCAS_CRM(data) + retstr += "advised: %s complement: %s" % (resolutions, complements) else: - retstr += " (no handler for TTI=%i)" % tti + if tti == 1: + (resolutions, complements, rat, mte, threat_id) = self.parseMB_TCAS_threatid(data) + retstr += "threat ID: %x advised: %s complement: %s" % (threat_id, resolutions, complements) + elif tti == 2: + (resolutions, complements, rat, mte, threat_alt, threat_range, threat_bearing) = self.parseMB_TCAS_threatloc(data) + retstr += "range: %i bearing: %i alt: %i advised: %s complement: %s" % (threat_range, threat_bearing, threat_alt, resolutions, complements) + else: + retstr += " (no handler for TTI=%i)" % tti if mte == 1: retstr += " (multiple threats)" if rat == 1: @@ -221,7 +231,7 @@ class output_print(air_modes.parse): else: retstr = "No handler for BDS1 == %i from %x" % (bds1, ecc) - if(msgtype == 20): + if(msgtype == 20 or msgtype == 16): retstr += " at %ift" % alt else: retstr += " ident %x" % ident diff --git a/python/parse.py b/python/parse.py index 506aec0..cfc20a0 100644 --- a/python/parse.py +++ b/python/parse.py @@ -193,6 +193,22 @@ class mb_reply(data_field): # "vds": (33,8), "vds1": (33,4), "vds2": (37,4) # } +class mv_reply(data_field): + offset = 33 + types = { "ara": (41,14), "mte": (60,1), "rac": (55,4), "rat": (59,1), + "vds": (33,8), "vds1": (33,4), "vds2": (37,4) + } + + def get_type(self): + vds1 = self.get_bits(33,4) + vds2 = self.get_bits(37,4) + if vds1 not in (3,) or vds2 not in (0,): + raise NoHandlerError(bds1) + return int(vds1) + + def get_numbits(self): + return 56 + #the whole Mode S packet type class modes_reply(data_field): types = { 0: {"df": (1,5), "vs": (6,1), "cc": (7,1), "sl": (9,3), "ri": (14,4), "ac": (20,13), "ap": (33,24)}, @@ -233,7 +249,7 @@ class parse: def parse11(self, data, ecc): interrogator = ecc & 0x0F - return [data["aa"], interrogator, data["ca"]] + return [data["aa"], interrogator, data["ca"]] categories = [["NO INFO", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED", "RESERVED"],\ ["NO INFO", "SURFACE EMERGENCY VEHICLE", "SURFACE SERVICE VEHICLE", "FIXED OBSTRUCTION", "CLUSTER OBSTRUCTION", "LINE OBSTRUCTION", "RESERVED"],\ @@ -404,3 +420,8 @@ class parse: (resolutions, complements) = self.parseMB_TCAS_resolutions(data) threat_alt = decode_alt(data["tida"], True) return (resolutions, complements, data["rat"], data["mte"], threat_alt, data["tidr"], data["tidb"]) + + #type 16 Coordination Reply Message + def parse_TCAS_CRM(self, data): + (resolutions, complements) = self.parseMB_TCAS_resolutions(data) + return (resolutions, complements, data["rat"], data["mte"])