Files
iOS/Sources/Shared/Environment/ConnectivityWrapper.swift
Bruno Pantaleão Gonçalves fa7af0a582 Detect SSID on watch to decide which endpoint to use to run actions (#2865)
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->

## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->

## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->

## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#

## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
2024-07-24 10:53:20 +02:00

115 lines
4.4 KiB
Swift

import Foundation
#if os(iOS)
import CoreTelephony
import Reachability
import SystemConfiguration.CaptiveNetwork
#endif
import Communicator
/// Wrapper around CoreTelephony, Reachability
public class ConnectivityWrapper {
public var connectivityDidChangeNotification: () -> Notification.Name
public var hasWiFi: () -> Bool
public var currentWiFiSSID: () -> String?
public var currentWiFiBSSID: () -> String?
public var currentNetworkHardwareAddress: () -> String?
public var simpleNetworkType: () -> NetworkType
public var cellularNetworkType: () -> NetworkType
public var networkAttributes: () -> [String: Any]
#if targetEnvironment(macCatalyst)
init() {
self.hasWiFi = { Current.macBridge.networkConnectivity.hasWiFi }
self.currentWiFiSSID = { Current.macBridge.networkConnectivity.wifi?.ssid }
self.currentWiFiBSSID = { Current.macBridge.networkConnectivity.wifi?.bssid }
self.connectivityDidChangeNotification = { Current.macBridge.networkConnectivityDidChangeNotification }
self.simpleNetworkType = {
switch Current.macBridge.networkConnectivity.networkType {
case .ethernet: return .ethernet
case .wifi: return .wifi
case .unknown: return .unknown
case .noNetwork: return .noConnection
}
}
self.currentNetworkHardwareAddress = { Current.macBridge.networkConnectivity.interface?.hardwareAddress }
self.cellularNetworkType = { .unknown }
self.networkAttributes = {
if let interface = Current.macBridge.networkConnectivity.interface {
return [
"Name": interface.name,
"Hardware Address": interface.hardwareAddress,
]
} else {
return [:]
}
}
}
#elseif os(iOS)
init() {
let reachability = try? Reachability()
do {
try reachability?.startNotifier()
} catch {
Current.Log.error("failed to start reachability notifier: \(error)")
}
self.hasWiFi = { true }
self.currentWiFiSSID = {
#if targetEnvironment(simulator)
return "Simulator"
#endif
guard let interfaces = CNCopySupportedInterfaces() as? [String] else { return nil }
for interface in interfaces {
guard let interfaceInfo = CNCopyCurrentNetworkInfo(interface as CFString) as NSDictionary? else {
continue
}
return interfaceInfo[kCNNetworkInfoKeySSID as String] as? String
}
return nil
}
self.currentWiFiBSSID = {
guard let interfaces = CNCopySupportedInterfaces() as? [String] else { return nil }
for interface in interfaces {
guard let interfaceInfo = CNCopyCurrentNetworkInfo(interface as CFString) as NSDictionary? else {
continue
}
return interfaceInfo[kCNNetworkInfoKeyBSSID as String] as? String
}
return nil
}
self.connectivityDidChangeNotification = { .reachabilityChanged }
self.simpleNetworkType = { reachability?.getSimpleNetworkType() ?? .unknown }
self.cellularNetworkType = { reachability?.getNetworkType() ?? .unknown }
self.currentNetworkHardwareAddress = { nil }
self.networkAttributes = { [:] }
}
#else
init() {
self.hasWiFi = { true }
self.currentWiFiSSID = {
let ssid = WatchUserDefaults.shared.string(for: .watchSSID)
Current.Log.verbose("Watch current WiFi SSID: \(String(describing: ssid))")
return ssid
}
self.currentWiFiBSSID = { nil }
self.connectivityDidChangeNotification = { .init(rawValue: "_noop_") }
self.simpleNetworkType = { .unknown }
self.cellularNetworkType = { .unknown }
self.currentNetworkHardwareAddress = { nil }
self.networkAttributes = { [:] }
}
#endif
#if os(iOS) && !targetEnvironment(macCatalyst)
public var telephonyCarriers: () -> [String: CTCarrier]? = {
CTTelephonyNetworkInfo().serviceSubscriberCellularProviders
}
public var telephonyRadioAccessTechnology: () -> [String: String]? = {
CTTelephonyNetworkInfo().serviceCurrentRadioAccessTechnology
}
#endif
}