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" "sync" ) var _ rt.Handler = (*Handler)(nil) type ( Handler struct { byteOrder binary.ByteOrder // 字节序 functions map[uint8]FunctionHandler dataMap map[uint8]*DataMgr mu sync.RWMutex } 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), dataMap: make(map[uint8]*DataMgr), mu: sync.RWMutex{}, } // 添加功能码对应功能 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) DataManager(address uint8) *DataMgr { p.mu.Lock() defer p.mu.Unlock() ret, ok := p.dataMap[address] if !ok { ret = NewDataManager(address) p.dataMap[address] = ret } return ret } 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()) }