feat: added additional wifi information (standard, security, channel) in the Network module (#941)

This commit is contained in:
Serhiy Mytrovtsiy
2022-05-26 18:56:55 +02:00
parent 49164388ca
commit e50d6aaf94
3 changed files with 183 additions and 33 deletions

View File

@@ -31,6 +31,37 @@ public struct Network_addr {
var v6: String? = nil
}
public struct Network_wifi {
var countryCode: String? = nil
var ssid: String? = nil
var RSSI: Int? = nil
var noise: Int? = nil
var transmitRate: Double? = nil
var transmitPower: Int? = nil
var standard: String? = nil
var mode: String? = nil
var security: String? = nil
var channel: String? = nil
var channelBand: String? = nil
var channelWidth: String? = nil
var channelNumber: String? = nil
mutating func reset() {
self.countryCode = nil
self.ssid = nil
self.RSSI = nil
self.noise = nil
self.transmitRate = nil
self.transmitPower = nil
self.standard = nil
self.mode = nil
self.security = nil
self.channel = nil
}
}
public struct Network_Usage: value_t {
var bandwidth: Bandwidth = (0, 0)
var total: Bandwidth = (0, 0)
@@ -42,8 +73,7 @@ public struct Network_Usage: value_t {
var connectionType: Network_t? = nil
var status: Bool = false
var countryCode: String? = nil
var ssid: String? = nil
var wifiDetails: Network_wifi = Network_wifi()
mutating func reset() {
self.bandwidth = (0, 0)
@@ -54,8 +84,7 @@ public struct Network_Usage: value_t {
self.interface = nil
self.connectionType = nil
self.countryCode = nil
self.ssid = nil
self.wifiDetails.reset()
}
public var widgetValue: Double = 0

View File

@@ -32,7 +32,6 @@ internal class Popup: NSStackView, Popup_p {
private var localIPField: ValueField? = nil
private var interfaceField: ValueField? = nil
private var ssidField: ValueField? = nil
private var macAdressField: ValueField? = nil
private var totalUploadField: ValueField? = nil
private var totalDownloadField: ValueField? = nil
@@ -42,6 +41,11 @@ internal class Popup: NSStackView, Popup_p {
private var publicIPv4Field: ValueField? = nil
private var publicIPv6Field: ValueField? = nil
private var ssidField: ValueField? = nil
private var standardField: ValueField? = nil
private var securityField: ValueField? = nil
private var channelField: ValueField? = nil
private var processesView: NSView? = nil
private var initialized: Bool = false
@@ -182,10 +186,15 @@ internal class Popup: NSStackView, Popup_p {
self.totalUploadField = popupWithColorRow(container, color: NSColor.systemRed, n: 5, title: "\(localizedString("Total upload")):", value: "0")
self.totalDownloadField = popupWithColorRow(container, color: NSColor.systemBlue, n: 4, title: "\(localizedString("Total download")):", value: "0")
self.connectionField = popupRow(container, n: 4, title: "\(localizedString("Status")):", value: localizedString("Unknown")).1
self.interfaceField = popupRow(container, n: 3, title: "\(localizedString("Interface")):", value: localizedString("Unknown")).1
self.ssidField = popupRow(container, n: 2, title: "\(localizedString("Network")):", value: localizedString("Unknown")).1
self.macAdressField = popupRow(container, n: 1, title: "\(localizedString("Physical address")):", value: localizedString("Unknown")).1
self.connectionField = popupRow(container, n: 0, title: "\(localizedString("Status")):", value: localizedString("Unknown")).1
self.ssidField = popupRow(container, n: 0, title: "\(localizedString("Network")):", value: localizedString("Unknown")).1
self.standardField = popupRow(container, n: 0, title: "\(localizedString("Standard")):", value: localizedString("Unknown")).1
self.securityField = popupRow(container, n: 0, title: "\(localizedString("Security")):", value: localizedString("Unknown")).1
self.channelField = popupRow(container, n: 0, title: "\(localizedString("Channel")):", value: localizedString("Unknown")).1
self.interfaceField = popupRow(container, n: 0, title: "\(localizedString("Interface")):", value: localizedString("Unknown")).1
self.macAdressField = popupRow(container, n: 0, title: "\(localizedString("Physical address")):", value: localizedString("Unknown")).1
self.localIPField = popupRow(container, n: 0, title: "\(localizedString("Local IP")):", value: localizedString("Unknown")).1
self.localIPField?.isSelectable = true
@@ -308,14 +317,28 @@ internal class Popup: NSStackView, Popup_p {
}
if value.connectionType == .wifi {
self.ssidField?.stringValue = value.ssid ?? "Unknown"
self.ssidField?.stringValue = value.wifiDetails.ssid ?? localizedString("Unknown")
if let v = value.wifiDetails.RSSI {
self.ssidField?.stringValue += " (\(v))"
}
self.standardField?.stringValue = value.wifiDetails.standard ?? localizedString("Unknown")
self.securityField?.stringValue = value.wifiDetails.security ?? localizedString("Unknown")
self.channelField?.stringValue = value.wifiDetails.channel ?? localizedString("Unknown")
let number = value.wifiDetails.channelNumber ?? localizedString("Unknown")
let band = value.wifiDetails.channelBand ?? localizedString("Unknown")
let width = value.wifiDetails.channelWidth ?? localizedString("Unknown")
self.channelField?.toolTip = "Channel number: \(number)\nChannel band: \(band)\nChannel width: \(width)"
} else {
self.ssidField?.stringValue = localizedString("Unavailable")
self.standardField?.stringValue = localizedString("Unavailable")
self.securityField?.stringValue = localizedString("Unavailable")
self.channelField?.stringValue = localizedString("Unavailable")
}
if let view = self.publicIPv4Field, view.stringValue != value.raddr.v4 {
if let addr = value.raddr.v4 {
view.stringValue = (value.countryCode != nil) ? "\(addr) (\(value.countryCode!))" : addr
view.stringValue = (value.wifiDetails.countryCode != nil) ? "\(addr) (\(value.wifiDetails.countryCode!))" : addr
} else {
view.stringValue = localizedString("Unknown")
}

View File

@@ -8,6 +8,7 @@
//
// Copyright © 2020 Serhiy Mytrovtsiy. All rights reserved.
//
// swiftlint:disable control_statement
import Cocoa
import Kit
@@ -20,6 +21,85 @@ struct ipResponse: Decodable {
var cc: String
}
extension CWPHYMode: CustomStringConvertible {
public var description: String {
switch(self) {
case .mode11a: return "802.11a"
case .mode11ac: return "802.11ac"
case .mode11b: return "802.11b"
case .mode11g: return "802.11g"
case .mode11n: return "802.11n"
case .modeNone: return "none"
@unknown default: return "unknown"
}
}
}
extension CWInterfaceMode: CustomStringConvertible {
public var description: String {
switch(self) {
case .hostAP: return "AP"
case .IBSS: return "Adhoc"
case .station: return "Station"
case .none: return "none"
@unknown default: return "unknown"
}
}
}
extension CWSecurity: CustomStringConvertible {
public var description: String {
switch(self) {
case .none: return "none"
case .WEP: return "WEP"
case .wpaPersonal: return "WPA Personal"
case .wpaPersonalMixed: return "WPA Personal Mixed"
case .wpa2Personal: return "WPA2 Personal"
case .personal: return "Personal"
case .dynamicWEP: return "Dynamic WEP"
case .wpaEnterprise: return "WPA Enterprise"
case .wpaEnterpriseMixed: return "WPA Enterprise Mixed"
case .wpa2Enterprise: return "WPA2 Enterprise"
case .enterprise: return "Enterprise"
case .unknown: return "unknown"
case .wpa3Personal: return "WPA3 Personal"
case .wpa3Enterprise: return "WPA3 Enterprise"
case .wpa3Transition: return "WPA3 Transition"
@unknown default: return "unknown"
}
}
}
extension CWChannelBand: CustomStringConvertible {
public var description: String {
switch(self) {
case .band2GHz: return "2 GHz"
case .band5GHz: return "5 Ghz"
case .bandUnknown: return "unknown"
@unknown default: return "unknown"
}
}
}
extension CWChannelWidth: CustomStringConvertible {
public var description: String {
switch(self) {
case .width20MHz: return "20 MHz"
case .width40MHz: return "40 MHz"
case .width80MHz: return "80 MHz"
case .width160MHz: return "160 MHz"
case .widthUnknown: return "unknown"
@unknown default: return "unknown"
}
}
}
extension CWChannel {
override public var description: String {
return "\(channelNumber) (\(channelBand), \(channelWidth))"
}
}
internal class UsageReader: Reader<Network_Usage> {
private var reachability: Reachability = Reachability(start: true)
private var usage: Network_Usage = Network_Usage()
@@ -212,32 +292,50 @@ internal class UsageReader: Reader<Network_Usage> {
self.getPublicIP()
}
if self.interfaceID != "" {
for interface in SCNetworkInterfaceCopyAll() as NSArray {
if let bsdName = SCNetworkInterfaceGetBSDName(interface as! SCNetworkInterface),
bsdName as String == self.interfaceID,
let type = SCNetworkInterfaceGetInterfaceType(interface as! SCNetworkInterface),
let displayName = SCNetworkInterfaceGetLocalizedDisplayName(interface as! SCNetworkInterface),
let address = SCNetworkInterfaceGetHardwareAddressString(interface as! SCNetworkInterface) {
self.usage.interface = Network_interface(displayName: displayName as String, BSDName: bsdName as String, address: address as String)
switch type {
case kSCNetworkInterfaceTypeEthernet:
self.usage.connectionType = .ethernet
case kSCNetworkInterfaceTypeIEEE80211, kSCNetworkInterfaceTypeWWAN:
self.usage.connectionType = .wifi
case kSCNetworkInterfaceTypeBluetooth:
self.usage.connectionType = .bluetooth
default:
self.usage.connectionType = .other
}
guard self.interfaceID != "" else {
return
}
for interface in SCNetworkInterfaceCopyAll() as NSArray {
if let bsdName = SCNetworkInterfaceGetBSDName(interface as! SCNetworkInterface), bsdName as String == self.interfaceID,
let type = SCNetworkInterfaceGetInterfaceType(interface as! SCNetworkInterface),
let displayName = SCNetworkInterfaceGetLocalizedDisplayName(interface as! SCNetworkInterface),
let address = SCNetworkInterfaceGetHardwareAddressString(interface as! SCNetworkInterface) {
self.usage.interface = Network_interface(displayName: displayName as String, BSDName: bsdName as String, address: address as String)
switch type {
case kSCNetworkInterfaceTypeEthernet:
self.usage.connectionType = .ethernet
case kSCNetworkInterfaceTypeIEEE80211, kSCNetworkInterfaceTypeWWAN:
self.usage.connectionType = .wifi
case kSCNetworkInterfaceTypeBluetooth:
self.usage.connectionType = .bluetooth
default:
self.usage.connectionType = .other
}
}
}
if let interface = CWWiFiClient.shared().interface(), self.usage.connectionType == .wifi {
self.usage.ssid = interface.ssid()
self.usage.countryCode = interface.countryCode()
if let interface = CWWiFiClient.shared().interface(withName: self.interfaceID), self.usage.connectionType == .wifi {
self.usage.wifiDetails.ssid = interface.ssid()
self.usage.wifiDetails.countryCode = interface.countryCode()
self.usage.wifiDetails.RSSI = interface.rssiValue()
self.usage.wifiDetails.noise = interface.noiseMeasurement()
self.usage.wifiDetails.transmitRate = interface.transmitRate()
self.usage.wifiDetails.transmitPower = interface.transmitPower()
self.usage.wifiDetails.standard = interface.activePHYMode().description
self.usage.wifiDetails.mode = interface.interfaceMode().description
self.usage.wifiDetails.security = interface.security().description
if let ch = interface.wlanChannel() {
self.usage.wifiDetails.channel = ch.description
self.usage.wifiDetails.channelBand = ch.channelBand.description
self.usage.wifiDetails.channelWidth = ch.channelWidth.description
self.usage.wifiDetails.channelNumber = ch.channelNumber.description
}
}
}