[修改]北京12号线计轴通信crc、svc等编码及校验逻辑

This commit is contained in:
thesai 2024-07-08 10:33:19 +08:00
parent b8dc207a0e
commit 4bdd91c18b
6 changed files with 386 additions and 442 deletions

View File

@ -181,13 +181,15 @@ type RsspNetConfig struct {
LocalPort int `json:"localPort" description:"本地端口"`
SourceAddr string `json:"sourceAddr" description:"源地址16进制2字节"`
TargetAddr string `json:"targetAddr" description:"目的地址16进制2字节"`
Sid1 string `json:"sid1" description:"SID_116进制4字节"`
Sid2 string `json:"sid2" description:"SID_216进制4字节"`
Sid1 string `json:"sid1" description:"联锁SID_116进制4字节"`
Sid2 string `json:"sid2" description:"联锁SID_216进制4字节"`
LocalSid1 string `json:"remoteSid" description:"计轴SID_116进制4字节"`
LocalSid2 string `json:"remoteSid2" description:"计轴SID_216进制4字节"`
Sinit1 string `json:"sinit1" description:"SINIT_116进制4字节"`
Sinit2 string `json:"sinit2" description:"SINIT_216进制4字节"`
DataVer1 string `json:"dataVer1" description:"DATAVER_116进制4字节"`
DataVer2 string `json:"dataVer2" description:"DATAVER_216进制4字节"`
MaxDeviation uint32 `json:"maxDeviation" description:"可容忍的最大时序偏差"`
MaxDeviation int `json:"maxDeviation" description:"可容忍的最大时序偏差"`
WaitSSRTimeout int `json:"waitSSRTimeout" description:"等待SSR回应的定时器超时值ms"`
Period int `json:"period" description:"RSD发送周期ms"`
}

View File

@ -28,8 +28,8 @@ const (
)
const (
T_POLY_1 = 0x0FC22F87 //通道1的时间戳生成多项式
T_POLY_2 = 0xC3E887E1 //通道2的时间戳生成多项式
T_POLY_1 uint32 = 0x0FC22F87 //通道1的时间戳生成多项式
T_POLY_2 uint32 = 0xC3E887E1 //通道2的时间戳生成多项式
)
const Twait_sse = 3 //默认sse等待回应的周期数

View File

@ -38,16 +38,21 @@ type serviceContext struct {
cancelFunc context.CancelFunc
ciSectionIndexConfigs []*proto.CiSectionCodePoint
sourceAddr uint16 //源地址 从配置中的16进制字符串转来的
targetAddr uint16 //目的地址 从配置中的16进制字符串转来的
sid1 uint32 //SID1 从配置中的16进制字符串转来的
sid2 uint32 //SID2 从配置中的16进制字符串转来的
msgChan <-chan []byte //消息队列
seqNum uint32 //当前的序列号
lastSeqNum uint32 //最近一次收到的序列号
lastTimeSeqParam uint32 //最近一次的有效时序参数
sseMsg *msg.SseMsg //发送出去的时序校验请求
sseWaitTimer <-chan time.Time //sse超时定时器
sourceAddr uint16 //源地址 从配置中的16进制字符串转来的
targetAddr uint16 //目的地址 从配置中的16进制字符串转来的
sid1 uint32 //联锁SID1 从配置中的16进制字符串转来的
sid2 uint32 //联锁SID2 从配置中的16进制字符串转来的
localSid1 uint32 //计轴SID1 从配置中的16进制字符串转来的
localSid2 uint32 //计轴SID2 从配置中的16进制字符串转来的
sinit1 uint32 //SINT16 从配置中的16进制字符串转来的
sinit2 uint32 //SINT26 从配置中的16进制字符串转来的
msgChan <-chan []byte //消息队列
seqNum uint32 //当前的序列号
lastSeqParam uint32 //最近一次的有效时序参数
lfsr1 lfsr //用来计算时间戳的lfsr
lfsr2 lfsr //用来计算时间戳的lfsr
sseMsg *msg.SseMsg //发送出去的时序校验请求
sseWaitTimer <-chan time.Time //sse超时定时器
}
func Start(simulation *memory.VerifySimulation) {
@ -83,11 +88,27 @@ func Start(simulation *memory.VerifySimulation) {
}
sid1, err := strconv.ParseUint(rsspConfig.NetAConfig.Sid1, 16, 32)
if err != nil {
panic(sys_error.New(fmt.Sprintf("%s集中站[%s]解析SID1[%s]出错", logTag, rsspConfig.StationCode, rsspConfig.NetAConfig.Sid1)))
panic(sys_error.New(fmt.Sprintf("%s集中站[%s]解析联锁SID1[%s]出错", logTag, rsspConfig.StationCode, rsspConfig.NetAConfig.Sid1)))
}
sid2, err := strconv.ParseUint(rsspConfig.NetAConfig.Sid2, 16, 32)
if err != nil {
panic(sys_error.New(fmt.Sprintf("%s集中站[%s]解析SID2[%s]出错", logTag, rsspConfig.StationCode, rsspConfig.NetAConfig.Sid2)))
panic(sys_error.New(fmt.Sprintf("%s集中站[%s]解析联锁SID2[%s]出错", logTag, rsspConfig.StationCode, rsspConfig.NetAConfig.Sid2)))
}
localSid1, err := strconv.ParseUint(rsspConfig.NetAConfig.LocalSid1, 16, 32)
if err != nil {
panic(sys_error.New(fmt.Sprintf("%s集中站[%s]解析计轴SID1[%s]出错", logTag, rsspConfig.StationCode, rsspConfig.NetAConfig.LocalSid1)))
}
localSid2, err := strconv.ParseUint(rsspConfig.NetAConfig.LocalSid2, 16, 32)
if err != nil {
panic(sys_error.New(fmt.Sprintf("%s集中站[%s]解析计轴SID2[%s]出错", logTag, rsspConfig.StationCode, rsspConfig.NetAConfig.LocalSid2)))
}
sinit1, err := strconv.ParseUint(rsspConfig.NetAConfig.Sinit1, 16, 32)
if err != nil {
panic(sys_error.New(fmt.Sprintf("%s集中站[%s]解析SINT1[%s]出错", logTag, rsspConfig.StationCode, rsspConfig.NetAConfig.Sinit1)))
}
sinit2, err := strconv.ParseUint(rsspConfig.NetAConfig.Sinit2, 16, 32)
if err != nil {
panic(sys_error.New(fmt.Sprintf("%s集中站[%s]解析SINT2[%s]出错", logTag, rsspConfig.StationCode, rsspConfig.NetAConfig.Sinit2)))
}
//服务初始化及启动
msgChan := make(chan []byte, 100)
@ -99,7 +120,14 @@ func Start(simulation *memory.VerifySimulation) {
targetAddr: uint16(targetAddr),
sid1: uint32(sid1),
sid2: uint32(sid2),
localSid1: uint32(localSid1),
localSid2: uint32(localSid2),
sinit1: uint32(sinit1),
sinit2: uint32(sinit2),
msgChan: msgChan,
seqNum: 1,
lfsr1: lfsr{value: uint32(localSid1)},
lfsr2: lfsr{value: uint32(localSid2)},
}
netAConfig := rsspConfig.NetAConfig
server := udp.NewServer(fmt.Sprintf(":%d", netAConfig.LocalPort), func(b []byte) {
@ -166,51 +194,6 @@ func (s *serviceContext) runCollectTask(ctx context.Context) {
}()
}
func (s *serviceContext) collect() *msg.RsdMsgBuilder {
worldData := entity.GetWorldData(s.sim.World)
amdEntry := entity.FindAxleManageDevice(worldData, s.config.StationCode)
amd := component.AxleManageDeviceType.Get(amdEntry)
stateInfos := msg.StateInfos{}
for _, cfg := range s.ciSectionIndexConfigs {
sectionRuntime := amd.Adrs[cfg.SectionId]
sectionEntry, ok := entity.GetEntityByUid(s.sim.World, cfg.SectionId)
sectionState := component.PhysicalSectionStateType.Get(sectionEntry)
if !ok {
continue
}
stateInfos = append(stateInfos, &msg.StateInfo{
CLR: !sectionState.Occ,
OCC: sectionState.Occ,
RAC: sectionRuntime.Rac,
RJO: sectionRuntime.Rjo,
RJT: sectionRuntime.Rjt,
})
}
userData := stateInfos.Encode()
builder := &msg.RsdMsgBuilder{
MsgHeader: msg.MsgHeader{
ProtocolType: msg.ProtocolType_Sync,
MessageType: msg.MessageType_A,
SourceAddr: s.sourceAddr,
TargetAddr: s.targetAddr,
},
SeqNum: s.seqNum,
Svc1: s.calculateSvc1(userData, s.seqNum),
Svc2: s.calculateSvc2(userData, s.seqNum),
UserData: userData,
}
s.seqNum++
return builder
}
func (s *serviceContext) calculateSvc1(userData []byte, seqNum uint32) uint32 {
return 0
}
func (s *serviceContext) calculateSvc2(userData []byte, seqNum uint32) uint32 {
return 0
}
func (s *serviceContext) runHandleMsgTask(ctx context.Context) {
go func() {
defer func() {
@ -242,6 +225,57 @@ func (s *serviceContext) runHandleMsgTask(ctx context.Context) {
}()
}
func (s *serviceContext) collect() *msg.RsdMsgBuilder {
worldData := entity.GetWorldData(s.sim.World)
amdEntry := entity.FindAxleManageDevice(worldData, s.config.StationCode)
amd := component.AxleManageDeviceType.Get(amdEntry)
stateInfos := msg.StateInfos{}
for _, cfg := range s.ciSectionIndexConfigs {
sectionRuntime := amd.Adrs[cfg.SectionId]
sectionEntry, ok := entity.GetEntityByUid(s.sim.World, cfg.SectionId)
sectionState := component.PhysicalSectionStateType.Get(sectionEntry)
if !ok {
continue
}
stateInfos = append(stateInfos, &msg.StateInfo{
CLR: !sectionState.Occ,
OCC: sectionState.Occ,
RAC: sectionRuntime.Rac,
RJO: sectionRuntime.Rjo,
RJT: sectionRuntime.Rjt,
})
}
userData := stateInfos.Encode()
builder := &msg.RsdMsgBuilder{
MsgHeader: msg.MsgHeader{
ProtocolType: msg.ProtocolType_Sync,
MessageType: msg.MessageType_A,
SourceAddr: s.sourceAddr,
TargetAddr: s.targetAddr,
},
SeqNum: s.seqNum,
Svc1: s.calculateSvc1(userData),
Svc2: s.calculateSvc2(userData),
UserData: userData,
}
s.seqNum++
return builder
}
func (s *serviceContext) calculateSvc1(userData []byte) uint32 {
return s.calculateSvc(userData, s.localSid1, msg.SCW_1, s.lfsr1)
}
func (s *serviceContext) calculateSvc2(userData []byte) uint32 {
return s.calculateSvc(userData, s.localSid2, msg.SCW_2, s.lfsr2)
}
func (s *serviceContext) calculateSvc(userData []byte, sid uint32, scw uint32, l lfsr) uint32 {
crc := message.Rssp_I_Crc32C1(userData)
l.add(0)
return crc ^ sid ^ l.value ^ scw
}
func (s *serviceContext) handleRsdMsg(data []byte) {
if s.sseMsg == nil { //正在时序校正过程中
return
@ -253,18 +287,13 @@ func (s *serviceContext) handleRsdMsg(data []byte) {
return
}
//校验
if !s.validateRsdMsg(rsdMsg) {
validateResult := s.validateRsdMsg(rsdMsg)
if validateResult == 0 {
return
} else if validateResult == 2 {
//开启时序校正流程
}
//流程处理
seqDeviation := rsdMsg.SeqNum - s.lastSeqNum
if s.lastSeqNum == 0 {
seqDeviation = 0
} else if seqDeviation < 0 || seqDeviation > s.config.NetAConfig.MaxDeviation { //序列号减小或时序差超出容忍限度
s.startSeeProgress()
return
}
s.lastSeqNum = rsdMsg.SeqNum
cmdInfos := msg.CmdInfos{}
err = cmdInfos.Decode(rsdMsg.UserData)
if err != nil {
@ -297,7 +326,7 @@ func (s *serviceContext) handleSseMsg(data []byte) {
return
}
//回复
s.lastSeqNum = sseMsg.SeqNum
s.lastSeqParam = sseMsg.SeqNum
ssrMsg := msg.SsrMsg{
MsgHeader: msg.MsgHeader{
ProtocolType: msg.ProtocolType_Sync,
@ -333,7 +362,7 @@ func (s *serviceContext) handleSsrMsg(data []byte) {
}
//完成校正时序
s.sseMsg = nil
s.lastSeqNum = ssrMsg.SeqNumSsr
s.lastSeqParam = ssrMsg.SeqNumSsr
}
// 启动SSE流程
@ -358,26 +387,36 @@ func (s *serviceContext) startSeeProgress() {
}
}
func (s *serviceContext) validateRsdMsg(rsdMsg *msg.RsdMsg) bool {
// 校验RSD消息
// return 0-时序校验之外的失败 1-成功 2-时序异常
func (s *serviceContext) validateRsdMsg(rsdMsg *msg.RsdMsg) int {
sourceAddr, _ := strconv.ParseUint(s.config.NetAConfig.SourceAddr, 16, 16)
if rsdMsg.SourceAddr != uint16(sourceAddr) {
logger().Error(fmt.Sprintf("源地址[%x]不正确[%s]", rsdMsg.SourceAddr, s.config.NetAConfig.SourceAddr))
return false
return 0
}
targetAddr, _ := strconv.ParseUint(s.config.NetAConfig.TargetAddr, 16, 16)
if rsdMsg.TargetAddr != uint16(targetAddr) {
logger().Error(fmt.Sprintf("目的地址[%x]不正确[%s]", rsdMsg.TargetAddr, s.config.NetAConfig.TargetAddr))
return false
return 0
}
if len(rsdMsg.UserData) != len(s.ciSectionIndexConfigs) {
logger().Error(fmt.Sprintf("用户数据长度[%d]与配置长度[%d]不符", len(rsdMsg.UserData), len(s.ciSectionIndexConfigs)))
return false
return 0
}
if message.Rssp_I_Crc16(rsdMsg.UserData) != rsdMsg.Tail {
logger().Error(fmt.Sprintf("报文验证失败"))
return false
logger().Error(fmt.Sprintf("报文验证失败"))
return 0
}
return true
if s.validateSvc1(rsdMsg.Svc1, rsdMsg.UserData) {
logger().Error(fmt.Sprintf("SVC1[%x]校验未通过", rsdMsg.Svc1))
return 2
}
if s.validateSvc2(rsdMsg.Svc2, rsdMsg.UserData) {
logger().Error(fmt.Sprintf("SVC2[%x]校验未通过", rsdMsg.Svc2))
return 2
}
return 1
}
func (s *serviceContext) validateSseMsg(sseMsg *msg.SseMsg) bool {
@ -392,6 +431,36 @@ func (s *serviceContext) validateSsrMsg(ssrMsg *msg.SsrMsg) bool {
return true
}
func (s *serviceContext) validateSvc1(svc uint32, userData []byte) bool {
return s.validateSvc(svc, msg.SCW_1, message.Rssp_I_Crc32C1(userData), s.sid1, s.sinit1)
}
func (s *serviceContext) validateSvc2(svc uint32, userData []byte) bool {
return s.validateSvc(svc, msg.SCW_2, message.Rssp_I_Crc32C2(userData), s.sid2, s.sinit2)
}
func (s *serviceContext) validateSvc(svc uint32, scw uint32, crc1 uint32, sid uint32, sinit uint32) bool {
seqParam := crc1 ^ svc ^ scw
if s.lastSeqParam == 0 {
s.lastSeqParam = seqParam
return true
}
for i := 0; i < s.config.NetAConfig.MaxDeviation; i++ {
seqLfsr := lfsr{value: sinit}
seqLfsr.add(s.lastSeqParam)
constLfsr := lfsr{value: sinit}
constLfsr.add(sid)
for j := 0; j < i; j++ {
seqLfsr.add(0)
constLfsr.add(0)
}
if seqLfsr.add(seqParam) == seqLfsr.add(sid) {
return true
}
}
return false
}
func (s *serviceContext) calculateSeqEnq1() uint32 {
return 0
}
@ -408,6 +477,23 @@ func (s *serviceContext) calculateSeqInit2(seqEnq2 uint32) uint32 {
return 0
}
type lfsr struct {
value uint32
}
func (l *lfsr) add(x uint32) uint32 {
l.value = l.value ^ x
var carry bool
for i := 0; i < 32; i++ {
carry = l.value&0x80000000 != 0
l.value = l.value << 1
if carry {
l.value ^= msg.T_POLY_1
}
}
return l.value
}
func logger() *slog.Logger {
loggerInit.Do(func() {
privateLogger = slog.Default().With("tag", logTag)

View File

@ -1,82 +1,200 @@
package main
import (
"encoding/binary"
"fmt"
"joylink.club/bj-rtsts-server/third_party/axle_device/beijing12/msg"
"joylink.club/bj-rtsts-server/third_party/message"
)
//func main() {
// var scw1 uint32 = 0xAE390B5A
// var t_p uint32 = 0x0FC22F87
// var sid1 uint32 = 0xa2bcfc8c
// var sinit uint32 = 0xb763ec88
//
// var svcn_1 uint32 = 0x08b12b3b
// //var svcn_1 uint32 = 0x3b2bb108
// var svcn uint32 = 0x547fd6ca
// //var svcn uint32 = 0xcad67f54
// var userData []byte = []byte{0x80, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00}
// crc1 := crc32Encode(userData)
//
// m := func(svc1 uint32) uint32 {
// return (svc1 ^ crc1) ^ scw1
// }
//
// rn_1 := m(svcn_1)
// rn := m(svcn)
// l1 := &Lfsr{
// value: sinit,
// p: t_p,
// }
// //l1.add(sid1)
// l1.add(rn_1)
// l1.add(rn)
// fmt.Printf("%x\n", l1.value)
//
// //sinit~<sid1~<sid1
// l2 := &Lfsr{
// value: sinit,
// p: t_p,
// }
// //l2.add(sid1)
// l2.add(sid1)
// l2.add(sid1)
// fmt.Printf("%x", l2.value)
//}
// 通过抓包数据测试svc校验逻辑
func main() {
var scw uint32 = 0xAE390B5A
var t_p uint32 = 0x0FC22F87
var sid uint32 = 0xa2bcfc8c
var scw1 uint32 = 0xAE390B5A
var sid1 uint32 = 0xa2bcfc8c
//var sid1 uint32 = 0x7665986c
//var sinit uint32 = 0xb763ec88
var sinit uint32 = 0xc8b60868
lfsr := Lfsr{
value: sid,
p: t_p,
}
lfsr.add(1)
var svcn_1 uint32 = 0xb4b6c3eb
svcn_1 = binary.LittleEndian.Uint32(binary.BigEndian.AppendUint32([]byte{}, svcn_1))
var svcn uint32 = 0xb4c640a2
svcn = binary.LittleEndian.Uint32(binary.BigEndian.AppendUint32([]byte{}, svcn))
var userData []byte = []byte{0x80, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00}
crc1 := crc32Encode(userData)
svc := crc1 ^ sid ^ lfsr.value ^ scw
fmt.Printf("%x\n", svc)
crc1 := crc32Encode1(userData)
m := func(svc1 uint32) uint32 {
return (svc1 ^ crc1) ^ scw1
}
rn_1 := m(svcn_1)
rn := m(svcn)
l1 := &Lfsr{
value: sinit,
}
//l1_1 := &Lfsr{value: rn}
//rn = l1_1.add(0)
l1.add(rn_1)
l1.add(0)
l1.add(rn)
fmt.Printf("%x\n", l1.value)
//sinit~<sid1~<sid1
l2 := &Lfsr{
value: sinit,
}
l2.add(sid1)
l2.add(0)
l2.add(sid1)
fmt.Printf("%x\n", l2.value)
fmt.Println(fmt.Sprintf("验证结果:%v", l1.value == l2.value))
}
func crc32Encode(data []byte) uint32 {
//// 通过抓包数据测试svc计算逻辑
//func main() {
// var scw uint32 = 0xAE390B5A
// var sid uint32 = 0xa2bcfc8c //remote sid0
// //var sid uint32 = 0xe9436c8e //remote sid1
// //var sid uint32 = 0x7665986c //local sid0
// //var sid uint32 = 0x67da286e //local sid1
//
// lfsr := Lfsr{
// value: sid,
// }
// lfsr.add(0)
// var userData []byte = []byte{0x80, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00}
// crc1 := crc32Encode1(userData)
// svc := crc1 ^ sid ^ lfsr.value ^ scw
// fmt.Printf("%x:%s\n", svc, "b4b6c3eb")
//}
func crc32Encode1(data []byte) uint32 {
return message.Rssp_I_Crc32C1(data)
}
type Lfsr struct {
value uint32
p uint32
}
func (l *Lfsr) add(x uint32) uint32 {
l.value = l.value ^ x
for i := 0; i < 1; i++ {
var carry bool
for i := 0; i < 32; i++ {
carry = l.value&0x80000000 != 0
l.value = l.value << 1
if l.value>>31 == 1 {
l.value ^= l.p
if carry {
l.value ^= msg.T_POLY_1
}
}
return l.value
}
//// FSFB2协议中POST_RXDATA(SIDSENDER)示例的测试
//func main() {
// var sinit uint32 = 0x0AA65708
// var sid uint32 = 0x59E82D0C
// var t8 uint32 = 0xEBDF7C2C
// var t9 uint32 = 0x0C806DD6
//
// sid_t8 := sid ^ t8
// fmt.Printf("%x\n", sid_t8)
// lfsr := Lfsr{
// value: sinit,
// }
// fmt.Printf("%x\n", lfsr.add(sid_t8))
// sid_t9 := sid ^ t9
// fmt.Printf("%x\n", sid_t9)
// fmt.Printf("%x\n", lfsr.add(sid_t9))
//
// l2 := Lfsr{value: 0}
// fmt.Printf("%X:%s", l2.add(lfsr.value), "BF550BA0")
//}
//// FSFB2协议中时间戳示例的测试
//func main() {
// var sid uint32 = 0x0B7A7124
// lfsr := Lfsr{
// value: sid,
// }
// fmt.Printf("%x\n", lfsr.add(0))
// fmt.Printf("%x\n", lfsr.add(0))
//}
//// FSFB2协议中CRC校验示例的测试
//func main() {
// dataStr := "00100010000000100010011100001111"
// runes := []rune(dataStr)
// for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
// runes[i], runes[j] = runes[j], runes[i]
// }
// dataStr = string(runes)
// data, err := strconv.ParseUint(dataStr, 2, 32)
// if err != nil {
// panic(err)
// }
// data2 := uint32(data)
// fmt.Printf("%x\n", onecrc32(0, uint32(data2), 0))
// mkcrctab(0)
// fmt.Printf("%x\n", Ncrc(0, binary.LittleEndian.AppendUint32([]byte{}, data2), 0))
// bytess := binary.LittleEndian.AppendUint32([]byte{}, data2)
// fmt.Printf("%x\n", crc32Encode1(bytess))
//}
//// // FSFB2协议中CRC校验示例的测试2
//func main() {
// var item1 uint32 = 0x013456ab
// var item uint32 = 0x44eeFFA4
// fmt.Printf("%x\n", onecrc32(0, item, onecrc32(0, item1, 0)))
// crctest := make([]byte, 8)
// binary.LittleEndian.PutUint32(crctest[0:4], item1)
// binary.LittleEndian.PutUint32(crctest[4:8], item)
// mkcrctab(0)
// fmt.Printf("%x\n", Ncrc(0, crctest, 0))
//}
var maskcrc []uint32 = []uint32{0xC672B008, 0x8806A731}
func onecrc32(ch uint, item uint32, start uint32) uint32 {
var accum uint32 = start
mask := maskcrc[ch]
for i := 32; i > 0; i-- {
if (item^accum)&1 == 1 {
accum = (accum >> 1) ^ mask
} else {
accum >>= 1
}
item >>= 1
}
return accum
}
const DIMTAB = 256
var crctab [2][DIMTAB]uint32
func onecrc(ch uint, item uint32, start uint32) uint32 {
accum := start
mask := maskcrc[ch]
for i := 8; i > 0; i-- {
if (item^accum)&1 != 0 {
accum = (accum >> 1) ^ mask
} else {
accum >>= 1
}
item >>= 1
}
return accum
}
func mkcrctab(ch uint) {
for i := 0; i < DIMTAB; i++ {
crctab[ch][i] = onecrc(ch, uint32(i), 0)
}
}
func Ncrc(ch uint, buf []byte, start uint32) uint32 {
crccode := start
for _, b := range buf {
crccode = crctab[ch][byte(crccode)^b] ^ ((crccode >> 8) & 0x00FFFFFF)
}
return crccode
}

View File

@ -4,320 +4,46 @@ import "github.com/snksoft/crc"
//rssp 协议中crc校验查表法实现
// // Crc16Table G(x)=X16+X11+X4+1计算初始值为0
// var crc16Table []uint32 = nil
// var crc32C1Table []uint32 = nil
// var crc32C2Table []uint32 = nil
const (
// SCW常量
RSSP_I_C1_SCW uint32 = 0xae390b5a
RSSP_I_C2_SCW uint32 = 0xc103589c
//时间戳生成多项式
RSSP_I_C1_TS uint32 = 0x0fc22f87
RSSP_I_C2_TS uint32 = 0xc3e887e1
)
var (
// crc16多项式为G(x)=X16+X11+X4+1
RSSP_I_CRC16 = &crc.Parameters{Width: 16, Polynomial: 0x0811, Init: 0x0, ReflectIn: true, ReflectOut: true, FinalXor: 0x0}
RSSP_I_CRC16 = crc.NewHash(&crc.Parameters{Width: 16, Polynomial: 0x0811, Init: 0x0, ReflectIn: true, ReflectOut: true, FinalXor: 0x0})
// 通道1 crc32多项式为0x100d4e63
RSSP_I_C1_CRC32 = &crc.Parameters{Width: 32, Polynomial: 0x100d4e63, Init: 0x0, ReflectIn: true, ReflectOut: true, FinalXor: 0x0}
RSSP_I_C1_CRC32 = crc.NewHash(&crc.Parameters{Width: 32, Polynomial: 0x100d4e63, Init: 0x0, ReflectIn: true, ReflectOut: true, FinalXor: 0x0})
// 通道2 crc32多项式为0x8ce56011
RSSP_I_C2_CRC32 = &crc.Parameters{Width: 32, Polynomial: 0x8ce56011, Init: 0x0, ReflectIn: true, ReflectOut: true, FinalXor: 0x0}
RSSP_I_C2_CRC32 = crc.NewHash(&crc.Parameters{Width: 32, Polynomial: 0x8ce56011, Init: 0x0, ReflectIn: true, ReflectOut: true, FinalXor: 0x0})
)
// Rssp_I_Crc16计算
func Rssp_I_Crc16(data []byte) uint16 {
return uint16(crc.CalculateCRC(RSSP_I_CRC16, data))
return uint16(RSSP_I_CRC16.CalculateCRC(data))
}
// 通道1的crc32
func Rssp_I_Crc32C1(data []byte) uint32 {
return uint32(crc.CalculateCRC(RSSP_I_C1_CRC32, data))
var result byte
for i, b := range data {
result = 0
for i := 0; i < 8; i++ {
result <<= 1
result |= b & 1
b >>= 1
}
data[i] = result
}
return uint32(RSSP_I_C1_CRC32.CalculateCRC(data))
}
// 通道2的crc32
func Rssp_I_Crc32C2(data []byte) uint32 {
return uint32(crc.CalculateCRC(RSSP_I_C2_CRC32, data))
}
// const ( //CRC生成多项式
// RsspCrc16GX uint32 = 0b1_0000_1000_0001_0001 //生成多项式 G(X)=X16+X11+X4+1
// RsspCrc32C1 uint32 = 0x100d4e63 //安全通道1 CRC32生成多项式
// RsspCrc32C2 uint32 = 0x8ce56011 //安全通道1 CRC32生成多项式
// )
// // InitRsspCrcTable 初始化RSSP协议中需要的CRC表
// func InitRsspCrcTable() {
// if crc16Table == nil {
// crc16Table = CreateCrcTable(RsspCrc16GX, 16, false)
// }
// if crc32C1Table == nil {
// crc32C1Table = CreateCrcTable(RsspCrc32C1, 32, false)
// }
// if crc32C2Table == nil {
// crc32C2Table = CreateCrcTable(RsspCrc32C2, 32, false)
// }
// }
// func RsspCrc16(data []byte) uint16 {
// return uint16(CrcTableBased(data, 16, 0, false, false, 0, crc16Table))
// }
// func RsspC1Crc32(data []byte) uint32 {
// return CrcTableBased(data, 32, 0, false, false, 0, crc32C1Table)
// }
// func RsspC2Crc32(data []byte) uint32 {
// return CrcTableBased(data, 32, 0, false, false, 0, crc32C2Table)
// }
// // CreateCrcTable 创建CRC表支持8、16、32位
// func CreateCrcTable(polynomial uint32, width int, input_reflected bool) []uint32 {
// var table = make([]uint32, 0, 256)
// for bt := 0x00; bt <= 0xff; bt++ {
// table = append(table, lookup(uint32(bt), polynomial, width, input_reflected))
// }
// return table
// }
/////////////////////////////////////////////////////////////////////////////
// // 反转(0b00001010->0b01010000)
// func reflect(data uint32, width int) uint32 {
// var register1 uint32 = 0
// var significant_mask uint32 = 0xffffffff >> (32 - width)
// var register_msb_mask uint32 = 1 << (width - 1)
// var register_lsb_mask uint32 = 1
// for i := 0; i < width; i++ {
// need_or := (data>>i)&register_lsb_mask == register_lsb_mask
// if need_or {
// register1 |= register_msb_mask >> i
// }
// }
// return register1 & significant_mask
// }
// // 计算单个数值的crc
// func lookup(data uint32,
// polynomial uint32,
// width int,
// input_reflected bool) uint32 {
// var register1 uint32 = 0
// var significant_mask uint32 = 0xffffffff >> (32 - width)
// var register_msb_mask uint32 = 1 << (width - 1)
// var register_lsb_mask uint32 = 1
// var byte_msb_mask uint32 = 0x80
// var byte_lsb_mask uint32 = 1
// if input_reflected {
// polynomial = reflect(polynomial, width)
// }
// for i := 0; i < 1+(width/8); i++ {
// var byteData uint32 = 0
// if i < 1 {
// byteData = data
// }
// for j := 0; j < 8; j++ {
// need_xor := false
// if input_reflected {
// need_xor = (register1 & register_lsb_mask) == register_lsb_mask
// register1 >>= 1
// need_or := (byteData & byte_lsb_mask) == byte_lsb_mask
// byteData >>= 1
// if need_or {
// register1 |= register_msb_mask
// }
// } else {
// need_xor = (register1 & register_msb_mask) == register_msb_mask
// register1 <<= 1
// need_or := (byteData & byte_msb_mask) == byte_msb_mask
// byteData <<= 1
// if need_or {
// register1 |= register_lsb_mask
// }
// }
// if need_xor {
// register1 ^= polynomial
// }
// }
// }
// return register1 & significant_mask
// }
// // CrcTableBased 查表法计算字节数组的crc
// func CrcTableBased(
// data []byte,
// width int,
// initial_value uint32,
// input_reflected bool,
// result_reflected bool,
// final_xor_value uint32,
// table []uint32) uint32 {
// //
// length := len(data)
// var register1 uint32 = initial_value
// var significant_mask uint32 = 0xffffffff >> (32 - width)
// var register_lsb_mask uint32 = 0xff
// if input_reflected {
// register1 = reflect(register1, width)
// }
// for i := 0; i < length; i++ {
// var byteData = uint32(data[i])
// var shift_out uint32 = 0
// if input_reflected {
// shift_out = register1 & register_lsb_mask
// register1 = (register1 >> 8) ^ table[shift_out^byteData]
// } else {
// shift_out = (register1 >> (width - 8)) & register_lsb_mask
// register1 = (register1 << 8) ^ table[shift_out^byteData]
// }
// }
// if input_reflected != result_reflected {
// register1 = reflect(register1, width)
// }
// return (register1 ^ final_xor_value) & significant_mask
// }
// func Crc(data []byte,
// polynomial uint32,
// width int,
// initial_value uint32,
// input_reflected bool,
// result_reflected bool,
// final_xor_value uint32) uint32 {
// length := len(data)
// var register1 uint32 = initial_value
// var significant_mask uint32 = 0xffffffff >> (32 - width)
// var register_lsb_mask uint32 = 0xff
// if input_reflected {
// register1 = reflect(register1, width)
// }
// for i := 0; i < length; i++ {
// var byteData uint32 = uint32(data[i])
// var shift_out uint32 = 0
// var value uint32 = 0
// if input_reflected {
// shift_out = register1 & register_lsb_mask
// value = lookup(shift_out^byteData, polynomial, width, input_reflected)
// register1 = (register1 >> 8) ^ value
// } else {
// shift_out = (register1 >> (width - 8)) & register_lsb_mask
// value = lookup(shift_out^byteData, polynomial, width, input_reflected)
// register1 = (register1 << 8) ^ value
// }
// }
// if input_reflected != result_reflected {
// register1 = reflect(register1, width)
// }
// return (register1 ^ final_xor_value) & significant_mask
// }
//////////////////////////LFSR//////////////////////////////
// 线性反馈移位寄存器
type RsspLFSR struct {
polynomial uint32 //生成多项式
width int //寄存器宽度
register uint32 //寄存器
initValue uint32 //初始值
rightShift bool //true-右移false-左移
}
func NewRsspLFSR(polynomial uint32, width int, init_value uint32, rightShift bool) *RsspLFSR {
var wd_msb_mask uint32 = 1 << (width - 1)
var wd_mask uint32 = 0xffffffff >> (32 - width)
init_value &= wd_mask
polynomial &= wd_mask
polynomial = (polynomial >> 1) | wd_msb_mask
//
return &RsspLFSR{polynomial: polynomial, width: width, register: init_value, initValue: init_value, rightShift: rightShift}
}
func (r *RsspLFSR) move() {
r.move0(r.rightShift)
}
func (r *RsspLFSR) MoveRight() *RsspLFSR {
r.move0(true)
return r
}
func (r *RsspLFSR) MoveLeft() *RsspLFSR {
r.move0(false)
return r
}
func (r *RsspLFSR) move0(rightShift bool) {
var significant_mask uint32 = 0xffffffff >> (32 - r.width)
//
r.register &= significant_mask
cb := r.register & r.polynomial & significant_mask
out := bitXor(cb, r.width)
if rightShift {
r.register >>= 1
r.register = r.register | (out << (r.width - 1))
} else {
r.register <<= 1
r.register = r.register | out
var result byte
for i, b := range data {
result = 0
for i := 0; i < 8; i++ {
result <<= 1
result |= b & 1
b >>= 1
}
data[i] = result
}
r.register &= significant_mask
}
func (r *RsspLFSR) GetAndMove() uint32 {
rt := r.register
r.move()
return rt
}
func (r *RsspLFSR) Get() uint32 {
return r.register
}
func (r *RsspLFSR) Reset() {
r.register = r.initValue
}
// return 0 或 1
func bitXor(data uint32, width int) uint32 {
var v uint32 = 0
var lsb_mask uint32 = 1
for i := 0; i < width; i++ {
v ^= data >> i
}
return v & lsb_mask
}
// ///////////////////////////////////////////////////////
const RsspSnMax = uint32(4294967295)
type RsspSn struct {
sn uint32 //顺序序列号最大值4294967295
initValue uint32
}
func NewRsspSn(initValue uint32) *RsspSn {
return &RsspSn{sn: initValue, initValue: initValue}
}
func (s *RsspSn) GetAndAdd() uint32 {
if s.sn < RsspSnMax {
s.sn++
return s.sn
} else {
s.sn = s.initValue
return s.sn
}
}
func (s *RsspSn) Get() uint32 {
return s.sn
return uint32(RSSP_I_C2_CRC32.CalculateCRC(data))
}

View File

@ -2,19 +2,31 @@ package message
import (
"fmt"
"github.com/snksoft/crc"
"testing"
)
func TestNewRsspLFSR(t *testing.T) {
lfsr := NewRsspLFSR(0x0FC22F87, 32, 0x7665986c, false)
for i := 0; i < 341; i++ {
lfsr.GetAndMove()
}
fmt.Printf("%x", lfsr.Get())
}
func TestRssp_I_Crc16(t *testing.T) {
bytes := []byte{0x01, 0x80, 0x3a, 0x30, 0x9e, 0x30, 0x24, 0x85, 00, 00, 0x23, 00, 0x3b, 0x2b, 0xb1, 0x08, 0xf8, 0xc0, 0x6c, 0x16, 0x80, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00}
crc := Rssp_I_Crc16(bytes)
fmt.Printf("crc16: %x\n", crc)
}
func BenchmarkRssp_I_Crc32C1(b *testing.B) {
var params = &crc.Parameters{
Width: 32,
Polynomial: 0x100d4e63,
ReflectIn: true,
ReflectOut: true,
Init: 0,
FinalXor: 0,
}
hash := crc.NewHash(params)
bytes := []byte{0x01, 0x80, 0x3a, 0x30, 0x9e, 0x30, 0x24, 0x85, 00, 00, 0x23, 00, 0x3b, 0x2b, 0xb1, 0x08, 0xf8, 0xc0, 0x6c, 0x16, 0x80, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00}
for i := 0; i < b.N; i++ {
hash.CalculateCRC(bytes)
}
//for i := 0; i < b.N; i++ {
// crc.CalculateCRC(params, bytes)
//}
}