From b32ecfab276fb8e1dff0e1d72ed819b548323328 Mon Sep 17 00:00:00 2001 From: Arturs Artamonovs Date: Tue, 16 Jul 2024 06:45:43 +0100 Subject: Working implementation of ADSB loaded from file. Net1090 can read from dump1090 socket --- ADSBDecoder.xcodeproj/project.pbxproj | 832 +++++++++++++++++++++++++++++++++- ADSBDecoder/AirplaneTracker.swift | 1 - ADSBDecoder/Configs.swift | 10 + ADSBDecoder/Decoder.swift | 34 +- ADSBDecoder/PositionDecoder.swift | 2 +- ADSBDecoder/main.swift | 3 - ADSBStats/main.swift | 118 +++++ LearnMapKit/ADSBRunner.swift | 110 ++++- LearnMapKit/ContentView.swift | 85 +++- LearnMapKit/FlighState.swift | 138 +++++- LearnMapKit/LearnMapKit.entitlements | 2 + LearnMapKit/LearnMapKitApp.swift | 26 -- Net1090/main.swift | 75 +++ 13 files changed, 1348 insertions(+), 88 deletions(-) create mode 100644 ADSBDecoder/Configs.swift create mode 100644 ADSBStats/main.swift create mode 100644 Net1090/main.swift diff --git a/ADSBDecoder.xcodeproj/project.pbxproj b/ADSBDecoder.xcodeproj/project.pbxproj index c78151e..010ce91 100644 --- a/ADSBDecoder.xcodeproj/project.pbxproj +++ b/ADSBDecoder.xcodeproj/project.pbxproj @@ -7,10 +7,86 @@ objects = { /* Begin PBXBuildFile section */ + 8D93B64C2C32030B00C91865 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D93B64B2C32030B00C91865 /* Utils.swift */; }; + 8D93B64F2C3206DD00C91865 /* AirplaneTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DB347C42C242BAC00F3C020 /* AirplaneTracker.swift */; }; + 8D93B6502C3206E700C91865 /* PositionDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DB347BE2C1C501200F3C020 /* PositionDecoder.swift */; }; + 8D93B6512C3206EB00C91865 /* Decoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DF756782C05A3D7008E8DFF /* Decoder.swift */; }; + 8D93B6532C32095300C91865 /* ADSBRegEx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D93B6522C32095300C91865 /* ADSBRegEx.swift */; }; + 8D93B6542C32095800C91865 /* ADSBRegEx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D93B6522C32095300C91865 /* ADSBRegEx.swift */; }; + 8D93B6552C32099B00C91865 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D93B64B2C32030B00C91865 /* Utils.swift */; }; + 8D93B6572C3D27A000C91865 /* Configs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D93B6562C3D27A000C91865 /* Configs.swift */; }; + 8D93B6582C3D290C00C91865 /* Configs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D93B6562C3D27A000C91865 /* Configs.swift */; }; + 8D93B6792C3FE6F400C91865 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D93B6782C3FE6F400C91865 /* main.swift */; }; + 8D93B67F2C3FEA0000C91865 /* NIO in Frameworks */ = {isa = PBXBuildFile; productRef = 8D93B67E2C3FEA0000C91865 /* NIO */; }; + 8D93B6812C3FEA5600C91865 /* NIO in Frameworks */ = {isa = PBXBuildFile; productRef = 8D93B6802C3FEA5600C91865 /* NIO */; }; + 8D93B6822C412C0A00C91865 /* Configs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D93B6562C3D27A000C91865 /* Configs.swift */; }; + 8D93B68A2C45986700C91865 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D93B6892C45986700C91865 /* main.swift */; }; + 8D93B68E2C4598A500C91865 /* Configs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D93B6562C3D27A000C91865 /* Configs.swift */; }; + 8D93B68F2C4598A900C91865 /* ADSBRegEx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D93B6522C32095300C91865 /* ADSBRegEx.swift */; }; + 8D93B6902C4598AC00C91865 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D93B64B2C32030B00C91865 /* Utils.swift */; }; + 8D93B6912C4598B300C91865 /* PositionDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DB347BE2C1C501200F3C020 /* PositionDecoder.swift */; }; + 8D93B6922C4598B800C91865 /* Decoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DF756782C05A3D7008E8DFF /* Decoder.swift */; }; + 8D93B6932C4598D900C91865 /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DF7567B2C09B7F7008E8DFF /* Query.swift */; }; + 8D93B6942C4598E300C91865 /* AirplaneTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DB347C42C242BAC00F3C020 /* AirplaneTracker.swift */; }; + 8D93B6962C45992F00C91865 /* ArgumentParser in Frameworks */ = {isa = PBXBuildFile; productRef = 8D93B6952C45992F00C91865 /* ArgumentParser */; }; + 8D93B6982C45993600C91865 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = 8D93B6972C45993600C91865 /* Collections */; }; + 8DB347BF2C1C501200F3C020 /* PositionDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DB347BE2C1C501200F3C020 /* PositionDecoder.swift */; }; + 8DB347C32C1C53ED00F3C020 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = 8DB347C22C1C53ED00F3C020 /* Collections */; }; + 8DB347C52C242BAC00F3C020 /* AirplaneTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DB347C42C242BAC00F3C020 /* AirplaneTracker.swift */; }; + 8DEC6F2E2C2E9C3000AC6209 /* ADSBRunner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DEC6F2D2C2E9C3000AC6209 /* ADSBRunner.swift */; }; + 8DEC6F302C2E9F0E00AC6209 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = 8DEC6F2F2C2E9F0E00AC6209 /* Collections */; }; + 8DEC6F322C31530C00AC6209 /* FlighState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DEC6F312C31530C00AC6209 /* FlighState.swift */; }; 8DF756632C0595AA008E8DFF /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DF756622C0595AA008E8DFF /* main.swift */; }; + 8DF7566C2C0595F6008E8DFF /* ArgumentParser in Frameworks */ = {isa = PBXBuildFile; productRef = 8DF7566B2C0595F6008E8DFF /* ArgumentParser */; }; + 8DF756742C059969008E8DFF /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DF756732C059969008E8DFF /* main.swift */; }; + 8DF756792C05A3D7008E8DFF /* Decoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DF756782C05A3D7008E8DFF /* Decoder.swift */; }; + 8DF7567A2C06F550008E8DFF /* Decoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DF756782C05A3D7008E8DFF /* Decoder.swift */; }; + 8DF7567C2C09B7F7008E8DFF /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DF7567B2C09B7F7008E8DFF /* Query.swift */; }; + 8DF756852C10556A008E8DFF /* LearnMapKitApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DF756842C10556A008E8DFF /* LearnMapKitApp.swift */; }; + 8DF756872C10556A008E8DFF /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DF756862C10556A008E8DFF /* ContentView.swift */; }; + 8DF756892C10556C008E8DFF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8DF756882C10556C008E8DFF /* Assets.xcassets */; }; + 8DF7568C2C10556C008E8DFF /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8DF7568B2C10556C008E8DFF /* Preview Assets.xcassets */; }; + 8DF756972C10556C008E8DFF /* LearnMapKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DF756962C10556C008E8DFF /* LearnMapKitTests.swift */; }; + 8DF756A12C10556C008E8DFF /* LearnMapKitUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DF756A02C10556C008E8DFF /* LearnMapKitUITests.swift */; }; + 8DF756A32C10556C008E8DFF /* LearnMapKitUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DF756A22C10556C008E8DFF /* LearnMapKitUITestsLaunchTests.swift */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 8DF756932C10556C008E8DFF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8DF756572C0595AA008E8DFF /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8DF756812C10556A008E8DFF; + remoteInfo = LearnMapKit; + }; + 8DF7569D2C10556C008E8DFF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8DF756572C0595AA008E8DFF /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8DF756812C10556A008E8DFF; + remoteInfo = LearnMapKit; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXCopyFilesBuildPhase section */ + 8D93B6742C3FE6F400C91865 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 8D93B6852C45986700C91865 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; 8DF7565D2C0595AA008E8DFF /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -20,15 +96,99 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + 8DF7566F2C059969008E8DFF /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 8D93B64B2C32030B00C91865 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; + 8D93B6522C32095300C91865 /* ADSBRegEx.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADSBRegEx.swift; sourceTree = ""; }; + 8D93B6562C3D27A000C91865 /* Configs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configs.swift; sourceTree = ""; }; + 8D93B6762C3FE6F400C91865 /* Net1090 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Net1090; sourceTree = BUILT_PRODUCTS_DIR; }; + 8D93B6782C3FE6F400C91865 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; + 8D93B6872C45986700C91865 /* ADSBStats */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ADSBStats; sourceTree = BUILT_PRODUCTS_DIR; }; + 8D93B6892C45986700C91865 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; + 8DB347BE2C1C501200F3C020 /* PositionDecoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionDecoder.swift; sourceTree = ""; }; + 8DB347C42C242BAC00F3C020 /* AirplaneTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AirplaneTracker.swift; sourceTree = ""; }; + 8DEC6F2D2C2E9C3000AC6209 /* ADSBRunner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADSBRunner.swift; sourceTree = ""; }; + 8DEC6F312C31530C00AC6209 /* FlighState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlighState.swift; sourceTree = ""; }; 8DF7565F2C0595AA008E8DFF /* ADSBDecoder */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ADSBDecoder; sourceTree = BUILT_PRODUCTS_DIR; }; 8DF756622C0595AA008E8DFF /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; + 8DF756712C059969008E8DFF /* Test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Test; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DF756732C059969008E8DFF /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; + 8DF756782C05A3D7008E8DFF /* Decoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Decoder.swift; sourceTree = ""; }; + 8DF7567B2C09B7F7008E8DFF /* Query.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Query.swift; sourceTree = ""; }; + 8DF756822C10556A008E8DFF /* LearnMapKit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LearnMapKit.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DF756842C10556A008E8DFF /* LearnMapKitApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LearnMapKitApp.swift; sourceTree = ""; }; + 8DF756862C10556A008E8DFF /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 8DF756882C10556C008E8DFF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 8DF7568B2C10556C008E8DFF /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 8DF7568D2C10556C008E8DFF /* LearnMapKit.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = LearnMapKit.entitlements; sourceTree = ""; }; + 8DF756922C10556C008E8DFF /* LearnMapKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LearnMapKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DF756962C10556C008E8DFF /* LearnMapKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LearnMapKitTests.swift; sourceTree = ""; }; + 8DF7569C2C10556C008E8DFF /* LearnMapKitUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LearnMapKitUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DF756A02C10556C008E8DFF /* LearnMapKitUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LearnMapKitUITests.swift; sourceTree = ""; }; + 8DF756A22C10556C008E8DFF /* LearnMapKitUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LearnMapKitUITestsLaunchTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 8D93B6732C3FE6F400C91865 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D93B67F2C3FEA0000C91865 /* NIO in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D93B6842C45986700C91865 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D93B6982C45993600C91865 /* Collections in Frameworks */, + 8D93B6962C45992F00C91865 /* ArgumentParser in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 8DF7565C2C0595AA008E8DFF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DB347C32C1C53ED00F3C020 /* Collections in Frameworks */, + 8DF7566C2C0595F6008E8DFF /* ArgumentParser in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DF7566E2C059969008E8DFF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DF7567F2C10556A008E8DFF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DEC6F302C2E9F0E00AC6209 /* Collections in Frameworks */, + 8D93B6812C3FEA5600C91865 /* NIO in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DF7568F2C10556C008E8DFF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DF756992C10556C008E8DFF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -38,11 +198,42 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 8D93B6772C3FE6F400C91865 /* Net1090 */ = { + isa = PBXGroup; + children = ( + 8D93B6782C3FE6F400C91865 /* main.swift */, + ); + path = Net1090; + sourceTree = ""; + }; + 8D93B6882C45986700C91865 /* ADSBStats */ = { + isa = PBXGroup; + children = ( + 8D93B6892C45986700C91865 /* main.swift */, + ); + path = ADSBStats; + sourceTree = ""; + }; + 8DB347C12C1C53ED00F3C020 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; 8DF756562C0595AA008E8DFF = { isa = PBXGroup; children = ( + 8DF756692C0595BB008E8DFF /* Data */, 8DF756612C0595AA008E8DFF /* ADSBDecoder */, + 8DF756722C059969008E8DFF /* Test */, + 8DF756832C10556A008E8DFF /* LearnMapKit */, + 8DF756952C10556C008E8DFF /* LearnMapKitTests */, + 8DF7569F2C10556C008E8DFF /* LearnMapKitUITests */, + 8D93B6772C3FE6F400C91865 /* Net1090 */, + 8D93B6882C45986700C91865 /* ADSBStats */, 8DF756602C0595AA008E8DFF /* Products */, + 8DB347C12C1C53ED00F3C020 /* Frameworks */, ); sourceTree = ""; }; @@ -50,6 +241,12 @@ isa = PBXGroup; children = ( 8DF7565F2C0595AA008E8DFF /* ADSBDecoder */, + 8DF756712C059969008E8DFF /* Test */, + 8DF756822C10556A008E8DFF /* LearnMapKit.app */, + 8DF756922C10556C008E8DFF /* LearnMapKitTests.xctest */, + 8DF7569C2C10556C008E8DFF /* LearnMapKitUITests.xctest */, + 8D93B6762C3FE6F400C91865 /* Net1090 */, + 8D93B6872C45986700C91865 /* ADSBStats */, ); name = Products; sourceTree = ""; @@ -58,13 +255,115 @@ isa = PBXGroup; children = ( 8DF756622C0595AA008E8DFF /* main.swift */, + 8DF756782C05A3D7008E8DFF /* Decoder.swift */, + 8DF7567B2C09B7F7008E8DFF /* Query.swift */, + 8DB347BE2C1C501200F3C020 /* PositionDecoder.swift */, + 8DB347C42C242BAC00F3C020 /* AirplaneTracker.swift */, + 8D93B64B2C32030B00C91865 /* Utils.swift */, + 8D93B6522C32095300C91865 /* ADSBRegEx.swift */, + 8D93B6562C3D27A000C91865 /* Configs.swift */, ); path = ADSBDecoder; sourceTree = ""; }; + 8DF756692C0595BB008E8DFF /* Data */ = { + isa = PBXGroup; + children = ( + ); + path = Data; + sourceTree = ""; + }; + 8DF756722C059969008E8DFF /* Test */ = { + isa = PBXGroup; + children = ( + 8DF756732C059969008E8DFF /* main.swift */, + ); + path = Test; + sourceTree = ""; + }; + 8DF756832C10556A008E8DFF /* LearnMapKit */ = { + isa = PBXGroup; + children = ( + 8DEC6F2D2C2E9C3000AC6209 /* ADSBRunner.swift */, + 8DF756862C10556A008E8DFF /* ContentView.swift */, + 8DF756842C10556A008E8DFF /* LearnMapKitApp.swift */, + 8DEC6F312C31530C00AC6209 /* FlighState.swift */, + 8DF756882C10556C008E8DFF /* Assets.xcassets */, + 8DF7568D2C10556C008E8DFF /* LearnMapKit.entitlements */, + 8DF7568A2C10556C008E8DFF /* Preview Content */, + ); + path = LearnMapKit; + sourceTree = ""; + }; + 8DF7568A2C10556C008E8DFF /* Preview Content */ = { + isa = PBXGroup; + children = ( + 8DF7568B2C10556C008E8DFF /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 8DF756952C10556C008E8DFF /* LearnMapKitTests */ = { + isa = PBXGroup; + children = ( + 8DF756962C10556C008E8DFF /* LearnMapKitTests.swift */, + ); + path = LearnMapKitTests; + sourceTree = ""; + }; + 8DF7569F2C10556C008E8DFF /* LearnMapKitUITests */ = { + isa = PBXGroup; + children = ( + 8DF756A02C10556C008E8DFF /* LearnMapKitUITests.swift */, + 8DF756A22C10556C008E8DFF /* LearnMapKitUITestsLaunchTests.swift */, + ); + path = LearnMapKitUITests; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 8D93B6752C3FE6F400C91865 /* Net1090 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8D93B67A2C3FE6F400C91865 /* Build configuration list for PBXNativeTarget "Net1090" */; + buildPhases = ( + 8D93B6722C3FE6F400C91865 /* Sources */, + 8D93B6732C3FE6F400C91865 /* Frameworks */, + 8D93B6742C3FE6F400C91865 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Net1090; + packageProductDependencies = ( + 8D93B67E2C3FEA0000C91865 /* NIO */, + ); + productName = Net1090; + productReference = 8D93B6762C3FE6F400C91865 /* Net1090 */; + productType = "com.apple.product-type.tool"; + }; + 8D93B6862C45986700C91865 /* ADSBStats */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8D93B68B2C45986700C91865 /* Build configuration list for PBXNativeTarget "ADSBStats" */; + buildPhases = ( + 8D93B6832C45986700C91865 /* Sources */, + 8D93B6842C45986700C91865 /* Frameworks */, + 8D93B6852C45986700C91865 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ADSBStats; + packageProductDependencies = ( + 8D93B6952C45992F00C91865 /* ArgumentParser */, + 8D93B6972C45993600C91865 /* Collections */, + ); + productName = ADSBStats; + productReference = 8D93B6872C45986700C91865 /* ADSBStats */; + productType = "com.apple.product-type.tool"; + }; 8DF7565E2C0595AA008E8DFF /* ADSBDecoder */ = { isa = PBXNativeTarget; buildConfigurationList = 8DF756662C0595AA008E8DFF /* Build configuration list for PBXNativeTarget "ADSBDecoder" */; @@ -78,10 +377,88 @@ dependencies = ( ); name = ADSBDecoder; + packageProductDependencies = ( + 8DF7566B2C0595F6008E8DFF /* ArgumentParser */, + 8DB347C22C1C53ED00F3C020 /* Collections */, + ); productName = ADSBDecoder; productReference = 8DF7565F2C0595AA008E8DFF /* ADSBDecoder */; productType = "com.apple.product-type.tool"; }; + 8DF756702C059969008E8DFF /* Test */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8DF756752C059969008E8DFF /* Build configuration list for PBXNativeTarget "Test" */; + buildPhases = ( + 8DF7566D2C059969008E8DFF /* Sources */, + 8DF7566E2C059969008E8DFF /* Frameworks */, + 8DF7566F2C059969008E8DFF /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Test; + productName = Test; + productReference = 8DF756712C059969008E8DFF /* Test */; + productType = "com.apple.product-type.tool"; + }; + 8DF756812C10556A008E8DFF /* LearnMapKit */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8DF756A42C10556C008E8DFF /* Build configuration list for PBXNativeTarget "LearnMapKit" */; + buildPhases = ( + 8DF7567E2C10556A008E8DFF /* Sources */, + 8DF7567F2C10556A008E8DFF /* Frameworks */, + 8DF756802C10556A008E8DFF /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = LearnMapKit; + packageProductDependencies = ( + 8DEC6F2F2C2E9F0E00AC6209 /* Collections */, + 8D93B6802C3FEA5600C91865 /* NIO */, + ); + productName = LearnMapKit; + productReference = 8DF756822C10556A008E8DFF /* LearnMapKit.app */; + productType = "com.apple.product-type.application"; + }; + 8DF756912C10556C008E8DFF /* LearnMapKitTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8DF756A72C10556C008E8DFF /* Build configuration list for PBXNativeTarget "LearnMapKitTests" */; + buildPhases = ( + 8DF7568E2C10556C008E8DFF /* Sources */, + 8DF7568F2C10556C008E8DFF /* Frameworks */, + 8DF756902C10556C008E8DFF /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8DF756942C10556C008E8DFF /* PBXTargetDependency */, + ); + name = LearnMapKitTests; + productName = LearnMapKitTests; + productReference = 8DF756922C10556C008E8DFF /* LearnMapKitTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 8DF7569B2C10556C008E8DFF /* LearnMapKitUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8DF756AA2C10556C008E8DFF /* Build configuration list for PBXNativeTarget "LearnMapKitUITests" */; + buildPhases = ( + 8DF756982C10556C008E8DFF /* Sources */, + 8DF756992C10556C008E8DFF /* Frameworks */, + 8DF7569A2C10556C008E8DFF /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8DF7569E2C10556C008E8DFF /* PBXTargetDependency */, + ); + name = LearnMapKitUITests; + productName = LearnMapKitUITests; + productReference = 8DF7569C2C10556C008E8DFF /* LearnMapKitUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -89,12 +466,32 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1530; + LastSwiftUpdateCheck = 1540; LastUpgradeCheck = 1530; TargetAttributes = { + 8D93B6752C3FE6F400C91865 = { + CreatedOnToolsVersion = 15.4; + }; + 8D93B6862C45986700C91865 = { + CreatedOnToolsVersion = 15.4; + }; 8DF7565E2C0595AA008E8DFF = { CreatedOnToolsVersion = 15.3; }; + 8DF756702C059969008E8DFF = { + CreatedOnToolsVersion = 15.3; + }; + 8DF756812C10556A008E8DFF = { + CreatedOnToolsVersion = 15.3; + }; + 8DF756912C10556C008E8DFF = { + CreatedOnToolsVersion = 15.3; + TestTargetID = 8DF756812C10556A008E8DFF; + }; + 8DF7569B2C10556C008E8DFF = { + CreatedOnToolsVersion = 15.3; + TestTargetID = 8DF756812C10556A008E8DFF; + }; }; }; buildConfigurationList = 8DF7565A2C0595AA008E8DFF /* Build configuration list for PBXProject "ADSBDecoder" */; @@ -106,27 +503,199 @@ Base, ); mainGroup = 8DF756562C0595AA008E8DFF; + packageReferences = ( + 8DF7566A2C0595F6008E8DFF /* XCRemoteSwiftPackageReference "swift-argument-parser" */, + 8DB347C02C1C53CB00F3C020 /* XCRemoteSwiftPackageReference "swift-collections" */, + 8D93B67D2C3FEA0000C91865 /* XCRemoteSwiftPackageReference "swift-nio" */, + ); productRefGroup = 8DF756602C0595AA008E8DFF /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 8DF7565E2C0595AA008E8DFF /* ADSBDecoder */, + 8DF756702C059969008E8DFF /* Test */, + 8DF756812C10556A008E8DFF /* LearnMapKit */, + 8DF756912C10556C008E8DFF /* LearnMapKitTests */, + 8DF7569B2C10556C008E8DFF /* LearnMapKitUITests */, + 8D93B6752C3FE6F400C91865 /* Net1090 */, + 8D93B6862C45986700C91865 /* ADSBStats */, ); }; /* End PBXProject section */ +/* Begin PBXResourcesBuildPhase section */ + 8DF756802C10556A008E8DFF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DF7568C2C10556C008E8DFF /* Preview Assets.xcassets in Resources */, + 8DF756892C10556C008E8DFF /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DF756902C10556C008E8DFF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DF7569A2C10556C008E8DFF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ + 8D93B6722C3FE6F400C91865 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D93B6792C3FE6F400C91865 /* main.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D93B6832C45986700C91865 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D93B6942C4598E300C91865 /* AirplaneTracker.swift in Sources */, + 8D93B6912C4598B300C91865 /* PositionDecoder.swift in Sources */, + 8D93B6932C4598D900C91865 /* Query.swift in Sources */, + 8D93B68A2C45986700C91865 /* main.swift in Sources */, + 8D93B68F2C4598A900C91865 /* ADSBRegEx.swift in Sources */, + 8D93B68E2C4598A500C91865 /* Configs.swift in Sources */, + 8D93B6922C4598B800C91865 /* Decoder.swift in Sources */, + 8D93B6902C4598AC00C91865 /* Utils.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 8DF7565B2C0595AA008E8DFF /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 8DB347C52C242BAC00F3C020 /* AirplaneTracker.swift in Sources */, + 8D93B6572C3D27A000C91865 /* Configs.swift in Sources */, + 8DF756792C05A3D7008E8DFF /* Decoder.swift in Sources */, + 8DF7567C2C09B7F7008E8DFF /* Query.swift in Sources */, 8DF756632C0595AA008E8DFF /* main.swift in Sources */, + 8D93B6532C32095300C91865 /* ADSBRegEx.swift in Sources */, + 8DB347BF2C1C501200F3C020 /* PositionDecoder.swift in Sources */, + 8D93B64C2C32030B00C91865 /* Utils.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DF7566D2C059969008E8DFF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DF7567A2C06F550008E8DFF /* Decoder.swift in Sources */, + 8DF756742C059969008E8DFF /* main.swift in Sources */, + 8D93B6822C412C0A00C91865 /* Configs.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DF7567E2C10556A008E8DFF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D93B64F2C3206DD00C91865 /* AirplaneTracker.swift in Sources */, + 8DF756872C10556A008E8DFF /* ContentView.swift in Sources */, + 8D93B6552C32099B00C91865 /* Utils.swift in Sources */, + 8DEC6F2E2C2E9C3000AC6209 /* ADSBRunner.swift in Sources */, + 8D93B6502C3206E700C91865 /* PositionDecoder.swift in Sources */, + 8D93B6582C3D290C00C91865 /* Configs.swift in Sources */, + 8D93B6512C3206EB00C91865 /* Decoder.swift in Sources */, + 8DEC6F322C31530C00AC6209 /* FlighState.swift in Sources */, + 8DF756852C10556A008E8DFF /* LearnMapKitApp.swift in Sources */, + 8D93B6542C32095800C91865 /* ADSBRegEx.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DF7568E2C10556C008E8DFF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DF756972C10556C008E8DFF /* LearnMapKitTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DF756982C10556C008E8DFF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8DF756A12C10556C008E8DFF /* LearnMapKitUITests.swift in Sources */, + 8DF756A32C10556C008E8DFF /* LearnMapKitUITestsLaunchTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 8DF756942C10556C008E8DFF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8DF756812C10556A008E8DFF /* LearnMapKit */; + targetProxy = 8DF756932C10556C008E8DFF /* PBXContainerItemProxy */; + }; + 8DF7569E2C10556C008E8DFF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8DF756812C10556A008E8DFF /* LearnMapKit */; + targetProxy = 8DF7569D2C10556C008E8DFF /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin XCBuildConfiguration section */ + 8D93B67B2C3FE6F400C91865 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 53B26AJZ4Z; + ENABLE_HARDENED_RUNTIME = YES; + MACOSX_DEPLOYMENT_TARGET = 14.5; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 8D93B67C2C3FE6F400C91865 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 53B26AJZ4Z; + ENABLE_HARDENED_RUNTIME = YES; + MACOSX_DEPLOYMENT_TARGET = 14.5; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 8D93B68C2C45986700C91865 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 53B26AJZ4Z; + ENABLE_HARDENED_RUNTIME = YES; + MACOSX_DEPLOYMENT_TARGET = 14.5; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 8D93B68D2C45986700C91865 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 53B26AJZ4Z; + ENABLE_HARDENED_RUNTIME = YES; + MACOSX_DEPLOYMENT_TARGET = 14.5; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; 8DF756642C0595AA008E8DFF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -250,11 +819,31 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = "$(TARGET_NAME)"; + RUN_DOCUMENTATION_COMPILER = YES; SWIFT_VERSION = 5.0; }; name = Debug; }; 8DF756682C0595AA008E8DFF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + RUN_DOCUMENTATION_COMPILER = YES; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 8DF756762C059969008E8DFF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 8DF756772C059969008E8DFF /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; @@ -263,9 +852,149 @@ }; name = Release; }; + 8DF756A52C10556C008E8DFF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = LearnMapKit/LearnMapKit.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"LearnMapKit/Preview Content\""; + DEVELOPMENT_TEAM = 53B26AJZ4Z; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = RadioTeam.LearnMapKit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 8DF756A62C10556C008E8DFF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = LearnMapKit/LearnMapKit.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"LearnMapKit/Preview Content\""; + DEVELOPMENT_TEAM = 53B26AJZ4Z; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = RadioTeam.LearnMapKit; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 8DF756A82C10556C008E8DFF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MACOSX_DEPLOYMENT_TARGET = 14.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = RadioTeam.LearnMapKitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LearnMapKit.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/LearnMapKit"; + }; + name = Debug; + }; + 8DF756A92C10556C008E8DFF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MACOSX_DEPLOYMENT_TARGET = 14.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = RadioTeam.LearnMapKitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LearnMapKit.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/LearnMapKit"; + }; + name = Release; + }; + 8DF756AB2C10556C008E8DFF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = RadioTeam.LearnMapKitUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = LearnMapKit; + }; + name = Debug; + }; + 8DF756AC2C10556C008E8DFF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = RadioTeam.LearnMapKitUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = LearnMapKit; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 8D93B67A2C3FE6F400C91865 /* Build configuration list for PBXNativeTarget "Net1090" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8D93B67B2C3FE6F400C91865 /* Debug */, + 8D93B67C2C3FE6F400C91865 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8D93B68B2C45986700C91865 /* Build configuration list for PBXNativeTarget "ADSBStats" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8D93B68C2C45986700C91865 /* Debug */, + 8D93B68D2C45986700C91865 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 8DF7565A2C0595AA008E8DFF /* Build configuration list for PBXProject "ADSBDecoder" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -284,7 +1013,108 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 8DF756752C059969008E8DFF /* Build configuration list for PBXNativeTarget "Test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8DF756762C059969008E8DFF /* Debug */, + 8DF756772C059969008E8DFF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8DF756A42C10556C008E8DFF /* Build configuration list for PBXNativeTarget "LearnMapKit" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8DF756A52C10556C008E8DFF /* Debug */, + 8DF756A62C10556C008E8DFF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8DF756A72C10556C008E8DFF /* Build configuration list for PBXNativeTarget "LearnMapKitTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8DF756A82C10556C008E8DFF /* Debug */, + 8DF756A92C10556C008E8DFF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8DF756AA2C10556C008E8DFF /* Build configuration list for PBXNativeTarget "LearnMapKitUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8DF756AB2C10556C008E8DFF /* Debug */, + 8DF756AC2C10556C008E8DFF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 8D93B67D2C3FEA0000C91865 /* XCRemoteSwiftPackageReference "swift-nio" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/apple/swift-nio.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.68.0; + }; + }; + 8DB347C02C1C53CB00F3C020 /* XCRemoteSwiftPackageReference "swift-collections" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/apple/swift-collections.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.1.1; + }; + }; + 8DF7566A2C0595F6008E8DFF /* XCRemoteSwiftPackageReference "swift-argument-parser" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/apple/swift-argument-parser.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.4.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 8D93B67E2C3FEA0000C91865 /* NIO */ = { + isa = XCSwiftPackageProductDependency; + package = 8D93B67D2C3FEA0000C91865 /* XCRemoteSwiftPackageReference "swift-nio" */; + productName = NIO; + }; + 8D93B6802C3FEA5600C91865 /* NIO */ = { + isa = XCSwiftPackageProductDependency; + package = 8D93B67D2C3FEA0000C91865 /* XCRemoteSwiftPackageReference "swift-nio" */; + productName = NIO; + }; + 8D93B6952C45992F00C91865 /* ArgumentParser */ = { + isa = XCSwiftPackageProductDependency; + package = 8DF7566A2C0595F6008E8DFF /* XCRemoteSwiftPackageReference "swift-argument-parser" */; + productName = ArgumentParser; + }; + 8D93B6972C45993600C91865 /* Collections */ = { + isa = XCSwiftPackageProductDependency; + package = 8DB347C02C1C53CB00F3C020 /* XCRemoteSwiftPackageReference "swift-collections" */; + productName = Collections; + }; + 8DB347C22C1C53ED00F3C020 /* Collections */ = { + isa = XCSwiftPackageProductDependency; + package = 8DB347C02C1C53CB00F3C020 /* XCRemoteSwiftPackageReference "swift-collections" */; + productName = Collections; + }; + 8DEC6F2F2C2E9F0E00AC6209 /* Collections */ = { + isa = XCSwiftPackageProductDependency; + package = 8DB347C02C1C53CB00F3C020 /* XCRemoteSwiftPackageReference "swift-collections" */; + productName = Collections; + }; + 8DF7566B2C0595F6008E8DFF /* ArgumentParser */ = { + isa = XCSwiftPackageProductDependency; + package = 8DF7566A2C0595F6008E8DFF /* XCRemoteSwiftPackageReference "swift-argument-parser" */; + productName = ArgumentParser; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 8DF756572C0595AA008E8DFF /* Project object */; } diff --git a/ADSBDecoder/AirplaneTracker.swift b/ADSBDecoder/AirplaneTracker.swift index f346201..96c4d5f 100644 --- a/ADSBDecoder/AirplaneTracker.swift +++ b/ADSBDecoder/AirplaneTracker.swift @@ -67,7 +67,6 @@ class AirPlaneTracker { } } - func getPosition(_ address: Int) -> (Double,Double)? { if (airplanes[address] == nil) { diff --git a/ADSBDecoder/Configs.swift b/ADSBDecoder/Configs.swift new file mode 100644 index 0000000..97ab31c --- /dev/null +++ b/ADSBDecoder/Configs.swift @@ -0,0 +1,10 @@ +// +// Configs.swift +// ADSBDecoder +// +// Created by Jacky Jack on 09/07/2024. +// + +import Foundation + +var decoder_debug_mode = true diff --git a/ADSBDecoder/Decoder.swift b/ADSBDecoder/Decoder.swift index 65a9ddd..a9724b6 100644 --- a/ADSBDecoder/Decoder.swift +++ b/ADSBDecoder/Decoder.swift @@ -25,7 +25,7 @@ class Decoder { var DataFormat: UInt32 = 0; init (_ adsb_data: String) { - print(adsb_data) + //print(adsb_data) self.adsb_data = adsb_data //get the first 8 bits as integer let startI = adsb_data.startIndex @@ -38,7 +38,7 @@ class Decoder { DataFormat = CM_DataFormat //let CM_TranspoderCapability = ControlMsg&(0x7) } - print("Data Format \(DataFormat)") + //print("Data Format \(DataFormat)") } func getDataFormat17() -> DataFormat17? { @@ -114,7 +114,7 @@ class DataFormat17 { endN = adsb_data.index(startN, offsetBy: 1) } } - print(bindata) + //print(bindata) //Decode Capability let cap = (bindata[0]>>1)&0x7 @@ -136,25 +136,33 @@ class DataFormat17 { //aircraft indentification and category if (tc_byte == 4) { let msg = ADSBTypeCodeIndentification(bindata[4...10]) - print("=====ADSB MESSSGE 04 =======") - print(msg) - print("============================") + if decoder_debug_mode { + print("=====ADSB MESSSGE 04 =======") + print(msg) + print("============================") + } messageIdentification = msg //airborn position } else if ((tc_byte >= 8) && (tc_byte <= 18)) { let msg = ADSBTypeCodeAirbonePositon(bindata[4...10]) - print(String(format:"=====ADSB MESSSGE %02d ======= AA:%04d", tc_byte, AddressAnnounced)) - print(msg) - print("============================") + if decoder_debug_mode { + print(String(format:"=====ADSB MESSSGE %02d ======= AA:%04d", tc_byte, AddressAnnounced)) + print(msg) + print("============================") + } messageAirbornPositon = msg //airborn velocity } else if (tc_byte == 19) { - print("=====ADSB MESSSGE 19 =======") - print("=====VELOCITY =======") + if decoder_debug_mode { + print("=====ADSB MESSSGE 19 =======") + print("=====VELOCITY =======") + } } else { - print("=====ADSB MESSSGE UNKNOWN =======") + if decoder_debug_mode { + print("=====ADSB MESSSGE UNKNOWN =======") + } } } } @@ -176,7 +184,7 @@ class ADSBTypeCodeIndentification: CustomStringConvertible { let char_6 = (bindata[9]&0xf)<<2 + (bindata[10]>>6) let char_7 = bindata[10]&0x3f - print(char_0, char_1, char_2,char_3,char_4,char_5,char_6,char_7) + //print(char_0, char_1, char_2,char_3,char_4,char_5,char_6,char_7) ICAOName = ICAO2String(char_0, char_1, char_2, char_3, char_4, char_5, char_6, char_7) //print("ICAO name \(ICAOName)") } diff --git a/ADSBDecoder/PositionDecoder.swift b/ADSBDecoder/PositionDecoder.swift index 7d77221..85b9d49 100644 --- a/ADSBDecoder/PositionDecoder.swift +++ b/ADSBDecoder/PositionDecoder.swift @@ -162,7 +162,7 @@ class PositionDecoder { let cpr_even = el1.even ? el1 : el2 let cpr_odd = (!el1.even) ? el1 : el2 - print("Position queue is ready to calculate location \(cpr_even) \(cpr_odd)") + //print("Position queue is ready to calculate location \(cpr_even) \(cpr_odd)") // from here https://github.com/antirez/dump1090/blob/master/dump1090.c#L1718 let AirDlat0:Double = 360.0/60.0 let AirDlat1:Double = 360.0/59.0 diff --git a/ADSBDecoder/main.swift b/ADSBDecoder/main.swift index 3148a9d..f75cdfb 100644 --- a/ADSBDecoder/main.swift +++ b/ADSBDecoder/main.swift @@ -81,9 +81,6 @@ for line in adsb_source.components(separatedBy: .newlines) { airbornposition.Altitude, airbornposition.CPRFormat == 0 ) - if let position = tracker.getPosition(d17.AddressAnnounced) { - print("position: \(position)") - } } q_df17_decoded.addDecoded(d17.TypeCode) } else { diff --git a/ADSBStats/main.swift b/ADSBStats/main.swift new file mode 100644 index 0000000..20ea285 --- /dev/null +++ b/ADSBStats/main.swift @@ -0,0 +1,118 @@ +// +// main.swift +// ADSBStats +// +// Created by Jacky Jack on 28/05/2024. +// + +import Foundation +import ArgumentParser +import RegexBuilder +//import SQLite3 + +decoder_debug_mode = false + +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 + count_messages += 1 + if let tokenMatch = try matchADSBLong.prefixMatch(in: line) { + 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() { + 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)") +} diff --git a/LearnMapKit/ADSBRunner.swift b/LearnMapKit/ADSBRunner.swift index 6d2bbc5..e05978c 100644 --- a/LearnMapKit/ADSBRunner.swift +++ b/LearnMapKit/ADSBRunner.swift @@ -34,81 +34,91 @@ enum DataStreamType { //get stream of decoded data, to tagged stream so all can be processed in sequence class ADSBDataQueue { - var icaoQueue: Deque = [] + //var icaoQueue: Deque = [] + var icaoArray: Array = [] var altQueue: Deque = [] var locQueue: Deque = [] - var tagQueue: Deque = [] + //var tagQueue: Deque<> = [] + var tagArray: Array = [] func getNextTag() -> DataStreamType { - if tagQueue.count < 0 { + if tagArray.count < 0 { return DataStreamType.EMPTY } - return tagQueue[tagQueue.count-1] + return tagArray[tagArray.count-1] } func addIcaoName(_ address: Int, _ icaoname: String) { - tagQueue.append(DataStreamType.ADSB_ICAO) - icaoQueue.append(ADSBICAOname(address: address, ICAOname: icaoname)) + tagArray.append(DataStreamType.ADSB_ICAO) + icaoArray.append(ADSBICAOname(address: address, ICAOname: icaoname)) } func addAltitude(_ address: Int, _ altitude: Int) { - tagQueue.append(DataStreamType.ADSB_ALTITUDE) + tagArray.append(DataStreamType.ADSB_ALTITUDE) altQueue.append(ADSBAltitude(address: address, altitude: altitude)) } func addLocation(_ address: Int, _ lat: Double, _ long: Double) { - tagQueue.append(DataStreamType.ADSB_LOCATION) + tagArray.append(DataStreamType.ADSB_LOCATION) locQueue.append(ADSBLocation(address: address, lat: lat, long: long)) } func getIcaoName() -> ADSBICAOname { - if tagQueue.count < 1 { - print("ADSB tag Queue is empry") - return ADSBICAOname(address:0,ICAOname: "") + if tagArray.count < 1 { + print("ADSB tag Queue is empty") + return ADSBICAOname(address:0,ICAOname: "TEmpty") } - let tag = tagQueue[tagQueue.count-1] + let tag = tagArray[tagArray.count-1] if tag != DataStreamType.ADSB_ICAO { print("ADSB Queue empty") - return ADSBICAOname(address:0,ICAOname: "") + return ADSBICAOname(address:0,ICAOname: "QEmpty") + } + tagArray.removeLast() + var ret_icao_name = ADSBICAOname(address:0, ICAOname: "Default") + if let last_icao_name = icaoArray.popLast() { + ret_icao_name = last_icao_name } - tagQueue.removeLast() - return icaoQueue.popLast()! + return ret_icao_name } func getAltitude() -> ADSBAltitude { - if tagQueue.count < 1 { + if tagArray.count < 1 { print("ADSB tag Queue is empry") return ADSBAltitude(address:0,altitude:0) } - let tag = tagQueue[tagQueue.count-1] + let tag = tagArray[tagArray.count-1] if tag != DataStreamType.ADSB_ALTITUDE { print("ADSB Queue empty") return ADSBAltitude(address:0,altitude:0) } - tagQueue.removeLast() + tagArray.removeLast() return altQueue.popLast()! } func getLocation() -> ADSBLocation { - if tagQueue.count < 1 { + if tagArray.count < 1 { print("ADSB tag Queue is empry") return ADSBLocation(address:0,lat:0.0,long:0.0) } - let tag = tagQueue[tagQueue.count-1] + let tag = tagArray[tagArray.count-1] if tag != DataStreamType.ADSB_LOCATION { print("ADSB Queue empty") return ADSBLocation(address:0,lat:0.0,long:0.0) } - tagQueue.removeLast() + tagArray.removeLast() return locQueue.popLast()! } func haveNum(_ num: Int) -> Bool { - if (tagQueue.count > num) { + if (tagArray.count > num) { return true } return false } + + func getCount() -> Int { + return tagArray.count + } } class ADSBFileRunner { @@ -117,13 +127,27 @@ class ADSBFileRunner { //track all airplanes var tracker = AirPlaneTracker() var adsb_source: String = "" + //should make it outside and use here? var adsb_tag_stream = ADSBDataQueue() + private var decoded_status: Bool = false init(filename:String) { self.filename = URL(fileURLWithPath:filename) } + init() { + self.filename = URL(fileURLWithPath:"") + } + + func setFileName(_ filename:String) { + self.filename = URL(fileURLWithPath: filename) + } + func openFile() { + if self.filename == URL(fileURLWithPath:"") { + print("File name for ADSBRunner not specified") + return + } print("File location [\(filename.absoluteString)]") //check if file excists @@ -139,7 +163,7 @@ class ADSBFileRunner { adsb_source = try String(contentsOfFile: filename.path) print("Loaded \(adsb_source.count) bytes") } catch { - print("Couldn't load text from a file \(filename.path)") + print("Couldn't load text from a file \(filename.path) \(error)") exit(1) } print("If there anything new in file") @@ -192,7 +216,47 @@ class ADSBFileRunner { print("Unknown adsb data line \(line)") } } + self.decoded_status = true //try to free the string after decoded //adsb_source = "" + for i in 0.. Bool { + return self.decoded_status + } + + func getPlainData(_ num_queries: Int) -> ADSBDataQueue { + var ret = ADSBDataQueue() + if adsb_tag_stream.haveNum(num_queries) { + + for _ in 0.. Int { + return self.adsb_tag_stream.getCount() } } diff --git a/LearnMapKit/ContentView.swift b/LearnMapKit/ContentView.swift index 08f4192..13ef64f 100644 --- a/LearnMapKit/ContentView.swift +++ b/LearnMapKit/ContentView.swift @@ -9,6 +9,31 @@ import SwiftUI import MapKit import Collections +struct FlightView: View { + + var evilClass: FlightState + + var body: some View { + //let i = evilClass.flight.count + let pos = CLLocationCoordinate2D(latitude: 55.80159, longitude:-3.13154) + Map() { + ForEach(0..<10, id:\.self) {i in + Annotation("plane\(i)", coordinate: pos) { + ZStack { + RoundedRectangle(cornerRadius: 10) + .fill(.background) + RoundedRectangle(cornerRadius: 10) + .stroke(.secondary,lineWidth: 5) + Image(systemName:"airplane.circle.fill") + .resizable() + .frame(width:20,height: 20) + } + }//.annotationTitles(.hidden) + } + } + } +} + struct ContentView: View { @State private var region = MKCoordinateRegion() @@ -17,6 +42,7 @@ struct ContentView: View { @Binding var pos_queue: Deque @EnvironmentObject var evilClass: FlightState + let initialPosition: MapCameraPosition = { let center = CLLocationCoordinate2D(latitude: 55.90159, longitude:-3.53154) let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1) @@ -53,7 +79,7 @@ struct ContentView: View { } Button("7") { print("Pressed 7") - print(evilClass.update_postions.count) + //print(evilClass.update_postions.count) } } .border(.blue) @@ -61,7 +87,7 @@ struct ContentView: View { //.padding() Map(initialPosition: initialPosition) { - Annotation("plane1", coordinate: position1) { + /*Annotation("plane1", coordinate: position1) { ZStack { RoundedRectangle(cornerRadius: 10) .fill(.background) @@ -104,7 +130,46 @@ struct ContentView: View { .resizable() .frame(width:20,height: 20) } - }.annotationTitles(.hidden) + }.annotationTitles(.hidden)*//* + ForEach(0.. some View { + let c = self.evilClass.flight.count + ForEach(0.. = [] + //default location currently for testing var fromFile: Bool = false + @Published var flight:[Int:FlightTracker] = [:] + + //configuration options + let default_file_path = "/Users/jackyjack/Downloads/2024_05_27_raw_adsb.txt" + let process_per_second = 120 + init() { var count = 0 - let ADSBtask = ADSBFileRunner(filename: "") + //let ADSBtask = ADSBFileRunner(filename: "") + let adsb_file = ADSBFileRunner(filename: self.default_file_path) + + + DispatchQueue.global(qos: .background).sync { + print("Open file") + adsb_file.openFile() + adsb_file.readFile() + } + + DispatchQueue.global(qos: .background).async { + print("Start decoding data") + adsb_file.decode() + print("Stop decoding data") + } + + //once a second read some data from decoded queue timer = Timer.scheduledTimer( withTimeInterval: 1, repeats: true ) { _ in - - //queue.append(MapADSBData(lat: 0.0, long: 0.0, alt: 1)) - - //let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in - print("Evil object \(count)") - //ADSBtask.runFromFile() - self.update_postions.append(ADSBLocation(address: 0, lat: 0.0, long: 0.0)) - // print(update_postions.count) - count += 1 - //} + //get the 10 entries if there is + if adsb_file.jobDone() { + print("Decoding done let get some data \(adsb_file.getCount())") + //if adsb_file + if adsb_file.getCount() > self.process_per_second { + let data = adsb_file.getPlainData(self.process_per_second) + //print(data.getCount()) + for idx in 0.. com.apple.security.app-sandbox + com.apple.security.files.downloads.read-only + com.apple.security.files.user-selected.read-only diff --git a/LearnMapKit/LearnMapKitApp.swift b/LearnMapKit/LearnMapKitApp.swift index 5fa170a..1b64510 100644 --- a/LearnMapKit/LearnMapKitApp.swift +++ b/LearnMapKit/LearnMapKitApp.swift @@ -10,8 +10,6 @@ import Collections //https://www.hackingwithswift.com/quick-start/swiftui/how-to-run-code-when-your-app-launches - - @main struct LearnMapKitApp: App { @@ -21,30 +19,6 @@ struct LearnMapKitApp: App { init() { print("Init app") - var update_postions: Deque = [] - DispatchQueue.global(qos: .background).sync { - print("Dispatch") - //var count = 0 - - - //let ADSBtask = ADSBRunner() - //queue.append(MapADSBData(lat: 0.0, long: 0.0, alt: 1)) - /* - let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in - print("Timer fired! \(count)") - ADSBtask.runFromFile() - update_postions.append(MapADSBData(lat: 0.0, long: 0.0, alt: 1)) - print(update_postions.count) - count += 1 - }*/ - print("Exit dispatch") - } - - //push all new data to state queue from a runner - DispatchQueue.global(qos: .background).sync { - // Update the UI on the main thread - let c = queue.count - } } diff --git a/Net1090/main.swift b/Net1090/main.swift new file mode 100644 index 0000000..93ff716 --- /dev/null +++ b/Net1090/main.swift @@ -0,0 +1,75 @@ +// +// main.swift +// Net1090 +// +// Created by Jacky Jack on 11/07/2024. +// + +import Foundation +import Network +import NIO + +class ADSBHandlder: ChannelInboundHandler { + typealias InboundIn = ByteBuffer + typealias OutboundOut = ByteBuffer + + func channelActive(context: ChannelHandlerContext) { + print("Channel is active") + } + + func channelRead(context: ChannelHandlerContext, data: NIOAny) { + var buffer = unwrapInboundIn(data) + let readableBytes = buffer.readableBytes + if let received = buffer.readString(length: readableBytes) { + print(received,terminator: "") + } + } + + func errorCaught(context: ChannelHandlerContext, error: any Error) { + print("error: \(error.localizedDescription)") + context.close(promise: nil) + } +} + +class TCPClient { + let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) + var host: String + var port: Int + + init(host: String, port: Int) { + self.host = host + self.port = port + } + + func start() throws { + do { + let channel = try ClientBootstrap(group: group) + .channelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1) + .channelInitializer{channel in + //channel.pipeline.add(handler: ADSBHandlder()) + channel.pipeline.addHandlers([ADSBHandlder()]) + }.connect(host: self.host, port: self.port) + .wait() + try channel.closeFuture.wait() + } catch let error { + print(error) + throw error + } + } + + func stop() { + + } +} + +print("Hello, World!") +print("Start listening client") + +let ADSBClient = TCPClient(host: "192.168.4.201", port: 30002) +do { + try ADSBClient.start() +} catch let error { + print("Error: \(error.localizedDescription)") + ADSBClient.stop() +} + -- cgit v1.2.3