package station import ( "sync" "github.com/nemunaire/repeater/internal/models" "github.com/nemunaire/repeater/internal/station/backend" ) var ( currentBackend backend.StationBackend mu sync.RWMutex ) // Initialize initializes the station discovery backend func Initialize(backendName string, config backend.BackendConfig) error { mu.Lock() defer mu.Unlock() // Close existing backend if any if currentBackend != nil { currentBackend.Close() } // Create new backend b, err := createBackend(backendName) if err != nil { return err } // Initialize the backend if err := b.Initialize(config); err != nil { return err } currentBackend = b return nil } // GetStations returns all connected stations as ConnectedDevice models func GetStations() ([]models.ConnectedDevice, error) { mu.RLock() defer mu.RUnlock() if currentBackend == nil { return nil, nil } stations, err := currentBackend.GetStations() if err != nil { return nil, err } devices := make([]models.ConnectedDevice, len(stations)) for i, s := range stations { devices[i] = toConnectedDevice(s) } return devices, nil } // toConnectedDevice converts a backend Station to the API model. Centralised // so handlers, the periodic refresh and the event callbacks all serialise the // same shape. func toConnectedDevice(s backend.Station) models.ConnectedDevice { return models.ConnectedDevice{ Name: s.Hostname, Type: s.Type, MAC: s.MAC, IP: s.IP, Vendor: s.Vendor, SignalDbm: s.Signal, RxBytes: s.RxBytes, TxBytes: s.TxBytes, ConnectedAt: s.ConnectedAt, } } // ToConnectedDevice exposes the conversion for callers in other packages. func ToConnectedDevice(s backend.Station) models.ConnectedDevice { return toConnectedDevice(s) } // StartEventMonitoring starts monitoring for station events func StartEventMonitoring(callbacks backend.EventCallbacks) error { mu.RLock() defer mu.RUnlock() if currentBackend == nil { return nil } return currentBackend.StartEventMonitoring(callbacks) } // StopEventMonitoring stops monitoring for station events func StopEventMonitoring() { mu.RLock() defer mu.RUnlock() if currentBackend != nil { currentBackend.StopEventMonitoring() } } // Close closes the current backend func Close() { mu.Lock() defer mu.Unlock() if currentBackend != nil { currentBackend.Close() currentBackend = nil } } // SupportsRealTimeEvents returns true if the current backend supports real-time events func SupportsRealTimeEvents() bool { mu.RLock() defer mu.RUnlock() if currentBackend == nil { return false } return currentBackend.SupportsRealTimeEvents() }