From 938a5cb150131bed33de03015bfe7340ed2a9205 Mon Sep 17 00:00:00 2001 From: Avery Black Date: Sat, 25 Jul 2020 18:40:57 -0700 Subject: [PATCH] Auto join to networks whenever not connected --- HeliPort/Appearance/StatusMenu.swift | 58 +++++++++++++--------------- HeliPort/NetworkManager.swift | 25 +++++++++++- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/HeliPort/Appearance/StatusMenu.swift b/HeliPort/Appearance/StatusMenu.swift index 0968bd41..cc8f8ce4 100644 --- a/HeliPort/Appearance/StatusMenu.swift +++ b/HeliPort/Appearance/StatusMenu.swift @@ -23,12 +23,12 @@ final class StatusMenu: NSMenu, NSMenuDelegate { private let heliPortUpdater = SUUpdater() - private let networkListUpdatePeriod: Double = 5 - private let statusUpdatePeriod: Double = 2 + private let statusUpdatePeriod: Double = 5 private var headerLength: Int = 0 private var networkListUpdateTimer: Timer? private var statusUpdateTimer: Timer? + private var isOpen: Bool = false private var status: itl_80211_state = ITL80211_S_INIT { didSet { @@ -245,7 +245,7 @@ final class StatusMenu: NSMenu, NSMenuDelegate { self.statusUpdateTimer = Timer.scheduledTimer( timeInterval: self.statusUpdatePeriod, target: self, - selector: #selector(self.updateStatus), + selector: #selector(self.updateNetworksAndStatus), userInfo: nil, repeats: true ) @@ -326,27 +326,18 @@ final class StatusMenu: NSMenu, NSMenuDelegate { } func menuWillOpen(_ menu: NSMenu) { - + isOpen = true showAllOptions = (NSApp.currentEvent?.modifierFlags.contains(.option))! let queue = DispatchQueue.global(qos: .default) queue.async { self.updateNetworkInfo() self.updateNetworkList() - self.networkListUpdateTimer = Timer.scheduledTimer( - timeInterval: self.networkListUpdatePeriod, - target: self, - selector: #selector(self.updateNetworkList), - userInfo: nil, - repeats: true - ) - let currentRunLoop = RunLoop.current - currentRunLoop.add(self.networkListUpdateTimer!, forMode: .common) - currentRunLoop.run() } } func menuDidClose(_ menu: NSMenu) { + isOpen = false networkListUpdateTimer?.invalidate() } @@ -382,16 +373,6 @@ final class StatusMenu: NSMenu, NSMenuDelegate { self.macItem.title = NSLocalizedString("Address: ") + macAddr self.itlwmVerItem.title = NSLocalizedString("Version: ") + itlwmVer } - - // If not connected, try to connect saved networks - var stationInfo = station_info_t() - var state: UInt32 = 0 - var power: Bool = false - get_power_state(&power) - if get_80211_state(&state) && power && - (state != ITL80211_S_RUN.rawValue || get_station_info(&stationInfo) != KERN_SUCCESS) { - NetworkManager.connectSavedNetworks() - } } } @@ -451,6 +432,11 @@ final class StatusMenu: NSMenu, NSMenuDelegate { } } + @objc private func updateNetworksAndStatus() { + updateStatus() + updateNetworkList() + } + @objc private func updateStatus() { DispatchQueue.global(qos: .background).async { var powerState: Bool = false @@ -564,17 +550,25 @@ final class StatusMenu: NSMenu, NSMenuDelegate { NetworkManager.scanNetwork { networkList in self.isNetworkListEmpty = networkList.count == 0 && !self.isNetworkConnected - var networkList = networkList - for index in 1 ..< self.networkItemList.count { - if let view = self.networkItemList[index].view as? WifiMenuItemView { - if networkList.count > 0 { - view.networkInfo = networkList.removeFirst() - view.visible = true - } else { - view.visible = false + if self.isOpen { + var networkListTmp = networkList + for index in 1 ..< self.networkItemList.count { + if let view = self.networkItemList[index].view as? WifiMenuItemView { + if networkListTmp.count > 0 { + view.networkInfo = networkListTmp.removeFirst() + view.visible = true + } else { + view.visible = false + } } } } + + // If not connected, try to connect saved networks + if self.status != ITL80211_S_RUN + && self.status != ITL80211_S_AUTH { + NetworkManager.connectSavedNetworks(networkList) + } } } diff --git a/HeliPort/NetworkManager.swift b/HeliPort/NetworkManager.swift index 679e86ab..db6bb600 100644 --- a/HeliPort/NetworkManager.swift +++ b/HeliPort/NetworkManager.swift @@ -27,6 +27,8 @@ final class NetworkManager { ITL80211_SECURITY_PERSONAL ] + static var credentialLock = false + class func connect(networkInfo: NetworkInfo, saveNetwork: Bool = false, _ callback: ((_ result: Bool) -> Void)? = nil) { @@ -107,17 +109,36 @@ final class NetworkManager { } } - class func connectSavedNetworks() { + class func connectSavedNetworks(_ scannedNetworks: [NetworkInfo]) { DispatchQueue.global(qos: .background).async { let dispatchSemaphore = DispatchSemaphore(value: 0) var connected = false - for network in CredentialsManager.instance.getSavedNetworks() where !connected { + + // We can get here stuck below for a bit waiting for credential passwords. + // Only allow one autoconnect request at a time and drop the rest + if self.credentialLock { + return + } + + self.credentialLock = true + + // Filter for only scanned networks + let savedNetworks = CredentialsManager.instance.getSavedNetworks() + .filter { entity in + scannedNetworks.contains { element in + element.ssid == entity.ssid } + } + + for network in savedNetworks where !connected { + Log.debug("Auto-joining \(network.ssid)") connect(networkInfo: network) { (result: Bool) -> Void in connected = result dispatchSemaphore.signal() } dispatchSemaphore.wait() } + + self.credentialLock = false } }