|
|
package handler
|
|
|
|
|
|
import (
|
|
|
"git.noahlan.cn/noahlan/ntool-biz/nmodbus/protocol"
|
|
|
"git.noahlan.cn/noahlan/ntool-biz/nmodbus/serialize"
|
|
|
"git.noahlan.cn/noahlan/ntool-biz/nmodbus/util"
|
|
|
)
|
|
|
|
|
|
// ReadHoldingRegisters 读保持寄存器(AI) 0x03
|
|
|
type ReadHoldingRegisters struct {
|
|
|
fnCode uint8
|
|
|
}
|
|
|
|
|
|
func NewReadHoldingRegisters(fnCode uint8) FunctionHandler {
|
|
|
return &ReadHoldingRegisters{fnCode: fnCode}
|
|
|
}
|
|
|
|
|
|
func (r *ReadHoldingRegisters) FnCode() uint8 {
|
|
|
return r.fnCode
|
|
|
}
|
|
|
|
|
|
// Function 读保持寄存器(AI) 功能码0x03
|
|
|
func (r *ReadHoldingRegisters) Function(s *Handler, req protocol.Packet, resp protocol.Packet) *protocol.MError {
|
|
|
register, numRegs, endRegister := serialize.RegisterAddressAndNumber(req.GetBody())
|
|
|
if endRegister > 65536 {
|
|
|
resp.SetBody([]byte{})
|
|
|
return &protocol.IllegalDataAddress
|
|
|
}
|
|
|
dataMgr := s.DataManager(req.GetAddress())
|
|
|
data := dataMgr.ReadHoldingRegisters(register, endRegister)
|
|
|
|
|
|
resp.SetBody(append([]byte{byte(numRegs * 2)}, util.Uint16ToBytes(s.byteOrder, data)...))
|
|
|
|
|
|
s.HandleLogic(r.fnCode, req, register, numRegs, data)
|
|
|
|
|
|
return &protocol.Success
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////// WriteHoldingRegister
|
|
|
|
|
|
// WriteHoldingRegister 写单个保持寄存器 功能码0x06
|
|
|
type WriteHoldingRegister struct {
|
|
|
fnCode uint8
|
|
|
}
|
|
|
|
|
|
func NewWriteHoldingRegister(fnCode uint8) FunctionHandler {
|
|
|
return &WriteHoldingRegister{fnCode: fnCode}
|
|
|
}
|
|
|
|
|
|
func (r *WriteHoldingRegister) FnCode() uint8 {
|
|
|
return r.fnCode
|
|
|
}
|
|
|
|
|
|
// Function 写单个保持寄存器 功能码0x06
|
|
|
func (r *WriteHoldingRegister) Function(s *Handler, req protocol.Packet, resp protocol.Packet) *protocol.MError {
|
|
|
data := req.GetBody()
|
|
|
register, value := serialize.RegisterAddressAndValue(data)
|
|
|
|
|
|
dataMgr := s.DataManager(req.GetAddress())
|
|
|
dataMgr.WriteSingleHoldingRegister(register, value)
|
|
|
|
|
|
resp.SetBody(data[0:4])
|
|
|
|
|
|
s.HandleLogic(r.fnCode, req, register, 1, value)
|
|
|
|
|
|
return &protocol.Success
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////// WriteHoldingRegisters
|
|
|
|
|
|
// WriteHoldingRegisters 写入 多个保持寄存器 功能码 0x10=16
|
|
|
type WriteHoldingRegisters struct {
|
|
|
fnCode uint8
|
|
|
}
|
|
|
|
|
|
func NewWriteHoldingRegisters(fnCode uint8) FunctionHandler {
|
|
|
return &WriteHoldingRegisters{fnCode: fnCode}
|
|
|
}
|
|
|
|
|
|
func (r *WriteHoldingRegisters) FnCode() uint8 {
|
|
|
return r.fnCode
|
|
|
}
|
|
|
|
|
|
// Function 写入 多个保持寄存器 功能码 0x10=16
|
|
|
func (r *WriteHoldingRegisters) Function(s *Handler, req protocol.Packet, resp protocol.Packet) *protocol.MError {
|
|
|
pkgData := req.GetBody()
|
|
|
register, numRegs, _ := serialize.RegisterAddressAndNumber(req.GetBody())
|
|
|
valueBytes := pkgData[5:]
|
|
|
var err *protocol.MError
|
|
|
var data []byte
|
|
|
|
|
|
if len(valueBytes)/2 != numRegs {
|
|
|
err = &protocol.IllegalDataAddress
|
|
|
}
|
|
|
|
|
|
// Copy data to memory
|
|
|
values := util.BytesToUint16(s.byteOrder, valueBytes)
|
|
|
dataMgr := s.DataManager(req.GetAddress())
|
|
|
|
|
|
valuesUpdated := dataMgr.WriteHoldingRegisters(values, register)
|
|
|
if valuesUpdated == numRegs {
|
|
|
err = &protocol.Success
|
|
|
data = pkgData[0:4]
|
|
|
} else {
|
|
|
err = &protocol.IllegalDataAddress
|
|
|
}
|
|
|
|
|
|
resp.SetBody(data)
|
|
|
|
|
|
s.HandleLogic(r.fnCode, req, register, numRegs, values)
|
|
|
|
|
|
return err
|
|
|
}
|