Rewrite entire network package and update wifi page

This commit is contained in:
NeilClack
2026-06-24 18:29:59 -05:00
parent 2d2069fd63
commit 953d0d8bc9
2 changed files with 114 additions and 50 deletions
+89 -18
View File
@@ -28,6 +28,22 @@ const (
nmDeviceTypeWifi uint32 = 2
nmDeviceStateActivated uint32 = 100
APFlagsPrivacy uint32 = 0x00000001 // Equivalent to NM_802_11_AP_FLAGS_PRIVACY
// Device states (from NM spec)
nmDeviceStateUnknown uint32 = 0
nmDeviceStateUnmanaged uint32 = 10
nmDeviceStateUnavailable uint32 = 20
nmDeviceStateDisconnected uint32 = 30
nmDeviceStateFailed uint32 = 120
// AP Security Flags (from NM_802_11_AP_SEC_*)
APFlagsWpaPsk uint32 = 0x00000100 // WPA-Personal
APFlagsWpaEap uint32 = 0x00000200 // WPA-Enterprise
APFlagsRsnPsk uint32 = 0x00000100 // WPA2-Personal (same flag as WPA-PSK)
APFlagsRsnSae uint32 = 0x00000400 // WPA3-Personal (SAE)
APFlagsRsnEap uint32 = 0x00000200 // WPA2-Enterprise (same flag as WPA-EAP)
APFlagsRsnOwe uint32 = 0x00000800 // OWE (Opportunistic Wireless Encryption)
APFlagsRsnEapSuiteB uint32 = 0x00001000 // WPA3-Enterprise
)
// ErrScanAborted is returned when a scan is cancelled via the stop channel.
@@ -128,7 +144,11 @@ func (m *Manager) FindDevices() error {
log.Printf("network: Skipping device %s, could not get DeviceType: %v", path, err)
continue
}
deviceType, _ := typeVariant.Value().(uint32)
deviceType, ok := typeVariant.Value().(uint32)
if !ok {
log.Printf("network: Skipping device %s, invalid DeviceType", path)
continue
}
var newDevice Device
switch deviceType {
@@ -141,10 +161,29 @@ func (m *Manager) FindDevices() error {
}
newDevice.Path = path
ifaceVariant, _ := deviceObj.GetProperty(nmDeviceInterface + ".Interface")
newDevice.InterfaceName, _ = ifaceVariant.Value().(string)
stateVariant, _ := deviceObj.GetProperty(nmDeviceInterface + ".State")
newDevice.State, _ = stateVariant.Value().(uint32)
// Safely get Interface property
ifaceVariant, err := deviceObj.GetProperty(nmDeviceInterface + ".Interface")
if err != nil {
log.Printf("network: Skipping device %s, could not get Interface: %v", path, err)
continue
}
if newDevice.InterfaceName, ok = ifaceVariant.Value().(string); !ok {
log.Printf("network: Skipping device %s, invalid Interface", path)
continue
}
// Safely get State property
stateVariant, err := deviceObj.GetProperty(nmDeviceInterface + ".State")
if err != nil {
log.Printf("network: Skipping device %s, could not get State: %v", path, err)
continue
}
if newDevice.State, ok = stateVariant.Value().(uint32); !ok {
log.Printf("network: Skipping device %s, invalid State", path)
continue
}
m.Devices = append(m.Devices, newDevice)
}
return nil
@@ -259,8 +298,8 @@ func (m *Manager) scanAccessPoints(apPaths []dbus.ObjectPath) ([]AccessPoint, er
continue
}
ssidBytes, _ := props["Ssid"].Value().([]byte)
if len(ssidBytes) == 0 {
ssidBytes, ok := props["Ssid"].Value().([]byte)
if !ok || len(ssidBytes) == 0 {
continue
}
@@ -272,12 +311,30 @@ func (m *Manager) scanAccessPoints(apPaths []dbus.ObjectPath) ([]AccessPoint, er
isProtected := (flags&APFlagsPrivacy != 0) || (wpaFlags != 0) || (rsnFlags != 0)
// Determine the key management type
// Determine key management type
var keyMgmt string
if wpaFlags != 0 {
keyMgmt = "wpa-psk"
if !isProtected {
keyMgmt = "none"
} else if wpaFlags != 0 {
// WPA (not WPA2/WPA3)
if wpaFlags&APFlagsWpaPsk != 0 {
keyMgmt = "wpa-psk"
} else if wpaFlags&APFlagsWpaEap != 0 {
keyMgmt = "wpa-eap"
} else {
keyMgmt = "wpa-psk" // Fallback
}
} else if rsnFlags != 0 {
keyMgmt = "wpa-psk"
// WPA2 or WPA3 (RSN)
if rsnFlags&APFlagsRsnSae != 0 {
keyMgmt = "sae" // WPA3-Personal
} else if rsnFlags&APFlagsRsnEapSuiteB != 0 {
keyMgmt = "eap-suite-b-192" // WPA3-Enterprise
} else if rsnFlags&APFlagsRsnEap != 0 {
keyMgmt = "wpa-eap" // WPA2-Enterprise
} else {
keyMgmt = "wpa-psk" // WPA2-Personal (default for RSN)
}
} else {
keyMgmt = "none"
}
@@ -313,6 +370,12 @@ func (m *Manager) Connect(wifiDevice Device, ap AccessPoint, passphrase string)
return fmt.Errorf("cannot connect: provided device is not a Wi-Fi device")
}
if wifiDevice.State == nmDeviceStateFailed ||
wifiDevice.State == nmDeviceStateUnmanaged ||
wifiDevice.State == nmDeviceStateUnavailable {
return fmt.Errorf("cannot connect: device is in an error state (state=%d)", wifiDevice.State)
}
settings := map[string]map[string]dbus.Variant{
"connection": {
"type": dbus.MakeVariant("802-11-wireless"),
@@ -365,14 +428,22 @@ func (m *Manager) Connect(wifiDevice Device, ap AccessPoint, passphrase string)
// pingTest with a short timeout to prevent the UI loop from hanging
func pingTest() bool {
// Use a dialer with a timeout instead of LookupHost which can hang
timeout := 2 * time.Second
conn, err := net.DialTimeout("tcp", "8.8.8.8:53", timeout)
if err != nil {
return false
targets := []string{
"1.1.1.1:53", // Cloudflare DNS
"8.8.8.8:53", // Google DNS
"9.9.9.9:53", // Quad9 DNS
"149.112.112.112:53", // Quad9 Alternate
}
conn.Close()
return true
timeout := 2 * time.Second
for _, target := range targets {
conn, err := net.DialTimeout("tcp", target, timeout)
if err == nil {
conn.Close()
return true
}
}
return false
}
// getAllProperties is a helper to fetch all properties for a D-Bus object interface.