diff --git a/ADSB_Encoder.py b/ADSB_Encoder.py index 0517832..df564aa 100755 --- a/ADSB_Encoder.py +++ b/ADSB_Encoder.py @@ -65,6 +65,7 @@ def argParser(): parser.add_argument('--realtime', action='store', default=cfg.getboolean('general', 'realtime'), type=auto_bool, dest='realtime', help='When running a CSV which has a timestamp column whether to run in realtime following the timestamp or if just follow intermessagegap. If realtime is set it will override intermessagegap. Default: %(default)s') # TODO Make it so it can do a static checksum or one/two bit error # TODO Velocity, Heading and vertical speed as argument + # TODO Callsign return parser.parse_args() def singlePlane(arguments): @@ -77,9 +78,12 @@ def singlePlane(arguments): df17_velocity = modes.vel_heading_encode(arguments.capability, arguments.icao, 450, 200, -1000) + df17_callsign = modes.callsign_encode(arguments.capability, arguments.icao, 'karit___') + ppm = PPM() df17_array_position = ppm.frame_1090es_ppm_modulate(df17_pos_even, df17_pos_odd) df17_array_velocity = ppm.frame_1090es_ppm_modulate(df17_velocity, df17_velocity) + df17_array_callsign = ppm.frame_1090es_ppm_modulate(df17_callsign, df17_callsign) hackrf = HackRF() #Position @@ -94,6 +98,12 @@ def singlePlane(arguments): gap_array = ppm.addGap(arguments.intermessagegap) samples_array = hackrf.hackrf_raw_IQ_format(gap_array) samples = samples+samples_array + #Callsign + samples_array = hackrf.hackrf_raw_IQ_format(df17_array_callsign) + samples = samples+samples_array + gap_array = ppm.addGap(arguments.intermessagegap) + samples_array = hackrf.hackrf_raw_IQ_format(gap_array) + samples = samples+samples_array return samples def manyPlanes(arguments): @@ -101,6 +111,7 @@ def manyPlanes(arguments): samples = bytearray() logger.info('Repeating the message %s times' % (arguments.repeats)) prevtimestamp = 0 + #TODO Callsign, speed, heading, vert speed in CSV for i in range(0, arguments.repeats): with open(arguments.csvfile, newline='') as csvfile: reader = csv.DictReader(csvfile, delimiter=',') @@ -145,9 +156,12 @@ def manyPlanes(arguments): df17_velocity = modes.vel_heading_encode(row['capability'], row['icao'], 450, 200, -1000) + df17_callsign = modes.callsign_encode(row['capability'], row['icao'], 'karit___') + ppm = PPM() df17_array_position = ppm.frame_1090es_ppm_modulate(df17_pos_even, df17_pos_odd) df17_array_velocity = ppm.frame_1090es_ppm_modulate(df17_velocity, df17_velocity) + df17_array_callsign = ppm.frame_1090es_ppm_modulate(df17_callsign, df17_callsign) hackrf = HackRF() #Position @@ -162,6 +176,12 @@ def manyPlanes(arguments): gap_array = ppm.addGap(arguments.intermessagegap) samples_array = hackrf.hackrf_raw_IQ_format(gap_array) samples = samples+samples_array + #Callsign + samples_array = hackrf.hackrf_raw_IQ_format(df17_array_callsign) + samples = samples+samples_array + gap_array = ppm.addGap(arguments.intermessagegap) + samples_array = hackrf.hackrf_raw_IQ_format(gap_array) + samples = samples+samples_array return samples def writeOutputFile(filename, data): diff --git a/ModeS.py b/ModeS.py index 2270abb..440eb3e 100644 --- a/ModeS.py +++ b/ModeS.py @@ -154,6 +154,67 @@ class ModeS: dfvel.append((dfvel_crc) & 0xff) return dfvel + #From https://github.com/jaywilhelm/ADSB-Out_Python on 2019-08-25 + # TODO the callsign must be 8 + def callsign_encode(self, ca, icao, csname): + if len(csname) > 8 or len(csname) <= 0: + print ("Name length error") + return null + csname = csname.upper() + + df = 17 + #ca = 5 + #icao = 0xabcdef + #csname = 'ABCD1234' + tc = 1 + ec = 1 + + #df = 17 + #ca = 5 + #icao = 0x4840D6 + #csname = 'KLM1023_' + #tc = 4 + #ec = 0 + + map = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ#####_###############0123456789######" + + dfname = [] + dfname.append((df << 3) | ca) + dfname.append((icao >> 16) & 0xff) + dfname.append((icao >> 8) & 0xff) + dfname.append((icao) & 0xff) + #2C C3 71 C3 2C E0 + dfname.append((tc << 3) | (ec)) + dfname.append((0xFC & (int(map.find(csname[0])) << 2)) | (0x03 & (int(map.find(csname[1])) >> 6))) + dfname.append((0xF0 & (int(map.find(csname[1])) << 4)) | (0x0F & (int(map.find(csname[2])) >> 2))) + dfname.append((0xF0 & (int(map.find(csname[2])) << 6)) | (0x3F & (int(map.find(csname[3])) >> 0))) + dfname.append((0xFC & (int(map.find(csname[4])) << 2)) | (0x03 & (int(map.find(csname[5])) >> 4))) + dfname.append((0xF0 & (int(map.find(csname[5])) << 4)) | (0x0F & (int(map.find(csname[6])) >> 2))) + dfname.append((0xF0 & (int(map.find(csname[6])) << 6)) | (0x3F & (int(map.find(csname[7])) >> 0))) + + #for i in range(6): + # print("{0:02X}".format(dfname[i+5])) + + dfname_str = "{0:02x} {1:02x} {2:02x} {3:02x} {4:02x} {5:02x} {6:02x} {7:02x} {8:02x} {9:02x} {10:02x}".format( + *dfname[0:11]) + #print(dfname_str) + dfname_str2 = "{0:02x}{1:02x}{2:02x}{3:02x}{4:02x}{5:02x}{6:02x}{7:02x}{8:02x}{9:02x}{10:02x}".format( + *dfname[0:11]) + crc_str = "%X" % self.bin2int(self.modes_crc(dfname_str2 + "000000", encode=True)) + #print(crc_str) + # print(dfvel_str), " %X" % +"000000", encode=True)) + # , "%X" % get_parity(hex2bin(dfvel_str+"000000"), extended=True)) + dfname_crc = self.bin2int(self.modes_crc(dfname_str2 + "000000", encode=True)) + dfname.append((dfname_crc >> 16) & 0xff) + dfname.append((dfname_crc >> 8) & 0xff) + dfname.append((dfname_crc) & 0xff) + #msg = [] + #dfname_str = "{0:02x}{1:02x}{2:02x}{3:02x}{4:02x}{5:02x}{6:02x}{7:02x}{8:02x}{9:02x}{10:02x}".format( + # *dfname[0:11]) + #print(csname) + #print(decode_callsign(dfname_str)) + return dfname + ############################################################### # Copyright (C) 2015 Junzi Sun (TU Delft)