rts-sim-testing-service/third_party/axle_device/rssp_server.go
2023-11-03 13:04:28 +08:00

184 lines
5.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package axle_device
import (
"joylink.club/bj-rtsts-server/third_party/message"
"log/slog"
)
// RsspChannel 实现rssp通信
type RsspChannel struct {
config *RsspConfig
//批次编号,发送序列号,周期计数器
sn *message.RsspSn
//安全通道1时间戳
ch1Ts *message.RsspLFSR
//安全通道2时间戳
ch2Ts *message.RsspLFSR
//协议交互类别
picType message.PicType
//true-A机false-B机
deviceA bool
//最近一次接收到的报文的安全通道1时间戳
rcvCh1Ts uint32
//最近一次接收到的报文的安全通道2时间戳
rcvCh2Ts uint32
//最近一次接收到的报文的序列号
rcvSn uint32
}
// HandleRsspMsg 处理接收到的rssp报文
func (s *RsspChannel) HandleRsspMsg(pack []byte) {
//报文头校验
head := &message.RsspHead{}
if !head.Parse(pack) { //解析报文头失败
slog.Debug("丢弃接收的RSSP报文解析报文头失败")
return
}
if !message.RsspHeadMcCheck(head) { //报文类别检测未通过
slog.Debug("丢弃接收的RSSP报文报文类别检测未通过")
return
}
if !message.RsspHeadPicCheck(head) { //协议交互类别检测未通过
slog.Debug("丢弃接收的RSSP报文协议交互类别检测未通过")
return
}
if !s.config.CheckAddress(head.Sa, head.Da) { //校验报文头中源地址和目的地址是否包含在已配置列表中
slog.Debug("丢弃接收的RSSP报文报文头中源地址或目的地址不在在已配置列表中")
return
}
//报文尾校验
if !message.RsspPackCrc16Check(pack) { //整个报文crc16校验未通过
slog.Debug("丢弃接收的RSSP报文报文尾CRC16校验未通过")
return
}
//解析得到RSD、SSE或SRE
rssp := message.ParseRsspPack(head, pack)
if rssp == nil { //解析具体rssp包失败
slog.Debug("丢弃接收的RSSP报文解析具体类别包失败")
return
}
//处理接收到的具体类别RSSP包
switch rssp.Type() {
case message.RSD_A:
fallthrough
case message.RSD_B:
s.handleRsspRsd(rssp.(*message.RsspRsd))
case message.SSE:
s.handleRsspSse(rssp.(*message.RsspSse))
case message.SSR:
s.handleRsspSsr(rssp.(*message.RsspSsr))
}
}
// 处理接收到的实时安全数据
func (s *RsspChannel) handleRsspRsd(rsd *message.RsspRsd) {
//序列号校验
//接收的序列号小于最近一次有效序列号则触发SSE时序校验
if rsd.Sn < s.rcvSn {
slog.Debug("丢弃接收的RSSP-RSD报文当前接收RSD的序列号小于最近一次接收的RSD的序列号触发SSE")
s.fireSse(rsd)
return
}
if rsd.Sn-s.rcvSn > s.config.Mtv {
slog.Debug("丢弃接收的RSSP-RSD报文当前接收RSD的序列号与最近一次接收的RSD的序列号差值过大触发SSE")
s.fireSse(rsd)
return
}
//SVC校验
}
// 触发时序校正请求
func (s *RsspChannel) fireSse(rsd *message.RsspRsd) {
}
// 接收到时序校正请求
func (s *RsspChannel) handleRsspSse(rsd *message.RsspSse) {
}
// 接收到时序校正应答
func (s *RsspChannel) handleRsspSsr(rsd *message.RsspSsr) {
}
// 将序列号和时间戳更新到下一个值
func (s *RsspChannel) freshSnTs() {
s.sn.GetAndAdd()
s.ch1Ts.GetAndMove()
s.ch2Ts.GetAndMove()
}
// 发送时序校正应答
func (s *RsspChannel) sendSsr(sse *message.RsspSse) {
ssr := &message.RsspSsr{}
//
ssr.Pic = message.PIC_MASTER
ssr.Mc = message.SSR
ssr.Sa = s.config.SrcAddr
ssr.Da = s.config.DstAddr
ssr.SrSn = s.sn.Get() //当前序列号
ssr.SeSn = sse.Sn
ssr.Tic1 = sse.SeqEnq1 ^ s.config.SID1 ^ s.ch1Ts.Get() ^ s.config.DataVer1
ssr.Tic2 = sse.SeqEnq2 ^ s.config.SID2 ^ s.ch2Ts.Get() ^ s.config.DataVer2
ssr.Dvn = 0x01 //预留固定值
//
rsspPack := ssr.Encode()
s.sendPack(rsspPack)
}
// 发送时序校正请求
func (s *RsspChannel) sendSse() {
sse := &message.RsspSse{}
//
sse.Pic = message.PIC_MASTER
sse.Mc = message.SSE
sse.Sa = s.config.SrcAddr
sse.Da = s.config.DstAddr
//时序校正请求,把最近一次接收到的报文中的序列号时间戳发送给发送方
sse.Sn = s.rcvSn
sse.SeqEnq1 = s.createSeqNeq(s.config.SID1, s.rcvCh1Ts)
sse.SeqEnq2 = s.createSeqNeq(s.config.SID2, s.rcvCh2Ts)
//
rsspPack := sse.Encode()
s.sendPack(rsspPack)
}
// 发送用户数据即通过rssp安全通道发送应用层数据通过rssp的RSD报文发送
func (s *RsspChannel) sendUserData(userData []byte) {
rsd := &message.RsspRsd{}
rsd.Pic = s.picType
if s.deviceA {
rsd.Mc = message.RSD_A
} else {
rsd.Mc = message.RSD_B
}
rsd.Sa = s.config.SrcAddr
rsd.Da = s.config.DstAddr
//
rsd.Sn = s.sn.Get()
rsd.Sdl = uint16(len(userData) + 8)
//安全校验通道SVC_1
crc_c1 := message.RsspC1Crc32(userData)
rsd.Svc1 = s.createSvcCode(crc_c1, s.config.SID1, s.ch1Ts.Get(), message.SCW_C1)
//安全校验通道SVC_2
crc_c2 := message.RsspC2Crc32(userData)
rsd.Svc1 = s.createSvcCode(crc_c2, s.config.SID2, s.ch2Ts.Get(), message.SCW_C2)
rsd.Sad = userData
//
rsspPack := rsd.Encode()
s.sendPack(rsspPack)
}
func (s *RsspChannel) createSvcCode(crc32 uint32, sid uint32, ts uint32, scw uint32) uint32 {
return crc32 ^ sid ^ ts ^ scw
}
func (s *RsspChannel) createSeqNeq(sid uint32, ts uint32) uint32 {
return sid ^ ts
}
// 通过网络发送数据
func (s *RsspChannel) sendPack(rsspPack []byte) {
}