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 }