121 lines
3.6 KiB
Go
121 lines
3.6 KiB
Go
|
package message
|
|||
|
|
|||
|
import "log/slog"
|
|||
|
|
|||
|
// CreateBtmRspFramesData 数据帧与状态应答帧同时发送给ATP
|
|||
|
// 共17帧,17X12个字节,每个帧12字节
|
|||
|
// msg - 应答器报文
|
|||
|
// msgPackError - true BTM解包发生错误,则数据帧及CRC32A/B全填“0xFF”
|
|||
|
func CreateBtmRspFramesData(statusRsp *BtmStatusRspFrame, msg []byte, msgPackError bool, msgTimeA uint32, msgTimeB uint32, tkTimeB uint32) ([]byte, bool) {
|
|||
|
if len(msg) > 104 { //数据帧最多存储13*8个字节
|
|||
|
return nil, false
|
|||
|
}
|
|||
|
//最近一次ATP查询请求序列号
|
|||
|
sn := statusRsp.FId.ID4
|
|||
|
//13个BtmDataMessageFrame [0x00,0x0c]
|
|||
|
dms := make([]*BtmDataMessageFrame, 13)
|
|||
|
for mr := 0x00; mr <= 0x0c; mr++ {
|
|||
|
dms[mr] = NewBtmDataMessageFrame(sn, byte(mr))
|
|||
|
dms[mr].Message = make([]byte, 8) //8字节数组,默认值0
|
|||
|
//
|
|||
|
if !msgPackError {
|
|||
|
mi := mr * 8
|
|||
|
if mi < len(msg) { //数据帧中有<=8个字节数据
|
|||
|
if mi+7 < len(msg) {
|
|||
|
dms[mr].Message = msg[mi : mi+8]
|
|||
|
} else {
|
|||
|
for i, d := range msg[mi:] {
|
|||
|
dms[mr].Message[i] = d
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
} else { //BTM解包发生错误,则数据帧及CRC32A/B全填“0xFF”
|
|||
|
for c := 0; c < 8; c++ {
|
|||
|
dms[mr].Message[c] = 0xff
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
//
|
|||
|
dtA := NewBtmDataMessageTimeAFrame(sn)
|
|||
|
dtA.TimeA = msgTimeA
|
|||
|
if !msgPackError {
|
|||
|
var crc32AData []byte
|
|||
|
crc32AData = append(crc32AData, msg...)
|
|||
|
crc32AData = append(crc32AData, canTimeToBytes(dtA.TimeA)...)
|
|||
|
dtA.Crc32A = calculateDataRspCrc32A(crc32AData) //CRC32A的校验范围是:报文+时间戳A
|
|||
|
} else { //BTM解包发生错误,则数据帧及CRC32A/B全填“0xFF”
|
|||
|
dtA.Crc32A = 0xff_ff_ff_ff
|
|||
|
}
|
|||
|
//
|
|||
|
dtB := NewBtmDataMessageTimeBFrame(sn)
|
|||
|
dtB.TimeB = msgTimeB
|
|||
|
if !msgPackError {
|
|||
|
var crc32BData []byte
|
|||
|
crc32BData = append(crc32BData, msg...)
|
|||
|
crc32BData = append(crc32BData, canTimeToBytes(dtB.TimeB)...)
|
|||
|
dtB.Crc32B = calculateDataRspCrc32B(crc32BData) //CRC32B的校验范围是:报文+时间戳B
|
|||
|
} else { //BTM解包发生错误,则数据帧及CRC32A/B全填“0xFF”
|
|||
|
dtB.Crc32B = 0xff_ff_ff_ff
|
|||
|
}
|
|||
|
//
|
|||
|
end := NewBtmDataMessageEndFrame(sn)
|
|||
|
end.TkB = tkTimeB
|
|||
|
//
|
|||
|
crc32CData := make([]byte, 0, 132) //17*8-4
|
|||
|
rt := make([]byte, 0, 204) //17*12
|
|||
|
// 状态应答帧
|
|||
|
statusData := statusRsp.Encode()
|
|||
|
crc32CData = append(crc32CData, canFrameContent(statusData)...)
|
|||
|
rt = append(rt, statusData.GetData()...)
|
|||
|
// 数据帧
|
|||
|
for _, dm := range dms {
|
|||
|
dmData := dm.Encode()
|
|||
|
crc32CData = append(crc32CData, canFrameContent(dmData)...)
|
|||
|
rt = append(rt, dmData.GetData()...)
|
|||
|
}
|
|||
|
// 消息时刻A
|
|||
|
dtAData := dtA.Encode()
|
|||
|
crc32CData = append(crc32CData, canFrameContent(dtAData)...)
|
|||
|
rt = append(rt, dtAData.GetData()...)
|
|||
|
// 消息时刻B
|
|||
|
dtBData := dtB.Encode()
|
|||
|
crc32CData = append(crc32CData, canFrameContent(dtBData)...)
|
|||
|
rt = append(rt, dtBData.GetData()...)
|
|||
|
// 消息结束帧
|
|||
|
crc32CData = append(crc32CData, canTimeToBytes(end.TkB)...)
|
|||
|
if len(crc32CData) != 132 {
|
|||
|
slog.Warn("BtmDataMessageEndFrame crc32 校验数据须132字节")
|
|||
|
return nil, false
|
|||
|
}
|
|||
|
end.Crc32C = calculateDataRspCrc32C(crc32CData)
|
|||
|
rt = append(rt, end.Encode().GetData()...)
|
|||
|
if len(rt) != 204 {
|
|||
|
slog.Warn("BTM响应ATP 17帧须136字节")
|
|||
|
return nil, false
|
|||
|
}
|
|||
|
//
|
|||
|
return rt, true
|
|||
|
}
|
|||
|
|
|||
|
// CAN帧中除去开始29bits的剩余8字节数据
|
|||
|
func canFrameContent(canFrame CanBusData) []byte {
|
|||
|
rd := NewCanBitsReader(canFrame.GetData(), canFrame.GetLastRowBitsLen())
|
|||
|
rd.ReadByte() //ID1
|
|||
|
rd.ReadByte() //ID2
|
|||
|
rd.ReadByte() //ID3
|
|||
|
rd.ReadBits(5) //ID4
|
|||
|
//
|
|||
|
rt := make([]byte, 0, 8)
|
|||
|
for {
|
|||
|
d, ok := rd.ReadByte()
|
|||
|
if !ok {
|
|||
|
break
|
|||
|
}
|
|||
|
rt = append(rt, d)
|
|||
|
}
|
|||
|
if len(rt) != 8 {
|
|||
|
panic("CAN帧中数据体须为8字节")
|
|||
|
}
|
|||
|
return rt
|
|||
|
}
|