rts-sim-testing-service/third_party/message/rssp.go

327 lines
7.2 KiB
Go
Raw Permalink Normal View History

2023-10-25 11:23:11 +08:00
package message
2023-10-25 17:03:48 +08:00
import (
"encoding/binary"
"fmt"
2023-11-01 17:46:24 +08:00
"strings"
2023-10-25 17:03:48 +08:00
)
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-11-01 17:46:24 +08:00
func (h *RsspHead) Parse(buf []byte) bool {
if len(buf) < 6 {
return false
}
h.decode(buf)
return true
}
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-11-01 17:46:24 +08:00
// RsspPackCrc16Check RSSP报文CRC16校验
func RsspPackCrc16Check(pack []byte) bool {
if len(pack) <= 2 { //报文长度不够,校验不通过
return false
}
//
pack16 := binary.LittleEndian.Uint16(pack[len(pack)-2:])
crc16 := Rssp_I_Crc16(pack[:len(pack)-2])
2023-11-01 17:46:24 +08:00
//
return crc16 == pack16
}
/////////////////////////////////////////////////
2023-10-25 11:23:11 +08:00
// RsspRsd 实时安全数据包
type RsspRsd struct {
RsspHead
2023-11-02 14:37:50 +08:00
//安全校验域-序列号(4Byte),可以是一个随时间周期变化的计数器
2023-10-25 11:23:11 +08:00
Sn uint32
//安全校验域-安全数据长度(2Byte)
Sdl uint16
//安全校验域-安全校验通道1(4Byte)
Svc1 uint32
//安全校验域-安全校验通道2(4Byte)
Svc2 uint32
//用户数据包-安全应用数据(总字节数480)
Sad []byte
//报文尾-CRC16(2Byte)
Crc16 uint16
}
2023-11-13 17:35:53 +08:00
func (r *RsspRsd) IsMaster() bool {
return r.Pic == PIC_MASTER
}
func (r *RsspRsd) IsSlave() bool {
return r.Pic == PIC_SLAVE
}
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 = Rssp_I_Crc16(data)
2023-10-25 11:23:11 +08:00
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 = Rssp_I_Crc16(data)
2023-10-25 17:03:48 +08:00
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 = Rssp_I_Crc16(data)
2023-10-25 17:03:48 +08:00
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
2023-11-01 17:46:24 +08:00
const ( //报文类型
2023-10-25 17:03:48 +08:00
RSD_A = RsspType(0x80)
RSD_B = RsspType(0x81)
SSE = RsspType(0x90)
SSR = RsspType(0x91)
)
2023-11-01 17:46:24 +08:00
// RsspHeadMcCheck 报文类型检测
func RsspHeadMcCheck(head *RsspHead) bool {
switch head.Mc {
2023-11-02 09:24:11 +08:00
case RSD_A:
return true
case RSD_B:
return true
case SSR:
return true
case SSE:
2023-11-01 17:46:24 +08:00
return true
default:
return false
}
}
type PicType = byte
const ( //协议交互类别
PIC_MASTER = PicType(0x01) //主机发送的安全数据
PIC_SLAVE = PicType(0x02) //备机发送的安全数据
)
// RsspHeadPicCheck 协议交互类别检测
func RsspHeadPicCheck(head *RsspHead) bool {
switch head.Pic {
2023-11-02 09:24:11 +08:00
case PIC_MASTER:
return true
case PIC_SLAVE:
2023-11-01 17:46:24 +08:00
return true
default:
return false
}
}
2023-11-02 09:24:11 +08:00
// ParseRsspPack 解析已经校验的RSSP数据包
func ParseRsspPack(ph *RsspHead, pack []byte) Rssper {
2023-10-25 17:03:48 +08:00
//
var codec RsspCodec
switch ph.Mc {
2023-11-02 09:24:11 +08:00
case RSD_A:
fallthrough
case RSD_B:
2023-10-25 17:03:48 +08:00
codec = &RsspRsd{}
case SSE:
codec = &RsspSse{}
case SSR:
codec = &RsspSsr{}
default:
2023-11-02 09:24:11 +08:00
return nil
2023-10-25 17:03:48 +08:00
}
//
2023-11-02 09:24:11 +08:00
if codec.Decode(pack) == nil {
return codec.(Rssper)
}
return nil
2023-10-25 17:03:48 +08:00
}
2023-11-01 17:46:24 +08:00
// PackToString 字节数组转换为16进制字节字符串
func PackToString(pack []byte) string {
b := &strings.Builder{}
first := true
for _, d := range pack {
if first {
b.WriteString(fmt.Sprintf("0x%0X", d))
first = false
} else {
b.WriteString(fmt.Sprintf(",0x%0X", d))
}
}
return b.String()
}
2023-11-02 14:37:50 +08:00
////////////////////////////////////////////////////////////////////