2023-11-17 18:00:53 +08:00
|
|
|
|
package message
|
|
|
|
|
|
|
|
|
|
//数据帧(0x80+扩展类型),一个CAN帧只能存储8个字节,对于一个应答器报文,分片到多个CAN数据帧中
|
|
|
|
|
|
|
|
|
|
// BtmDataMessageFrame 数据帧-应答器报文
|
|
|
|
|
// offset = [0x00,0x0c] 共13个即可用于存储应答器报文的共104个字节
|
|
|
|
|
type BtmDataMessageFrame struct {
|
|
|
|
|
//帧ID
|
|
|
|
|
FId CanFrameId
|
|
|
|
|
//8字节,应答器报文片段
|
2024-04-02 18:20:10 +08:00
|
|
|
|
Message []byte
|
|
|
|
|
IsTrainPcSim bool
|
2023-11-17 18:00:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-02 18:20:10 +08:00
|
|
|
|
func NewBtmDataMessageFrame(sn byte, offset byte, isTrainPcSim bool) *BtmDataMessageFrame {
|
2023-11-20 10:24:55 +08:00
|
|
|
|
return &BtmDataMessageFrame{
|
2024-04-02 18:20:10 +08:00
|
|
|
|
FId: *NewCanFrameId(CAN_ADDR_RSP_ATP, CAN_ADDR_RSP_BTM, 0x80+offset, sn),
|
|
|
|
|
IsTrainPcSim: isTrainPcSim,
|
2023-11-20 10:24:55 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-21 17:20:03 +08:00
|
|
|
|
func (f *BtmDataMessageFrame) Encode() *CanetFrame {
|
|
|
|
|
cf := &CanetFrame{}
|
2024-04-02 18:20:10 +08:00
|
|
|
|
cf.IsTrainPcSim = f.IsTrainPcSim
|
2023-11-21 17:20:03 +08:00
|
|
|
|
cf.CanId = f.FId
|
|
|
|
|
cf.CanLen = 8
|
|
|
|
|
cf.FF = true
|
|
|
|
|
cf.RTR = false
|
2023-11-20 10:24:55 +08:00
|
|
|
|
//
|
2023-11-21 17:20:03 +08:00
|
|
|
|
writer := NewCanBitsWriter(8)
|
2023-11-20 10:24:55 +08:00
|
|
|
|
//
|
|
|
|
|
for _, data := range f.Message {
|
|
|
|
|
writer.AddByte(data)
|
|
|
|
|
}
|
2023-11-21 17:20:03 +08:00
|
|
|
|
cf.CanData = writer.(CanBusData).GetData()
|
|
|
|
|
//
|
|
|
|
|
return cf
|
2023-11-20 10:24:55 +08:00
|
|
|
|
}
|
2023-11-21 17:20:03 +08:00
|
|
|
|
func (f *BtmDataMessageFrame) Decode(cf *CanetFrame) bool {
|
|
|
|
|
f.FId = cf.CanId
|
|
|
|
|
//
|
|
|
|
|
reader := NewCanBitsReader(cf.CanData, 8)
|
2023-11-20 10:24:55 +08:00
|
|
|
|
//
|
|
|
|
|
f.Message = make([]byte, 0, 8)
|
|
|
|
|
for c := 0; c < 8; c++ {
|
|
|
|
|
data, ok := reader.ReadByte()
|
|
|
|
|
if !ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.Message = append(f.Message, data)
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////
|
|
|
|
|
|
2023-11-17 18:00:53 +08:00
|
|
|
|
// BtmDataMessageTimeAFrame 数据帧-时间戳A
|
|
|
|
|
// offset = 0x0d
|
|
|
|
|
type BtmDataMessageTimeAFrame struct {
|
|
|
|
|
//帧ID
|
|
|
|
|
FId CanFrameId
|
|
|
|
|
//时间戳A
|
|
|
|
|
TimeA uint32
|
|
|
|
|
//CRC
|
2024-04-02 18:20:10 +08:00
|
|
|
|
Crc32A uint32
|
|
|
|
|
IsTrainPcSim bool
|
2023-11-17 18:00:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-07-11 14:58:34 +08:00
|
|
|
|
func NewBtmDataMessageTimeAFrame2(sn byte, isTrainPcSim bool) *BtmDataMessageTimeAFrame {
|
|
|
|
|
return &BtmDataMessageTimeAFrame{
|
|
|
|
|
FId: *NewCanFrameId(CAN_ADDR_RSP_ATP, CAN_ADDR_RSP_BTM, 0x80+0x0e, sn),
|
|
|
|
|
IsTrainPcSim: isTrainPcSim,
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-02 18:20:10 +08:00
|
|
|
|
func NewBtmDataMessageTimeAFrame(sn byte, isTrainPcSim bool) *BtmDataMessageTimeAFrame {
|
2023-11-20 10:24:55 +08:00
|
|
|
|
return &BtmDataMessageTimeAFrame{
|
2024-04-02 18:20:10 +08:00
|
|
|
|
FId: *NewCanFrameId(CAN_ADDR_RSP_ATP, CAN_ADDR_RSP_BTM, 0x80+0x0d, sn),
|
|
|
|
|
IsTrainPcSim: isTrainPcSim,
|
2023-11-20 10:24:55 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-21 17:20:03 +08:00
|
|
|
|
func (f *BtmDataMessageTimeAFrame) Encode() *CanetFrame {
|
|
|
|
|
cf := &CanetFrame{}
|
2024-04-02 18:20:10 +08:00
|
|
|
|
cf.IsTrainPcSim = f.IsTrainPcSim
|
2023-11-21 17:20:03 +08:00
|
|
|
|
cf.CanId = f.FId
|
|
|
|
|
cf.CanLen = 8
|
|
|
|
|
cf.FF = true
|
|
|
|
|
cf.RTR = false
|
2023-11-20 10:24:55 +08:00
|
|
|
|
//
|
2023-11-21 17:20:03 +08:00
|
|
|
|
writer := NewCanBitsWriter(8)
|
2023-11-20 10:24:55 +08:00
|
|
|
|
//
|
|
|
|
|
byteMsk := uint32(0x00_00_00_ff)
|
|
|
|
|
//
|
|
|
|
|
writer.AddByte(byte((f.TimeA >> 24) & byteMsk))
|
|
|
|
|
writer.AddByte(byte((f.TimeA >> 16) & byteMsk))
|
|
|
|
|
writer.AddByte(byte((f.TimeA >> 8) & byteMsk))
|
|
|
|
|
writer.AddByte(byte(f.TimeA & byteMsk))
|
|
|
|
|
//
|
|
|
|
|
writer.AddByte(byte((f.Crc32A >> 24) & byteMsk))
|
|
|
|
|
writer.AddByte(byte((f.Crc32A >> 16) & byteMsk))
|
|
|
|
|
writer.AddByte(byte((f.Crc32A >> 8) & byteMsk))
|
|
|
|
|
writer.AddByte(byte(f.Crc32A & byteMsk))
|
|
|
|
|
//
|
2023-11-21 17:20:03 +08:00
|
|
|
|
cf.CanData = writer.(CanBusData).GetData()
|
|
|
|
|
//
|
|
|
|
|
return cf
|
2023-11-20 10:24:55 +08:00
|
|
|
|
}
|
2023-11-20 16:55:07 +08:00
|
|
|
|
|
2023-11-21 17:20:03 +08:00
|
|
|
|
func (f *BtmDataMessageTimeAFrame) Decode(cf *CanetFrame) bool {
|
|
|
|
|
f.FId = cf.CanId
|
|
|
|
|
//
|
|
|
|
|
reader := NewCanBitsReader(cf.CanData, 8)
|
2023-11-20 10:24:55 +08:00
|
|
|
|
//
|
|
|
|
|
f.TimeA = 0
|
|
|
|
|
a1, a1Ok := reader.ReadByte()
|
|
|
|
|
if !a1Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.TimeA |= uint32(a1) << 24
|
|
|
|
|
//
|
|
|
|
|
a2, a2Ok := reader.ReadByte()
|
|
|
|
|
if !a2Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.TimeA |= uint32(a2) << 16
|
|
|
|
|
//
|
|
|
|
|
a3, a3Ok := reader.ReadByte()
|
|
|
|
|
if !a3Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.TimeA |= uint32(a3) << 8
|
|
|
|
|
//
|
|
|
|
|
a4, a4Ok := reader.ReadByte()
|
|
|
|
|
if !a4Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.TimeA |= uint32(a4)
|
|
|
|
|
//
|
|
|
|
|
f.Crc32A = 0
|
|
|
|
|
c1, c1Ok := reader.ReadByte()
|
|
|
|
|
if !c1Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.Crc32A |= uint32(c1) << 24
|
|
|
|
|
//
|
|
|
|
|
c2, c2Ok := reader.ReadByte()
|
|
|
|
|
if !c2Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.Crc32A |= uint32(c2) << 16
|
|
|
|
|
//
|
|
|
|
|
c3, c3Ok := reader.ReadByte()
|
|
|
|
|
if !c3Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.Crc32A |= uint32(c3) << 8
|
|
|
|
|
//
|
|
|
|
|
c4, c4Ok := reader.ReadByte()
|
|
|
|
|
if !c4Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.Crc32A |= uint32(c4)
|
|
|
|
|
//
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////
|
|
|
|
|
|
2023-11-17 18:00:53 +08:00
|
|
|
|
// BtmDataMessageTimeBFrame 数据帧-时间戳B
|
|
|
|
|
// offset = 0x0e
|
|
|
|
|
type BtmDataMessageTimeBFrame struct {
|
|
|
|
|
//帧ID
|
|
|
|
|
FId CanFrameId
|
|
|
|
|
//时间戳B
|
|
|
|
|
TimeB uint32
|
|
|
|
|
//CRC
|
2024-04-02 18:20:10 +08:00
|
|
|
|
Crc32B uint32
|
|
|
|
|
IsTrainPcSim bool
|
2023-11-17 18:00:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-02 18:20:10 +08:00
|
|
|
|
func NewBtmDataMessageTimeBFrame(sn byte, isTrainPcSim bool) *BtmDataMessageTimeBFrame {
|
2023-11-20 10:24:55 +08:00
|
|
|
|
return &BtmDataMessageTimeBFrame{
|
2024-04-02 18:20:10 +08:00
|
|
|
|
FId: *NewCanFrameId(CAN_ADDR_RSP_ATP, CAN_ADDR_RSP_BTM, 0x80+0x0e, sn),
|
|
|
|
|
IsTrainPcSim: isTrainPcSim,
|
2023-11-20 10:24:55 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-21 17:20:03 +08:00
|
|
|
|
func (f *BtmDataMessageTimeBFrame) Encode() *CanetFrame {
|
|
|
|
|
cf := &CanetFrame{}
|
2024-04-02 18:20:10 +08:00
|
|
|
|
cf.IsTrainPcSim = f.IsTrainPcSim
|
2023-11-21 17:20:03 +08:00
|
|
|
|
cf.CanId = f.FId
|
|
|
|
|
cf.CanLen = 8
|
|
|
|
|
cf.FF = true
|
|
|
|
|
cf.RTR = false
|
2023-11-20 10:24:55 +08:00
|
|
|
|
//
|
2023-11-21 17:20:03 +08:00
|
|
|
|
writer := NewCanBitsWriter(8)
|
2023-11-20 10:24:55 +08:00
|
|
|
|
//
|
|
|
|
|
byteMsk := uint32(0x00_00_00_ff)
|
|
|
|
|
//
|
|
|
|
|
writer.AddByte(byte((f.TimeB >> 24) & byteMsk))
|
|
|
|
|
writer.AddByte(byte((f.TimeB >> 16) & byteMsk))
|
|
|
|
|
writer.AddByte(byte((f.TimeB >> 8) & byteMsk))
|
|
|
|
|
writer.AddByte(byte(f.TimeB & byteMsk))
|
|
|
|
|
//
|
|
|
|
|
writer.AddByte(byte((f.Crc32B >> 24) & byteMsk))
|
|
|
|
|
writer.AddByte(byte((f.Crc32B >> 16) & byteMsk))
|
|
|
|
|
writer.AddByte(byte((f.Crc32B >> 8) & byteMsk))
|
|
|
|
|
writer.AddByte(byte(f.Crc32B & byteMsk))
|
|
|
|
|
//
|
2023-11-21 17:20:03 +08:00
|
|
|
|
cf.CanData = writer.(CanBusData).GetData()
|
|
|
|
|
//
|
|
|
|
|
return cf
|
2023-11-20 10:24:55 +08:00
|
|
|
|
}
|
2023-11-21 17:20:03 +08:00
|
|
|
|
func (f *BtmDataMessageTimeBFrame) Decode(cf *CanetFrame) bool {
|
|
|
|
|
f.FId = cf.CanId
|
|
|
|
|
//
|
|
|
|
|
reader := NewCanBitsReader(cf.CanData, 8)
|
2023-11-20 10:24:55 +08:00
|
|
|
|
//
|
|
|
|
|
f.TimeB = 0
|
|
|
|
|
a1, a1Ok := reader.ReadByte()
|
|
|
|
|
if !a1Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.TimeB |= uint32(a1) << 24
|
|
|
|
|
//
|
|
|
|
|
a2, a2Ok := reader.ReadByte()
|
|
|
|
|
if !a2Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.TimeB |= uint32(a2) << 16
|
|
|
|
|
//
|
|
|
|
|
a3, a3Ok := reader.ReadByte()
|
|
|
|
|
if !a3Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.TimeB |= uint32(a3) << 8
|
|
|
|
|
//
|
|
|
|
|
a4, a4Ok := reader.ReadByte()
|
|
|
|
|
if !a4Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.TimeB |= uint32(a4)
|
|
|
|
|
//
|
|
|
|
|
f.Crc32B = 0
|
|
|
|
|
c1, c1Ok := reader.ReadByte()
|
|
|
|
|
if !c1Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.Crc32B |= uint32(c1) << 24
|
|
|
|
|
//
|
|
|
|
|
c2, c2Ok := reader.ReadByte()
|
|
|
|
|
if !c2Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.Crc32B |= uint32(c2) << 16
|
|
|
|
|
//
|
|
|
|
|
c3, c3Ok := reader.ReadByte()
|
|
|
|
|
if !c3Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.Crc32B |= uint32(c3) << 8
|
|
|
|
|
//
|
|
|
|
|
c4, c4Ok := reader.ReadByte()
|
|
|
|
|
if !c4Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.Crc32B |= uint32(c4)
|
|
|
|
|
//
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
|
|
2023-11-17 18:00:53 +08:00
|
|
|
|
// BtmDataMessageEndFrame 数据帧-结束
|
|
|
|
|
// offset = 0x7f
|
|
|
|
|
type BtmDataMessageEndFrame struct {
|
|
|
|
|
//帧ID
|
|
|
|
|
FId CanFrameId
|
|
|
|
|
//TK time B
|
|
|
|
|
TkB uint32
|
|
|
|
|
//CRC32C校验包含对状态应答帧与数据帧的总校验,总共为8×17-4=132字节,4-即Crc32C
|
|
|
|
|
//1个状态应答帧 + 13个BtmDataMessageFrame + 1个BtmDataMessageTimeAFrame + 1个BtmDataMessageTimeBFrame + 1个BtmDataMessageEndFrame
|
2024-04-02 18:20:10 +08:00
|
|
|
|
Crc32C uint32
|
|
|
|
|
IsTrainPcSim bool
|
2023-11-17 18:00:53 +08:00
|
|
|
|
}
|
2023-11-20 10:24:55 +08:00
|
|
|
|
|
2024-07-11 14:58:34 +08:00
|
|
|
|
func NewBtmDataMessageEndFrame2(sn byte, isTrainPcSim bool) *BtmDataMessageEndFrame {
|
|
|
|
|
return &BtmDataMessageEndFrame{
|
|
|
|
|
FId: *NewCanFrameId(CAN_ADDR_RSP_ATP, CAN_ADDR_RSP_BTM, 0xff, sn),
|
|
|
|
|
IsTrainPcSim: isTrainPcSim,
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-02 18:20:10 +08:00
|
|
|
|
func NewBtmDataMessageEndFrame(sn byte, isTrainPcSim bool) *BtmDataMessageEndFrame {
|
2023-11-20 10:24:55 +08:00
|
|
|
|
return &BtmDataMessageEndFrame{
|
2024-04-02 18:20:10 +08:00
|
|
|
|
FId: *NewCanFrameId(CAN_ADDR_RSP_ATP, CAN_ADDR_RSP_BTM, 0x80+0x7f, sn),
|
|
|
|
|
IsTrainPcSim: isTrainPcSim,
|
2023-11-20 10:24:55 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-11-21 17:20:03 +08:00
|
|
|
|
func (f *BtmDataMessageEndFrame) Encode() *CanetFrame {
|
|
|
|
|
cf := &CanetFrame{}
|
2024-04-02 18:20:10 +08:00
|
|
|
|
cf.IsTrainPcSim = f.IsTrainPcSim
|
2023-11-21 17:20:03 +08:00
|
|
|
|
cf.CanId = f.FId
|
|
|
|
|
cf.CanLen = 8
|
|
|
|
|
cf.FF = true
|
|
|
|
|
cf.RTR = false
|
2023-11-20 10:24:55 +08:00
|
|
|
|
//
|
2023-11-21 17:20:03 +08:00
|
|
|
|
writer := NewCanBitsWriter(8)
|
2023-11-20 10:24:55 +08:00
|
|
|
|
//
|
|
|
|
|
byteMsk := uint32(0x00_00_00_ff)
|
|
|
|
|
//
|
|
|
|
|
writer.AddByte(byte((f.TkB >> 24) & byteMsk))
|
|
|
|
|
writer.AddByte(byte((f.TkB >> 16) & byteMsk))
|
|
|
|
|
writer.AddByte(byte((f.TkB >> 8) & byteMsk))
|
|
|
|
|
writer.AddByte(byte(f.TkB & byteMsk))
|
|
|
|
|
//
|
|
|
|
|
writer.AddByte(byte((f.Crc32C >> 24) & byteMsk))
|
|
|
|
|
writer.AddByte(byte((f.Crc32C >> 16) & byteMsk))
|
|
|
|
|
writer.AddByte(byte((f.Crc32C >> 8) & byteMsk))
|
|
|
|
|
writer.AddByte(byte(f.Crc32C & byteMsk))
|
|
|
|
|
//
|
2023-11-21 17:20:03 +08:00
|
|
|
|
cf.CanData = writer.(CanBusData).GetData()
|
|
|
|
|
//
|
|
|
|
|
return cf
|
2023-11-20 10:24:55 +08:00
|
|
|
|
}
|
2023-11-21 17:20:03 +08:00
|
|
|
|
func (f *BtmDataMessageEndFrame) Decode(cf *CanetFrame) bool {
|
|
|
|
|
f.FId = cf.CanId
|
|
|
|
|
//
|
|
|
|
|
reader := NewCanBitsReader(cf.CanData, 8)
|
2023-11-20 10:24:55 +08:00
|
|
|
|
//
|
|
|
|
|
f.TkB = 0
|
|
|
|
|
a1, a1Ok := reader.ReadByte()
|
|
|
|
|
if !a1Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.TkB |= uint32(a1) << 24
|
|
|
|
|
//
|
|
|
|
|
a2, a2Ok := reader.ReadByte()
|
|
|
|
|
if !a2Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.TkB |= uint32(a2) << 16
|
|
|
|
|
//
|
|
|
|
|
a3, a3Ok := reader.ReadByte()
|
|
|
|
|
if !a3Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.TkB |= uint32(a3) << 8
|
|
|
|
|
//
|
|
|
|
|
a4, a4Ok := reader.ReadByte()
|
|
|
|
|
if !a4Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.TkB |= uint32(a4)
|
|
|
|
|
//
|
|
|
|
|
f.Crc32C = 0
|
|
|
|
|
c1, c1Ok := reader.ReadByte()
|
|
|
|
|
if !c1Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.Crc32C |= uint32(c1) << 24
|
|
|
|
|
//
|
|
|
|
|
c2, c2Ok := reader.ReadByte()
|
|
|
|
|
if !c2Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.Crc32C |= uint32(c2) << 16
|
|
|
|
|
//
|
|
|
|
|
c3, c3Ok := reader.ReadByte()
|
|
|
|
|
if !c3Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.Crc32C |= uint32(c3) << 8
|
|
|
|
|
//
|
|
|
|
|
c4, c4Ok := reader.ReadByte()
|
|
|
|
|
if !c4Ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
f.Crc32C |= uint32(c4)
|
|
|
|
|
//
|
|
|
|
|
return true
|
|
|
|
|
}
|
2023-11-20 16:55:07 +08:00
|
|
|
|
|
|
|
|
|
// 32位时间戳,转换成字节数组
|
|
|
|
|
// 大端模型
|
|
|
|
|
func canTimeToBytes(ts uint32) []byte {
|
|
|
|
|
rt := make([]byte, 0, 4)
|
|
|
|
|
byteMsk := uint32(0x00_00_00_ff)
|
|
|
|
|
rt = append(rt, byte((ts>>24)&byteMsk))
|
|
|
|
|
rt = append(rt, byte((ts>>16)&byteMsk))
|
|
|
|
|
rt = append(rt, byte((ts>>8)&byteMsk))
|
|
|
|
|
rt = append(rt, byte(ts&byteMsk))
|
|
|
|
|
return rt
|
|
|
|
|
}
|