-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathserverFile.go
109 lines (94 loc) · 2.46 KB
/
serverFile.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package modbus
type fileReadRequest struct {
file int
address int
count int
}
type fileWriteRequest struct {
file int
address int
values []int
}
func (s *server) x14ReadFileRecord(mb Modbus, request *dataReader, response *dataBuilder) error {
size, err := request.byte()
err = request.canRead(size)
if err != nil {
return err
}
if size%7 != 0 {
return IllegalValueErrorF("Expected subrequest size to be a multiple of 7, not %v", size)
}
xsize := 1
reqs := make([]fileReadRequest, size/7)
for i := range reqs {
code, _ := request.byte()
if code != 0x06 {
return IllegalValueErrorF("Expected SubRequest reference 0x06 but got 0x%02x", code)
}
file, _ := request.word()
addr, _ := request.word()
count, _ := request.word()
reqs[i] = fileReadRequest{file, addr, count}
xsize += 2 + count*2
}
if xsize > 253 { //(PDU limit)
return IllegalFunctionErrorF("File Record Requests will exceed limit of payload, max 253, requested %v", xsize)
}
atomic := s.StartAtomic()
defer atomic.Complete()
response.byte(xsize)
for _, req := range reqs {
recs, err := s.ReadFileRecords(atomic, req.file, req.address, req.count)
if err != nil {
return err
}
response.byte(1 + len(recs)*2)
response.byte(0x06)
response.words(recs...)
}
return nil
}
func (s *server) x15WriteFileRecord(mb Modbus, request *dataReader, response *dataBuilder) error {
size, err := request.byte()
err = request.canRead(size)
if err != nil {
return err
}
reqs := make([]fileWriteRequest, 0)
for request.cursor < size {
err = request.canRead(7)
if err != nil {
return err
}
code, _ := request.byte()
if code != 0x06 {
return IllegalValueErrorF("Expected SubRequest reference 0x06 but got 0x%02x", code)
}
file, _ := request.word()
addr, _ := request.word()
count, _ := request.word()
values, err := request.words(count)
if err != nil {
return err
}
reqs = append(reqs, fileWriteRequest{file, addr, values})
}
atomic := s.StartAtomic()
defer atomic.Complete()
response.byte(size)
for _, req := range reqs {
current, err := s.ReadFileRecords(atomic, req.file, req.address, len(req.values))
if err != nil {
return err
}
repl, err := s.updateFiles(s, atomic, req.file, req.address, req.values, current)
err = s.WriteFileRecords(atomic, req.file, req.address, repl)
if err != nil {
return err
}
response.byte(0x06)
response.words(req.file, req.address, len(req.values))
response.words(repl...)
}
return nil
}