This commit is contained in:
xzb 2023-11-03 17:12:52 +08:00
parent 55c8302d3d
commit 3ba386ed60
2 changed files with 92 additions and 19 deletions

View File

@ -3,18 +3,18 @@ package axle_device
// RsspConfig CI系统与计轴设备的安全通信协议配置参数
// 计轴设备(管理一个集中站的所有计轴器)配置
type RsspConfig 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 //每个安全通信会话可容忍的最大时序偏差,即当前接收的RSD的序列号与上一次RSD的序列号最大允许差值
Udl uint32 //每个安全通信会话RSD应用数据长度发送和接收的配置值支持固定长度和可变长度;0-可变长度大于0即固定长度
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
SsrRsspTimeout uint32 //等待SSR回应的定时器超时值,为RsspTimer时间,1=SendingPeriod
Mtv uint32 //每个安全通信会话可容忍的最大时序偏差,即当前接收的RSD的序列号与上一次RSD的序列号最大允许差值
Udl uint32 //每个安全通信会话RSD应用数据长度发送和接收的配置值支持固定长度和可变长度;0-可变长度大于0即固定长度
}
// CheckAddress 检测目标源地址目的地址是否在配置中

View File

@ -7,8 +7,11 @@ import (
// RsspChannel 实现rssp通信
type RsspChannel struct {
//rssp安全通信配置
config *RsspConfig
//批次编号,发送序列号,周期计数器
//rssp时钟
rsspTimer *RsspTimer
//批次编号,发送序列号
sn *message.RsspSn
//安全通道1时间戳
ch1Ts *message.RsspLFSR
@ -24,10 +27,42 @@ type RsspChannel struct {
rcvCh2Ts uint32
//最近一次接收到的报文的序列号
rcvSn uint32
//时序校验请求发送记录
sendSseRecord *SseFireRecord
}
// HandleRsspMsg 处理接收到的rssp报文
func (s *RsspChannel) HandleRsspMsg(pack []byte) {
// RsspTimer rssp时钟每一个tick周期为config.SendingPeriod
type RsspTimer struct {
t uint64
}
func (s *RsspTimer) tick() {
s.t++
}
func (s *RsspTimer) now() uint64 {
return s.t
}
// SseFireRecord 发送时序校验请求的记录
type SseFireRecord struct {
send *message.RsspSse //已经发送的时序校验请求
rsspTime uint64 //发送时序校验请求时的rssp时间
}
func (s *SseFireRecord) record(send *message.RsspSse, rsspTime uint64) {
s.send = send
s.rsspTime = rsspTime
}
func (s *SseFireRecord) clear() {
s.send = nil
s.rsspTime = 0
}
func (s *SseFireRecord) hasRecord() bool {
return s.send != nil
}
// 处理接收到的rssp报文
func (s *RsspChannel) handleRsspMsg(pack []byte) {
//报文头校验
head := &message.RsspHead{}
if !head.Parse(pack) { //解析报文头失败
@ -72,6 +107,10 @@ func (s *RsspChannel) HandleRsspMsg(pack []byte) {
// 处理接收到的实时安全数据
func (s *RsspChannel) handleRsspRsd(rsd *message.RsspRsd) {
if rsd.Pic != message.PIC_MASTER {
slog.Debug("丢弃接收的RSSP-RSD报文来自备系")
return
}
//序列号校验
//接收的序列号小于最近一次有效序列号则触发SSE时序校验
if rsd.Sn < s.rcvSn {
@ -79,18 +118,38 @@ func (s *RsspChannel) handleRsspRsd(rsd *message.RsspRsd) {
s.fireSse(rsd)
return
}
if rsd.Sn-s.rcvSn > s.config.Mtv {
dSn := rsd.Sn - s.rcvSn
if dSn > s.config.Mtv {
slog.Debug("丢弃接收的RSSP-RSD报文当前接收RSD的序列号与最近一次接收的RSD的序列号差值过大触发SSE")
s.fireSse(rsd)
return
}
//SVC校验
c1Crc32 := message.RsspC1Crc32(rsd.Sad)
c1SidTs := c1Crc32 ^ rsd.Svc1 ^ message.SCW_C1
//
c2Crc32 := message.RsspC2Crc32(rsd.Sad)
c2SidTs := c2Crc32 ^ rsd.Svc2 ^ message.SCW_C2
//todo ... SVC校验待完善
_ = c1SidTs
_ = c2SidTs
//校验通过
//记录本次接收RSD的序列号和安全校验通道时间戳
s.rcvSn = rsd.Sn
s.rcvCh1Ts = c1SidTs ^ s.config.SID1
s.rcvCh2Ts = c2SidTs ^ s.config.SID2
//通知应用层接收应用数据
s.rcvUserData(rsd.Sad)
}
// 从安全通道成功接收到应用层数据
func (s *RsspChannel) rcvUserData(userData []byte) {
}
// 触发时序校正请求
func (s *RsspChannel) fireSse(rsd *message.RsspRsd) {
s.sendSse()
}
// 接收到时序校正请求
@ -99,8 +158,22 @@ func (s *RsspChannel) handleRsspSse(rsd *message.RsspSse) {
}
// 接收到时序校正应答
func (s *RsspChannel) handleRsspSsr(rsd *message.RsspSsr) {
func (s *RsspChannel) handleRsspSsr(ssr *message.RsspSsr) {
//SSR校验
if !s.sendSseRecord.hasRecord() {
slog.Debug("丢弃接收的RSSP-SSR报文未发起过SSE时序校正请求")
return
}
if s.rsspTimer.t-s.sendSseRecord.rsspTime > uint64(s.config.SsrRsspTimeout) {
slog.Debug("丢弃接收的RSSP-SSR报文等待SSE响应超时")
return
}
if ssr.SeSn != s.sendSseRecord.send.Sn {
slog.Debug("丢弃接收的RSSP-SSR报文SSR与SSE不对应")
return
}
//恢复时序
//todo
}
// 将序列号和时间戳更新到下一个值