示例#1
0
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
示例#2
0
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
示例#3
0
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
示例#4
0
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 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)
示例#7
0
    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
示例#8
0
    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
示例#9
0
        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")

示例#11
0
 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}})
示例#12
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'}})
示例#13
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': {'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'}})
示例#14
0
 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'}})
示例#15
0
 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}})
示例#16
0
 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()
示例#17
0
		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'] :
示例#18
0
 def get_packet(self):
     return asterix.parse(self.__sock.recv(4096))
示例#19
0
    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'}})
示例#20
0
__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
示例#22
0
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()
示例#23
0
__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