2023-10-25 11:23:11 +08:00
|
|
|
|
package message
|
|
|
|
|
|
2023-10-25 17:03:48 +08:00
|
|
|
|
import (
|
|
|
|
|
"encoding/binary"
|
|
|
|
|
"fmt"
|
|
|
|
|
)
|
2023-10-25 11:23:11 +08:00
|
|
|
|
|
|
|
|
|
//RSSP-1 V1.0 铁路信号安全通信协议
|
|
|
|
|
|
|
|
|
|
// RsspHead rssp报文头
|
|
|
|
|
type RsspHead struct {
|
|
|
|
|
//报文头-协议交互类别(1Byte)
|
|
|
|
|
Pic byte
|
|
|
|
|
//报文头-报文类别(1Byte)
|
|
|
|
|
Mc byte
|
|
|
|
|
//报文头-源地址(2Byte)
|
|
|
|
|
Sa uint16
|
|
|
|
|
//报文头-目地址(2Byte)
|
|
|
|
|
Da uint16
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-26 16:03:05 +08:00
|
|
|
|
const (
|
|
|
|
|
RsspCrc16GX uint32 = 0b1_0000_1000_0001_0001 //生成多项式 G(X)=X16+X11+X4+1
|
|
|
|
|
)
|
|
|
|
|
|
2023-10-25 17:03:48 +08:00
|
|
|
|
func (h *RsspHead) Type() RsspType {
|
|
|
|
|
return h.Mc
|
|
|
|
|
}
|
|
|
|
|
func (h *RsspHead) decode(buf []byte) {
|
|
|
|
|
ri := 0
|
|
|
|
|
//报文头
|
|
|
|
|
h.Pic = buf[ri]
|
|
|
|
|
ri++
|
|
|
|
|
h.Mc = buf[ri]
|
|
|
|
|
ri++
|
|
|
|
|
h.Sa = binary.LittleEndian.Uint16(buf[ri : ri+2])
|
|
|
|
|
ri += 2
|
|
|
|
|
h.Da = binary.LittleEndian.Uint16(buf[ri : ri+2])
|
|
|
|
|
ri += 2
|
|
|
|
|
}
|
|
|
|
|
func (h *RsspHead) encode() []byte {
|
|
|
|
|
data := make([]byte, 0, 6)
|
|
|
|
|
//报文头
|
|
|
|
|
data = append(data, h.Pic)
|
|
|
|
|
data = append(data, h.Mc)
|
|
|
|
|
data = binary.LittleEndian.AppendUint16(data, h.Sa)
|
|
|
|
|
data = binary.LittleEndian.AppendUint16(data, h.Da)
|
|
|
|
|
//
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////
|
|
|
|
|
|
2023-10-25 11:23:11 +08:00
|
|
|
|
// RsspRsd 实时安全数据包
|
|
|
|
|
type RsspRsd struct {
|
|
|
|
|
RsspHead
|
|
|
|
|
//安全校验域-序列号(4Byte)
|
|
|
|
|
Sn uint32
|
|
|
|
|
//安全校验域-安全数据长度(2Byte)
|
|
|
|
|
Sdl uint16
|
|
|
|
|
//安全校验域-安全校验通道1(4Byte)
|
|
|
|
|
Svc1 uint32
|
|
|
|
|
//安全校验域-安全校验通道2(4Byte)
|
|
|
|
|
Svc2 uint32
|
|
|
|
|
//用户数据包-安全应用数据(总字节数480)
|
|
|
|
|
Sad []byte
|
|
|
|
|
//报文尾-CRC16(2Byte)
|
|
|
|
|
Crc16 uint16
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-26 16:03:05 +08:00
|
|
|
|
const (
|
|
|
|
|
CRC32_G_C1 = (uint64(0x01) << 32) | uint64(0x100d4e63) //crc32生成多项式
|
|
|
|
|
CRC32_G_C2 = (uint64(0x01) << 32) | uint64(0x8ce56011) //crc32生成多项式
|
|
|
|
|
SCW_C1 = uint32(0xae390b5a) //SCW常
|
|
|
|
|
SCW_C2 = uint32(0xc103589c) //SCW常
|
|
|
|
|
SJC_C1 = uint32(0x0fc22f87) //时间戳生成多项式
|
|
|
|
|
SJC_C2 = uint32(0xc3e887e1) //时间戳生成多项式
|
|
|
|
|
)
|
|
|
|
|
|
2023-10-25 11:23:11 +08:00
|
|
|
|
func (r *RsspRsd) Encode() []byte {
|
|
|
|
|
data := make([]byte, 0, 6+14+len(r.Sad)+2)
|
|
|
|
|
//报文头
|
2023-10-25 17:03:48 +08:00
|
|
|
|
data = append(data, r.RsspHead.encode()...)
|
2023-10-25 11:23:11 +08:00
|
|
|
|
//安全校验域
|
|
|
|
|
data = binary.LittleEndian.AppendUint32(data, r.Sn)
|
|
|
|
|
data = binary.LittleEndian.AppendUint16(data, r.Sdl)
|
|
|
|
|
data = binary.LittleEndian.AppendUint32(data, r.Svc1)
|
|
|
|
|
data = binary.LittleEndian.AppendUint32(data, r.Svc2)
|
|
|
|
|
//用户数据包
|
|
|
|
|
data = append(data, r.Sad...)
|
|
|
|
|
//报文尾-CRC16
|
|
|
|
|
r.Crc16 = uint16(NewCrc(uint64(RsspCrc16GX), 17, data).Generate())
|
|
|
|
|
data = binary.LittleEndian.AppendUint16(data, r.Crc16)
|
|
|
|
|
//
|
|
|
|
|
return data
|
|
|
|
|
}
|
2023-10-25 17:03:48 +08:00
|
|
|
|
func (r *RsspRsd) Decode(buf []byte) error {
|
|
|
|
|
//报文头
|
|
|
|
|
r.RsspHead.decode(buf)
|
|
|
|
|
ri := 6
|
|
|
|
|
//安全校验域
|
|
|
|
|
r.Sn = binary.LittleEndian.Uint32(buf[ri : ri+4])
|
|
|
|
|
ri += 4
|
|
|
|
|
r.Sdl = binary.LittleEndian.Uint16(buf[ri : ri+2])
|
|
|
|
|
ri += 2
|
|
|
|
|
r.Svc1 = binary.LittleEndian.Uint32(buf[ri : ri+4])
|
|
|
|
|
ri += 4
|
|
|
|
|
r.Svc2 = binary.LittleEndian.Uint32(buf[ri : ri+4])
|
|
|
|
|
ri += 4
|
|
|
|
|
//用户数据
|
|
|
|
|
sadLen := int(r.Sdl) - 8
|
|
|
|
|
r.Sad = buf[ri : ri+sadLen]
|
|
|
|
|
ri += sadLen
|
|
|
|
|
//报文尾
|
|
|
|
|
r.Crc16 = binary.LittleEndian.Uint16(buf[ri : ri+2])
|
|
|
|
|
//
|
2023-10-25 11:23:11 +08:00
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-25 17:03:48 +08:00
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
|
|
2023-10-25 11:23:11 +08:00
|
|
|
|
// RsspSse 时序校正请求包
|
|
|
|
|
type RsspSse struct {
|
|
|
|
|
RsspHead
|
|
|
|
|
//安全校验域-序列号(4Byte)
|
|
|
|
|
Sn uint32
|
|
|
|
|
//安全校验域-时序校正请求通道1(4Byte)
|
|
|
|
|
SeqEnq1 uint32
|
|
|
|
|
//安全校验域-时序校正请求通道2(4Byte)
|
|
|
|
|
SeqEnq2 uint32
|
|
|
|
|
//报文尾-CRC16(2Byte)
|
|
|
|
|
Crc16 uint16
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-25 17:03:48 +08:00
|
|
|
|
func (r *RsspSse) Encode() []byte {
|
|
|
|
|
data := make([]byte, 0, 20)
|
|
|
|
|
//报文头
|
|
|
|
|
data = append(data, r.RsspHead.encode()...)
|
|
|
|
|
//安全校验域
|
|
|
|
|
data = binary.LittleEndian.AppendUint32(data, r.Sn)
|
|
|
|
|
data = binary.LittleEndian.AppendUint32(data, r.SeqEnq1)
|
|
|
|
|
data = binary.LittleEndian.AppendUint32(data, r.SeqEnq2)
|
|
|
|
|
//报文尾-CRC16
|
|
|
|
|
r.Crc16 = uint16(NewCrc(uint64(RsspCrc16GX), 17, data).Generate())
|
|
|
|
|
data = binary.LittleEndian.AppendUint16(data, r.Crc16)
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
func (r *RsspSse) Decode(buf []byte) error {
|
|
|
|
|
//报文头
|
|
|
|
|
r.RsspHead.decode(buf)
|
|
|
|
|
//安全校验域
|
|
|
|
|
ri := 6
|
|
|
|
|
r.Sn = binary.LittleEndian.Uint32(buf[ri : ri+4])
|
|
|
|
|
ri += 4
|
|
|
|
|
r.SeqEnq1 = binary.LittleEndian.Uint32(buf[ri : ri+4])
|
|
|
|
|
ri += 4
|
|
|
|
|
r.SeqEnq2 = binary.LittleEndian.Uint32(buf[ri : ri+4])
|
|
|
|
|
ri += 4
|
|
|
|
|
//报文尾
|
|
|
|
|
r.Crc16 = binary.LittleEndian.Uint16(buf[ri : ri+2])
|
|
|
|
|
//
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////
|
|
|
|
|
|
2023-10-25 11:23:11 +08:00
|
|
|
|
// RsspSsr 时序校正应答包,用于回应SSE
|
|
|
|
|
type RsspSsr struct {
|
|
|
|
|
RsspHead
|
|
|
|
|
//安全校验域-应答方的序列号(4Byte)
|
|
|
|
|
SrSn uint32
|
|
|
|
|
//安全校验域-请求方的序列号(4Byte)
|
|
|
|
|
SeSn uint32
|
|
|
|
|
//安全校验域-时序初始化通道1(4Byte)
|
|
|
|
|
Tic1 uint32
|
|
|
|
|
//安全校验域-时序初始化通道2(4Byte)
|
|
|
|
|
Tic2 uint32
|
|
|
|
|
//安全校验域-数据版本号(1Byte)
|
|
|
|
|
Dvn byte
|
|
|
|
|
//报文尾-CRC16(2Byte)
|
|
|
|
|
Crc16 uint16
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-25 17:03:48 +08:00
|
|
|
|
func (r *RsspSsr) Encode() []byte {
|
|
|
|
|
data := make([]byte, 0, 25)
|
|
|
|
|
//报文头
|
|
|
|
|
data = append(data, r.RsspHead.encode()...)
|
|
|
|
|
//安全校验域
|
|
|
|
|
data = binary.LittleEndian.AppendUint32(data, r.SrSn)
|
|
|
|
|
data = binary.LittleEndian.AppendUint32(data, r.SeSn)
|
|
|
|
|
data = binary.LittleEndian.AppendUint32(data, r.Tic1)
|
|
|
|
|
data = binary.LittleEndian.AppendUint32(data, r.Tic2)
|
|
|
|
|
data = append(data, r.Dvn)
|
|
|
|
|
//报文尾-CRC16
|
|
|
|
|
r.Crc16 = uint16(NewCrc(uint64(RsspCrc16GX), 17, data).Generate())
|
|
|
|
|
data = binary.LittleEndian.AppendUint16(data, r.Crc16)
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
func (r *RsspSsr) Decode(buf []byte) error {
|
|
|
|
|
//报文头
|
|
|
|
|
r.RsspHead.decode(buf)
|
|
|
|
|
//安全校验域
|
|
|
|
|
ri := 6
|
|
|
|
|
r.SrSn = binary.LittleEndian.Uint32(buf[ri : ri+4])
|
|
|
|
|
ri += 4
|
|
|
|
|
r.SeSn = binary.LittleEndian.Uint32(buf[ri : ri+4])
|
|
|
|
|
ri += 4
|
|
|
|
|
r.Tic1 = binary.LittleEndian.Uint32(buf[ri : ri+4])
|
|
|
|
|
ri += 4
|
|
|
|
|
r.Tic2 = binary.LittleEndian.Uint32(buf[ri : ri+4])
|
|
|
|
|
ri += 4
|
|
|
|
|
r.Dvn = buf[ri]
|
|
|
|
|
ri += 1
|
|
|
|
|
//报文尾
|
|
|
|
|
r.Crc16 = binary.LittleEndian.Uint16(buf[ri : ri+2])
|
|
|
|
|
//
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
type RsspCodec interface {
|
|
|
|
|
Encode() []byte
|
|
|
|
|
Decode(buf []byte) error
|
|
|
|
|
}
|
|
|
|
|
type Rssper interface {
|
|
|
|
|
Type() RsspType
|
|
|
|
|
}
|
|
|
|
|
type RsspType = byte
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
RSD_A = RsspType(0x80)
|
|
|
|
|
RSD_B = RsspType(0x81)
|
|
|
|
|
SSE = RsspType(0x90)
|
|
|
|
|
SSR = RsspType(0x91)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// ParseRsspPack 解析RSSP数据包
|
|
|
|
|
func ParseRsspPack(pack []byte) (Rssper, error) {
|
|
|
|
|
// pack 进行CRC16循环冗余校验,检测整个包的完整性
|
|
|
|
|
gCrc16 := uint16(NewCrc(uint64(RsspCrc16GX), 17, pack[0:len(pack)-2]).Generate())
|
|
|
|
|
pCrc16 := binary.LittleEndian.Uint16(pack[len(pack)-2 : len(pack)])
|
|
|
|
|
if gCrc16 != pCrc16 {
|
|
|
|
|
return nil, fmt.Errorf("ParseRsspPack 整个数据包CRC16校验未通过")
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
ph := &RsspHead{}
|
|
|
|
|
ph.decode(pack)
|
|
|
|
|
//
|
|
|
|
|
var codec RsspCodec
|
|
|
|
|
switch ph.Mc {
|
|
|
|
|
case RSD_A | RSD_B:
|
|
|
|
|
codec = &RsspRsd{}
|
|
|
|
|
case SSE:
|
|
|
|
|
codec = &RsspSse{}
|
|
|
|
|
case SSR:
|
|
|
|
|
codec = &RsspSsr{}
|
|
|
|
|
default:
|
|
|
|
|
return nil, fmt.Errorf("ParseRsspPack 无法识别的报文类型码[0x%x]", ph.Mc)
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
e := codec.Decode(pack)
|
|
|
|
|
return codec.(Rssper), e
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-25 11:23:11 +08:00
|
|
|
|
// //////////////////CRC循环冗余校验--移位寄存器///////////////////////////
|
|
|
|
|
|
|
|
|
|
type crc struct {
|
|
|
|
|
//生成多项式,即二进制位数,如生成多项式X4+X3+1对应二进制11001共5位,生成的校验码长度为4
|
|
|
|
|
g uint64
|
2023-10-26 13:48:53 +08:00
|
|
|
|
//生成多项式二进制长度
|
|
|
|
|
gl int
|
2023-10-25 11:23:11 +08:00
|
|
|
|
//移位寄存器
|
2023-10-26 13:48:53 +08:00
|
|
|
|
reg *sReg
|
2023-10-25 11:23:11 +08:00
|
|
|
|
//消息数据
|
2023-10-26 13:48:53 +08:00
|
|
|
|
m *crcBitPipe
|
|
|
|
|
//补零
|
|
|
|
|
b *crcBitPipe
|
2023-10-25 11:23:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewCrc CRC循环冗余校验
|
|
|
|
|
//
|
|
|
|
|
// g : 生成多项式
|
2023-10-26 13:48:53 +08:00
|
|
|
|
// gl : 生成多项式的长度即二进制位数,gl值为8的倍数加1
|
2023-10-25 11:23:11 +08:00
|
|
|
|
// m : 被校验的消息数据
|
2023-10-26 13:48:53 +08:00
|
|
|
|
func NewCrc(g uint64, gl int, m []byte) *crc {
|
|
|
|
|
|
|
|
|
|
return &crc{g: g, gl: gl, m: NewCrcBitPipe(m), b: NewCrcBit0Pipe(gl - 1), reg: NewReg(gl)}
|
2023-10-25 11:23:11 +08:00
|
|
|
|
}
|
2023-10-26 13:48:53 +08:00
|
|
|
|
func (c *crc) canToReg() bool {
|
|
|
|
|
if c.m.HasFlowBit() {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
if c.b.HasFlowBit() {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 被校验数据尽可能入移位寄存器
|
|
|
|
|
func (c *crc) mToReg() {
|
|
|
|
|
for c.reg.Glb() <= 0 { //寄存器左侧有0位
|
|
|
|
|
if c.m.HasFlowBit() {
|
|
|
|
|
c.reg.Ifr(c.m.FlowBit())
|
|
|
|
|
} else if c.b.HasFlowBit() {
|
|
|
|
|
c.reg.Ifr(c.b.FlowBit())
|
|
|
|
|
} else {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generate 生成CRC效验码
|
2023-10-25 11:23:11 +08:00
|
|
|
|
func (c *crc) Generate() uint64 {
|
2023-10-26 13:48:53 +08:00
|
|
|
|
for c.canToReg() {
|
|
|
|
|
c.mToReg()
|
|
|
|
|
if c.reg.Glb() >= 1 {
|
|
|
|
|
c.reg.Xor(c.g)
|
|
|
|
|
} else {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return c.reg.RegV()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 把字节数组包装成bit流,bit从byte左侧流出
|
|
|
|
|
type crcBitPipe struct {
|
|
|
|
|
buf []byte
|
|
|
|
|
bi int //当前流出的字节在buf中的下标,[0,len(buf)-1]
|
|
|
|
|
i int //在当前流出的字节中,当前可流出的bit在字节中的位置,[7,0]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewCrcBitPipe(buf []byte) *crcBitPipe {
|
|
|
|
|
return &crcBitPipe{buf: buf, bi: 0, i: 7}
|
|
|
|
|
}
|
|
|
|
|
func NewCrcBit0Pipe(n int) *crcBitPipe {
|
|
|
|
|
y := n % 8
|
|
|
|
|
z := n / 8
|
|
|
|
|
yy := 0
|
|
|
|
|
if y > 0 {
|
|
|
|
|
yy = 1
|
|
|
|
|
}
|
|
|
|
|
cap := z + yy
|
|
|
|
|
buf := make([]byte, 0, cap)
|
|
|
|
|
for i := 0; i < cap; i++ {
|
|
|
|
|
buf = append(buf, 0x00)
|
|
|
|
|
}
|
|
|
|
|
si := 7
|
|
|
|
|
if y > 0 {
|
|
|
|
|
si = y - 1
|
|
|
|
|
}
|
|
|
|
|
return &crcBitPipe{buf: buf, bi: 0, i: si}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FlowBit 从左侧流出一个bit
|
|
|
|
|
// 正常返回值为0或1,流结束返回大于1的值
|
|
|
|
|
func (p *crcBitPipe) FlowBit() byte {
|
|
|
|
|
if p.HasFlowBit() {
|
|
|
|
|
rt := 0x01 & (p.buf[p.bi] >> p.i)
|
|
|
|
|
p.i--
|
|
|
|
|
if p.i < 0 {
|
|
|
|
|
p.bi++
|
|
|
|
|
p.i = 7
|
|
|
|
|
}
|
|
|
|
|
return rt
|
|
|
|
|
}
|
|
|
|
|
return 2
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *crcBitPipe) HasFlowBit() bool {
|
|
|
|
|
return p.bi < len(p.buf) && p.i >= 0
|
|
|
|
|
}
|
|
|
|
|
func (p *crcBitPipe) Reset() *crcBitPipe {
|
|
|
|
|
p.bi = 0
|
|
|
|
|
p.i = 7
|
|
|
|
|
return p
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 移位寄存器,最长64位
|
|
|
|
|
type sReg struct {
|
|
|
|
|
m uint64 //寄存器存储
|
|
|
|
|
l int //寄存器长度
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewReg(l int) *sReg {
|
|
|
|
|
return &sReg{m: 0, l: l}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Glb 寄存器最左侧bit位值
|
|
|
|
|
func (r *sReg) Glb() byte {
|
|
|
|
|
return byte(0x01 & (r.m >> (r.l - 1)))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ifr 从寄存器右侧移入一个bit
|
|
|
|
|
func (r *sReg) Ifr(bit byte) *sReg {
|
|
|
|
|
r.m = (r.m << 1) | uint64(bit)
|
|
|
|
|
return r
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// And 寄存器的值与v位与操作,结果存入寄存器
|
|
|
|
|
func (r *sReg) And(v uint64) *sReg {
|
|
|
|
|
r.m = r.m & v
|
|
|
|
|
return r
|
|
|
|
|
}
|
|
|
|
|
func (r *sReg) Xor(v uint64) *sReg {
|
|
|
|
|
r.m = r.m ^ v
|
|
|
|
|
return r
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RegV 获取寄存器中的值
|
|
|
|
|
func (r *sReg) RegV() uint64 {
|
|
|
|
|
return r.m
|
2023-10-25 11:23:11 +08:00
|
|
|
|
}
|