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 //接收方每个安全通信会话对应的发送周期值,单位ms sendingPeriod uint32 //主安全通道 rsspChannel *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 ra.sendingPeriod = cfg.RsspCfg.SendingPeriod // mrc := &RsspChannel{} ra.rsspChannel = mrc.Init(&cfg.RsspCfg) // 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.rsspChannel != nil { s.rsspChannel.handleUserData = s.rcvCmdMsg s.rsspChannel.Start() } // sendContext, sendCancel := context.WithCancel(context.Background()) go s.periodRun(sendContext) s.cancelSendStatus = sendCancel // return nil } func (s *rsspAxle) Stop() { if s.rsspChannel != nil { s.rsspChannel.Stop() } // if s.cancelSendStatus != nil { s.cancelSendStatus() } s.messageManager = nil } func (s *rsspAxle) periodRun(runContext context.Context) { time.Sleep(2 * time.Second) 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 <-runContext.Done(): return default: } //slog.Debug("计轴设备periodRun") 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.Warn(e.Error()) } // time.Sleep(time.Duration(s.sendingPeriod) * time.Millisecond) //更新周期性参数 s.rsspChannel.NextPeriod() } } // 发送计轴区段状态给联锁 func (s *rsspAxle) sendStatusMsg(msg *message.SectionStatusMsgPack) { data := msg.Encode() //向主通道发送 if s.rsspChannel != nil { //slog.Debug("计轴设备发送SectionStatusMsgPack", "区段状态个数", len(msg.Sms), "packLen", len(data)) s.rsspChannel.SendUserData(data) } }