rssp
This commit is contained in:
parent
ebc2bc7cc6
commit
5f81e591ef
|
@ -0,0 +1,23 @@
|
|||
package axle_device
|
||||
|
||||
// AxleDeviceConfig CI系统与计轴设备的安全通信协议配置参数
|
||||
// 计轴设备(管理一个集中站的所有计轴器)配置
|
||||
type AxleDeviceConfig struct {
|
||||
SrcAddr uint16 //16位源地址
|
||||
DstAddr uint16 //16位目的地址
|
||||
DataVer1 uint32 //通道1数据版本
|
||||
DataVer2 uint32 //通道2数据版本
|
||||
SID1 uint32 //通道1源标识
|
||||
SID2 uint32 //通道2源标识
|
||||
SINIT1 uint32 //通道1序列初始
|
||||
SINIT2 uint32 //通道2序列初始
|
||||
SendingPeriod uint32 //接收方每个安全通信会话对应的发送周期值,单位ms
|
||||
SSRTimeout uint32 //等待SSR回应的定时器超时值,单位ms
|
||||
Mtv uint32 //每个安全通信会话可容忍的最大时序偏差
|
||||
Udl uint32 //每个安全通信会话RSD应用数据长度发送和接收的配置值(支持固定长度和可变长度);0-可变长度,大于0即固定长度
|
||||
}
|
||||
|
||||
// CheckAddress 检测目标源地址目的地址是否在配置中
|
||||
func (c *AxleDeviceConfig) CheckAddress(srcAddr uint16, dstAddr uint16) bool {
|
||||
return true
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package axle_device
|
||||
|
||||
import (
|
||||
"joylink.club/bj-rtsts-server/third_party/message"
|
||||
)
|
||||
|
||||
//实现rssp通信流程
|
||||
|
||||
// 处理接收到的rssp报文
|
||||
func handleRsspMsg(pack []byte, config *AxleDeviceConfig) {
|
||||
//报文头校验
|
||||
head := &message.RsspHead{}
|
||||
if !head.Parse(pack) { //解析报文头失败
|
||||
return
|
||||
}
|
||||
if !message.RsspHeadMcCheck(head) { //报文类别检测未通过
|
||||
return
|
||||
}
|
||||
if !message.RsspHeadPicCheck(head) { //协议交互类别检测未通过
|
||||
return
|
||||
}
|
||||
if !config.CheckAddress(head.Sa, head.Da) { //校验报文头中源地址和目的地址是否包含在已配置列表中
|
||||
return
|
||||
}
|
||||
//报文尾校验
|
||||
if !message.RsspPackCrc16Check(pack) { //整个报文crc16校验未通过
|
||||
return
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@ package message
|
|||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//RSSP-1 V1.0 铁路信号安全通信协议
|
||||
|
@ -19,6 +20,13 @@ type RsspHead struct {
|
|||
Da uint16
|
||||
}
|
||||
|
||||
func (h *RsspHead) Parse(buf []byte) bool {
|
||||
if len(buf) < 6 {
|
||||
return false
|
||||
}
|
||||
h.decode(buf)
|
||||
return true
|
||||
}
|
||||
func (h *RsspHead) Type() RsspType {
|
||||
return h.Mc
|
||||
}
|
||||
|
@ -47,6 +55,20 @@ func (h *RsspHead) encode() []byte {
|
|||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
// RsspPackCrc16Check RSSP报文CRC16校验
|
||||
func RsspPackCrc16Check(pack []byte) bool {
|
||||
if len(pack) <= 2 { //报文长度不够,校验不通过
|
||||
return false
|
||||
}
|
||||
//
|
||||
pack16 := binary.LittleEndian.Uint16(pack[len(pack)-2:])
|
||||
crc16 := RsspCrc16(pack[:len(pack)-2])
|
||||
//
|
||||
return crc16 == pack16
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
// RsspRsd 实时安全数据包
|
||||
type RsspRsd struct {
|
||||
RsspHead
|
||||
|
@ -224,13 +246,40 @@ type Rssper interface {
|
|||
}
|
||||
type RsspType = byte
|
||||
|
||||
const (
|
||||
const ( //报文类型
|
||||
RSD_A = RsspType(0x80)
|
||||
RSD_B = RsspType(0x81)
|
||||
SSE = RsspType(0x90)
|
||||
SSR = RsspType(0x91)
|
||||
)
|
||||
|
||||
// RsspHeadMcCheck 报文类型检测
|
||||
func RsspHeadMcCheck(head *RsspHead) bool {
|
||||
switch head.Mc {
|
||||
case RSD_A | RSD_B | SSE | SSR:
|
||||
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 {
|
||||
case PIC_MASTER | PIC_SLAVE:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// ParseRsspPack 解析RSSP数据包
|
||||
func ParseRsspPack(pack []byte) (Rssper, error) {
|
||||
// pack 进行CRC16循环冗余校验,检测整个包的完整性
|
||||
|
@ -258,3 +307,18 @@ func ParseRsspPack(pack []byte) (Rssper, error) {
|
|||
e := codec.Decode(pack)
|
||||
return codec.(Rssper), e
|
||||
}
|
||||
|
||||
// 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()
|
||||
}
|
||||
|
|
|
@ -98,11 +98,6 @@ func initWorld(s *memory.VerifySimulation) error {
|
|||
|
||||
// 运行仿真第三方模块
|
||||
func runThirdParty(s *memory.VerifySimulation) error {
|
||||
/*
|
||||
if s != nil { //测试时不启动第三方服务
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
// 动力学启动
|
||||
err := dynamics.Default().Start(s)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue