From 46e2baaa1e7f6eaac3ff615d21d214b6bb9a62c9 Mon Sep 17 00:00:00 2001 From: xzb <223@qq.com> Date: Wed, 22 Nov 2023 11:22:37 +0800 Subject: [PATCH] btm --- third_party/can_btm/balise_btm.go | 85 +++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/third_party/can_btm/balise_btm.go b/third_party/can_btm/balise_btm.go index ce4900d..cd03c63 100644 --- a/third_party/can_btm/balise_btm.go +++ b/third_party/can_btm/balise_btm.go @@ -5,6 +5,7 @@ import ( "joylink.club/bj-rtsts-server/third_party/message" "joylink.club/bj-rtsts-server/third_party/udp" "log/slog" + "sort" ) // btm与canet(网口-CAN口转换器) @@ -16,11 +17,27 @@ type btmCanetClient struct { localUdpPort int remoteUdpPort int remoteIp string + trainId string +} +type BtmCanetClient interface { + Start() + Stop() + TrainId() string +} +type BtmMessageManager interface { + BtmRcvAtpReqFrame(trainId string, atpReq *message.AtpRequestFrame) + BtmScanBaliseContent(trainId string) } +func NewBtmCanetClient(trainId string, remoteIp string, remoteUdpPort int, localUdpPort int) BtmCanetClient { + return &btmCanetClient{trainId: trainId, remoteIp: remoteIp, remoteUdpPort: remoteUdpPort, localUdpPort: localUdpPort} +} +func (s *btmCanetClient) TrainId() string { + return s.trainId +} func (s *btmCanetClient) Start() { // - s.udpServer = udp.NewServer(fmt.Sprintf(":%d", s.localUdpPort), s.handleCannetFrames) + s.udpServer = udp.NewServer(fmt.Sprintf(":%d", s.localUdpPort), s.handleCanetFrames) s.udpServer.Listen() // s.udpClient = udp.NewClient(fmt.Sprintf("%s:%d", s.remoteIp, s.remoteUdpPort)) @@ -34,16 +51,78 @@ func (s *btmCanetClient) Stop() { s.udpClient.Close() } } -func (s *btmCanetClient) handleCannetFrames(cfs []byte) { +func (s *btmCanetClient) handleCanetFrames(cfs []byte) { //一个cannet 帧 13字节 if len(cfs) > 0 && len(cfs)%13 == 0 { cfSum := len(cfs) / 13 + dms := make([]*message.CanetFrame, 0, 16) //13个应答器报文数据帧+TimeA帧+TimeB帧+结束帧 for cfi := 0; cfi < cfSum; cfi++ { cfStart := cfi * 13 cf := message.NewCanetFrame(cfs[cfStart : cfStart+13]) - fmt.Println(cf.String()) + // + switch cf.CanFrameType() { + case message.CfReq: + s.dealWithAptReq(cf) + case message.CfStatusRsp: + s.dealWithBtmStatusRsp(cf) + case message.CfTimeSync: + s.dealWithBtmTimeSyncRsp(cf) + case message.CfMsg: + fallthrough + case message.CfMsgTimeA: + fallthrough + case message.CfMsgTimeB: + fallthrough + case message.CfMsgEnd: + dms = append(dms, cf) + default: + slog.Warn("CanetFrame帧没有具体对应的应用帧", "CannetFrame", cf.String()) + } //switch + } //for + //将数据包按ID3即0x80+offset由小到大排序 + sort.SliceStable(dms, func(i, j int) bool { + return dms[i].CanId.ID3 < dms[j].CanId.ID3 + }) + //有数据帧,但是不足16帧 + if len(dms) > 0 { + if len(dms) != 16 { + slog.Warn("接收到数据帧,但数据帧数量不足16帧") + } else { + s.dealWithBtmDataFrames(dms) + } } + } else { slog.Warn("从cannet接收数据,未满足条件‘len(cfs) > 0 && len(cfs)%13 == 0‘", "len(cfs)", len(cfs)) } } + +// 处理接收的ATP查询请求帧 +func (s *btmCanetClient) dealWithAptReq(f *message.CanetFrame) { + atpReq := &message.AtpRequestFrame{} + if !atpReq.Decode(f) { + slog.Warn("CanetFrame解码成AtpRequestFrame失败", "CanetFrame", f.String()) + } + //处理查询请求 + slog.Debug(fmt.Sprintf("处理查询请求:%s", atpReq.String())) + //todo +} + +////////////////////////////////////////////////////////////////////////////////////////// + +// 处理接收的状态应答帧 +func (s *btmCanetClient) dealWithBtmStatusRsp(f *message.CanetFrame) { + slog.Debug(fmt.Sprintf("接收到状态应答帧%s", f.String())) +} + +// 处理接收的时间同步校验应答帧 +func (s *btmCanetClient) dealWithBtmTimeSyncRsp(f *message.CanetFrame) { + slog.Debug(fmt.Sprintf("接收到时间同步校验应答帧%s", f.String())) +} + +// 处理接收到的16帧数据帧 +func (s *btmCanetClient) dealWithBtmDataFrames(dms []*message.CanetFrame) { + for _, dm := range dms { + slog.Debug(fmt.Sprintf("接收到数据帧%s", dm.String())) + } +}