Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 26 additions & 32 deletions HeliPort/Appearance/StatusMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
)
Expand Down Expand Up @@ -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()
}

Expand Down Expand Up @@ -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()
}
}
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
}
}

Expand Down
25 changes: 23 additions & 2 deletions HeliPort/NetworkManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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) {

Expand Down Expand Up @@ -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
}
}

Expand Down