diff --git a/Docsis Toolkit.xcodeproj/project.pbxproj b/Docsis Toolkit.xcodeproj/project.pbxproj index b2f1f6e..def5088 100644 --- a/Docsis Toolkit.xcodeproj/project.pbxproj +++ b/Docsis Toolkit.xcodeproj/project.pbxproj @@ -15,6 +15,9 @@ E2218CE41EF2D54A004298F6 /* BumpBuildNumber.py in Resources */ = {isa = PBXBuildFile; fileRef = E2218CE21EF2D54A004298F6 /* BumpBuildNumber.py */; }; E2218D0D1EF2D68F004298F6 /* XMLDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = E2218D0A1EF2D68F004298F6 /* XMLDictionary.m */; }; E2218D111EF2D6F1004298F6 /* SettingsWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2218D101EF2D6F1004298F6 /* SettingsWindowController.swift */; }; + E2218D151EF2E470004298F6 /* ConnectionLossOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2218D141EF2E470004298F6 /* ConnectionLossOperation.swift */; }; + E2218D171EF2E4EA004298F6 /* Shared.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2218D161EF2E4EA004298F6 /* Shared.swift */; }; + E2218D191EF2F0D8004298F6 /* FrequencyOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2218D181EF2F0D8004298F6 /* FrequencyOperation.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -40,6 +43,9 @@ E2218D081EF2D68F004298F6 /* XMLDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XMLDictionary.h; sourceTree = ""; }; E2218D0A1EF2D68F004298F6 /* XMLDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XMLDictionary.m; sourceTree = ""; }; E2218D101EF2D6F1004298F6 /* SettingsWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsWindowController.swift; sourceTree = ""; }; + E2218D141EF2E470004298F6 /* ConnectionLossOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionLossOperation.swift; sourceTree = ""; }; + E2218D161EF2E4EA004298F6 /* Shared.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Shared.swift; sourceTree = ""; }; + E2218D181EF2F0D8004298F6 /* FrequencyOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FrequencyOperation.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -120,7 +126,9 @@ isa = PBXGroup; children = ( E2218D121EF2D754004298F6 /* Delegates */, + E2218D131EF2E443004298F6 /* Operations */, E2218D0F1EF2D6E5004298F6 /* Views */, + E2218D161EF2E4EA004298F6 /* Shared.swift */, ); name = Swift; sourceTree = ""; @@ -151,6 +159,15 @@ name = Delegates; sourceTree = ""; }; + E2218D131EF2E443004298F6 /* Operations */ = { + isa = PBXGroup; + children = ( + E2218D141EF2E470004298F6 /* ConnectionLossOperation.swift */, + E2218D181EF2F0D8004298F6 /* FrequencyOperation.swift */, + ); + name = Operations; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXLegacyTarget section */ @@ -251,8 +268,11 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + E2218D171EF2E4EA004298F6 /* Shared.swift in Sources */, E2218D0D1EF2D68F004298F6 /* XMLDictionary.m in Sources */, E2218D111EF2D6F1004298F6 /* SettingsWindowController.swift in Sources */, + E2218D151EF2E470004298F6 /* ConnectionLossOperation.swift in Sources */, + E2218D191EF2F0D8004298F6 /* FrequencyOperation.swift in Sources */, E2218C9B1EF2D345004298F6 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Docsis Toolkit.xcodeproj/xcuserdata/Kili2.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Docsis Toolkit.xcodeproj/xcuserdata/Kili2.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..cb814a8 --- /dev/null +++ b/Docsis Toolkit.xcodeproj/xcuserdata/Kili2.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Logger4/AppDelegate.swift b/Logger4/AppDelegate.swift index 4bcd735..4a178b6 100644 --- a/Logger4/AppDelegate.swift +++ b/Logger4/AppDelegate.swift @@ -5,6 +5,8 @@ // Created by Kilian Hofmann on 15.06.17. // Copyright © 2017 Kilian Hofmann. All rights reserved. // +// Folder Structure "~/KDLog/YEAR.docsisplist2/MONTH/DAY/FILE" +// import Cocoa @@ -12,6 +14,11 @@ import Cocoa class AppDelegate: NSObject, NSApplicationDelegate { // MARK: - Things that have to be kept alive for the application lifetime + // lock for mutex access to files + var lock: pthread_mutex_t = pthread_mutex_t() + // Date formaters + let justDate: DateFormatter = DateFormatter() + let justTime: DateFormatter = DateFormatter() // Status Item var statusItem: NSStatusItem = NSStatusItem() // URL Session for DOCSIS data and Internet check @@ -21,8 +28,6 @@ class AppDelegate: NSObject, NSApplicationDelegate { // Timers var timerFreqs: Timer = Timer() var timerFails: Timer = Timer() - // Document content list - var content: NSMutableDictionary = NSMutableDictionary() // MARK: - Application Lifecycle @@ -33,6 +38,19 @@ class AppDelegate: NSObject, NSApplicationDelegate { pref.showWindow(nil) } + // Init lock + pthread_mutex_init(&((NSApp.delegate as! AppDelegate).lock), nil) + + // Setup date formatters + justDate.dateStyle = DateFormatter.Style.medium + justDate.timeStyle = DateFormatter.Style.none + justDate.locale = Locale(identifier: "de_DE") + + justTime.dateStyle = .none + justTime.timeStyle = .medium + justTime.timeZone = NSTimeZone.local + justTime.locale = Locale(identifier: "de_DE") + // Set status item statusItem = NSStatusBar.system().statusItem(withLength: -2) statusItem.title = "AL" @@ -52,9 +70,10 @@ class AppDelegate: NSObject, NSApplicationDelegate { // Add menu statusItem.menu = menu - // Check if directory exists, creat or exit + // Check if directory exists, create or exit let fileManager = FileManager.default var directory: ObjCBool = ObjCBool(false) + pthread_mutex_lock(&((NSApp.delegate as! AppDelegate).lock)) let exists: Bool = fileManager.fileExists(atPath: ("~/KDLog" as NSString).expandingTildeInPath, isDirectory: &directory) if exists && directory.boolValue { } else if exists { @@ -70,6 +89,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { exit(1); } } + pthread_mutex_unlock(&((NSApp.delegate as! AppDelegate).lock)) // Init timers if UserDefaults.standard.string(forKey: "upstream") != nil || UserDefaults.standard.string(forKey: "downstream") != nil { @@ -90,8 +110,8 @@ class AppDelegate: NSObject, NSApplicationDelegate { } func logFails(_: Timer) { -// let connectionLossOperation: ConnectionLossOperation = ConnectionLossOperation() -// OperationQueue.main.addOperation(connectionLossOperation) + let connectionLossOperation: ConnectionLossOperation = ConnectionLossOperation() + OperationQueue.main.addOperation(connectionLossOperation) } // MARK: - General functions diff --git a/Logger4/ConnectionLossOperation.swift b/Logger4/ConnectionLossOperation.swift new file mode 100644 index 0000000..8c3353c --- /dev/null +++ b/Logger4/ConnectionLossOperation.swift @@ -0,0 +1,71 @@ +// +// ConnectionLossOperation.swift +// Docsis Toolkit +// +// Created by Kilian Hofmann on 15.06.17. +// Copyright © 2017 Kilian Hofmann. All rights reserved. +// + +import Cocoa + +class ConnectionLossOperation: Operation { + var result1: Bool = false + var result2: Bool = false + + override init() { + + } + + override func main() { + // Get date for folder structure + let time : Date = Date() + let start: Array = (NSApp.delegate as! AppDelegate).justDate.string(from: time).components(separatedBy: ".") + // Line to write + let entry: String = String(format: "%@\n", (NSApp.delegate as! AppDelegate).justTime.string(from: time)) + // File manager + let fileManager: FileManager = FileManager.default + // Path to file + let file: String = NSString(format: "~/KDLog/%@.docsisplist2/%@/%@/KDLog.txt", start[2], start[1], start[0]).expandingTildeInPath + // Make all relevant directories if not present + pthread_mutex_lock(&((NSApp.delegate as! AppDelegate).lock)) + let dir: NSString = NSString(format: "~/KDLog/%@.docsisplist2/%@/%@", start[2], start[1], start[0]) + do { + try fileManager.createDirectory(atPath: dir.expandingTildeInPath, withIntermediateDirectories: true, attributes: nil) + } + catch let error as NSError{ + NSLog("ERROR ON SUBDIRECTORY CREATION: \(error.localizedDescription)") + } + pthread_mutex_unlock(&((NSApp.delegate as! AppDelegate).lock)) + // Check connection requests + let request: URLRequest = URLRequest.init(url: URL.init(string: "http://checkip.dyndns.org")!, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10) + let request2: URLRequest = URLRequest.init(url: URL.init(string: "http://www.google.de")!, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10) + // Generate tasks + let task1: URLSessionDataTask = (NSApp.delegate as! AppDelegate).urlSession.dataTask(with: request) { + data, response, error in + + if error != nil && data == nil && self.result2 { + log(entry, path: file) + self.result2 = false; + NSLog("Internet loss logged!") + } + else if error != nil && response == nil && data == nil { + self.result1 = true; + } + } + let task2: URLSessionDataTask = (NSApp.delegate as! AppDelegate).urlSession.dataTask(with: request2) { + data, response, error in + + if error != nil && data == nil && self.result1 { + log(entry, path: file) + self.result1 = false; + NSLog("Internet loss logged!") + } + else if error != nil && response == nil && data == nil { + self.result2 = true; + } + } + // Start tasks + task1.resume() + task2.resume() + } +} diff --git a/Logger4/FrequencyOperation.swift b/Logger4/FrequencyOperation.swift new file mode 100644 index 0000000..087a3e1 --- /dev/null +++ b/Logger4/FrequencyOperation.swift @@ -0,0 +1,42 @@ +// +// FrequencyOperation.swift +// Docsis Toolkit +// +// Created by Kilian Hofmann on 15.06.17. +// Copyright © 2017 Kilian Hofmann. All rights reserved. +// + +import Cocoa + +class FrequencyOperation: Operation { + + // DOCSIS 3.0 Upstream Power Limits as per Specification March 5. 2015 + let upstreamOne = ["qpsk": "62.18", "8qam": "58.21", "16qam": "58.21", "32qam": "57", "64qam": "57", "128qam": "-"] + let upstreamTwo = ["qpsk": "59.18", "8qam": "55.21", "16qam": "55.21", "32qam": "54", "64qam": "54", "128qam": "-"] + let upstreamThreeOrFour = ["qpsk": "56.18", "8qam": "52.21", "16qam": "52.21", "32qam": "51", "64qam": "51", "128qam": "-"] + let modulationAdjust: NSDictionary = ["qpsk": "-1.18", "8qam": "-0.21", "16qam": "-0.21", "32qam" : "0", "64qam": "0", "128qam": "0.05"] + // XML Parser + let parser: XMLDictionaryParser = XMLDictionaryParser() + + override init() { + + } + + override func main() { + // Get date for folder structure + let time : Date = Date() + let start: Array = (NSApp.delegate as! AppDelegate).justDate.string(from: time).components(separatedBy: ".") + // File manager + let fileManager: FileManager = FileManager.default + // Make all relevant directories if not present + pthread_mutex_lock(&((NSApp.delegate as! AppDelegate).lock)) + let dir: NSString = NSString(format: "~/KDLog/%@.docsisplist2/%@/%@", start[2], start[1], start[0]) + do { + try fileManager.createDirectory(atPath: dir.expandingTildeInPath, withIntermediateDirectories: true, attributes: nil) + } + catch let error as NSError{ + NSLog("ERROR ON SUBDIRECTORY CREATION: \(error.localizedDescription)") + } + pthread_mutex_unlock(&((NSApp.delegate as! AppDelegate).lock)) + } +} diff --git a/Logger4/Info.plist b/Logger4/Info.plist index 0f8561e..703c2a0 100644 --- a/Logger4/Info.plist +++ b/Logger4/Info.plist @@ -17,7 +17,7 @@ CFBundleShortVersionString 4.0 CFBundleVersion - 6 + 13 LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) LSUIElement diff --git a/Logger4/Shared.swift b/Logger4/Shared.swift new file mode 100644 index 0000000..5163f5c --- /dev/null +++ b/Logger4/Shared.swift @@ -0,0 +1,26 @@ +// +// Shared.swift +// Docsis Toolkit +// +// Created by Kilian Hofmann on 15.06.17. +// Copyright © 2017 Kilian Hofmann. All rights reserved. +// + +import Cocoa + +func log(_ entry: String, path: String) { + let file: FileHandle? = FileHandle(forUpdatingAtPath: path) + if file == nil { + do{ + try (entry).write(toFile: path, atomically: true, encoding: String.Encoding.utf8) + } + catch { + NSLog("WRITE TO FILE FAILED\n"); + } + } else { + file?.seekToEndOfFile(); + let data = (entry as NSString).data(using: String.Encoding.utf8.rawValue) + file?.write(data!) + file?.closeFile() + } +} diff --git a/Logger4/buildnum.ver b/Logger4/buildnum.ver index 76a5037..3501c27 100644 --- a/Logger4/buildnum.ver +++ b/Logger4/buildnum.ver @@ -1,2 +1,2 @@ version 4.0 -build 6 +build 13