package message import ( "encoding/binary" "fmt" "log/slog" ) // 返回应答器数据帧(数据帧 + timeA+timeB+结束帧) func CreateBtmAtpDataRspFramesData(statusRsp *BtmHeadFrame, msg []byte, msgPackError, haxBaliseData bool, msgTimeA uint32, msgTimeB uint32, tkTimeB uint32) ([]byte, bool) { sn := statusRsp.CanId.ID4 //应答器整个是16个数据帧,其中报文占13帧,timeA,timeB 占2帧,最后是结束帧 //数据 dms := make([]*BtmDataMessageAtpFrame, 13) for mr := 0x00; mr <= 0x0c; mr++ { dms[mr] = CreateBtmDataMessageDataAtpFrame(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 := createTimeA(sn, DATA_TIME_A_OFFSET, msgTimeA, msgPackError, msg, haxBaliseData) dtB := createTimeA(sn, DATA_TIME_B_OFFSET, msgTimeB, msgPackError, msg, haxBaliseData) dtACf := dtA.Encode() dtBCf := dtB.Encode() //结束帧 end := createDataAtpEnd(sn, tkTimeB, statusRsp.CanData, msg, dtACf.CanData, dtBCf.CanData) endCf := end.Encode() rt := make([]byte, 0) //17*12 for _, dmCf := range dms { rt = append(rt, dmCf.Encode().Encode()...) } rt = append(rt, dtACf.Encode()...) rt = append(rt, dtBCf.Encode()...) rt = append(rt, endCf.Encode()...) if len(rt) != 192 { slog.Warn(fmt.Sprintf("len(rt)!=192 实际数据长度:%v", len(rt))) return nil, false } return rt, true } func createDataAtpEnd(sn byte, time uint32, statusData, msg, dtAData, dtBData []byte) *BtmDataMessageAtpTimeAndEndFrame { end := BtmDataMessageEndAtpFrame(sn) end.Time = time crc32cData := make([]byte, 0) crc32cData = append(crc32cData, statusData...) crc32cData = append(crc32cData, msg...) crc32cData = append(crc32cData, dtAData...) crc32cData = append(crc32cData, dtBData...) crc32cData = binary.BigEndian.AppendUint32(crc32cData, end.Time) end.Crc32 = Can_Crc32(crc32cData) return end } func createTimeA(sn, offset byte, time uint32, msgPackError bool, msg []byte, hasBaliseData bool) *BtmDataMessageAtpTimeAndEndFrame { tf := CreateBtmDataMessageTimeAtpFrame(sn, offset) tf.Time = time if !msgPackError { var crcData []byte crcData = append(crcData, msg...) crcData = binary.BigEndian.AppendUint32(crcData, time) if !hasBaliseData { tf.Crc32 = 0 } else { if offset == DATA_TIME_A_OFFSET { tf.Crc32 = Can_Crc32A(crcData) //CRC32A的校验范围是:报文+时间戳B } else { tf.Crc32 = Can_Crc32B(crcData) //CRC32B的校验范围是:报文+时间戳B } } } else { //BTM解包发生错误,则数据帧及CRC32A/B全填“0xFF” tf.Crc32 = 0xff_ff_ff_ff } return tf } // CreateBtmRspFramesData BTM与ATP之间为双向通信,ATP(主)定时发送请求帧,BTM(从)在未接收到应答器报文时回复状态应答器帧和时间同步帧,在接收到应答器报文时回复所有帧 // // 数据帧与状态应答帧同时发送给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 = Can_Crc32(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 = Can_Crc32(crc32BData) //CRC32B的校验范围是:报文+时间戳B } else { //BTM解包发生错误,则数据帧及CRC32A/B全填“0xFF” dtB.Crc32B = 0xff_ff_ff_ff } // end := NewBtmDataMessageEndFrame(sn) end.TkB = tkTimeB // statusCf := statusRsp.Encode() dmsCfs := make([]*CanetFrame, 0, 13) for _, dm := range dms { dmsCfs = append(dmsCfs, dm.Encode()) } dtACf := dtA.Encode() dtBCf := dtB.Encode() // crc32cData := make([]byte, 0, 132) crc32cData = append(crc32cData, statusCf.CanData...) for _, dmCf := range dmsCfs { crc32cData = append(crc32cData, dmCf.CanData...) } crc32cData = append(crc32cData, dtACf.CanData...) crc32cData = append(crc32cData, dtBCf.CanData...) crc32cData = append(crc32cData, canTimeToBytes(end.TkB)...) // end.Crc32C = Can_Crc32(crc32cData) // endCf := end.Encode() // rt := make([]byte, 0, 221) //17*13 rt = append(rt, statusCf.Encode()...) for _, dmCf := range dmsCfs { rt = append(rt, dmCf.Encode()...) } rt = append(rt, dtACf.Encode()...) rt = append(rt, dtBCf.Encode()...) rt = append(rt, endCf.Encode()...) if len(rt) != 221 { slog.Warn("len(rt)!=221") return nil, false } return rt, true }