mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-13 00:42:49 -05:00
switch hto monorepo structure
This commit is contained in:
232
backend/internal/server/network/backend_iwd.go
Normal file
232
backend/internal/server/network/backend_iwd.go
Normal file
@@ -0,0 +1,232 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
iwdBusName = "net.connman.iwd"
|
||||
iwdObjectPath = "/"
|
||||
iwdAdapterInterface = "net.connman.iwd.Adapter"
|
||||
iwdDeviceInterface = "net.connman.iwd.Device"
|
||||
iwdStationInterface = "net.connman.iwd.Station"
|
||||
iwdNetworkInterface = "net.connman.iwd.Network"
|
||||
iwdKnownNetworkInterface = "net.connman.iwd.KnownNetwork"
|
||||
dbusObjectManager = "org.freedesktop.DBus.ObjectManager"
|
||||
dbusPropertiesInterface = "org.freedesktop.DBus.Properties"
|
||||
)
|
||||
|
||||
type connectAttempt struct {
|
||||
ssid string
|
||||
netPath dbus.ObjectPath
|
||||
start time.Time
|
||||
deadline time.Time
|
||||
sawAuthish bool
|
||||
connectedAt time.Time
|
||||
sawIPConfig bool
|
||||
sawPromptRetry bool
|
||||
finalized bool
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
type IWDBackend struct {
|
||||
conn *dbus.Conn
|
||||
state *BackendState
|
||||
stateMutex sync.RWMutex
|
||||
promptBroker PromptBroker
|
||||
onStateChange func()
|
||||
|
||||
devicePath dbus.ObjectPath
|
||||
stationPath dbus.ObjectPath
|
||||
adapterPath dbus.ObjectPath
|
||||
|
||||
iwdAgent *IWDAgent
|
||||
|
||||
stopChan chan struct{}
|
||||
sigWG sync.WaitGroup
|
||||
curAttempt *connectAttempt
|
||||
attemptMutex sync.RWMutex
|
||||
recentScans map[string]time.Time
|
||||
recentScansMu sync.Mutex
|
||||
}
|
||||
|
||||
func NewIWDBackend() (*IWDBackend, error) {
|
||||
backend := &IWDBackend{
|
||||
state: &BackendState{
|
||||
Backend: "iwd",
|
||||
WiFiEnabled: true,
|
||||
},
|
||||
stopChan: make(chan struct{}),
|
||||
recentScans: make(map[string]time.Time),
|
||||
}
|
||||
|
||||
return backend, nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) Initialize() error {
|
||||
conn, err := dbus.ConnectSystemBus()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to system bus: %w", err)
|
||||
}
|
||||
b.conn = conn
|
||||
|
||||
if err := b.discoverDevices(); err != nil {
|
||||
conn.Close()
|
||||
return fmt.Errorf("failed to discover iwd devices: %w", err)
|
||||
}
|
||||
|
||||
if err := b.updateState(); err != nil {
|
||||
conn.Close()
|
||||
return fmt.Errorf("failed to get initial state: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) Close() {
|
||||
close(b.stopChan)
|
||||
b.sigWG.Wait()
|
||||
|
||||
if b.iwdAgent != nil {
|
||||
b.iwdAgent.Close()
|
||||
}
|
||||
|
||||
if b.conn != nil {
|
||||
b.conn.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (b *IWDBackend) discoverDevices() error {
|
||||
obj := b.conn.Object(iwdBusName, iwdObjectPath)
|
||||
|
||||
var objects map[dbus.ObjectPath]map[string]map[string]dbus.Variant
|
||||
err := obj.Call(dbusObjectManager+".GetManagedObjects", 0).Store(&objects)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get managed objects: %w", err)
|
||||
}
|
||||
|
||||
for path, interfaces := range objects {
|
||||
if _, hasStation := interfaces[iwdStationInterface]; hasStation {
|
||||
b.stationPath = path
|
||||
}
|
||||
if _, hasDevice := interfaces[iwdDeviceInterface]; hasDevice {
|
||||
b.devicePath = path
|
||||
|
||||
if devProps, ok := interfaces[iwdDeviceInterface]; ok {
|
||||
if nameVar, ok := devProps["Name"]; ok {
|
||||
if name, ok := nameVar.Value().(string); ok {
|
||||
b.stateMutex.Lock()
|
||||
b.state.WiFiDevice = name
|
||||
b.stateMutex.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, hasAdapter := interfaces[iwdAdapterInterface]; hasAdapter {
|
||||
b.adapterPath = path
|
||||
}
|
||||
}
|
||||
|
||||
if b.stationPath == "" || b.devicePath == "" {
|
||||
return fmt.Errorf("no WiFi device found")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) GetCurrentState() (*BackendState, error) {
|
||||
state := *b.state
|
||||
state.WiFiNetworks = append([]WiFiNetwork(nil), b.state.WiFiNetworks...)
|
||||
state.WiredConnections = append([]WiredConnection(nil), b.state.WiredConnections...)
|
||||
|
||||
return &state, nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) OnUserCanceledPrompt() {
|
||||
b.stateMutex.RLock()
|
||||
cancelledSSID := b.state.ConnectingSSID
|
||||
b.stateMutex.RUnlock()
|
||||
|
||||
b.setConnectError("user-canceled")
|
||||
|
||||
if cancelledSSID != "" {
|
||||
if err := b.ForgetWiFiNetwork(cancelledSSID); err != nil {
|
||||
}
|
||||
}
|
||||
|
||||
if b.onStateChange != nil {
|
||||
b.onStateChange()
|
||||
}
|
||||
}
|
||||
|
||||
func (b *IWDBackend) OnPromptRetry(ssid string) {
|
||||
b.attemptMutex.RLock()
|
||||
att := b.curAttempt
|
||||
b.attemptMutex.RUnlock()
|
||||
|
||||
if att != nil && att.ssid == ssid {
|
||||
att.mu.Lock()
|
||||
att.sawPromptRetry = true
|
||||
att.mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (b *IWDBackend) MarkIPConfigSeen() {
|
||||
b.attemptMutex.RLock()
|
||||
att := b.curAttempt
|
||||
b.attemptMutex.RUnlock()
|
||||
if att != nil {
|
||||
att.mu.Lock()
|
||||
att.sawIPConfig = true
|
||||
att.mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (b *IWDBackend) GetPromptBroker() PromptBroker {
|
||||
return b.promptBroker
|
||||
}
|
||||
|
||||
func (b *IWDBackend) SetPromptBroker(broker PromptBroker) error {
|
||||
if broker == nil {
|
||||
return fmt.Errorf("broker cannot be nil")
|
||||
}
|
||||
|
||||
b.promptBroker = broker
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *IWDBackend) SubmitCredentials(token string, secrets map[string]string, save bool) error {
|
||||
if b.promptBroker == nil {
|
||||
return fmt.Errorf("prompt broker not initialized")
|
||||
}
|
||||
|
||||
return b.promptBroker.Resolve(token, PromptReply{
|
||||
Secrets: secrets,
|
||||
Save: save,
|
||||
Cancel: false,
|
||||
})
|
||||
}
|
||||
|
||||
func (b *IWDBackend) CancelCredentials(token string) error {
|
||||
if b.promptBroker == nil {
|
||||
return fmt.Errorf("prompt broker not initialized")
|
||||
}
|
||||
|
||||
return b.promptBroker.Resolve(token, PromptReply{
|
||||
Cancel: true,
|
||||
})
|
||||
}
|
||||
|
||||
func (b *IWDBackend) StopMonitoring() {
|
||||
select {
|
||||
case <-b.stopChan:
|
||||
return
|
||||
default:
|
||||
close(b.stopChan)
|
||||
}
|
||||
b.sigWG.Wait()
|
||||
}
|
||||
Reference in New Issue
Block a user