From bfaf00aedaafd457964a6ef875a9ef7c5211c9f7 Mon Sep 17 00:00:00 2001 From: xzb <223@qq.com> Date: Tue, 21 Nov 2023 18:13:50 +0800 Subject: [PATCH] btm --- third_party/can_btm/balise_btm.go | 49 ++++++++++++++++++++++++++++ third_party/message/can_net.go | 53 +++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 third_party/can_btm/balise_btm.go diff --git a/third_party/can_btm/balise_btm.go b/third_party/can_btm/balise_btm.go new file mode 100644 index 0000000..ce4900d --- /dev/null +++ b/third_party/can_btm/balise_btm.go @@ -0,0 +1,49 @@ +package can_btm + +import ( + "fmt" + "joylink.club/bj-rtsts-server/third_party/message" + "joylink.club/bj-rtsts-server/third_party/udp" + "log/slog" +) + +// btm与canet(网口-CAN口转换器) +type btmCanetClient struct { + //udp + udpServer udp.UdpServer + //udp + udpClient udp.UdpClient + localUdpPort int + remoteUdpPort int + remoteIp string +} + +func (s *btmCanetClient) Start() { + // + s.udpServer = udp.NewServer(fmt.Sprintf(":%d", s.localUdpPort), s.handleCannetFrames) + 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() + } + if s.udpClient != nil { + s.udpClient.Close() + } +} +func (s *btmCanetClient) handleCannetFrames(cfs []byte) { + //一个cannet 帧 13字节 + if len(cfs) > 0 && len(cfs)%13 == 0 { + cfSum := len(cfs) / 13 + for cfi := 0; cfi < cfSum; cfi++ { + cfStart := cfi * 13 + cf := message.NewCanetFrame(cfs[cfStart : cfStart+13]) + fmt.Println(cf.String()) + } + } else { + slog.Warn("从cannet接收数据,未满足条件‘len(cfs) > 0 && len(cfs)%13 == 0‘", "len(cfs)", len(cfs)) + } +} diff --git a/third_party/message/can_net.go b/third_party/message/can_net.go index c76be01..38ba530 100644 --- a/third_party/message/can_net.go +++ b/third_party/message/can_net.go @@ -2,6 +2,7 @@ package message import ( "fmt" + "log/slog" "strings" ) @@ -69,3 +70,55 @@ func (p *CanetFrame) String() string { } return sb.String() } + +// CanFrameType 获取canet帧类型 +func (p *CanetFrame) CanFrameType() CanFrameType { + switch p.CanId.ID3 { + case 0x01: + { //状态应答帧0x01 + return CfStatusRsp + } + case 0x8d: + { //msgTimeA数据帧0x80+0x0d + return CfMsgTimeA + } + case 0x8e: + { //msgTimeB数据帧0x80+0x0e + return CfMsgTimeB + } + case 0xff: + { //msgEnd数据帧0x80+0x7f + return CfMsgEnd + } + case 0x02: + { + if p.CanId.ID1 == 0x62 && p.CanId.ID2 == 0x81 { + return CfReq + } else { + return CfTimeSync + } + } + default: + if p.CanId.ID3 >= 0x80 && p.CanId.ID3 <= 0x8c { //数据帧0x80+(0x00-0x0c) + return CfMsg + } else { + slog.Warn(fmt.Sprintf("无法识别的Canet帧[%s]", p.String())) + return CfNon + } + } +} + +// CanFrameType 帧类型定义 +type CanFrameType = byte + +// Can帧类型枚举 +const ( + CfNon = CanFrameType(0) + CfReq = CanFrameType(1) //查询帧0x02 + CfStatusRsp = CanFrameType(2) //状态应答帧0x01 + CfTimeSync = CanFrameType(3) //时间同步校验帧0x02 + CfMsg = CanFrameType(4) //数据帧0x80+(0x00-0x0c) + CfMsgTimeA = CanFrameType(5) //msgTimeA数据帧0x80+0x0d + CfMsgTimeB = CanFrameType(6) //msgTimeB数据帧0x80+0x0e + CfMsgEnd = CanFrameType(7) //msgEnd数据帧0x80+0x7f +)