rts-sim-testing-service/third_party/interlock/beijing11/interlock.go

127 lines
3.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package beijing11 北京11号线联锁通信
package beijing11
import (
"fmt"
"joylink.club/bj-rtsts-server/config"
"joylink.club/bj-rtsts-server/third_party/udp"
"log/slog"
"sync"
)
var (
initMutex = sync.Mutex{}
interlockMap = make(map[string]*InterlockProxy)
logTag = "[北京11号线联锁通信]"
)
func GetInstant(c *config.InterlockConfig, msgManager MsgManager) *InterlockProxy {
initMutex.Lock()
defer initMutex.Unlock()
if interlockMap[c.Code] == nil {
interlockMap[c.Code] = &InterlockProxy{runConfig: c, msgManager: msgManager}
}
return interlockMap[c.Code]
}
type MsgManager interface {
HandleReadRegisterMsg(req *ReadRegisterReq) (*ReadRegisterRes, error)
HandleWriteRegisterMsg(req *WriteRegisterReq) error
HandleDownstreamMsg(data []byte) error
CollectUpstreamMsg() []byte
}
type msgManager struct {
}
type InterlockProxy struct {
runConfig *config.InterlockConfig //联锁通信配置
msgManager MsgManager //消息获取与处理接口0
client udp.UdpClient //向上位机发送数据的UDP客户端
server udp.UdpServer //接收上位机数据的UDP服务端
running bool //此服务正在运行的标志
}
func (i *InterlockProxy) Start() {
if i.runConfig == nil || i.runConfig.Ip == "" || !i.runConfig.Open {
return
}
if i.running {
panic("启动联锁消息服务错误: 存在正在运行的任务")
}
//UDP通信设施
i.server = udp.NewServer(fmt.Sprintf(":%d", i.runConfig.LocalPort), i.handleUpperData)
err := i.server.Listen()
if err != nil {
panic("启动联锁消息服务错误无法启动UDP服务")
}
i.running = true
i.client = udp.NewClient(fmt.Sprintf("%v:%v", i.runConfig.Ip, i.runConfig.RemotePort))
}
// 处理来自上位机的数据
func (i *InterlockProxy) handleUpperData(data []byte) {
baseData := &BaseStruct{}
err := baseData.Decode(data)
if err != nil {
slog.Error(logTag + "数据解析出错:" + err.Error())
return
}
switch baseData.ControlWord {
case ControlWord.ReadRegister:
req := &ReadRegisterReq{}
err := req.Decode(baseData.Data)
if err != nil {
slog.Error(logTag + "读寄存器数据解析出错:" + err.Error())
return
}
res, err := i.msgManager.HandleReadRegisterMsg(req)
if err != nil {
slog.Error(logTag + "读寄存器数据处理出错:" + err.Error())
return
}
resData := &BaseStruct{
ID: baseData.ID,
ControlWord: ControlWord.Response,
Data: res.Encode(),
}
i.SendToUpper(resData.Encode())
case ControlWord.WriteRegister:
req := &WriteRegisterReq{}
err := req.Decode(baseData.Data)
if err != nil {
slog.Error(logTag + "写寄存器数据解析出错:" + err.Error())
return
}
err = i.msgManager.HandleWriteRegisterMsg(req)
if err != nil {
slog.Error(logTag + "写寄存器数据处理出错:" + err.Error())
return
}
case ControlWord.DownStream:
err = i.msgManager.HandleDownstreamMsg(baseData.Data)
if err != nil {
slog.Error(logTag + "下行数据处理出错:" + err.Error())
return
}
}
}
func (i *InterlockProxy) SendToUpper(data []byte) {
err := i.client.Send(data)
slog.Error(logTag + "向上位机发送数据失败:" + err.Error())
}
func (i *InterlockProxy) Stop() {
initMutex.Lock()
defer initMutex.Unlock()
delete(interlockMap, i.runConfig.Code)
if i.client != nil {
i.client.Close()
}
if i.server != nil {
i.server.Close()
}
i.running = false
}