2023-11-21 18:13:50 +08:00
|
|
|
|
package can_btm
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
2023-11-24 15:20:05 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/config"
|
2024-02-06 16:39:56 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/const/balise_const"
|
|
|
|
|
"joylink.club/bj-rtsts-server/dto/state_proto"
|
2023-11-21 18:13:50 +08:00
|
|
|
|
"joylink.club/bj-rtsts-server/third_party/message"
|
|
|
|
|
"joylink.club/bj-rtsts-server/third_party/udp"
|
2023-12-05 09:37:34 +08:00
|
|
|
|
"joylink.club/ecs"
|
|
|
|
|
"joylink.club/rtsssimulation/entity"
|
2023-11-21 18:13:50 +08:00
|
|
|
|
"log/slog"
|
2023-11-22 11:22:37 +08:00
|
|
|
|
"sort"
|
2024-02-06 16:39:56 +08:00
|
|
|
|
"strings"
|
2023-11-24 15:20:05 +08:00
|
|
|
|
"sync"
|
|
|
|
|
"time"
|
2023-11-21 18:13:50 +08:00
|
|
|
|
)
|
|
|
|
|
|
2023-11-24 15:20:05 +08:00
|
|
|
|
//使用:当有多个虚拟车时,同一时刻只有一个虚拟车与CANET关联
|
|
|
|
|
|
|
|
|
|
// BtmCanetManager BTM CANET 管理器
|
|
|
|
|
type BtmCanetManager interface {
|
2023-12-05 09:37:34 +08:00
|
|
|
|
EvnWorld() ecs.World
|
2023-11-24 15:20:05 +08:00
|
|
|
|
//GetBtmCanetConfig 获取CANET配置信息
|
|
|
|
|
GetBtmCanetConfig() config.BtmCanetConfig
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-21 18:13:50 +08:00
|
|
|
|
// btm与canet(网口-CAN口转换器)
|
|
|
|
|
type btmCanetClient struct {
|
2023-11-24 15:20:05 +08:00
|
|
|
|
bcm BtmCanetManager
|
2023-11-23 16:30:48 +08:00
|
|
|
|
//udp server
|
2023-11-21 18:13:50 +08:00
|
|
|
|
udpServer udp.UdpServer
|
2023-11-23 16:30:48 +08:00
|
|
|
|
//udp client
|
|
|
|
|
udpClient udp.UdpClient
|
|
|
|
|
//udp 本地侦听端口
|
|
|
|
|
localUdpPort int
|
|
|
|
|
//udp 远程端口
|
2023-11-21 18:13:50 +08:00
|
|
|
|
remoteUdpPort int
|
2023-11-23 16:30:48 +08:00
|
|
|
|
//udp 远程ip
|
|
|
|
|
remoteIp string
|
|
|
|
|
//最近一次车载ATP系统查询帧序号
|
|
|
|
|
atpReqSn byte
|
2023-11-30 09:57:20 +08:00
|
|
|
|
//btm最近一次接收到atp查询请求的时间
|
|
|
|
|
//当BTM超过150ms即3个周期没有收到atq下发的查询帧,则清空报文缓冲区
|
|
|
|
|
atpReqTime *time.Time
|
2023-11-24 15:20:05 +08:00
|
|
|
|
//最近一次车载ATP系统查询帧CRC16校验结果,true-校验通过
|
2023-11-23 16:30:48 +08:00
|
|
|
|
atpReqCrc16Check bool
|
2023-11-24 15:20:05 +08:00
|
|
|
|
//btm系统时间,每次接收到ATP查询请求帧时同步一次时间
|
2024-04-02 18:20:10 +08:00
|
|
|
|
btmTime BtmClock
|
2023-11-24 15:20:05 +08:00
|
|
|
|
//数据流水号
|
|
|
|
|
dsn byte
|
2023-11-24 16:01:28 +08:00
|
|
|
|
//重发的数据
|
|
|
|
|
resendData *resendData
|
2023-12-05 09:37:34 +08:00
|
|
|
|
//车载BTM天线,探测应答器
|
|
|
|
|
baliseDetector *BaliseDetector
|
2023-11-24 15:20:05 +08:00
|
|
|
|
}
|
2024-02-06 16:39:56 +08:00
|
|
|
|
|
2024-08-05 16:32:21 +08:00
|
|
|
|
func (s *btmCanetClient) FindNotSendState() (state_proto.BTMState, bool) {
|
|
|
|
|
s.baliseDetector.eqLock.Lock()
|
|
|
|
|
defer s.baliseDetector.eqLock.Unlock()
|
2024-02-06 16:39:56 +08:00
|
|
|
|
detector := s.baliseDetector
|
2024-08-05 16:32:21 +08:00
|
|
|
|
for _, info := range detector.eq {
|
|
|
|
|
if info != nil && !info.IsSend {
|
|
|
|
|
info.IsSend = true
|
|
|
|
|
return s.getStateFromDeta(info, uint32(detector.baliseCounter), uint32(detector.messageCounter), detector.aboveBalise), true
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return state_proto.BTMState{}, false
|
|
|
|
|
}
|
2024-04-02 18:20:10 +08:00
|
|
|
|
|
2024-08-05 16:32:21 +08:00
|
|
|
|
/*
|
|
|
|
|
func (s *btmCanetClient) GetAllData() {
|
|
|
|
|
detector := s.baliseDetector
|
|
|
|
|
for _, info := range detector.eq {
|
|
|
|
|
slog.Info("获取应答器信息 id:%v,是否发送:%v", info.BaliseId)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
func (s *btmCanetClient) getStateFromDeta(info *BtmAntennaScanningBaliseInfo, bc, mc uint32, aboveBalise bool) state_proto.BTMState {
|
2024-02-06 16:39:56 +08:00
|
|
|
|
var telegram string
|
2024-07-25 14:55:46 +08:00
|
|
|
|
var tel128 string
|
2024-08-05 16:32:21 +08:00
|
|
|
|
var dis int64
|
|
|
|
|
var baliseId string
|
|
|
|
|
|
2024-02-21 14:54:17 +08:00
|
|
|
|
if /*detector.aboveBalise &&*/ info != nil && len(info.telegram) != 0 {
|
2024-02-06 16:39:56 +08:00
|
|
|
|
telegram = fmt.Sprintf("%X", info.telegram)
|
2024-07-25 14:55:46 +08:00
|
|
|
|
tel128 = fmt.Sprintf("%X", info.telegram128)
|
2024-08-05 16:32:21 +08:00
|
|
|
|
dis = info.Distance
|
|
|
|
|
baliseId = info.BaliseId
|
2024-02-06 16:39:56 +08:00
|
|
|
|
} else {
|
|
|
|
|
telegram = strings.Repeat("00", balise_const.UserTelegramByteLen)
|
2024-07-25 14:55:46 +08:00
|
|
|
|
tel128 = strings.Repeat("00", balise_const.TelegramByteLen)
|
2024-02-06 16:39:56 +08:00
|
|
|
|
}
|
2024-08-05 16:32:21 +08:00
|
|
|
|
|
2024-02-06 16:39:56 +08:00
|
|
|
|
return state_proto.BTMState{
|
2024-08-05 16:32:21 +08:00
|
|
|
|
BaliseId: baliseId,
|
2024-02-06 16:39:56 +08:00
|
|
|
|
DataSerialNumber: uint32(s.dsn),
|
2024-08-05 16:32:21 +08:00
|
|
|
|
BaliseCount: bc,
|
|
|
|
|
MessageCounter: mc,
|
2024-02-06 16:39:56 +08:00
|
|
|
|
Telegram: telegram,
|
2024-07-25 14:55:46 +08:00
|
|
|
|
Telegram128: tel128,
|
2024-04-09 08:55:33 +08:00
|
|
|
|
Distance: dis,
|
2024-08-05 16:32:21 +08:00
|
|
|
|
AboveBalise: aboveBalise,
|
2024-02-06 16:39:56 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-08-05 16:32:21 +08:00
|
|
|
|
func (s *btmCanetClient) GetState() state_proto.BTMState {
|
|
|
|
|
detector := s.baliseDetector
|
|
|
|
|
info := detector.eq[len(detector.eq)-1]
|
|
|
|
|
return s.getStateFromDeta(info, uint32(detector.baliseCounter), uint32(detector.messageCounter), detector.aboveBalise)
|
|
|
|
|
|
|
|
|
|
}
|
2024-02-06 16:39:56 +08:00
|
|
|
|
|
2024-04-02 18:20:10 +08:00
|
|
|
|
type BtmClock struct {
|
|
|
|
|
BtmTk uint32 //与ATP系统同步的时间ms
|
|
|
|
|
SysTk time.Time //本地系统时间
|
2023-11-22 11:22:37 +08:00
|
|
|
|
}
|
2023-11-24 15:20:05 +08:00
|
|
|
|
|
|
|
|
|
// 获取以btmTk为基准的当前时间ms
|
2024-04-02 18:20:10 +08:00
|
|
|
|
func (c *BtmClock) TkNow() uint32 {
|
|
|
|
|
return c.BtmTk + uint32(time.Now().UnixMilli()-c.SysTk.UnixMilli())
|
2023-11-24 15:20:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-22 11:22:37 +08:00
|
|
|
|
type BtmCanetClient interface {
|
2023-11-24 15:20:05 +08:00
|
|
|
|
Start(bcm BtmCanetManager)
|
2023-11-22 11:22:37 +08:00
|
|
|
|
Stop()
|
2023-12-05 09:37:34 +08:00
|
|
|
|
//HandleTrainHeadPositionInfo 处理收到列车位置信息
|
2024-06-06 17:57:30 +08:00
|
|
|
|
HandleTrainHeadPositionInfo(w ecs.World, vobcBtm *state_proto.VobcBtmState, h *TrainHeadPositionInfo)
|
2024-08-13 09:09:25 +08:00
|
|
|
|
// GetState 获取BTM显示状态 + btm最新的状态
|
|
|
|
|
//
|
|
|
|
|
// Deprecated 请从列车的btmBaliseCache中获取
|
2024-02-06 16:39:56 +08:00
|
|
|
|
GetState() state_proto.BTMState
|
2024-08-05 16:32:21 +08:00
|
|
|
|
//GetAllData()
|
|
|
|
|
FindNotSendState() (state_proto.BTMState, bool)
|
2023-11-22 11:22:37 +08:00
|
|
|
|
}
|
2023-11-21 18:13:50 +08:00
|
|
|
|
|
2023-11-24 15:20:05 +08:00
|
|
|
|
var (
|
|
|
|
|
btmClientLocker sync.Mutex
|
|
|
|
|
btmClient BtmCanetClient
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func Default() BtmCanetClient {
|
|
|
|
|
defer btmClientLocker.Unlock()
|
2024-06-06 17:57:30 +08:00
|
|
|
|
btmClientLocker.Lock()
|
2023-11-24 15:20:05 +08:00
|
|
|
|
if btmClient == nil {
|
2023-12-05 09:37:34 +08:00
|
|
|
|
btmClient = &btmCanetClient{baliseDetector: &BaliseDetector{}}
|
2023-11-24 15:20:05 +08:00
|
|
|
|
}
|
|
|
|
|
return btmClient
|
2023-11-22 11:22:37 +08:00
|
|
|
|
}
|
2023-12-05 11:24:43 +08:00
|
|
|
|
|
|
|
|
|
// HandleTrainHeadPositionInfo 处理来自动力学的列车位置信息
|
2024-06-06 17:57:30 +08:00
|
|
|
|
func (s *btmCanetClient) HandleTrainHeadPositionInfo(w ecs.World, vobcBtm *state_proto.VobcBtmState, h *TrainHeadPositionInfo) {
|
2023-12-05 09:37:34 +08:00
|
|
|
|
//slog.Debug(h.String())
|
|
|
|
|
wd := entity.GetWorldData(w)
|
|
|
|
|
repo := wd.Repo
|
2024-08-05 16:32:21 +08:00
|
|
|
|
|
|
|
|
|
//s.baliseDetector.detect(wd, repo, h, vobcBtm)
|
|
|
|
|
h2 := &TrainHeadPositionInfo{
|
|
|
|
|
TrainId: h.TrainId,
|
|
|
|
|
Up: h.Up,
|
|
|
|
|
Link: h.OldLink,
|
|
|
|
|
LinkOffset: h.OldLinkOffset,
|
|
|
|
|
Speed: h.Speed,
|
|
|
|
|
Acceleration: h.Acceleration}
|
|
|
|
|
s.baliseDetector.detect2(wd, repo, h, h2, vobcBtm)
|
2023-12-05 09:37:34 +08:00
|
|
|
|
}
|
2023-11-24 15:20:05 +08:00
|
|
|
|
func (s *btmCanetClient) Start(bcm BtmCanetManager) {
|
|
|
|
|
s.bcm = bcm
|
|
|
|
|
cfg := s.bcm.GetBtmCanetConfig()
|
2023-11-27 09:14:20 +08:00
|
|
|
|
//测试用
|
2023-11-28 13:30:10 +08:00
|
|
|
|
//cfg.Open = true
|
|
|
|
|
//cfg.RemoteUdpPort = 5555
|
|
|
|
|
//cfg.RemoteIp = "192.168.3.5"
|
|
|
|
|
//cfg.LocalUdpPort = 6666
|
2023-11-27 09:14:20 +08:00
|
|
|
|
//
|
2023-11-24 15:20:05 +08:00
|
|
|
|
if !cfg.Open {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
s.localUdpPort = cfg.LocalUdpPort
|
|
|
|
|
s.remoteIp = cfg.RemoteIp
|
|
|
|
|
s.remoteUdpPort = cfg.RemoteUdpPort
|
2023-11-21 18:13:50 +08:00
|
|
|
|
//
|
2023-11-22 11:22:37 +08:00
|
|
|
|
s.udpServer = udp.NewServer(fmt.Sprintf(":%d", s.localUdpPort), s.handleCanetFrames)
|
2023-11-21 18:13:50 +08:00
|
|
|
|
s.udpServer.Listen()
|
|
|
|
|
//
|
|
|
|
|
s.udpClient = udp.NewClient(fmt.Sprintf("%s:%d", s.remoteIp, s.remoteUdpPort))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *btmCanetClient) Stop() {
|
|
|
|
|
if s.udpServer != nil {
|
|
|
|
|
s.udpServer.Close()
|
2023-11-24 15:20:05 +08:00
|
|
|
|
s.udpServer = nil
|
2023-11-21 18:13:50 +08:00
|
|
|
|
}
|
|
|
|
|
if s.udpClient != nil {
|
|
|
|
|
s.udpClient.Close()
|
2023-11-24 15:20:05 +08:00
|
|
|
|
s.udpClient = nil
|
2023-11-21 18:13:50 +08:00
|
|
|
|
}
|
2024-08-05 16:32:21 +08:00
|
|
|
|
for d := range s.baliseDetector.eq {
|
|
|
|
|
s.baliseDetector.eq[d] = nil
|
|
|
|
|
}
|
2023-11-21 18:13:50 +08:00
|
|
|
|
}
|
2023-11-22 11:22:37 +08:00
|
|
|
|
func (s *btmCanetClient) handleCanetFrames(cfs []byte) {
|
2023-11-29 14:10:25 +08:00
|
|
|
|
defer func() {
|
|
|
|
|
if e := recover(); e != nil {
|
|
|
|
|
slog.Debug(fmt.Sprintf("handleCanetFrames异常[%s]", e))
|
|
|
|
|
}
|
|
|
|
|
}()
|
2023-11-21 18:13:50 +08:00
|
|
|
|
//一个cannet 帧 13字节
|
|
|
|
|
if len(cfs) > 0 && len(cfs)%13 == 0 {
|
|
|
|
|
cfSum := len(cfs) / 13
|
2023-11-22 11:22:37 +08:00
|
|
|
|
dms := make([]*message.CanetFrame, 0, 16) //13个应答器报文数据帧+TimeA帧+TimeB帧+结束帧
|
2023-11-21 18:13:50 +08:00
|
|
|
|
for cfi := 0; cfi < cfSum; cfi++ {
|
|
|
|
|
cfStart := cfi * 13
|
2024-07-25 14:55:46 +08:00
|
|
|
|
cf := message.NewCanetFrame(cfs[cfStart : cfStart+13])
|
2023-11-22 11:22:37 +08:00
|
|
|
|
//
|
|
|
|
|
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)
|
|
|
|
|
}
|
2023-11-21 18:13:50 +08:00
|
|
|
|
}
|
2023-11-22 11:22:37 +08:00
|
|
|
|
|
2023-11-21 18:13:50 +08:00
|
|
|
|
} else {
|
|
|
|
|
slog.Warn("从cannet接收数据,未满足条件‘len(cfs) > 0 && len(cfs)%13 == 0‘", "len(cfs)", len(cfs))
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-22 11:22:37 +08:00
|
|
|
|
|
|
|
|
|
// 处理接收的ATP查询请求帧
|
|
|
|
|
func (s *btmCanetClient) dealWithAptReq(f *message.CanetFrame) {
|
2023-11-30 09:57:20 +08:00
|
|
|
|
now := time.Now()
|
2023-11-22 11:22:37 +08:00
|
|
|
|
atpReq := &message.AtpRequestFrame{}
|
|
|
|
|
if !atpReq.Decode(f) {
|
|
|
|
|
slog.Warn("CanetFrame解码成AtpRequestFrame失败", "CanetFrame", f.String())
|
2023-11-23 16:30:48 +08:00
|
|
|
|
return
|
2023-11-22 11:22:37 +08:00
|
|
|
|
}
|
|
|
|
|
//处理查询请求
|
2023-11-27 15:09:10 +08:00
|
|
|
|
//slog.Debug(fmt.Sprintf("处理查询请求:%s", atpReq.String()))
|
2023-11-23 16:30:48 +08:00
|
|
|
|
//
|
2024-04-02 18:20:10 +08:00
|
|
|
|
s.btmTime.BtmTk = atpReq.Time
|
|
|
|
|
s.btmTime.SysTk = now
|
2023-11-23 16:30:48 +08:00
|
|
|
|
s.atpReqSn = atpReq.FId.ID4
|
|
|
|
|
s.atpReqCrc16Check = atpReq.Crc16CheckOk
|
2023-12-05 10:57:31 +08:00
|
|
|
|
s.baliseDetector.powerAmplifierSwitch = atpReq.PowerAmplifierTurnOn
|
2023-11-30 09:57:20 +08:00
|
|
|
|
//记录atp查询时间
|
|
|
|
|
s.atpReqTime = &now
|
2023-12-05 09:37:34 +08:00
|
|
|
|
//ATP 是否要求BTM 重发上一应答器报文
|
|
|
|
|
isResendRequest := atpReq.ResendRequest == 2 //0b10
|
|
|
|
|
if isResendRequest {
|
|
|
|
|
s.rspResendToAtp()
|
|
|
|
|
} else {
|
2023-12-05 13:49:22 +08:00
|
|
|
|
sb := s.baliseDetector.doScan()
|
2023-12-05 09:37:34 +08:00
|
|
|
|
if sb != nil {
|
|
|
|
|
slog.Debug(fmt.Sprintf("BTM经过应答器[%s],BTM与ATP时间差[%d]ms", sb.BaliseId, time.Now().UnixMilli()-sb.Time.UnixMilli()))
|
|
|
|
|
s.rspToAtp(sb)
|
2023-12-05 10:57:31 +08:00
|
|
|
|
} else {
|
|
|
|
|
s.rspToAtp(nil)
|
2023-12-05 09:37:34 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *btmCanetClient) createTrainBtmStatus() *TrainBtmStatus {
|
|
|
|
|
return &TrainBtmStatus{
|
2023-12-05 10:57:31 +08:00
|
|
|
|
PowerAmplifierOn: s.baliseDetector.powerAmplifierSwitch,
|
2023-12-05 09:37:34 +08:00
|
|
|
|
PowerAmplifierFault: false,
|
2023-12-05 10:57:31 +08:00
|
|
|
|
AboveBalise: s.baliseDetector.aboveBalise,
|
2023-12-05 09:37:34 +08:00
|
|
|
|
AntennaFault: false,
|
2023-12-05 10:57:31 +08:00
|
|
|
|
BaliseCounter: s.baliseDetector.baliseCounter,
|
|
|
|
|
MessageCounter: s.baliseDetector.messageCounter,
|
2023-12-05 09:37:34 +08:00
|
|
|
|
}
|
2023-11-22 11:22:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-23 18:14:01 +08:00
|
|
|
|
// BTM发送响应给ATP
|
|
|
|
|
// 当收到应答器报文时响应:时间同步帧、状态应答帧、数据帧
|
|
|
|
|
// 当未收到应答器报文时响应:时间同步帧、状态应答帧
|
2023-12-05 09:37:34 +08:00
|
|
|
|
func (s *btmCanetClient) rspResendToAtp() {
|
2023-11-24 16:01:28 +08:00
|
|
|
|
//重发上一报文处理
|
2023-12-05 09:37:34 +08:00
|
|
|
|
if s.resendData != nil && s.resendData.canResend() {
|
2023-11-24 16:01:28 +08:00
|
|
|
|
s.resendData.countAdd1()
|
|
|
|
|
s.sendCanetFrame(s.resendData.data)
|
|
|
|
|
return
|
|
|
|
|
}
|
2023-12-05 09:37:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// BTM发送响应给ATP
|
|
|
|
|
// 当收到应答器报文时响应:时间同步帧、状态应答帧、数据帧
|
|
|
|
|
// 当未收到应答器报文时响应:时间同步帧、状态应答帧
|
|
|
|
|
func (s *btmCanetClient) rspToAtp(sb *BtmAntennaScanningBaliseInfo) {
|
2023-11-24 15:20:05 +08:00
|
|
|
|
//BTM状态
|
2024-07-25 14:55:46 +08:00
|
|
|
|
statusF := message.NewBtmStatusRspFrame(s.atpReqSn)
|
2023-12-05 09:37:34 +08:00
|
|
|
|
btmStatus := s.createTrainBtmStatus()
|
|
|
|
|
|
2023-11-24 15:20:05 +08:00
|
|
|
|
statusF.AntennaFault = btmStatus.AntennaFault
|
|
|
|
|
statusF.BaliseCounter = byte(btmStatus.BaliseCounter)
|
|
|
|
|
statusF.MessageCounter = byte(btmStatus.MessageCounter)
|
|
|
|
|
statusF.PowerAmplifierOn = btmStatus.PowerAmplifierOn
|
2024-04-02 18:20:10 +08:00
|
|
|
|
statusF.TkTimeA = s.btmTime.TkNow()
|
2023-11-24 15:20:05 +08:00
|
|
|
|
statusF.PowerAmplifierFailure = btmStatus.PowerAmplifierFault
|
|
|
|
|
statusF.DetailedCode = 0
|
|
|
|
|
if btmStatus.AboveBalise {
|
|
|
|
|
statusF.DetailedCode = 0x07
|
|
|
|
|
}
|
|
|
|
|
statusF.AtpReqCrcCheckWrong = !s.atpReqCrc16Check
|
|
|
|
|
statusF.Dsn = s.dsn
|
2024-04-02 18:20:10 +08:00
|
|
|
|
|
2023-11-24 15:20:05 +08:00
|
|
|
|
s.dsnAdd1()
|
|
|
|
|
//
|
2023-11-23 18:14:01 +08:00
|
|
|
|
//true-收到应答器报文
|
2023-12-05 10:57:31 +08:00
|
|
|
|
isRcvTelegram := sb != nil && len(sb.telegram) > 0
|
2023-11-23 18:14:01 +08:00
|
|
|
|
if isRcvTelegram { //当收到应答器报文时响应:时间同步帧、状态应答帧、数据帧
|
2024-07-25 14:55:46 +08:00
|
|
|
|
statusDataCf, statusDataCfOk := message.CreateBtmRspFramesData(statusF, sb.telegram, false, s.btmTime.TkNow(), s.btmTime.TkNow(), s.btmTime.TkNow())
|
2023-11-24 15:20:05 +08:00
|
|
|
|
if statusDataCfOk {
|
2024-07-25 14:55:46 +08:00
|
|
|
|
timeSyncF := message.NewBtmTimeSyncCheckFrame(s.atpReqSn)
|
2024-04-02 18:20:10 +08:00
|
|
|
|
timeSyncF.T2 = s.btmTime.BtmTk
|
|
|
|
|
timeSyncF.T3 = s.btmTime.TkNow()
|
2023-11-24 15:20:05 +08:00
|
|
|
|
s.sendCanetFrame(timeSyncF.Encode().Encode())
|
|
|
|
|
//
|
2023-11-24 16:01:28 +08:00
|
|
|
|
s.resendData = newResendData(statusDataCf)
|
2023-11-24 15:20:05 +08:00
|
|
|
|
s.sendCanetFrame(statusDataCf)
|
|
|
|
|
} else {
|
|
|
|
|
slog.Warn("BtmCanetClient应答帧、数据帧编码失败")
|
|
|
|
|
}
|
2023-11-23 18:14:01 +08:00
|
|
|
|
} else { //当未收到应答器报文时响应:时间同步帧、状态应答帧
|
2024-07-25 14:55:46 +08:00
|
|
|
|
timeSyncF := message.NewBtmTimeSyncCheckFrame(s.atpReqSn)
|
2024-04-02 18:20:10 +08:00
|
|
|
|
timeSyncF.T2 = s.btmTime.BtmTk
|
|
|
|
|
timeSyncF.T3 = s.btmTime.TkNow()
|
2023-11-24 15:20:05 +08:00
|
|
|
|
s.sendCanetFrame(timeSyncF.Encode().Encode())
|
|
|
|
|
//
|
2023-11-23 18:14:01 +08:00
|
|
|
|
statusCf := statusF.Encode().Encode()
|
|
|
|
|
s.sendCanetFrame(statusCf)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 发送Canet帧,一帧13字节
|
|
|
|
|
func (s *btmCanetClient) sendCanetFrame(cf []byte) {
|
|
|
|
|
s.udpClient.Send(cf)
|
|
|
|
|
}
|
2023-11-24 15:20:05 +08:00
|
|
|
|
func (s *btmCanetClient) dsnAdd1() {
|
|
|
|
|
if s.dsn >= 255 {
|
|
|
|
|
s.dsn = 0
|
|
|
|
|
} else {
|
|
|
|
|
s.dsn++
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-23 18:14:01 +08:00
|
|
|
|
|
2023-11-24 16:01:28 +08:00
|
|
|
|
// 准备重发的状态应答帧和报文数据帧
|
|
|
|
|
type resendData struct {
|
|
|
|
|
data []byte //重发的数据
|
|
|
|
|
count int //重发次数
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newResendData(data []byte) *resendData {
|
|
|
|
|
return &resendData{
|
|
|
|
|
data: data,
|
|
|
|
|
count: 0,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
func (r *resendData) canResend() bool {
|
|
|
|
|
return r.count <= 3
|
|
|
|
|
}
|
|
|
|
|
func (r *resendData) countAdd1() {
|
|
|
|
|
r.count++
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-22 11:22:37 +08:00
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// 处理接收的状态应答帧
|
|
|
|
|
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()))
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-12-05 09:37:34 +08:00
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
type TrainBtmStatus struct {
|
|
|
|
|
PowerAmplifierOn bool //BTM功率放大器是否开启
|
|
|
|
|
PowerAmplifierFault bool //BTM功率放大器是否有故障
|
|
|
|
|
AntennaFault bool //BTM应答器天线是否有故障
|
|
|
|
|
AboveBalise bool //BTM当前是否在应答器上方
|
|
|
|
|
BaliseCounter int //应答器计数(每过一个应答器加一,在同一个应答器内不变)
|
|
|
|
|
MessageCounter int //报文计数器(每解出一个应答器报文加一)
|
|
|
|
|
}
|