-
Notifications
You must be signed in to change notification settings - Fork 0
/
state.go
88 lines (79 loc) · 2.18 KB
/
state.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package gw
import (
"bytes"
"encoding/json"
"os"
"sync"
)
// GatewayState is a state object for the gateway. The state object keeps track of the
// device -> lora device ID mappings
type GatewayState struct {
GatewayID string `json:"gatewayId"`
LocalID string `json:"localId"`
IDMappings map[string]string `json:"deviceMapping"`
mutex *sync.Mutex
}
// NewStateFromFile reads the state from a file. If the file name is empty or if the file doesn't exist an
// empty state struct will be returned
func NewStateFromFile(filename string) (*GatewayState, error) {
ret := &GatewayState{
IDMappings: make(map[string]string),
mutex: &sync.Mutex{},
}
if filename == "" {
return ret, nil
}
buf, err := os.ReadFile(filename)
if err != nil {
if os.IsNotExist(err) {
return ret, nil
}
return nil, err
}
if err := json.NewDecoder(bytes.NewBuffer(buf)).Decode(ret); err != nil {
return nil, err
}
return ret, nil
}
// Save writes the state to a file if the file name is set.
func (g *GatewayState) Save(filename string) error {
if filename == "" {
return nil
}
g.mutex.Lock()
defer g.mutex.Unlock()
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(g); err != nil {
return err
}
return os.WriteFile(filename, buf.Bytes(), 0700)
}
// SetMapping sets the ID mapping for the Span device ID to the gateway internal ID
func (g *GatewayState) SetMapping(deviceID, otherID string) {
g.mutex.Lock()
defer g.mutex.Unlock()
g.IDMappings[deviceID] = otherID
}
// GetMapping retrieves the mapping between the Span device ID and the internal ID
func (g *GatewayState) GetMapping(deviceID string) string {
g.mutex.Lock()
defer g.mutex.Unlock()
return g.IDMappings[deviceID]
}
// GetReverseMapping returns the device ID corresponding to the local ID
func (g *GatewayState) GetReverseMapping(localID string) string {
g.mutex.Lock()
defer g.mutex.Unlock()
for id, local := range g.IDMappings {
if local == localID {
return id
}
}
return ""
}
// RemoveMapping removes a mapping between the Span device ID and the internal ID
func (g *GatewayState) RemoveMapping(id string) {
g.mutex.Lock()
defer g.mutex.Unlock()
delete(g.IDMappings, id)
}