You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
1.9 KiB
Go
82 lines
1.9 KiB
Go
1 year ago
|
package handler
|
||
|
|
||
|
import (
|
||
|
"encoding/binary"
|
||
|
"git.noahlan.cn/noahlan/nnet/connection"
|
||
|
"git.noahlan.cn/noahlan/nnet/packet"
|
||
|
rt "git.noahlan.cn/noahlan/nnet/router"
|
||
|
"git.noahlan.cn/noahlan/ntool-biz/nmodbus/protocol"
|
||
|
"git.noahlan.cn/noahlan/ntool/nlog"
|
||
|
)
|
||
|
|
||
|
var _ rt.Handler = (*Handler)(nil)
|
||
|
|
||
|
type (
|
||
|
Handler struct {
|
||
|
byteOrder binary.ByteOrder // 字节序
|
||
|
|
||
|
functions map[uint8]FunctionHandler
|
||
|
|
||
|
DiscreteInputs []byte // 离散输入
|
||
|
Coils []byte // 线圈
|
||
|
HoldingRegisters []uint16 // 保持寄存器
|
||
|
InputRegisters []uint16 // 输入寄存器
|
||
|
}
|
||
|
|
||
|
FunctionHandler func(handler *Handler, pkg protocol.Packet) ([]byte, *protocol.MError)
|
||
|
)
|
||
|
|
||
|
func NewHandler(byteOrder binary.ByteOrder) *Handler {
|
||
|
p := &Handler{
|
||
|
byteOrder: byteOrder,
|
||
|
functions: make(map[uint8]FunctionHandler),
|
||
|
DiscreteInputs: make([]byte, 65536),
|
||
|
Coils: make([]byte, 65536),
|
||
|
HoldingRegisters: make([]uint16, 65536),
|
||
|
InputRegisters: make([]uint16, 65536),
|
||
|
}
|
||
|
|
||
|
// 添加功能码对应功能
|
||
|
p.functions[0x01] = ReadCoils
|
||
|
p.functions[0x02] = ReadDiscreteInputs
|
||
|
p.functions[0x03] = ReadHoldingRegisters
|
||
|
p.functions[0x04] = ReadInputRegisters
|
||
|
p.functions[0x05] = WriteSingleCoil
|
||
|
p.functions[0x06] = WriteHoldingRegister
|
||
|
p.functions[0x0F] = WriteMultipleCoils
|
||
|
p.functions[0x10] = WriteHoldingRegisters
|
||
|
|
||
|
return p
|
||
|
}
|
||
|
|
||
|
func (p *Handler) RegisterFunction(fnCode uint8, fn FunctionHandler) {
|
||
|
p.functions[fnCode] = fn
|
||
|
}
|
||
|
|
||
|
func (p *Handler) Handle(conn *connection.Connection, pkg packet.IPacket) {
|
||
|
pp, ok := pkg.(protocol.Packet)
|
||
|
if !ok {
|
||
|
nlog.Error(packet.ErrWrongPacketType)
|
||
|
}
|
||
|
var (
|
||
|
err *protocol.MError
|
||
|
data []byte
|
||
|
)
|
||
|
|
||
|
resp := pp.Copy()
|
||
|
|
||
|
fnCode := pp.GetFunction()
|
||
|
fn, ok := p.functions[fnCode]
|
||
|
if ok {
|
||
|
data, err = fn(p, pp)
|
||
|
resp.SetBody(data)
|
||
|
} else {
|
||
|
err = &protocol.IllegalFunction
|
||
|
}
|
||
|
|
||
|
if err != &protocol.Success {
|
||
|
resp.SetError(err)
|
||
|
}
|
||
|
_ = conn.Send(resp.GetHeader(), resp.GetBody())
|
||
|
}
|