154 lines
3.6 KiB
Go
154 lines
3.6 KiB
Go
package axle_device
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"joylink.club/bj-rtsts-server/config"
|
|
"joylink.club/bj-rtsts-server/third_party/message"
|
|
"log/slog"
|
|
"runtime/debug"
|
|
"time"
|
|
)
|
|
|
|
//计轴设备与联锁系统安全通信应用层实现
|
|
|
|
type RsspAxle interface {
|
|
//Start 启动计轴设备与联锁系统安全通信服务
|
|
Start(amm AxleMessageManager) error
|
|
//Stop 停止计轴设备与联锁系统安全通信服务
|
|
Stop()
|
|
}
|
|
|
|
type rsspAxle struct {
|
|
//所属城市
|
|
city string
|
|
//所属线路
|
|
lineId string
|
|
//所属集中站
|
|
centralizedStation string
|
|
//主安全通道
|
|
masterRssp *RsspChannel
|
|
//备安全通道
|
|
slaveRssp *RsspChannel
|
|
//收到应用层消息回调
|
|
messageManager AxleMessageManager
|
|
//发送区段状态任务
|
|
cancelSendStatus context.CancelFunc
|
|
}
|
|
|
|
func InitRsspAxle(cfg *config.RsspAxleConfig) RsspAxle {
|
|
ra := &rsspAxle{}
|
|
//
|
|
ra.city = cfg.City
|
|
ra.lineId = cfg.LineId
|
|
ra.centralizedStation = cfg.CentralizedStation
|
|
//
|
|
cfgLen := len(cfg.RsspCfgs)
|
|
var masterConfig, slaveConfig *config.RsspConfig
|
|
if cfgLen >= 1 {
|
|
masterConfig = &cfg.RsspCfgs[0]
|
|
}
|
|
if cfgLen >= 2 {
|
|
slaveConfig = &cfg.RsspCfgs[1]
|
|
}
|
|
if masterConfig != nil {
|
|
mrc := &RsspChannel{}
|
|
ra.masterRssp = mrc.Init(masterConfig)
|
|
}
|
|
if slaveConfig != nil {
|
|
src := &RsspChannel{}
|
|
ra.slaveRssp = src.Init(slaveConfig)
|
|
}
|
|
//
|
|
return ra
|
|
}
|
|
|
|
// rssp 安全层执行
|
|
func (s *rsspAxle) rcvCmdMsg(data []byte) {
|
|
msg := &message.SectionCmdMsgPack{}
|
|
msg.Decode(data)
|
|
s.messageManager.HandleSectionCmdMsg(s.city, s.lineId, s.centralizedStation, msg)
|
|
}
|
|
func (s *rsspAxle) Start(amm AxleMessageManager) error {
|
|
s.messageManager = amm
|
|
//设置安全通道层
|
|
if s.masterRssp != nil {
|
|
s.masterRssp.handleUserData = s.rcvCmdMsg
|
|
s.masterRssp.Start()
|
|
}
|
|
if s.slaveRssp != nil {
|
|
s.slaveRssp.handleUserData = s.rcvCmdMsg
|
|
s.slaveRssp.Start()
|
|
}
|
|
//
|
|
sendContext, sendCancel := context.WithCancel(context.Background())
|
|
go s.doTaskSendStatus(sendContext)
|
|
s.cancelSendStatus = sendCancel
|
|
//
|
|
return nil
|
|
}
|
|
func (s *rsspAxle) Stop() {
|
|
if s.masterRssp != nil {
|
|
s.masterRssp.Stop()
|
|
}
|
|
if s.slaveRssp != nil {
|
|
s.slaveRssp.Stop()
|
|
}
|
|
//
|
|
if s.cancelSendStatus != nil {
|
|
s.cancelSendStatus()
|
|
}
|
|
if s.cancelSendStatus != nil {
|
|
s.cancelSendStatus()
|
|
}
|
|
s.messageManager = nil
|
|
}
|
|
func (s *rsspAxle) doTaskSendStatus(sendContext context.Context) {
|
|
defer func() {
|
|
if e := recover(); e != nil {
|
|
slog.Error(fmt.Sprintf("[%s-%s-%s]定时发送计轴区段状态任务异常", s.city, s.lineId, s.centralizedStation), "error", e, "stack", string(debug.Stack()))
|
|
debug.PrintStack()
|
|
}
|
|
}()
|
|
for {
|
|
select {
|
|
case <-sendContext.Done():
|
|
return
|
|
default:
|
|
}
|
|
if s.messageManager == nil {
|
|
slog.Warn(fmt.Sprintf("[%s-%s-%s]定时发送计轴区段状态任务因messageManager不存在退出", s.city, s.lineId, s.centralizedStation))
|
|
return
|
|
}
|
|
//收集区段状态
|
|
sectionStatusMsg, e := s.messageManager.CollectSectionStatus(s.city, s.lineId, s.centralizedStation)
|
|
if e == nil {
|
|
if sectionStatusMsg != nil {
|
|
msgPack := &message.SectionStatusMsgPack{}
|
|
msgPack.Ck = 0 //暂时无用
|
|
msgPack.Sms = sectionStatusMsg
|
|
s.sendStatusMsg(msgPack)
|
|
}
|
|
} else {
|
|
slog.Debug(e.Error())
|
|
}
|
|
//todo
|
|
time.Sleep(300 * time.Millisecond)
|
|
}
|
|
}
|
|
|
|
// 发送计轴区段状态给联锁
|
|
func (s *rsspAxle) sendStatusMsg(msg *message.SectionStatusMsgPack) {
|
|
data := msg.Encode()
|
|
//向备通道发送
|
|
if s.slaveRssp != nil {
|
|
data_s := make([]byte, len(data))
|
|
copy(data_s, data)
|
|
s.slaveRssp.sendUserData(data_s)
|
|
}
|
|
//向主通道发送
|
|
if s.masterRssp != nil {
|
|
s.masterRssp.sendUserData(data)
|
|
}
|
|
}
|