Add websocket wifi updates

This commit is contained in:
nemunaire 2026-01-01 17:42:53 +07:00
commit 1477d909b0
11 changed files with 755 additions and 10 deletions

View file

@ -7,6 +7,7 @@ import (
"time"
"github.com/godbus/dbus/v5"
"github.com/gorilla/websocket"
"github.com/nemunaire/repeater/internal/models"
"github.com/nemunaire/repeater/internal/wifi/iwd"
)
@ -16,12 +17,14 @@ const (
)
var (
wlanInterface string
dbusConn *dbus.Conn
iwdManager *iwd.Manager
station *iwd.Station
agent *iwd.Agent
agentManager *iwd.AgentManager
wlanInterface string
dbusConn *dbus.Conn
iwdManager *iwd.Manager
station *iwd.Station
agent *iwd.Agent
agentManager *iwd.AgentManager
eventMonitor *iwd.SignalMonitor
wifiBroadcaster *WifiBroadcaster
)
// Initialize initializes the WiFi service with iwd D-Bus connection
@ -68,6 +71,48 @@ func Close() {
}
}
// GetCachedNetworks returns previously discovered networks without triggering a scan
func GetCachedNetworks() ([]models.WiFiNetwork, error) {
// Get ordered networks without scanning
networkInfos, err := station.GetOrderedNetworks()
if err != nil {
return nil, fmt.Errorf("erreur lors de la récupération des réseaux: %v", err)
}
var networks []models.WiFiNetwork
seenSSIDs := make(map[string]bool)
for _, netInfo := range networkInfos {
network := iwd.NewNetwork(dbusConn, netInfo.Path)
props, err := network.GetProperties()
if err != nil {
continue
}
if props.Name == "" || seenSSIDs[props.Name] {
continue
}
seenSSIDs[props.Name] = true
wifiNet := models.WiFiNetwork{
SSID: props.Name,
Signal: signalToStrength(int(netInfo.Signal) / 100),
Security: mapSecurityType(props.Type),
BSSID: generateSyntheticBSSID(props.Name),
Channel: 0,
}
networks = append(networks, wifiNet)
}
// Sort by signal strength (descending)
sort.Slice(networks, func(i, j int) bool {
return networks[i].Signal > networks[j].Signal
})
return networks, nil
}
// ScanNetworks scans for available WiFi networks
func ScanNetworks() ([]models.WiFiNetwork, error) {
// Check if already scanning
@ -120,6 +165,11 @@ func ScanNetworks() ([]models.WiFiNetwork, error) {
return networks[i].Signal > networks[j].Signal
})
// Broadcast to WebSocket clients if available
if wifiBroadcaster != nil {
wifiBroadcaster.BroadcastScanUpdate(networks)
}
return networks, nil
}
@ -191,6 +241,59 @@ func GetConnectedSSID() string {
return props.Name
}
// StartEventMonitoring initializes D-Bus signal monitoring and WebSocket broadcasting
func StartEventMonitoring() error {
// Initialize broadcaster
wifiBroadcaster = NewWifiBroadcaster()
// Create signal monitor
eventMonitor = iwd.NewSignalMonitor(dbusConn, station)
// Register callbacks
eventMonitor.OnStateChange(handleStateChange)
eventMonitor.OnScanComplete(handleScanComplete)
// Start monitoring
return eventMonitor.Start()
}
// StopEventMonitoring stops D-Bus signal monitoring
func StopEventMonitoring() {
if eventMonitor != nil {
eventMonitor.Stop()
}
}
// RegisterWebSocketClient registers a new WebSocket client for WiFi events
func RegisterWebSocketClient(conn *websocket.Conn) {
if wifiBroadcaster != nil {
wifiBroadcaster.RegisterClient(conn)
}
}
// UnregisterWebSocketClient removes a WebSocket client
func UnregisterWebSocketClient(conn *websocket.Conn) {
if wifiBroadcaster != nil {
wifiBroadcaster.UnregisterClient(conn)
}
}
// handleStateChange is called when WiFi connection state changes
func handleStateChange(newState iwd.StationState, connectedSSID string) {
if wifiBroadcaster != nil {
wifiBroadcaster.BroadcastStateChange(string(newState), connectedSSID)
}
}
// handleScanComplete is called when a WiFi scan completes
func handleScanComplete() {
// Get updated network list
networks, err := GetCachedNetworks()
if err == nil && wifiBroadcaster != nil {
wifiBroadcaster.BroadcastScanUpdate(networks)
}
}
// mapSecurityType maps iwd security types to display format
func mapSecurityType(iwdType string) string {
switch iwdType {