|
|
@@ -0,0 +1,181 @@ |
|
|
|
|
|
package appcontext |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
|
"github.com/AFASystems/presence/internal/pkg/model" |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
// Manager provides centralized access to application state |
|
|
|
|
|
type Manager struct { |
|
|
|
|
|
beacons model.BeaconsList |
|
|
|
|
|
settings model.Settings |
|
|
|
|
|
beaconEvents model.BeaconEventList |
|
|
|
|
|
beaconsLookup map[string]struct{} |
|
|
|
|
|
latestList model.LatestBeaconsList |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// NewManager creates a new application context manager with default values |
|
|
|
|
|
func NewManager() *Manager { |
|
|
|
|
|
return &Manager{ |
|
|
|
|
|
beacons: model.BeaconsList{ |
|
|
|
|
|
Beacons: make(map[string]model.Beacon), |
|
|
|
|
|
}, |
|
|
|
|
|
settings: model.Settings{ |
|
|
|
|
|
Settings: model.SettingsVal{ |
|
|
|
|
|
LocationConfidence: 4, |
|
|
|
|
|
LastSeenThreshold: 15, |
|
|
|
|
|
BeaconMetricSize: 30, |
|
|
|
|
|
HASendInterval: 5, |
|
|
|
|
|
HASendChangesOnly: false, |
|
|
|
|
|
RSSIEnforceThreshold: false, |
|
|
|
|
|
RSSIMinThreshold: 100, |
|
|
|
|
|
}, |
|
|
|
|
|
}, |
|
|
|
|
|
beaconEvents: model.BeaconEventList{ |
|
|
|
|
|
Beacons: make(map[string]model.BeaconEvent), |
|
|
|
|
|
}, |
|
|
|
|
|
beaconsLookup: make(map[string]struct{}), |
|
|
|
|
|
latestList: model.LatestBeaconsList{ |
|
|
|
|
|
LatestList: make(map[string]model.Beacon), |
|
|
|
|
|
}, |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetBeacons returns thread-safe access to beacons list |
|
|
|
|
|
func (m *Manager) GetBeacons() *model.BeaconsList { |
|
|
|
|
|
return &m.beacons |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetSettings returns thread-safe access to settings |
|
|
|
|
|
func (m *Manager) GetSettings() *model.Settings { |
|
|
|
|
|
return &m.settings |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetBeaconEvents returns thread-safe access to beacon events |
|
|
|
|
|
func (m *Manager) GetBeaconEvents() *model.BeaconEventList { |
|
|
|
|
|
return &m.beaconEvents |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetBeaconsLookup returns thread-safe access to beacon lookup map |
|
|
|
|
|
func (m *Manager) GetBeaconsLookup() map[string]struct{} { |
|
|
|
|
|
return m.beaconsLookup |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetLatestList returns thread-safe access to latest beacons list |
|
|
|
|
|
func (m *Manager) GetLatestList() *model.LatestBeaconsList { |
|
|
|
|
|
return &m.latestList |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// AddBeaconToLookup adds a beacon ID to the lookup map |
|
|
|
|
|
func (m *Manager) AddBeaconToLookup(id string) { |
|
|
|
|
|
m.beaconsLookup[id] = struct{}{} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// RemoveBeaconFromLookup removes a beacon ID from the lookup map |
|
|
|
|
|
func (m *Manager) RemoveBeaconFromLookup(id string) { |
|
|
|
|
|
delete(m.beaconsLookup, id) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// BeaconExists checks if a beacon exists in the lookup |
|
|
|
|
|
func (m *Manager) BeaconExists(id string) bool { |
|
|
|
|
|
_, exists := m.beaconsLookup[id] |
|
|
|
|
|
return exists |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetBeacon returns a beacon by ID (thread-safe) |
|
|
|
|
|
func (m *Manager) GetBeacon(id string) (model.Beacon, bool) { |
|
|
|
|
|
m.beacons.Lock.RLock() |
|
|
|
|
|
defer m.beacons.Lock.RUnlock() |
|
|
|
|
|
|
|
|
|
|
|
beacon, exists := m.beacons.Beacons[id] |
|
|
|
|
|
return beacon, exists |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// UpdateBeacon updates a beacon in the list (thread-safe) |
|
|
|
|
|
func (m *Manager) UpdateBeacon(id string, beacon model.Beacon) { |
|
|
|
|
|
m.beacons.Lock.Lock() |
|
|
|
|
|
defer m.beacons.Lock.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
m.beacons.Beacons[id] = beacon |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetBeaconEvent returns a beacon event by ID (thread-safe) |
|
|
|
|
|
func (m *Manager) GetBeaconEvent(id string) (model.BeaconEvent, bool) { |
|
|
|
|
|
m.beaconEvents.Lock.RLock() |
|
|
|
|
|
defer m.beaconEvents.Lock.RUnlock() |
|
|
|
|
|
|
|
|
|
|
|
event, exists := m.beaconEvents.Beacons[id] |
|
|
|
|
|
return event, exists |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// UpdateBeaconEvent updates a beacon event in the list (thread-safe) |
|
|
|
|
|
func (m *Manager) UpdateBeaconEvent(id string, event model.BeaconEvent) { |
|
|
|
|
|
m.beaconEvents.Lock.Lock() |
|
|
|
|
|
defer m.beaconEvents.Lock.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
m.beaconEvents.Beacons[id] = event |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetLatestBeacon returns the latest beacon by ID (thread-safe) |
|
|
|
|
|
func (m *Manager) GetLatestBeacon(id string) (model.Beacon, bool) { |
|
|
|
|
|
m.latestList.Lock.RLock() |
|
|
|
|
|
defer m.latestList.Lock.RUnlock() |
|
|
|
|
|
|
|
|
|
|
|
beacon, exists := m.latestList.LatestList[id] |
|
|
|
|
|
return beacon, exists |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// UpdateLatestBeacon updates the latest beacon in the list (thread-safe) |
|
|
|
|
|
func (m *Manager) UpdateLatestBeacon(id string, beacon model.Beacon) { |
|
|
|
|
|
m.latestList.Lock.Lock() |
|
|
|
|
|
defer m.latestList.Lock.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
m.latestList.LatestList[id] = beacon |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetAllBeacons returns a copy of all beacons |
|
|
|
|
|
func (m *Manager) GetAllBeacons() map[string]model.Beacon { |
|
|
|
|
|
m.beacons.Lock.RLock() |
|
|
|
|
|
defer m.beacons.Lock.RUnlock() |
|
|
|
|
|
|
|
|
|
|
|
beacons := make(map[string]model.Beacon) |
|
|
|
|
|
for id, beacon := range m.beacons.Beacons { |
|
|
|
|
|
beacons[id] = beacon |
|
|
|
|
|
} |
|
|
|
|
|
return beacons |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetAllLatestBeacons returns a copy of all latest beacons |
|
|
|
|
|
func (m *Manager) GetAllLatestBeacons() map[string]model.Beacon { |
|
|
|
|
|
m.latestList.Lock.RLock() |
|
|
|
|
|
defer m.latestList.Lock.RUnlock() |
|
|
|
|
|
|
|
|
|
|
|
beacons := make(map[string]model.Beacon) |
|
|
|
|
|
for id, beacon := range m.latestList.LatestList { |
|
|
|
|
|
beacons[id] = beacon |
|
|
|
|
|
} |
|
|
|
|
|
return beacons |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetBeaconCount returns the number of tracked beacons |
|
|
|
|
|
func (m *Manager) GetBeaconCount() int { |
|
|
|
|
|
m.beacons.Lock.RLock() |
|
|
|
|
|
defer m.beacons.Lock.RUnlock() |
|
|
|
|
|
|
|
|
|
|
|
return len(m.beacons.Beacons) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// GetSettingsValue returns current settings as a value |
|
|
|
|
|
func (m *Manager) GetSettingsValue() model.SettingsVal { |
|
|
|
|
|
m.settings.Lock.RLock() |
|
|
|
|
|
defer m.settings.Lock.RUnlock() |
|
|
|
|
|
|
|
|
|
|
|
return m.settings.Settings |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// UpdateSettings updates the system settings (thread-safe) |
|
|
|
|
|
func (m *Manager) UpdateSettings(newSettings model.SettingsVal) { |
|
|
|
|
|
m.settings.Lock.Lock() |
|
|
|
|
|
defer m.settings.Lock.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
m.settings.Settings = newSettings |
|
|
|
|
|
} |