def pcap_to_json(pcap_file, field_list, json_dir, key_sep='__'): """Parse a pcap file to a json file""" file_name = os.path.basename(pcap_file) with open(pcap_file, 'rb') as pcapfile, open( os.path.join(json_dir, file_name + '.json'), 'wt') as f: print("Start reading file {}".format(pcap_file)) pcap = dpkt.pcap.Reader(pcapfile) cntr = 0 for _, buf in pcap: # print('Pcap2Csv {}: parsing packet {}'.format(pcap_file, cntr)) cntr += 1 eth = dpkt.ethernet.Ethernet(buf) data = eth.ip.udp.data # Parse data parsed = asterix.parse(data) for i, item in enumerate(parsed): item = json.dumps(item) f.write(item) f.write('\n\n') if i == 50: break break return True
def get_field_from_pcap(pcap_file, field_sep='__'): """Get all possible data fields from a raw data file. Data fields returned as chained keys (from raw dictionary) """ with open(pcap_file, 'rb') as f: pcap = dpkt.pcap.Reader(f) val_fields = [] meta_fields = [] all_fields = [] cntr = 0 print("Start processing file {}".format(pcap_file)) for _, buf in pcap: eth = dpkt.ethernet.Ethernet(buf) data = eth.ip.udp.data print('Pcap2Field {}: parsing packet {}'.format(pcap_file, cntr)) cntr += 1 # Parse data parsed = asterix.parse(data) for item in parsed: # Get keys path paths = list(get_chained_key(item)) # return a list for path in paths: path = field_sep.join(path) # return a string path = clean_key_path( path) # remove duplicate from compound items if path not in all_fields: all_fields.append(path) if ((field_sep + 'val') in path or path in ['category', 'len', 'crc', 'ts']): # check if this field is value, not description if path not in val_fields: val_fields.append(path) else: if path not in meta_fields: meta_fields.append(path) val_fields.sort() meta_fields.sort() all_fields.sort() return all_fields, val_fields, meta_fields
def pcap_to_csv(pcap_file, field_list, csv_dir, key_sep='__'): """Parse a pcap file to a csv file""" file_name = os.path.basename(pcap_file) date = get_date_from_file_path(pcap_file) with open(pcap_file, 'rb') as pcapfile, open(os.path.join(csv_dir, file_name + '.csv'), 'w', newline='') as csvfile: print("Start reading file {}".format(pcap_file)) pcap = dpkt.pcap.Reader(pcapfile) cntr = 0 writer = csv.writer(csvfile, delimiter=',') # write header name line csv_field_list = ['Date'] + field_list writer.writerow(csv_field_list) for _, buf in pcap: # print('Pcap2Csv {}: parsing packet {}'.format(pcap_file, cntr)) cntr += 1 eth = dpkt.ethernet.Ethernet(buf) data = eth.ip.udp.data # Parse data parsed = asterix.parse(data) for item in parsed: data_row = [] # empty data row data_row.append(date) for i in range(0, len(field_list) ): # field_list doesn't have TIMESTAMP field chained_key = field_list[i].split( key_sep) # convert field name to array of keys try: val = get_from_dict(item, chained_key) data_row.append(val) except KeyError: # field not found in item, write empty string to csv at this position data_row.append('') # make sure the length od data lines always equal length of header line assert (len(data_row) == len(csv_field_list)) writer.writerow(data_row) return True
def get_sample_dict_pcap(pcap_file, txt_file): """Show a sample of dictionay from pcap""" with open(pcap_file, 'rb') as f: pcap = dpkt.pcap.Reader(f) for _, buf in pcap: eth = dpkt.ethernet.Ethernet(buf) data = eth.ip.udp.data # Parse data parsed = asterix.parse(data) n = min(len(parsed), 10) sample = parsed[0:n] # print(sample) with open(txt_file, 'w') as file: file.write(json.dumps(sample)) break
def run(self): """ Receive asterix packets :return: """ print("Starting " + self.name) self.sock.bind(('', 5000)) mreq = struct.pack("=4sl", socket.inet_aton("224.51.105.104"), socket.INADDR_ANY) self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) while self.counter: if exitFlag: self.name.exit() asterix_packet = self.sock.recv(10240) parsed = asterix.parse(asterix_packet) #print('%d. Receiver received = %s' % (self.counter, parsed)) print(asterix.describe(parsed)) self.counter -= 1 print("Exiting " + self.name)
def idle_task(self): '''called on idle''' if self.sock is None: return try: pkt = self.sock.recv(10240) except Exception: return try: if pkt.startswith(b'PICKLED:'): pkt = pkt[8:] # pickled packet try: amsg = [pickle.loads(pkt)] except pickle.UnpicklingError: amsg = asterix.parse(pkt) else: amsg = asterix.parse(pkt) self.pkt_count += 1 self.console.set_status('ASTX', 'ASTX %u/%u' % (self.pkt_count, self.adsb_packets_sent), row=6) except Exception: print("bad packet") return try: logpkt = b'AST:' + struct.pack('<dI', time.time(), len(pkt)) + pkt self.logfile.write(logpkt) except Exception: pass for m in amsg: if self.asterix_settings.debug > 1: print(m) lat = m['I105']['Lat']['val'] lon = m['I105']['Lon']['val'] alt_f = m['I130']['Alt']['val'] climb_rate_fps = m['I220']['RoC']['val'] sac = m['I010']['SAC']['val'] sic = m['I010']['SIC']['val'] trkn = m['I040']['TrkN']['val'] # fake ICAO_address icao_address = trkn & 0xFFFF # use squawk for time in 0.1 second increments. This allows for old msgs to be discarded on vehicle # when using more than one link to vehicle squawk = (int(self.mpstate.attitude_time_s * 10) & 0xFFFF) alt_m = alt_f * 0.3048 # asterix is WGS84, ArduPilot uses AMSL, which is EGM96 alt_m += self.asterix_settings.wgs84_to_AMSL # consider filtering this packet out; if it's not close to # either home or the vehicle position don't send it adsb_pkt = self.master.mav.adsb_vehicle_encode(icao_address, int(lat*1e7), int(lon*1e7), mavutil.mavlink.ADSB_ALTITUDE_TYPE_GEOMETRIC, int(alt_m*1000), # mm 0, # heading 0, # hor vel int(climb_rate_fps * 0.3048 * 100), # cm/s "%08x" % icao_address, 100 + (trkn // 10000), 1.0, (mavutil.mavlink.ADSB_FLAGS_VALID_COORDS | mavutil.mavlink.ADSB_FLAGS_VALID_ALTITUDE | mavutil.mavlink.ADSB_FLAGS_VALID_VELOCITY | mavutil.mavlink.ADSB_FLAGS_VALID_HEADING), squawk) if icao_address in self.tracks: self.tracks[icao_address].update(adsb_pkt, self.get_time()) else: self.tracks[icao_address] = Track(adsb_pkt) if self.asterix_settings.debug > 0: print(adsb_pkt) # send on all links if self.should_send_adsb_pkt(adsb_pkt): self.adsb_packets_sent += 1 for i in range(len(self.mpstate.mav_master)): conn = self.mpstate.mav_master[i] #if adsb_pkt.hor_velocity < 1: # print(adsb_pkt) conn.mav.send(adsb_pkt) else: self.adsb_packets_not_sent += 1 adsb_mod = self.module('adsb') if adsb_mod: # the adsb module is loaded, display on the map adsb_mod.mavlink_packet(adsb_pkt) try: for sysid in self.mpstate.sysid_outputs: # fwd to sysid clients adsb_pkt.pack(self.mpstate.sysid_outputs[sysid].mav) self.mpstate.sysid_outputs[sysid].write(adsb_pkt.get_msgbuf()) except Exception: pass now = time.time() delta = now - self.adsb_byterate_update_timestamp if delta > 5: self.adsb_byterate_update_timestamp = now bytes_per_adsb_packet = 38 # FIXME: find constant self.adsb_byterate = (self.adsb_packets_sent - self.adsb_last_packets_sent)/delta * bytes_per_adsb_packet self.adsb_last_packets_sent = self.adsb_packets_sent
def idle_task(self): '''called on idle''' if self.sock is None: return try: pkt = self.sock.recv(10240) except Exception: return try: if pkt.startswith(b'PICKLED:'): pkt = pkt[8:] # pickled packet try: amsg = [pickle.loads(pkt)] except pickle.UnpicklingError: amsg = asterix.parse(pkt) else: amsg = asterix.parse(pkt) self.pkt_count += 1 self.console.set_status('ASTX', 'ASTX %u/%u' % (self.pkt_count, self.adsb_packets_sent), row=6) except Exception: print("bad packet") return try: logpkt = b'AST:' + struct.pack('<dI', time.time(), len(pkt)) + pkt self.logfile.write(logpkt) except Exception: pass for m in amsg: if self.asterix_settings.debug > 1: print(m) lat = m['I105']['Lat']['val'] lon = m['I105']['Lon']['val'] alt_f = m['I130']['Alt']['val'] climb_rate_fps = m['I220']['RoC']['val'] sac = m['I010']['SAC']['val'] sic = m['I010']['SIC']['val'] trkn = m['I040']['TrkN']['val'] # fake ICAO_address icao_address = trkn & 0xFFFF # use squawk for time in 0.1 second increments. This allows for old msgs to be discarded on vehicle # when using more than one link to vehicle squawk = (int(self.mpstate.attitude_time_s * 10) & 0xFFFF) alt_m = alt_f * 0.3048 # asterix is WGS84, ArduPilot uses AMSL, which is EGM96 alt_m += self.asterix_settings.wgs84_to_AMSL # consider filtering this packet out; if it's not close to # either home or the vehicle position don't send it adsb_pkt = self.master.mav.adsb_vehicle_encode( icao_address, int(lat * 1e7), int(lon * 1e7), mavutil.mavlink.ADSB_ALTITUDE_TYPE_GEOMETRIC, int(alt_m * 1000), # mm 0, # heading 0, # hor vel int(climb_rate_fps * 0.3048 * 100), # cm/s "%08x" % icao_address, 100 + (trkn // 10000), 1.0, (mavutil.mavlink.ADSB_FLAGS_VALID_COORDS | mavutil.mavlink.ADSB_FLAGS_VALID_ALTITUDE | mavutil.mavlink.ADSB_FLAGS_VALID_VELOCITY | mavutil.mavlink.ADSB_FLAGS_VALID_HEADING), squawk) if icao_address in self.tracks: self.tracks[icao_address].update(adsb_pkt, self.get_time()) else: self.tracks[icao_address] = Track(adsb_pkt) if self.asterix_settings.debug > 0: print(adsb_pkt) # send on all links if self.should_send_adsb_pkt(adsb_pkt): self.adsb_packets_sent += 1 for i in range(len(self.mpstate.mav_master)): conn = self.mpstate.mav_master[i] #if adsb_pkt.hor_velocity < 1: # print(adsb_pkt) conn.mav.send(adsb_pkt) else: self.adsb_packets_not_sent += 1 adsb_mod = self.module('adsb') if adsb_mod: # the adsb module is loaded, display on the map adsb_mod.mavlink_packet(adsb_pkt) try: for sysid in self.mpstate.sysid_outputs: # fwd to sysid clients adsb_pkt.pack(self.mpstate.sysid_outputs[sysid].mav) self.mpstate.sysid_outputs[sysid].write( adsb_pkt.get_msgbuf()) except Exception: pass now = time.time() delta = now - self.adsb_byterate_update_timestamp if delta > 5: self.adsb_byterate_update_timestamp = now bytes_per_adsb_packet = 38 # FIXME: find constant self.adsb_byterate = ( self.adsb_packets_sent - self.adsb_last_packets_sent) / delta * bytes_per_adsb_packet self.adsb_last_packets_sent = self.adsb_packets_sent
header_bytes = f.read(final_header_size) if len(header_bytes) != final_header_size: break (data_size, board_nr, line_nr, rec_day, time1, time2, time3) = struct.unpack(final_header_format, header_bytes) timems = (time1 * 65536 + time2 * 256 + time3) * 10 packet_size = data_size - final_header_size - final_padding_size timestamp = datetime.timedelta(milliseconds=timems) print("%d.\ttime=%s\tSize=%d\tboard=%d\tline=%d\tday=%d)" % (packetnr, timestamp, packet_size, board_nr, line_nr, rec_day)) packetnr += 1 packet_bytes = f.read(packet_size) # Parse packet packets = asterix.parse(packet_bytes) #print(packets) for packet in packets: print(packet) padding_bytes = f.read(4) padding = struct.unpack("BBBB", padding_bytes) if padding != final_padding_value: print("Wrong padding!!") exit(1) print("Finished")
while True: header_bytes = f.read(final_header_size) if len(header_bytes) != final_header_size: break (data_size, board_nr, line_nr, rec_day, time1, time2, time3) = struct.unpack(final_header_format, header_bytes) timems = (time1*65536+time2*256+time3)*10 packet_size = data_size-final_header_size-final_padding_size timestamp = datetime.timedelta(milliseconds=timems) print("%d.\ttime=%s\tSize=%d\tboard=%d\tline=%d\tday=%d)" % (packetnr, timestamp, packet_size, board_nr, line_nr, rec_day)) packetnr += 1 packet_bytes = f.read(packet_size) # Parse packet packets = asterix.parse(packet_bytes) #print(packets) for packet in packets: print(packet) padding_bytes = f.read(4) padding = struct.unpack("BBBB", padding_bytes) if padding != final_padding_value: print("Wrong padding!!") exit(1) print("Finished")
def test_ParseCAT048_nodescription(self): sample_filename = asterix.get_sample_file('cat048.raw') with open(sample_filename, "rb") as f: data = f.read() packet = asterix.parse(data, verbose=False) self.maxDiff = None self.assertIsNotNone(packet) self.assertIsNotNone(packet[0]) self.assertIs(len(packet), 1) self.assertTrue('I220' in packet[0]) self.assertEqual(packet[0]['category'], 48) self.assertEqual(packet[0]['len'], 45) self.assertEqual(packet[0]['crc'], 'C150ED0E') self.assertTrue('ts' in packet[0]) self.assertEqual(packet[0]['I220']['ACAddr']['val'], '3C660C') self.assertEqual(packet[0]['I010'], {'SAC': {'val': 25}, 'SIC': {'val': 201}}) self.assertEqual(packet[0]['I170'], {'GHO': {'val': 0}, 'TCC': {'val': 0}, 'RAD': {'val': 2}, 'spare': {'val': 0}, 'TRE': {'val': 0}, 'CDM': {'val': 0}, 'CNF': {'val': 0}, 'SUP': {'val': 0}, 'FX': {'val': 0}, 'DOU': {'val': 0}, 'MAH': {'val': 0}}) self.assertEqual(packet[0]['I200'], {'CGS': {'val': 434.94}, 'CHdg': {'val': 124.002685546875}}) self.assertEqual(packet[0]['I220'], {'ACAddr': {'val': '3C660C'}}) self.assertEqual(packet[0]['I250'][0], {'TARGET_ALT_STATUS': {'val': 0}, 'res': {'val': 0}, 'FMS_ALT': {'val': 0.0}, 'APP': {'val': 0}, 'ALT_HOLD': {'val': 0}, 'TARGET_ALT_SOURCE': {'val': 0}, 'BDS': {'val': '40'}, 'FMS_ALT_STATUS': {'val': 0}, 'BP_STATUS': {'val': 1}, 'BP': {'val': 227.0}, 'MODE_STATUS': {'val': 0}, 'VNAV': {'val': 0}, 'MCP_ALT_STATUS': {'val': 1}, 'MCP_ALT': {'val': 33008.0}}) self.assertEqual(packet[0]['I040'], {'THETA': {'val': 340.13671875}, 'RHO': {'val': 197.68359375}}) self.assertEqual(packet[0]['I240'], {'TId': {'val': 'DLH65A '}}) self.assertEqual(packet[0]['I140'], {'ToD': {'val': 27354.6015625}}) self.assertEqual(packet[0]['I070'], {'Mode3A': {'val': '1000'}, 'V': {'val': 0}, 'L': {'val': 0}, 'spare': {'val': 0}, 'G': {'val': 0}}) self.assertEqual(packet[0]['I161'], {'Tn': {'val': 3563}}) self.assertEqual(packet[0]['I020'], {'SIM': {'val': 0}, 'TYP': {'val': 5}, 'RAB': {'val': 0}, 'RDP': {'val': 0}, 'FX': {'val': 0}, 'SPI': {'val': 0}}) self.assertEqual(packet[0]['I090'], {'V': {'val': 0}, 'FL': {'val': 330.0}, 'G': {'val': 0}}) self.assertEqual(packet[0]['I230'], {'COM': {'val': 1}, 'BDS37': {'val': 5}, 'ModeSSSC': {'val': 1}, 'STAT': {'val': 0}, 'AIC': {'val': 1}, 'BDS16': {'val': 1}, 'spare': {'val': 0}, 'ARC': {'val': 1}, 'SI': {'val': 0}})
def test_ParseCAT062CAT065(self): sample_filename = asterix.get_sample_file('cat062cat065.raw') with open(sample_filename, "rb") as f: data = f.read() packet = asterix.parse(data) self.assertIsNotNone(packet) self.assertIsNotNone(packet[0]) self.assertIs(len(data), 195) self.assertIs(len(packet), 3) self.assertIs(packet[0]['category'], 62) self.assertIs(packet[0]['len'], 66) self.assertEqual(packet[0]['crc'], '9CB473BE') self.assertIs(packet[1]['category'], 62) self.assertIs(packet[1]['len'], 114) self.assertEqual(packet[1]['crc'], '5A6E1F96') self.assertIs(packet[2]['category'], 65) self.assertIs(packet[2]['len'], 9) self.assertEqual(packet[2]['crc'], '8B7DA47A') self.assertEqual(packet[0]['I220'], {'RoC': {'val': -443.75, 'desc': 'Rate of Climb/Descent'}}) self.assertEqual(packet[0]['I015'], {'SID': {'val': 4, 'desc': 'Service Identification'}}) self.assertEqual(packet[0]['I290']['MDS'], {'MDS': {'val': 63.75, 'desc': 'Age of the last Mode S detection used to update the track'}}) self.assertEqual(packet[0]['I290']['PSR'], {'PSR': {'val': 7.25, 'desc': 'Age of the last primary detection used to update the track'}}) self.assertEqual(packet[0]['I290']['SSR'], {'SSR': {'val': 0.0, 'desc': 'Age of the last secondary detection used to update the track'}}) self.assertEqual(packet[0]['I135'], { 'QNH': {'meaning': 'No QNH correction applied', 'val': 0, 'desc': 'QNH'}, 'CTBA': {'max': 150000.0, 'min': -1500.0, 'val': 15700.0, 'desc': 'Calculated Track Barometric Alt'}}) self.assertEqual(packet[0]['I136'], { 'MFL': {'max': 150000.0, 'min': -1500.0, 'val': 15700.0, 'desc': 'Measured Flight Level'}}) self.assertEqual(packet[0]['I185'], {'Vx': {'max': 8191.75, 'min': -8192.0, 'val': -51.25, 'desc': 'Vx'}, 'Vy': {'max': 8191.75, 'min': -8192.0, 'val': 170.0, 'desc': 'Vy'}}) self.assertEqual(packet[0]['I080'], {'STP': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'MD5': {'meaning': 'No Mode 5 interrogation', 'val': 0, 'desc': ''}, 'FPC': {'meaning': 'Not flight-plan correlated', 'val': 0, 'desc': ''}, 'AMA': {'meaning': 'track not resulting from amalgamation process', 'val': 0, 'desc': ''}, 'CNF': {'meaning': 'Confirmed track', 'val': 0, 'desc': ''}, 'TSE': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'ME': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'FX': {'meaning': 'End of data item', 'val': 0, 'desc': ''}, 'CST': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'PSR': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'MDS': { 'meaning': 'Age of the last received Mode S track update is higher than system dependent threshold', 'val': 1, 'desc': ''}, 'MI': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'SRC': {'meaning': 'height from coverage', 'val': 4, 'desc': 'Source of calculated track altitude for I062/130'}, 'SIM': {'meaning': 'Actual track', 'val': 0, 'desc': ''}, 'KOS': {'meaning': 'Background service used', 'val': 1, 'desc': ''}, 'AFF': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'MRH': {'meaning': 'Barometric altitude (Mode C) more reliable', 'val': 0, 'desc': 'Most Reliable Height'}, 'MON': {'meaning': 'Multisensor track', 'val': 0, 'desc': ''}, 'TSB': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'SUC': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'MD4': {'meaning': 'No Mode 4 interrogation', 'val': 0, 'desc': ''}, 'SPI': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'ADS': { 'meaning': 'Age of the last received ADS-B track update is higher than system dependent threshold', 'val': 1, 'desc': ''}, 'AAC': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'SSR': {'meaning': 'Default value', 'val': 0, 'desc': ''}}) self.assertEqual(packet[0]['I070'], {'ToT': {'val': 30911.6640625, 'desc': 'Time Of Track Information'}}) self.assertEqual(packet[0]['I100'], {'Y': {'val': -106114.0, 'desc': 'Y'}, 'X': {'val': -239083.0, 'desc': 'X'}}) self.assertEqual(packet[0]['I200'], {'VERTA': {'meaning': 'Descent', 'val': 2, 'desc': 'Vertical Rate'}, 'spare': {'const': 0, 'val': 0, 'desc': 'Spare bit set to zero'}, 'LONGA': {'meaning': 'Decreasing Groundspeed', 'val': 2, 'desc': 'Longitudinal Acceleration'}, 'TRANSA': {'meaning': 'Constant Course', 'val': 0, 'desc': 'Transversal Acceleration'}, 'ADF': {'meaning': 'No altitude discrepancy', 'val': 0, 'desc': 'Altitude Discrepancy Flag'}}) self.assertEqual(packet[0]['I130'], { 'Alt': {'max': 150000.0, 'min': -1500.0, 'val': 43300.0, 'desc': 'Altitude'}}) self.assertEqual(packet[0]['I060'], {'CH': {'meaning': 'No Change', 'val': 0, 'desc': 'Change in Mode 3/A'}, 'G': {'desc': 'Change in Mode 3/A', 'meaning': 'Default', 'val': 0}, 'V': {'desc': 'Change in Mode 3/A', 'meaning': 'Code validated', 'val': 0}, 'spare': {'const': 0, 'val': 0, 'desc': 'Spare bits set to 0'}, 'Mode3A': {'val': '4276', 'desc': 'Mode-3/A reply in octal representation'}}) self.assertEqual(packet[0]['I295']['MDA'], {'MDA': {'val': 0, 'desc': ''}}) self.assertEqual(packet[0]['I295']['MFL'], {'MFL': {'val': 0.0, 'desc': ''}}) self.assertEqual(packet[0]['I010'], {'SAC': {'val': 25, 'desc': 'System Area Code'}, 'SIC': {'val': 100, 'desc': 'System Identification Code'}}) self.assertEqual(packet[0]['I340']['TYP'], { 'TYP': {'val': 2, 'meaning': 'Single SSR detection', 'desc': 'Report Type'}, 'TST': {'val': 0, 'meaning': 'Real target report', 'desc': ''}, 'spare': {'val': 0, 'desc': 'Spare bits set to zero', 'const': 0}, 'RAB': {'val': 0, 'meaning': 'Report from aircraft transponder', 'desc': ''}, 'SIM': {'val': 0, 'meaning': 'Actual target report', 'desc': ''}}) self.assertEqual(packet[0]['I340']['SID'], { 'SAC': {'val': 25, 'desc': 'System Area Code'}, 'SIC': {'val': 13, 'desc': 'System Identification Code'}}) self.assertEqual(packet[0]['I340']['MDC'], { 'CG': {'val': 0, 'meaning': 'Default', 'desc': ''}, 'CV': {'val': 0, 'meaning': 'Code validated', 'desc': ''}, 'ModeC': {'max': 1270.0, 'val': 157.0, 'min': -12.0, 'desc': 'Last Measured Mode C Code'}}) self.assertEqual(packet[0]['I340']['MDA'], { 'L': {'val': 0, 'meaning': 'MODE 3/A code as derived from the reply of the transponder', 'desc': ''}, 'V': {'val': 0, 'meaning': 'Code validated', 'desc': ''}, 'Mode3A': {'val': '4276', 'desc': 'Mode 3/A reply under the form of 4 digits in octal representation'}, 'G': {'val': 0, 'meaning': 'Default', 'desc': ''}, 'spare': {'val': 0, 'desc': 'Spare bit set to zero', 'const': 0}}) self.assertEqual(packet[0]['I340']['POS'], { 'RHO': {'max': 256.0, 'val': 186.6875, 'desc': 'Measured distance'}, 'THETA': {'val': 259.453125, 'desc': 'Measured azimuth'}}) self.assertEqual(packet[0]['I105'], { 'Lat': {'val': 44.73441302776337, 'desc': 'Latitude in WGS.84 in two's complement. Range -90 < latitude < 90 deg.'}, 'Lon': {'val': 13.0415278673172, 'desc': 'Longitude in WGS.84 in two's complement. Range -180 < longitude < 180 deg.'}}) self.assertEqual(packet[0]['I040'], {'TrkN': {'val': 4980, 'desc': 'Track number'}}) self.assertEqual(packet[0]['I210'], {'Ax': {'val': 0.0, 'desc': 'Ax'}, 'Ay': {'val': 0.0, 'desc': 'Ay'}}) self.assertEqual(packet[1]['I220'], {'RoC': {'val': 0.0, 'desc': 'Rate of Climb/Descent'}}) self.assertEqual(packet[1]['I015'], {'SID': {'val': 4, 'desc': 'Service Identification'}}) self.assertEqual(packet[1]['I290']['MDS'], {'MDS': {'val': 0.0, 'desc': 'Age of the last Mode S detection used to update the track'}}) self.assertEqual(packet[1]['I290']['SSR'], {'SSR': {'val': 0.0, 'desc': 'Age of the last secondary detection used to update the track'}}) self.assertEqual(packet[1]['I135'], { 'QNH': {'meaning': 'No QNH correction applied', 'val': 0, 'desc': 'QNH'}, 'CTBA': {'max': 150000.0, 'min': -1500.0, 'val': 35000.0, 'desc': 'Calculated Track Barometric Alt'}}) self.assertEqual(packet[1]['I136'], { 'MFL': {'max': 150000.0, 'min': -1500.0, 'val': 35000.0, 'desc': 'Measured Flight Level'}}) self.assertEqual(packet[1]['I185'], {'Vx': {'max': 8191.75, 'min': -8192.0, 'val': 141.5, 'desc': 'Vx'}, 'Vy': {'max': 8191.75, 'min': -8192.0, 'val': -170.75, 'desc': 'Vy'}}) self.assertEqual(packet[1]['I080'], {'STP': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'MD5': {'meaning': 'No Mode 5 interrogation', 'val': 0, 'desc': ''}, 'FPC': {'meaning': 'Flight plan correlated', 'val': 1, 'desc': ''}, 'AMA': {'meaning': 'track not resulting from amalgamation process', 'val': 0, 'desc': ''}, 'CNF': {'meaning': 'Confirmed track', 'val': 0, 'desc': ''}, 'TSE': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'ME': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'FX': {'meaning': 'End of data item', 'val': 0, 'desc': ''}, 'CST': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'PSR': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'MDS': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'MI': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'SRC': {'meaning': 'triangulation', 'val': 3, 'desc': 'Source of calculated track altitude for I062/130'}, 'SIM': {'meaning': 'Actual track', 'val': 0, 'desc': ''}, 'KOS': {'meaning': 'Background service used', 'val': 1, 'desc': ''}, 'AFF': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'MRH': {'meaning': 'Barometric altitude (Mode C) more reliable', 'val': 0, 'desc': 'Most Reliable Height'}, 'MON': {'meaning': 'Multisensor track', 'val': 0, 'desc': ''}, 'TSB': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'SUC': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'MD4': {'meaning': 'No Mode 4 interrogation', 'val': 0, 'desc': ''}, 'SPI': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'ADS': { 'meaning': 'Age of the last received ADS-B track update is higher than system dependent threshold', 'val': 1, 'desc': ''}, 'AAC': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'SSR': {'meaning': 'Default value', 'val': 0, 'desc': ''}}) self.assertEqual(packet[1]['I070'], {'ToT': {'val': 30911.828125, 'desc': 'Time Of Track Information'}}) self.assertEqual(packet[1]['I100'], {'Y': {'val': -36106.5, 'desc': 'Y'}, 'X': {'val': -72564.5, 'desc': 'X'}}) self.assertEqual(packet[1]['I200'], {'VERTA': {'meaning': 'Level', 'val': 0, 'desc': 'Vertical Rate'}, 'spare': {'const': 0, 'val': 0, 'desc': 'Spare bit set to zero'}, 'LONGA': {'meaning': 'Constant Groundspeed', 'val': 0, 'desc': 'Longitudinal Acceleration'}, 'TRANSA': {'meaning': 'Constant Course', 'val': 0, 'desc': 'Transversal Acceleration'}, 'ADF': {'meaning': 'No altitude discrepancy', 'val': 0, 'desc': 'Altitude Discrepancy Flag'}}) self.assertEqual(packet[1]['I130'], { 'Alt': {'max': 150000.0, 'min': -1500.0, 'val': 35312.5, 'desc': 'Altitude'}}) self.assertEqual(packet[1]['I060'], {'CH': {'meaning': 'No Change', 'val': 0, 'desc': 'Change in Mode 3/A'}, 'G': {'desc': 'Change in Mode 3/A', 'meaning': 'Default', 'val': 0}, 'V': {'desc': 'Change in Mode 3/A', 'meaning': 'Code validated', 'val': 0}, 'spare': {'const': 0, 'val': 0, 'desc': 'Spare bits set to 0'}, 'Mode3A': {'val': '2535', 'desc': 'Mode-3/A reply in octal representation'}}) self.assertEqual(packet[1]['I295']['MFL'], {'MFL': {'val': 0.0, 'desc': ''}}) self.assertEqual(packet[1]['I390']['DEP'], {'DEP': {'desc': 'Departure Airport', 'val': 'EDDL'}}) self.assertEqual(packet[1]['I390']['TAC'], {'TYPE': {'desc': 'Type of Aircraft', 'val': 'B738'}}) self.assertEqual(packet[1]['I390']['DST'],{'DES': {'desc': 'Destination Airport', 'val': 'HELX'}}) self.assertEqual(packet[1]['I390']['IFI'], { 'spare': {'const': 0, 'desc': 'spare bits set to zero', 'val': 0}, 'NBR': {'desc': '', 'val': 29233709}, 'TYP': {'meaning': 'Unit 1 internal flight number', 'desc': '', 'val': 1}}) self.assertEqual(packet[1]['I390']['RDS'], {'NU1': {'desc': 'First number', 'val': ' '}, 'LTR': {'desc': 'Letter', 'val': ' '}, 'NU2': {'desc': 'Second number', 'val': ' '}}) self.assertEqual(packet[1]['I390']['WTC'], {'WTC': {'desc': 'Wake Turbulence Category', 'val': 'M'}}) self.assertEqual(packet[1]['I390']['CSN'], {'CS': {'desc': 'Callsign', 'val': 'SXD4723'}}) self.assertEqual(packet[1]['I390']['TAG'], { 'SIC': {'desc': 'System Identification Code', 'val': 100}, 'SAC': {'desc': 'System Area Code', 'val': 25}}) self.assertEqual(packet[1]['I390']['FCT'], { 'spare': {'const': 0, 'desc': 'spare bit set to zero', 'val': 0}, 'FR1FR2': {'meaning': 'Instrument Flight Rules', 'desc': '', 'val': 0}, 'RVSM': {'meaning': 'Approved', 'desc': '', 'val': 1}, 'GATOAT': {'meaning': 'General Air Traffic', 'desc': '', 'val': 1}, 'HPR': {'meaning': 'Normal Priority Flight', 'desc': '', 'val': 0}}) self.assertEqual(packet[1]['I390']['CFL'], {'CFL': {'desc': 'Current Cleared Flight Level', 'val': 350.0}}) self.assertEqual(packet[1]['I010'], {'SAC': {'val': 25, 'desc': 'System Area Code'}, 'SIC': {'val': 100, 'desc': 'System Identification Code'}}) self.assertEqual(packet[1]['I340']['TYP'], { 'TYP': {'desc': 'Report Type', 'meaning': 'Single ModeS Roll-Call', 'val': 5}, 'TST': {'desc': '', 'meaning': 'Real target report', 'val': 0}, 'SIM': {'desc': '', 'meaning': 'Actual target report', 'val': 0}, 'RAB': {'desc': '', 'meaning': 'Report from aircraft transponder', 'val': 0}, 'spare': {'desc': 'Spare bits set to zero', 'val': 0, 'const': 0}}) self.assertEqual(packet[1]['I340']['POS'], { 'RHO': {'desc': 'Measured distance', 'val': 93.1953125, 'max': 256.0}, 'THETA': {'desc': 'Measured azimuth', 'val': 271.4666748046875}}) self.assertEqual(packet[1]['I340']['MDA'], { 'G': {'desc': '', 'meaning': 'Default', 'val': 0}, 'L': {'desc': '', 'meaning': 'MODE 3/A code as derived from the reply of the transponder', 'val': 0}, 'V': {'desc': '', 'meaning': 'Code validated', 'val': 0}, 'Mode3A': {'desc': 'Mode 3/A reply under the form of 4 digits in octal representation', 'val': '2535'}, 'spare': {'desc': 'Spare bit set to zero', 'val': 0, 'const': 0}}) self.assertEqual(packet[1]['I340']['MDC'], {'ModeC': {'min': -12.0, 'desc': 'Last Measured Mode C Code', 'val': 350.0, 'max': 1270.0}, 'CG': {'desc': '', 'meaning': 'Default', 'val': 0}, 'CV': {'desc': '', 'meaning': 'Code validated', 'val': 0}}) self.assertEqual(packet[1]['I340']['SID'], { 'SIC': {'desc': 'System Identification Code', 'val': 13}, 'SAC': {'desc': 'System Area Code', 'val': 25}}) self.assertEqual(packet[1]['I380']['COM'], { 'COM': {'val': 1, 'meaning': 'Comm. A and Comm. B capability', 'desc': 'Communications capability of the transponder'}, 'SSC': {'val': 1, 'meaning': 'Yes', 'desc': 'Specific service capability'}, 'STAT': {'val': 0, 'meaning': 'No alert, no SPI, aircraft airborne', 'desc': 'Flight Status'}, 'spare': {'val': 0, 'const': 0, 'desc': 'Spare bits set to zero'}, 'B1A': {'val': 1, 'desc': 'BDS 1,0 bit 16'}, 'B1B': {'val': 6, 'desc': 'BDS 1,0 bits 37/40'}, 'ARC': {'val': 1, 'meaning': '25 ft resolution', 'desc': 'Altitude reporting capability'}, 'AIC': {'val': 1, 'meaning': 'Yes', 'desc': 'Aircraft identification capability'}}) self.assertEqual(packet[1]['I380']['ADR'], {'ADR': {'val': '3C0A55', 'desc': 'Target Address'}}) self.assertEqual(packet[1]['I380']['ID'], {'ACID': {'val': 'SXD4723 ', 'desc': 'Target Identification'}}) self.assertEqual(packet[1]['I105'], {'Lat': {'val': 45.40080785751343, 'desc': 'Latitude in WGS.84 in two's complement. Range -90 < latitude < 90 deg.'}, 'Lon': {'val': 15.13318419456482, 'desc': 'Longitude in WGS.84 in two's complement. Range -180 < longitude < 180 deg.'}}) self.assertEqual(packet[1]['I040'], {'TrkN': {'val': 7977, 'desc': 'Track number'}}) self.assertEqual(packet[1]['I210'], {'Ax': {'val': 0.0, 'desc': 'Ax'}, 'Ay': {'val': 0.0, 'desc': 'Ay'}}) self.assertEqual(packet[2]['I015'], {'SID': {'val': 4, 'desc': 'Service Identification'}}) self.assertEqual(packet[2]['I020'], {'BTN': {'val': 24, 'desc': 'Batch Number'}}) self.assertEqual(packet[2]['I010'], {'SAC': {'val': 25, 'desc': 'Source Area Code'}, 'SIC': {'val': 100, 'desc': 'Source Identification Code'}}) self.assertEqual(packet[2]['I030'], {'ToD': {'val': 30913.0546875, 'desc': 'Time Of Message'}}) self.assertEqual(packet[2]['I000'], {'Typ': {'meaning': 'End of Batch', 'val': 2, 'desc': 'Message Type'}})
def test_ParseCAT062CAT065(self): sample_filename = asterix.get_sample_file('cat062cat065.raw') with open(sample_filename, "rb") as f: data = f.read() packet = asterix.parse(data) self.assertIsNotNone(packet) self.assertIsNotNone(packet[0]) self.assertIs(len(data), 195) self.assertIs(len(packet), 3) self.assertIs(packet[0]['category'], 62) self.assertIs(packet[0]['len'], 66) self.assertEqual(packet[0]['crc'], '9CB473BE') self.assertIs(packet[1]['category'], 62) self.assertIs(packet[1]['len'], 114) self.assertEqual(packet[1]['crc'], '5A6E1F96') self.assertIs(packet[2]['category'], 65) self.assertIs(packet[2]['len'], 9) self.assertEqual(packet[2]['crc'], '8B7DA47A') self.assertEqual(packet[0]['I220'], {'RoC': {'val': -443.75, 'desc': 'Rate of Climb/Descent'}}) self.assertEqual(packet[0]['I015'], {'SID': {'val': 4, 'desc': 'Service Identification'}}) self.assertEqual(packet[0]['I290'], { 'MDS': {'val': 63.75, 'desc': 'Age of the last Mode S detection used to update the track'}, 'ES': {'val': 0, 'desc': 'ADS-B Extended Squitter age'}, 'PSR': {'val': 7.25, 'desc': 'Age of the last primary detection used to update the track'}, 'FX': {'meaning': 'no extension', 'val': 0, 'desc': 'Extension indicator'}, 'VDL': {'val': 0, 'desc': 'ADS-B VDL Mode 4 age'}, 'ADS': {'val': 0, 'desc': 'ADS-C age'}, 'TRK': {'val': 0, 'desc': 'Track age'}, 'SSR': {'val': 0.0, 'desc': 'Age of the last secondary detection used to update the track'}}) self.assertEqual(packet[0]['I135'], { 'QNH': {'meaning': 'No QNH correction applied', 'val': 0, 'desc': 'QNH'}, 'CTBA': {'max': 150000.0, 'min': -1500.0, 'val': 15700.0, 'desc': 'Calculated Track Barometric Alt'}}) self.assertEqual(packet[0]['I136'], { 'MFL': {'max': 150000.0, 'min': -1500.0, 'val': 15700.0, 'desc': 'Measured Flight Level'}}) self.assertEqual(packet[0]['I185'], {'Vx': {'max': 8191.75, 'min': -8192.0, 'val': -51.25, 'desc': 'Vx'}, 'Vy': {'max': 8191.75, 'min': -8192.0, 'val': 170.0, 'desc': 'Vy'}}) self.assertEqual(packet[0]['I080'], {'STP': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'MD5': {'meaning': 'No Mode 5 interrogation', 'val': 0, 'desc': ''}, 'FPC': {'meaning': 'Not flight-plan correlated', 'val': 0, 'desc': ''}, 'AMA': {'meaning': 'track not resulting from amalgamation process', 'val': 0, 'desc': ''}, 'CNF': {'meaning': 'Confirmed track', 'val': 0, 'desc': ''}, 'TSE': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'ME': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'FX': {'meaning': 'End of data item', 'val': 0, 'desc': ''}, 'CST': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'PSR': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'MDS': { 'meaning': 'Age of the last received Mode S track update is higher than system dependent threshold', 'val': 1, 'desc': ''}, 'MI': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'SRC': {'meaning': 'height from coverage', 'val': 4, 'desc': 'Source of calculated track altitude for I062/130'}, 'SIM': {'meaning': 'Actual track', 'val': 0, 'desc': ''}, 'KOS': {'meaning': 'Background service used', 'val': 1, 'desc': ''}, 'AFF': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'MRH': {'meaning': 'Barometric altitude (Mode C) more reliable', 'val': 0, 'desc': 'Most Reliable Height'}, 'MON': {'meaning': 'Multisensor track', 'val': 0, 'desc': ''}, 'TSB': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'SUC': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'MD4': {'meaning': 'No Mode 4 interrogation', 'val': 0, 'desc': ''}, 'SPI': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'ADS': { 'meaning': 'Age of the last received ADS-B track update is higher than system dependent threshold', 'val': 1, 'desc': ''}, 'AAC': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'SSR': {'meaning': 'Default value', 'val': 0, 'desc': ''}}) self.assertEqual(packet[0]['I070'], {'ToT': {'val': 30911.6640625, 'desc': 'Time Of Track Information'}}) self.assertEqual(packet[0]['I100'], {'Y': {'val': -106114.0, 'desc': 'Y'}, 'X': {'val': -239083.0, 'desc': 'X'}}) self.assertEqual(packet[0]['I200'], {'VERTA': {'meaning': 'Descent', 'val': 2, 'desc': 'Vertical Rate'}, 'spare': {'const': 0, 'val': 0, 'desc': 'Spare bit set to zero'}, 'LONGA': {'meaning': 'Decreasing Groundspeed', 'val': 2, 'desc': 'Longitudinal Acceleration'}, 'TRANSA': {'meaning': 'Constant Course', 'val': 0, 'desc': 'Transversal Acceleration'}, 'ADF': {'meaning': 'No altitude discrepancy', 'val': 0, 'desc': 'Altitude Discrepancy Flag'}}) self.assertEqual(packet[0]['I130'], { 'Alt': {'max': 150000.0, 'min': -1500.0, 'val': 43300.0, 'desc': 'Altitude'}}) self.assertEqual(packet[0]['I060'], {'CH': {'meaning': 'No Change', 'val': 0, 'desc': 'Change in Mode 3/A'}, 'spare': {'const': 0, 'val': 0, 'desc': 'Spare bits set to 0'}, 'Mode3A': {'val': '4276', 'desc': 'Mode-3/A reply in octal representation'}}) self.assertEqual(packet[0]['I295'], {'MD2': {'val': 0, 'desc': ''}, 'MD5': {'val': 0, 'desc': ''}, 'MFL': {'val': 0.0, 'desc': ''}, 'MDA': {'val': 0.0, 'desc': ''}, 'FX': {'meaning': 'no extension', 'val': 0, 'desc': 'Extension indicator'}, 'MHG': {'val': 0, 'desc': ''}, 'MD1': {'val': 0, 'desc': ''}, 'MD4': {'val': 0, 'desc': ''}}) self.assertEqual(packet[0]['I010'], {'SAC': {'val': 25, 'desc': 'System Area Code'}, 'SIC': {'val': 100, 'desc': 'System Identification Code'}}) self.assertEqual(packet[0]['I340'], {'SID': {'val': 1, 'desc': 'Sensor Identification'}, 'Mode3A': {'val': '4276', 'desc': 'Mode 3/A reply under the form of 4 digits in octal representation'}, 'HEI': {'val': 0, 'desc': 'Measured 3-D Height'}, 'TST': {'meaning': 'Real target report', 'val': 0, 'desc': ''}, 'G': {'meaning': 'Default', 'val': 0, 'desc': ''}, 'V': {'meaning': 'Code validated', 'val': 0, 'desc': ''}, 'CG': {'meaning': 'Default', 'val': 0, 'desc': ''}, 'FX': {'meaning': 'no extension', 'val': 0, 'desc': 'Extension indicator'}, 'ModeC': {'max': 1270.0, 'min': -12.0, 'val': 157.0, 'desc': 'Last Measured Mode C Code'}, 'CV': {'meaning': 'Code validated', 'val': 0, 'desc': ''}, 'SAC': {'val': 25, 'desc': 'System Area Code'}, 'RHO': {'max': 256.0, 'val': 186.6875, 'desc': 'Measured distance'}, 'SIM': {'meaning': 'Actual target report', 'val': 0, 'desc': ''}, 'MDA': {'val': 1, 'desc': 'Last Measured Mode 3/A code'}, 'SIC': {'val': 13, 'desc': 'System Identification Code'}, 'THETA': {'val': 259.453125, 'desc': 'Measured azimuth'}, 'POS': {'val': 1, 'desc': 'Measured Position'}, 'TYP': {'meaning': 'Single SSR detection', 'val': 2, 'desc': 'Report Type'}, 'RAB': {'meaning': 'Report from aircraft transponder', 'val': 0, 'desc': ''}, 'spare': {'const': 0, 'val': 0, 'desc': 'Spare bits set to zero'}, 'L': { 'meaning': 'MODE 3/A code as derived from the reply of the transponder', 'val': 0, 'desc': ''}, 'MDC': {'val': 1, 'desc': 'Last Measured Mode C code'}}) self.assertEqual(packet[0]['I105'], { 'Lat': {'val': 44.73441302776337, 'desc': 'Latitude in WGS.84 in twos complement. Range -90 < latitude < 90 deg.'}, 'Lon': {'val': 13.0415278673172, 'desc': 'Longitude in WGS.84 in twos complement. Range -180 < longitude < 180 deg.'}}) self.assertEqual(packet[0]['I040'], {'TrkN': {'val': 4980, 'desc': 'Track number'}}) self.assertEqual(packet[0]['I210'], {'Ax': {'val': 0.0, 'desc': 'Ax'}, 'Ay': {'val': 0.0, 'desc': 'Ay'}}) self.assertEqual(packet[1]['I220'], {'RoC': {'val': 0.0, 'desc': 'Rate of Climb/Descent'}}) self.assertEqual(packet[1]['I015'], {'SID': {'val': 4, 'desc': 'Service Identification'}}) self.assertEqual(packet[1]['I290'], { 'MDS': {'val': 0.0, 'desc': 'Age of the last Mode S detection used to update the track'}, 'ES': {'val': 0, 'desc': 'ADS-B Extended Squitter age'}, 'PSR': {'val': 1.0, 'desc': 'Age of the last primary detection used to update the track'}, 'FX': {'meaning': 'no extension', 'val': 0, 'desc': 'Extension indicator'}, 'VDL': {'val': 0, 'desc': 'ADS-B VDL Mode 4 age'}, 'ADS': {'val': 0, 'desc': 'ADS-C age'}, 'TRK': {'val': 0, 'desc': 'Track age'}, 'SSR': {'val': 0.0, 'desc': 'Age of the last secondary detection used to update the track'}}) self.assertEqual(packet[1]['I135'], { 'QNH': {'meaning': 'No QNH correction applied', 'val': 0, 'desc': 'QNH'}, 'CTBA': {'max': 150000.0, 'min': -1500.0, 'val': 35000.0, 'desc': 'Calculated Track Barometric Alt'}}) self.assertEqual(packet[1]['I136'], { 'MFL': {'max': 150000.0, 'min': -1500.0, 'val': 35000.0, 'desc': 'Measured Flight Level'}}) self.assertEqual(packet[1]['I185'], {'Vx': {'max': 8191.75, 'min': -8192.0, 'val': 141.5, 'desc': 'Vx'}, 'Vy': {'max': 8191.75, 'min': -8192.0, 'val': -170.75, 'desc': 'Vy'}}) self.assertEqual(packet[1]['I080'], {'STP': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'MD5': {'meaning': 'No Mode 5 interrogation', 'val': 0, 'desc': ''}, 'FPC': {'meaning': 'Flight plan correlated', 'val': 1, 'desc': ''}, 'AMA': {'meaning': 'track not resulting from amalgamation process', 'val': 0, 'desc': ''}, 'CNF': {'meaning': 'Confirmed track', 'val': 0, 'desc': ''}, 'TSE': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'ME': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'FX': {'meaning': 'End of data item', 'val': 0, 'desc': ''}, 'CST': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'PSR': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'MDS': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'MI': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'SRC': {'meaning': 'triangulation', 'val': 3, 'desc': 'Source of calculated track altitude for I062/130'}, 'SIM': {'meaning': 'Actual track', 'val': 0, 'desc': ''}, 'KOS': {'meaning': 'Background service used', 'val': 1, 'desc': ''}, 'AFF': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'MRH': {'meaning': 'Barometric altitude (Mode C) more reliable', 'val': 0, 'desc': 'Most Reliable Height'}, 'MON': {'meaning': 'Multisensor track', 'val': 0, 'desc': ''}, 'TSB': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'SUC': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'MD4': {'meaning': 'No Mode 4 interrogation', 'val': 0, 'desc': ''}, 'SPI': {'meaning': 'default value', 'val': 0, 'desc': ''}, 'ADS': { 'meaning': 'Age of the last received ADS-B track update is higher than system dependent threshold', 'val': 1, 'desc': ''}, 'AAC': {'meaning': 'Default value', 'val': 0, 'desc': ''}, 'SSR': {'meaning': 'Default value', 'val': 0, 'desc': ''}}) self.assertEqual(packet[1]['I070'], {'ToT': {'val': 30911.828125, 'desc': 'Time Of Track Information'}}) self.assertEqual(packet[1]['I100'], {'Y': {'val': -36106.5, 'desc': 'Y'}, 'X': {'val': -72564.5, 'desc': 'X'}}) self.assertEqual(packet[1]['I200'], {'VERTA': {'meaning': 'Level', 'val': 0, 'desc': 'Vertical Rate'}, 'spare': {'const': 0, 'val': 0, 'desc': 'Spare bit set to zero'}, 'LONGA': {'meaning': 'Constant Groundspeed', 'val': 0, 'desc': 'Longitudinal Acceleration'}, 'TRANSA': {'meaning': 'Constant Course', 'val': 0, 'desc': 'Transversal Acceleration'}, 'ADF': {'meaning': 'No altitude discrepancy', 'val': 0, 'desc': 'Altitude Discrepancy Flag'}}) self.assertEqual(packet[1]['I130'], { 'Alt': {'max': 150000.0, 'min': -1500.0, 'val': 35312.5, 'desc': 'Altitude'}}) self.assertEqual(packet[1]['I060'], {'CH': {'meaning': 'No Change', 'val': 0, 'desc': 'Change in Mode 3/A'}, 'spare': {'const': 0, 'val': 0, 'desc': 'Spare bits set to 0'}, 'Mode3A': {'val': '2535', 'desc': 'Mode-3/A reply in octal representation'}}) self.assertEqual(packet[1]['I295'], {'MD2': {'val': 0, 'desc': ''}, 'MD5': {'val': 0, 'desc': ''}, 'MFL': {'val': 0.0, 'desc': ''}, 'MDA': {'val': 0.0, 'desc': ''}, 'FX': {'meaning': 'no extension', 'val': 0, 'desc': 'Extension indicator'}, 'MHG': {'val': 0, 'desc': ''}, 'MD1': {'val': 0, 'desc': ''}, 'MD4': {'val': 0, 'desc': ''}}) self.assertEqual(packet[1]['I390'], {'FCT': {'val': 1, 'desc': 'Flight Category'}, 'TYPE': {'val': 'B738', 'desc': 'Type of Aircraft'}, 'NBR': {'val': 29233709, 'desc': ''}, 'GATOAT': {'meaning': 'General Air Traffic', 'val': 1, 'desc': ''}, 'STD': {'val': 0, 'desc': 'Standard Instrument Departure'}, 'CTL': {'val': 0, 'desc': 'Current Control Position'}, 'RVSM': {'meaning': 'Approved', 'val': 1, 'desc': ''}, 'CS': {'val': 'SXD4723', 'desc': 'Callsign'}, 'DST': {'val': 1, 'desc': 'Destination Airport'}, 'AST': {'val': 0, 'desc': 'Aircraft Stand'}, 'FX': {'meaning': 'no extension', 'val': 0, 'desc': 'Extension indicator'}, 'IFI': {'val': 1, 'desc': 'IFPS_FLIGHT_ID'}, 'STS': {'val': 0, 'desc': 'Stand Status'}, 'RDS': {'val': 1, 'desc': 'Runway Designation'}, 'DES': {'val': 'HELX', 'desc': 'Destination Airport'}, 'CFL': {'val': 350.0, 'desc': 'Current Cleared Flight Level'}, 'DEP': {'val': 'EDDL', 'desc': 'Departure Airport'}, 'PEC': {'val': 0, 'desc': 'Pre-emergency Callsign'}, 'TAC': {'val': 1, 'desc': 'Type of Aircraft'}, 'SAC': {'val': 25, 'desc': 'System Area Code'}, 'NU2': {'val': ' ', 'desc': 'Second number'}, 'spare': {'const': 0, 'val': 0, 'desc': 'spare bit set to zero'}, 'PEM': {'val': 0, 'desc': 'Pre-emergency Mode 3/A code'}, 'HPR': {'meaning': 'Normal Priority Flight', 'val': 0, 'desc': ''}, 'SIC': {'val': 100, 'desc': 'System Identification Code'}, 'FR1FR2': {'meaning': 'Instrument Flight Rules', 'val': 0, 'desc': ''}, 'TAG': {'val': 1, 'desc': 'FPPS Identification Tag'}, 'TYP': {'meaning': 'Unit 1 internal flight number', 'val': 1, 'desc': ''}, 'TOD': {'val': 0, 'desc': 'Time of Departure'}, 'NU1': {'val': ' ', 'desc': 'First number'}, 'LTR': {'val': ' ', 'desc': 'Letter'}, 'CSN': {'val': 1, 'desc': 'Callsign'}, 'STA': {'val': 0, 'desc': 'Standard Instrument Arrival'}, 'WTC': {'val': 'M', 'desc': 'Wake Turbulence Category'}}) self.assertEqual(packet[1]['I010'], {'SAC': {'val': 25, 'desc': 'System Area Code'}, 'SIC': {'val': 100, 'desc': 'System Identification Code'}}) self.assertEqual(packet[1]['I340'], {'SID': {'val': 1, 'desc': 'Sensor Identification'}, 'Mode3A': {'val': '2535', 'desc': 'Mode 3/A reply under the form of 4 digits in octal representation'}, 'HEI': {'val': 0, 'desc': 'Measured 3-D Height'}, 'TST': {'meaning': 'Real target report', 'val': 0, 'desc': ''}, 'G': {'meaning': 'Default', 'val': 0, 'desc': ''}, 'V': {'meaning': 'Code validated', 'val': 0, 'desc': ''}, 'CG': {'meaning': 'Default', 'val': 0, 'desc': ''}, 'FX': {'meaning': 'no extension', 'val': 0, 'desc': 'Extension indicator'}, 'ModeC': {'max': 1270.0, 'min': -12.0, 'val': 350.0, 'desc': 'Last Measured Mode C Code'}, 'CV': {'meaning': 'Code validated', 'val': 0, 'desc': ''}, 'SAC': {'val': 25, 'desc': 'System Area Code'}, 'RHO': {'max': 256.0, 'val': 93.1953125, 'desc': 'Measured distance'}, 'SIM': {'meaning': 'Actual target report', 'val': 0, 'desc': ''}, 'MDA': {'val': 1, 'desc': 'Last Measured Mode 3/A code'}, 'SIC': {'val': 13, 'desc': 'System Identification Code'}, 'THETA': {'val': 271.4666748046875, 'desc': 'Measured azimuth'}, 'POS': {'val': 1, 'desc': 'Measured Position'}, 'TYP': {'meaning': 'Single ModeS Roll-Call', 'val': 5, 'desc': 'Report Type'}, 'RAB': {'meaning': 'Report from aircraft transponder', 'val': 0, 'desc': ''}, 'spare': {'const': 0, 'val': 0, 'desc': 'Spare bits set to zero'}, 'L': { 'meaning': 'MODE 3/A code as derived from the reply of the transponder', 'val': 0, 'desc': ''}, 'MDC': {'val': 1, 'desc': 'Last Measured Mode C code'}}) self.assertEqual(packet[1]['I380'], {'ACID': {'val': 'SXD4723 ', 'desc': 'Target Identification'}, 'FSS': {'val': 0, 'desc': 'Final State SelectedAltitude'}, 'STAT': {'meaning': 'No alert, no SPI, aircraft airborne', 'val': 0, 'desc': 'Flight Status'}, 'ARC': {'meaning': '25 ft resolution', 'val': 1, 'desc': 'Altitude reporting capability'}, 'COM': {'meaning': 'Comm. A and Comm. B capability', 'val': 1, 'desc': 'Communications capability of the transponder'}, 'ID': {'val': 1, 'desc': 'Target Identification'}, 'TID': {'val': 0, 'desc': 'Trajectory Intent Data'}, 'AIC': {'meaning': 'Yes', 'val': 1, 'desc': 'Aircraft identification capability'}, 'B1B': {'val': 6, 'desc': 'BDS 1,0 bits 37/40'}, 'SAL': {'val': 0, 'desc': 'Selected Altitude'}, 'SAB': {'val': 0, 'desc': 'Status reported by ADS-B'}, 'spare': {'const': 0, 'val': 0, 'desc': 'Spare bits set to zero'}, 'ACS': {'val': 0, 'desc': 'ACAS Resolution Advisory Report'}, 'TAS': {'val': 0, 'desc': 'True Airspeed'}, 'ADR': {'val': '3C0A55', 'desc': 'Target Address'}, 'SSC': {'meaning': 'Yes', 'val': 1, 'desc': 'Specific service capability'}, 'MHG': {'val': 0, 'desc': 'Magnetic Heading'}, 'IAS': {'val': 0, 'desc': 'Indicated Airspeed/Mach Number'}, 'FX': {'meaning': 'no extension', 'val': 0, 'desc': 'Extension indicator'}, 'TIS': {'val': 0, 'desc': 'Trajectory Intent Status'}, 'GVR': {'val': 0, 'desc': 'Geometric Vertical Rate'}, 'B1A': {'val': 1, 'desc': 'BDS 1,0 bit 16'}, 'BVR': {'val': 0, 'desc': 'Barometric Vertical Rate'}}) self.assertEqual(packet[1]['I105'], {'Lat': {'val': 45.40080785751343, 'desc': 'Latitude in WGS.84 in twos complement. Range -90 < latitude < 90 deg.'}, 'Lon': {'val': 15.13318419456482, 'desc': 'Longitude in WGS.84 in twos complement. Range -180 < longitude < 180 deg.'}}) self.assertEqual(packet[1]['I040'], {'TrkN': {'val': 7977, 'desc': 'Track number'}}) self.assertEqual(packet[1]['I210'], {'Ax': {'val': 0.0, 'desc': 'Ax'}, 'Ay': {'val': 0.0, 'desc': 'Ay'}}) self.assertEqual(packet[2]['I015'], {'SID': {'val': 4, 'desc': 'Service Identification'}}) self.assertEqual(packet[2]['I020'], {'BTN': {'val': 24, 'desc': 'Batch Number'}}) self.assertEqual(packet[2]['I010'], {'SAC': {'val': 25, 'desc': 'Source Area Code'}, 'SIC': {'val': 100, 'desc': 'Source Identification Code'}}) self.assertEqual(packet[2]['I030'], {'ToD': {'val': 30913.0546875, 'desc': 'Time Of Message'}}) self.assertEqual(packet[2]['I000'], {'Typ': {'meaning': 'End of Batch', 'val': 2, 'desc': 'Message Type'}})
def test_ParseCAT048(self): sample_filename = asterix.get_sample_file('cat048.raw') with open(sample_filename, "rb") as f: data = f.read() packet = asterix.parse(data) self.maxDiff = None self.assertIsNotNone(packet) self.assertIsNotNone(packet[0]) self.assertIs(len(packet), 1) self.assertTrue('I220' in packet[0]) self.assertEqual(packet[0]['category'], 48) self.assertEqual(packet[0]['len'], 45) self.assertEqual(packet[0]['crc'], 'C150ED0E') self.assertTrue('ts' in packet[0]) self.assertEqual(packet[0]['I220']['ACAddr']['val'], '3C660C') self.assertEqual(packet[0]['I220']['ACAddr']['desc'], 'AircraftAddress') self.assertEqual(packet[0]['I010'], {'SAC': {'desc': 'System Area Code', 'val': 25}, 'SIC': {'desc': 'System Identification Code', 'val': 201}}) self.assertEqual(packet[0]['I170'], {'GHO': {'desc': 'GHO', 'val': 0, 'meaning': 'True target track'}, 'TCC': {'desc': 'TCC', 'val': 0, 'meaning': 'Radar plane'}, 'RAD': {'desc': 'RAD', 'val': 2, 'meaning': 'SSR/ModeS Track'}, 'spare': {'desc': 'spare bits set to 0', 'const': 0, 'val': 0}, 'TRE': {'desc': 'TRE', 'val': 0, 'meaning': 'Track still alive'}, 'CDM': {'desc': 'CDM', 'val': 0, 'meaning': 'Maintaining'}, 'CNF': {'desc': 'CNF', 'val': 0, 'meaning': 'Confirmed Track'}, 'SUP': {'desc': 'SUP', 'val': 0, 'meaning': 'Track from cluster network - NO'}, 'FX': {'desc': 'FX', 'val': 0, 'meaning': 'End of Data Item'}, 'DOU': {'desc': 'DOU', 'val': 0, 'meaning': 'Normal confidence'}, 'MAH': {'desc': 'MAH', 'val': 0, 'meaning': 'No horizontal man. sensed'}}) self.assertEqual(packet[0]['I200'], {'CGS': {'desc': 'Calculated groundspeed', 'val': 434.94}, 'CHdg': {'desc': 'Calculated heading', 'val': 124.002685546875}}) self.assertEqual(packet[0]['I220'], {'ACAddr': {'desc': 'AircraftAddress', 'val': '3C660C'}}) self.assertEqual(packet[0]['I250'], {'ALT_HOLD': {'val': 0, 'desc': 'ALT HOLD Mode', 'meaning': 'Not active'}, 'APP': {'val': 0, 'desc': 'APPROACH Mode', 'meaning': 'Not active'}, 'BP_STATUS': {'val': 1, 'desc': 'Barometric Pressure Status'}, 'MODE_STATUS': {'val': 0, 'desc': 'Status of MCP/FCU Mode Bits'}, 'MCP_ALT': {'val': 33008.0, 'desc': 'MCP/FCU Selected Altitude'}, 'VNAV': {'val': 0, 'desc': 'VNAV Mode', 'meaning': 'Not active'}, 'FMS_ALT_STATUS': {'val': 0, 'desc': 'FMS Altitude Status'}, 'FMS_ALT': {'val': 0.0, 'desc': 'FMS Selected Altitude'}, 'res': {'val': 0, 'desc': 'Reserved'}, 'MCP_ALT_STATUS': {'val': 1, 'desc': 'MCP Altitude Status'}, 'TARGET_ALT_STATUS': {'val': 0, 'desc': 'Status of Target ALT source bits', 'meaning': 'No source information provided'}, 'BP': {'val': 227.0, 'desc': 'Barometric Pressure'}, 'TARGET_ALT_SOURCE': {'val': 0, 'desc': 'Target ALT source', 'meaning': 'Unknown'}}) self.assertEqual(packet[0]['I040'], {'THETA': {'desc': '', 'val': 340.13671875}, 'RHO': {'desc': '', 'max': 256.0, 'val': 197.68359375}}) self.assertEqual(packet[0]['I240'], {'TId': {'desc': 'Characters 1-8 (coded on 6 bits each) defining target identification', 'val': 'DLH65A '}}) self.assertEqual(packet[0]['I140'], {'ToD': {'desc': 'Time Of Day', 'val': 27354.6015625}}) self.assertEqual(packet[0]['I070'], {'Mode3A': {'desc': 'Mode-3/A reply code', 'val': '1000'}, 'V': {'desc': '', 'val': 0, 'meaning': 'Code validated'}, 'L': {'desc': '', 'val': 0, 'meaning': 'Mode-3/A code as derived from the reply of the transponder'}, 'spare': {'desc': 'spare bit set to 0', 'const': 0, 'val': 0}, 'G': {'desc': '', 'val': 0, 'meaning': 'Default'}}) self.assertEqual(packet[0]['I161'], {'Tn': {'desc': 'Track Number', 'val': 3563}}) self.assertEqual(packet[0]['I020'], {'SIM': {'desc': 'SIM', 'val': 0, 'meaning': 'Actual target report'}, 'TYP': {'desc': 'TYP', 'val': 5, 'meaning': 'Single ModeS Roll-Call'}, 'RAB': {'desc': 'RAB', 'val': 0, 'meaning': 'Report from aircraft transponder'}, 'RDP': {'desc': 'RDP', 'val': 0, 'meaning': 'Report from RDP Chain 1'}, 'FX': {'desc': 'FX', 'val': 0, 'meaning': 'End of Data Item'}, 'SPI': {'desc': 'SPI', 'val': 0, 'meaning': 'Absence of SPI'}}) self.assertEqual(packet[0]['I090'], {'V': {'desc': '', 'val': 0, 'meaning': 'Code validated'}, 'FL': {'desc': 'FlightLevel', 'val': 330.0}, 'G': {'desc': '', 'val': 0, 'meaning': 'Default'}}) self.assertEqual(packet[0]['I230'], {'COM': {'desc': 'COM', 'val': 1}, 'BDS37': {'desc': 'BDS 1,0 bits 37/40', 'val': 5}, 'ModeSSSC': {'desc': 'ModeS Specific Service Capability', 'val': 1, 'meaning': 'Yes'}, 'STAT': {'desc': 'STAT', 'val': 0}, 'AIC': {'desc': 'Aircraft identification capability', 'val': 1, 'meaning': 'Yes'}, 'BDS16': {'desc': 'BDS 1,0 bit 16', 'val': 1}, 'spare': {'desc': 'spare bit set to 0', 'const': 0, 'val': 0}, 'ARC': {'desc': 'Altitude reporting capability', 'val': 1, 'meaning': '25ft resolution'}, 'SI': {'desc': 'SI/II Transponder Capability', 'val': 0, 'meaning': 'SI-Code Capable'}})
def generate_csv_for_all_mac(files): global NB_PARSE_ERRORS global LOG tsOld = 0 for file in files: fichier = file try: f = open("/part1/" + fichier, "rb") pcap = dpkt.pcap.Reader(f) for ts, buf in pcap: if batch_disabled == None: if tsOld == 0: tsOld = ts else: sleep(ts - tsOld) tsOld = ts eth = dpkt.ethernet.Ethernet(buf) dst = mac_addr(eth.dst) if dst == '01:00:5e:50:10:c4': continue try: data = eth.data.data.data except: data = eth.data.data try: parsed = asterix.parse(data) l = len(parsed) i = 0 while i < l: cat = parsed[i]['category'] src = 'NaN' tid = 'NaN' sac = 'NaN' sic = 'NaN' tod = 'NaN' tn = 'NaN' theta = 'NaN' rho = 'NaN' fl = 'NaN' cgs = 'NaN' chdg = 'NaN' try: src = mac_addr(eth.src) except: pass try: tid = parsed[i]['I240']['TId']['val'] except: pass try: sac = parsed[i]['I010']['SAC']['val'] except: pass try: sic = parsed[i]['I010']['SIC']['val'] except: pass try: tod = parsed[i]['I140']['ToD']['val'] except: pass try: tn = parsed[i]['I161']['Tn']['val'] except: pass try: theta = parsed[i]['I040']['THETA']['val'] except: pass try: rho = parsed[i]['I040']['RHO']['val'] except: pass try: fl = parsed[i]['I090']['FL']['val'] except: pass try: cgs = parsed[i]['I200']['CGS']['val'] except: pass try: chdg = parsed[i]['I200']['CHdg']['val'] except: pass yield str(src) + ',' + str(cat) + ',' + str( tid) + ',' + str(ts) + ',' + dst + ',' + str( sac) + ',' + str(sic) + ',' + str( tod) + ',' + str(tn) + ',' + str( theta ) + ',' + str(rho) + ',' + str( fl) + ',' + str(cgs) + ',' + str( chdg) + '\n' i = i + 1 except: NB_PARSE_ERRORS += 1 LOG = str(ts) + "\n" + str(buf) + "\n" pass else: pass f.close() except: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(DATACENTER2_ADDRESS) if batch_disabled == None: sock.sendall(b'FILE:%s' % (file)) else: sock.sendall(b'FILE false:%s' % (file)) while True: line = sock.recv(1024) if line != "END": yield line + b'\n' else: break sock.close()
date = name[0:10] with open(input_dir+filename) as in_file : with open(output_dir+name+'.csv', 'w') as out_file : writer = csv.writer(out_file, delimiter='\t') pcap = dpkt.pcap.Reader(in_file) cntr=1 for ts, buf in pcap: eth = dpkt.ethernet.Ethernet(buf) data = eth.ip.udp.data cntr += 1 # Parse data parsed = asterix.parse(data) time = False for packet in parsed : plane = [False for i in range(6)] addr = False if 'I220' in packet : if 'ACAddr' in packet['I220']: if 'val' in packet['I220']['ACAddr']: addr = str(packet['I220']['ACAddr']['val']) for time_label in ['I030', 'I140'] : if time_label in packet : if 'ToD' in packet[time_label] : if 'val' in packet[time_label]['ToD'] :
def get_packet(self): return asterix.parse(self.__sock.recv(4096))
def test_ParseCAT048(self): sample_filename = asterix.get_sample_file('cat048.raw') with open(sample_filename, "rb") as f: data = f.read() packet = asterix.parse(data) self.maxDiff = None self.assertIsNotNone(packet) self.assertIsNotNone(packet[0]) self.assertIs(len(packet), 1) self.assertTrue('I220' in packet[0]) self.assertEqual(packet[0]['category'], 48) self.assertEqual(packet[0]['len'], 45) self.assertEqual(packet[0]['crc'], 'C150ED0E') self.assertTrue('ts' in packet[0]) self.assertEqual(packet[0]['I220']['ACAddr']['val'], '3C660C') self.assertEqual(packet[0]['I220']['ACAddr']['desc'], 'AircraftAddress') self.assertEqual(packet[0]['I010'], {'SAC': {'desc': 'System Area Code', 'val': 25}, 'SIC': {'desc': 'System Identification Code', 'val': 201}}) self.assertEqual(packet[0]['I170'], {'GHO': {'desc': 'GHO', 'val': 0, 'meaning': 'True target track'}, 'TCC': {'desc': 'TCC', 'val': 0, 'meaning': 'Radar plane'}, 'RAD': {'desc': 'RAD', 'val': 2, 'meaning': 'SSR/ModeS Track'}, 'spare': {'desc': 'spare bits set to 0', 'const': 0, 'val': 0}, 'TRE': {'desc': 'TRE', 'val': 0, 'meaning': 'Track still alive'}, 'CDM': {'desc': 'CDM', 'val': 0, 'meaning': 'Maintaining'}, 'CNF': {'desc': 'CNF', 'val': 0, 'meaning': 'Confirmed Track'}, 'SUP': {'desc': 'SUP', 'val': 0, 'meaning': 'Track from cluster network - NO'}, 'FX': {'desc': 'FX', 'val': 0, 'meaning': 'End of Data Item'}, 'DOU': {'desc': 'DOU', 'val': 0, 'meaning': 'Normal confidence'}, 'MAH': {'desc': 'MAH', 'val': 0, 'meaning': 'No horizontal man. sensed'}}) self.assertEqual(packet[0]['I200'], {'CGS': {'desc': 'Calculated groundspeed', 'val': 434.94}, 'CHdg': {'desc': 'Calculated heading', 'val': 124.002685546875}}) self.assertEqual(packet[0]['I220'], {'ACAddr': {'desc': 'AircraftAddress', 'val': '3C660C'}}) self.assertEqual(packet[0]['I250'][0], {'TARGET_ALT_STATUS': {'desc': 'Status of Target ALT source bits', 'meaning': 'No source information provided', 'val': 0}, 'res': {'desc': 'Reserved', 'val': 0}, 'FMS_ALT': {'desc': 'FMS Selected Altitude', 'val': 0.0}, 'APP': {'desc': 'APPROACH Mode', 'meaning': 'Not active', 'val': 0}, 'ALT_HOLD': {'desc': 'ALT HOLD Mode', 'meaning': 'Not active', 'val': 0}, 'TARGET_ALT_SOURCE': {'desc': 'Target ALT source', 'meaning': 'Unknown', 'val': 0}, 'BDS': {'desc': 'BDS register', 'val': '40'}, 'FMS_ALT_STATUS': {'desc': 'FMS Altitude Status', 'val': 0}, 'BP_STATUS': {'desc': 'Barometric Pressure Status', 'val': 1}, 'BP': {'desc': 'Barometric Pressure', 'val': 227.0}, 'MODE_STATUS': {'desc': 'Status of MCP/FCU Mode Bits', 'val': 0}, 'VNAV': {'desc': 'VNAV Mode', 'meaning': 'Not active', 'val': 0}, 'MCP_ALT_STATUS': {'desc': 'MCP Altitude Status', 'val': 1}, 'MCP_ALT': {'desc': 'MCP/FCU Selected Altitude', 'val': 33008.0}}) self.assertEqual(packet[0]['I040'], {'THETA': {'desc': '', 'val': 340.13671875}, 'RHO': {'desc': '', 'max': 256.0, 'val': 197.68359375}}) self.assertEqual(packet[0]['I240'], {'TId': {'desc': 'Characters 1-8 (coded on 6 bits each) defining target identification', 'val': 'DLH65A '}}) self.assertEqual(packet[0]['I140'], {'ToD': {'desc': 'Time Of Day', 'val': 27354.6015625}}) self.assertEqual(packet[0]['I070'], {'Mode3A': {'desc': 'Mode-3/A reply code', 'val': '1000'}, 'V': {'desc': '', 'val': 0, 'meaning': 'Code validated'}, 'L': {'desc': '', 'val': 0, 'meaning': 'Mode-3/A code as derived from the reply of the transponder'}, 'spare': {'desc': 'spare bit set to 0', 'const': 0, 'val': 0}, 'G': {'desc': '', 'val': 0, 'meaning': 'Default'}}) self.assertEqual(packet[0]['I161'], {'Tn': {'desc': 'Track Number', 'val': 3563}}) self.assertEqual(packet[0]['I020'], {'SIM': {'desc': 'SIM', 'val': 0, 'meaning': 'Actual target report'}, 'TYP': {'desc': 'TYP', 'val': 5, 'meaning': 'Single ModeS Roll-Call'}, 'RAB': {'desc': 'RAB', 'val': 0, 'meaning': 'Report from aircraft transponder'}, 'RDP': {'desc': 'RDP', 'val': 0, 'meaning': 'Report from RDP Chain 1'}, 'FX': {'desc': 'FX', 'val': 0, 'meaning': 'End of Data Item'}, 'SPI': {'desc': 'SPI', 'val': 0, 'meaning': 'Absence of SPI'}}) self.assertEqual(packet[0]['I090'], {'V': {'desc': '', 'val': 0, 'meaning': 'Code validated'}, 'FL': {'desc': 'FlightLevel', 'val': 330.0}, 'G': {'desc': '', 'val': 0, 'meaning': 'Default'}}) self.assertEqual(packet[0]['I230'], {'COM': {'desc': 'COM', 'val': 1}, 'BDS37': {'desc': 'BDS 1,0 bits 37/40', 'val': 5}, 'ModeSSSC': {'desc': 'ModeS Specific Service Capability', 'val': 1, 'meaning': 'Yes'}, 'STAT': {'desc': 'STAT', 'val': 0}, 'AIC': {'desc': 'Aircraft identification capability', 'val': 1, 'meaning': 'Yes'}, 'BDS16': {'desc': 'BDS 1,0 bit 16', 'val': 1}, 'spare': {'desc': 'spare bit set to 0', 'const': 0, 'val': 0}, 'ARC': {'desc': 'Altitude reporting capability', 'val': 1, 'meaning': '25ft resolution'}, 'SI': {'desc': 'SI/II Transponder Capability', 'val': 0, 'meaning': 'SI-Code Capable'}})
__author__ = 'dsalanti' import asterix # Read example file from packet resources sample_filename = asterix.get_sample_file('cat062cat065.raw') with open(sample_filename, "rb") as f: data = f.read() # Parse data parsed = asterix.parse(data) print(parsed) # describe Asterix data formatted = asterix.describe(parsed) print(formatted)
#!/usr/bin/python __author__ = 'dsalanti' import socket import struct import asterix sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('', 21111)) mreq = struct.pack("=4sl", socket.inet_aton("232.1.1.11"), socket.INADDR_ANY) sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) counter = 1 while True: asterix_packet = sock.recv(10240) parsed = asterix.parse(asterix_packet) print('%d. Receiver received = %s' % (counter, parsed)) counter += 1
def stream_from_pcap_directly(socket, file="2019-12-09-1751.pcap", batch_disabled=None): global NB_PARSE_ERRORS global LOG tsOld = 0 fichier = file f = open("/add/" + fichier, "rb") pcap = dpkt.pcap.Reader(f) for ts, buf in pcap: if batch_disabled == None: if tsOld == 0: tsOld = ts else: sleep(ts - tsOld) tsOld = ts eth = dpkt.ethernet.Ethernet(buf) dst = mac_addr(eth.dst) if dst == '01:00:5e:50:10:c4': continue try: data = eth.data.data.data except: data = eth.data.data try: parsed = asterix.parse(data) l = len(parsed) i = 0 while i < l: cat = parsed[i]['category'] src = 'Nan' tid = 'NaN' sac = 'NaN' sic = 'NaN' tod = 'NaN' tn = 'NaN' theta = 'NaN' rho = 'NaN' fl = 'NaN' cgs = 'NaN' chdg = 'NaN' try: src = mac_addr(eth.src) except: pass try: tid = parsed[i]['I240']['TId']['val'] except: pass try: sac = parsed[i]['I010']['SAC']['val'] except: pass try: sic = parsed[i]['I010']['SIC']['val'] except: pass try: tod = parsed[i]['I140']['ToD']['val'] except: pass try: tn = parsed[i]['I161']['Tn']['val'] except: pass try: theta = parsed[i]['I040']['THETA']['val'] except: pass try: rho = parsed[i]['I040']['RHO']['val'] except: pass try: fl = parsed[i]['I090']['FL']['val'] except: pass try: cgs = parsed[i]['I200']['CGS']['val'] except: pass try: chdg = parsed[i]['I200']['CHdg']['val'] except: pass socket.sendall( b'%s' % (str(src) + ',' + str(cat) + ',' + str(tid) + ',' + str(ts) + ',' + dst + ',' + str(sac) + ',' + str(sic) + ',' + str(tod) + ',' + str(tn) + ',' + str(theta) + ',' + str(rho) + ',' + str(fl) + ',' + str(cgs) + ',' + str(chdg) + '\n')) i = i + 1 except: NB_PARSE_ERRORS += 1 LOG = str(ts) + "\n" + str(buf) + "\n" pass else: pass socket.sendall(b'END') socket.close() f.close()
__author__ = 'dsalanti' import asterix print(asterix.__version__) # Read example file from packet resources sample_filename = asterix.get_sample_file('cat062cat065.raw') with open(sample_filename, "rb") as f: data = f.read() # Parse data description=True print('Items with description') print('----------------------') parsed = asterix.parse(data) for packet in parsed: for item in packet.items(): print(item) print('Items without description') print('----------------------') # Parse data description=False parsed = asterix.parse(data, verbose=False) for packet in parsed: for item in packet.items(): print(item) print('Textual description of data') print('----------------------') # describe Asterix data
#!/usr/bin/python __author__ = 'dsalanti' import socket import struct import asterix sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('', 21111)) mreq = struct.pack("=4sl", socket.inet_aton("232.1.1.11"), socket.INADDR_ANY) sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) counter=1 while True: asterix_packet = sock.recv(10240) parsed = asterix.parse(asterix_packet) print('%d. Receiver received = %s' % (counter, parsed)) counter += 1