// // main.swift // ADSBDecoder // // Created by Jacky Jack on 28/05/2024. // import Foundation import ArgumentParser import RegexBuilder import SQLite3 struct CommandLineArgs: ParsableCommand { @Option(name: .shortAndLong) var inputfile: String @Flag(name: .shortAndLong) var debug:Bool = false @Flag(name: .shortAndLong) var version:Bool = false @Flag(name: .shortAndLong) var show_stats:Bool = false } let args = CommandLineArgs.parseOrExit() let fileUrl = URL(fileURLWithPath:args.inputfile) print("File location [\(fileUrl.absoluteString)]") //check if file excists if (checkIfFileExists(fileUrl.path) == false) { print("Supplied path \(fileUrl.path) doesnt exists") exit(1) } //load the file with adsb data var adsb_source = "" do { adsb_source = try String(contentsOfFile: fileUrl.path) print("Loaded \(adsb_source.count) bytes") } catch { print("Couldn't load text from a file \(fileUrl.path)") exit(1) } //gather stats var q_df = QueryDF() var q_dftc = QueryDF17TC() var q_decoded = QueryDecodedMessages() var q_df17_decoded = QueryDF17TC_decoded() //track all airplanes var tracker = AirPlaneTracker() //parse line by line var count_messages=0 for line in adsb_source.components(separatedBy: .newlines) { var found=false //print("\(cnt) \(line)") count_messages += 1 if let tokenMatch = try matchADSBLong.prefixMatch(in: line) { //print("\(String(tokenMatch.output))") found = true let str = String(tokenMatch.output) let startIndex = str.index(str.startIndex, offsetBy: 1) let endIndex = str.index(str.endIndex, offsetBy: -2) let decoder = Decoder(String(str[startIndex...endIndex])) if decoder.DataFormat == 17 { if let d17 = decoder.getDataFormat17() { //print(d17) q_dftc.addTC(d17.TypeCode) q_decoded.addDecoded() if (d17.TypeCode == 4) { if let indentification = d17.messageIdentification { tracker.addDF17Indentification(d17.AddressAnnounced, indentification.ICAOName) } q_df17_decoded.addDecoded(4) } else if (d17.TypeCode >= 9 && d17.TypeCode <= 18) { if let airbornposition = d17.messageAirbornPositon { tracker.addDF17AirBornPosition( d17.AddressAnnounced, airbornposition.Latitude, airbornposition.Longitude, airbornposition.Altitude, airbornposition.CPRFormat == 0 ) } q_df17_decoded.addDecoded(d17.TypeCode) } else { q_df17_decoded.addUndecode(d17.TypeCode) } } } else { q_decoded.addUndecoded() } q_df.addDF(decoder.DataFormat) }; if let tokenMatch = try matchADSBShort.prefixMatch(in: line) { print("\(tokenMatch.output)") found = true q_decoded.addUndecoded() }; if (found == false) { print("Unknown adsb data line \(line)") } } if args.show_stats { print("----STAT----") //q_df.showStat() print(q_df) print(q_dftc) print(q_decoded) print(q_df17_decoded) tracker.printAllICAOnames() print("Total message:\(count_messages)") }