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

127 lines
3.4 KiB
Go
Raw Normal View History

2024-05-13 13:17:16 +08:00
// 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
}