first commit
This commit is contained in:
BIN
协议资料/Non-Idiots-Guide-to-AIS-for-the-BMEA.pdf
Normal file
BIN
协议资料/Non-Idiots-Guide-to-AIS-for-the-BMEA.pdf
Normal file
Binary file not shown.
BIN
协议资料/R-REC-M.1371-5-201402-I!!PDF-C.pdf
Normal file
BIN
协议资料/R-REC-M.1371-5-201402-I!!PDF-C.pdf
Normal file
Binary file not shown.
BIN
协议资料/R-REC-M.2092-1-202202-I!!PDF-C.pdf
Normal file
BIN
协议资料/R-REC-M.2092-1-202202-I!!PDF-C.pdf
Normal file
Binary file not shown.
BIN
协议资料/R23-WP5B-C-0315!H4-N04.07!MSW-E(1).docx
Normal file
BIN
协议资料/R23-WP5B-C-0315!H4-N04.07!MSW-E(1).docx
Normal file
Binary file not shown.
BIN
协议资料/Release/CDemoTestDlg.obj
Normal file
BIN
协议资料/Release/CDemoTestDlg.obj
Normal file
Binary file not shown.
BIN
协议资料/Release/CDspProgramData.obj
Normal file
BIN
协议资料/Release/CDspProgramData.obj
Normal file
Binary file not shown.
BIN
协议资料/Release/ColoredListCtrl.obj
Normal file
BIN
协议资料/Release/ColoredListCtrl.obj
Normal file
Binary file not shown.
37
协议资料/Release/DemoCAN.Build.CppClean.log
Normal file
37
协议资料/Release/DemoCAN.Build.CppClean.log
Normal file
@@ -0,0 +1,37 @@
|
||||
e:\vdes\上位机\controller2.0.0\release\democan.pch
|
||||
e:\vdes\上位机\controller2.0.0\release\vc142.pdb
|
||||
e:\vdes\上位机\controller2.0.0\release\stdafx.obj
|
||||
e:\vdes\上位机\controller2.0.0\release\serialport.obj
|
||||
e:\vdes\上位机\controller2.0.0\release\demovdedlg.obj
|
||||
e:\vdes\上位机\controller2.0.0\release\demostatedlg.obj
|
||||
e:\vdes\上位机\controller2.0.0\release\democandlg.obj
|
||||
e:\vdes\上位机\controller2.0.0\release\democan.obj
|
||||
e:\vdes\上位机\controller2.0.0\release\coloredlistctrl.obj
|
||||
e:\vdes\上位机\controller2.0.0\release\cdspprogramdata.obj
|
||||
e:\vdes\上位机\controller2.0.0\release\cdemotestdlg.obj
|
||||
e:\vdes\上位机\controller2.0.0\release\democan.exe
|
||||
e:\vdes\上位机\controller2.0.0\release\usbcan_demo.pdb
|
||||
e:\vdes\上位机\controller2.0.0\release\democan.res
|
||||
e:\vdes\上位机\controller2.0.1\release\cdemotestdlg.obj
|
||||
e:\vdes\上位机\controller2.0.1\release\cdspprogramdata.obj
|
||||
e:\vdes\上位机\controller2.0.1\release\coloredlistctrl.obj
|
||||
e:\vdes\上位机\controller2.0.1\release\democan.obj
|
||||
e:\vdes\上位机\controller2.0.1\release\democandlg.obj
|
||||
e:\vdes\上位机\controller2.0.1\release\demostatedlg.obj
|
||||
e:\vdes\上位机\controller2.0.1\release\demovdedlg.obj
|
||||
e:\vdes\上位机\controller2.0.1\release\serialport.obj
|
||||
e:\vdes\上位机\controller2.0.1\release\stdafx.obj
|
||||
e:\vdes\上位机\controller2.0.1\release\democan.res
|
||||
e:\vdes\上位机\controller2.0.1\release\democan.pch
|
||||
e:\vdes\上位机\controller2.0.1\release\usbcan_demo.pdb
|
||||
e:\vdes\上位机\controller2.0.1\release\vc142.pdb
|
||||
e:\vdes\上位机\controller2.0.1\release\democan.exe
|
||||
e:\vdes\上位机\controller2.0.1\release\democan.tlog\cl.command.1.tlog
|
||||
e:\vdes\上位机\controller2.0.1\release\democan.tlog\cl.read.1.tlog
|
||||
e:\vdes\上位机\controller2.0.1\release\democan.tlog\cl.write.1.tlog
|
||||
e:\vdes\上位机\controller2.0.1\release\democan.tlog\link.command.1.tlog
|
||||
e:\vdes\上位机\controller2.0.1\release\democan.tlog\link.read.1.tlog
|
||||
e:\vdes\上位机\controller2.0.1\release\democan.tlog\link.write.1.tlog
|
||||
e:\vdes\上位机\controller2.0.1\release\democan.tlog\rc.command.1.tlog
|
||||
e:\vdes\上位机\controller2.0.1\release\democan.tlog\rc.read.1.tlog
|
||||
e:\vdes\上位机\controller2.0.1\release\democan.tlog\rc.write.1.tlog
|
||||
BIN
协议资料/Release/DemoCAN.exe
Normal file
BIN
协议资料/Release/DemoCAN.exe
Normal file
Binary file not shown.
11
协议资料/Release/DemoCAN.exe.recipe
Normal file
11
协议资料/Release/DemoCAN.exe.recipe
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<ProjectOutputs>
|
||||
<ProjectOutput>
|
||||
<FullPath>E:\VDES\上位机\controller2.0.1\Release\DemoCAN.exe</FullPath>
|
||||
</ProjectOutput>
|
||||
</ProjectOutputs>
|
||||
<ContentFiles />
|
||||
<SatelliteDlls />
|
||||
<NonRecipeFileRefs />
|
||||
</Project>
|
||||
49
协议资料/Release/DemoCAN.log
Normal file
49
协议资料/Release/DemoCAN.log
Normal file
@@ -0,0 +1,49 @@
|
||||
StdAfx.cpp
|
||||
_WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h)
|
||||
CDemoTestDlg.cpp
|
||||
E:\VDES\上位机\controller2.0.1\CDemoTestDlg.cpp(113,10): warning C4101: “exitcode”: 未引用的局部变量
|
||||
E:\VDES\上位机\controller2.0.1\CDemoTestDlg.cpp(516,15): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\CDemoTestDlg.cpp(1058,7): warning C4101: “fileExist”: 未引用的局部变量
|
||||
CDspProgramData.cpp
|
||||
ColoredListCtrl.cpp
|
||||
DemoCAN.cpp
|
||||
DemoCANDlg.cpp
|
||||
E:\VDES\上位机\controller2.0.1\DemoCANDlg.cpp(507,15): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoCANDlg.cpp(512,15): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoCANDlg.cpp(534,25): warning C4018: “<”: 有符号/无符号不匹配
|
||||
E:\VDES\上位机\controller2.0.1\DemoCANDlg.cpp(937,20): warning C4244: “初始化”: 从“ULONGLONG”转换到“UINT”,可能丢失数据
|
||||
E:\VDES\上位机\controller2.0.1\DemoCANDlg.cpp(1020,9): warning C4996: 'localtime': This function or variable may be unsafe. Consider using localtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
|
||||
E:\VDES\上位机\controller2.0.1\DemoCANDlg.cpp(1830,10): warning C4996: 'WSAAsyncSelect': Use WSAEventSelect() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
|
||||
E:\VDES\上位机\controller2.0.1\DemoCANDlg.cpp(1841,29): warning C4996: 'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
|
||||
E:\VDES\上位机\controller2.0.1\DemoCANDlg.cpp(1887,16): warning C4244: “初始化”: 从“ULONGLONG”转换到“int”,可能丢失数据
|
||||
E:\VDES\上位机\controller2.0.1\DemoCANDlg.cpp(1923,16): warning C4244: “初始化”: 从“ULONGLONG”转换到“int”,可能丢失数据
|
||||
E:\VDES\上位机\controller2.0.1\DemoCANDlg.cpp(2668,13): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoCANDlg.cpp(3863,19): warning C4996: '_tcstok': This function or variable may be unsafe. Consider using _tcstok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
|
||||
E:\VDES\上位机\controller2.0.1\DemoCANDlg.cpp(3864,19): warning C4996: '_tcstok': This function or variable may be unsafe. Consider using _tcstok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
|
||||
DemoStateDlg.cpp
|
||||
DemoVDEDlg.cpp
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(563,15): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(564,15): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(565,15): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(566,15): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(701,25): warning C4244: “=”: 从“ULONGLONG”转换到“UINT32”,可能丢失数据
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(726,13): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(727,13): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(861,13): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(862,13): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(930,13): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(931,13): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(1005,13): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(1006,13): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(1081,13): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(1082,13): warning C4309: “=”: 截断常量值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(1176,24): warning C4244: “=”: 从“ULONGLONG”转换到“UINT32”,可能丢失数据
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(1202,16): warning C4018: “<”: 有符号/无符号不匹配
|
||||
SerialPort.cpp
|
||||
正在生成代码...
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(905): warning C4715: “DemoVDEDlg::Lvds_Send_LinkID”: 不是所有的控件路径都返回值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(980): warning C4715: “DemoVDEDlg::Lvds_Send_Buffer_Config”: 不是所有的控件路径都返回值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(1057): warning C4715: “DemoVDEDlg::Lvds_Send_Satellite_Param”: 不是所有的控件路径都返回值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(1124): warning C4715: “DemoVDEDlg::Lvds_Send_Message_ID”: 不是所有的控件路径都返回值
|
||||
E:\VDES\上位机\controller2.0.1\DemoVDEDlg.cpp(1480): warning C4715: “DemoVDEDlg::Arguments_Auto_Configuration”: 不是所有的控件路径都返回值
|
||||
DemoCAN.vcxproj -> E:\VDES\上位机\controller2.0.1\Release\DemoCAN.exe
|
||||
BIN
协议资料/Release/DemoCAN.obj
Normal file
BIN
协议资料/Release/DemoCAN.obj
Normal file
Binary file not shown.
BIN
协议资料/Release/DemoCAN.pch
Normal file
BIN
协议资料/Release/DemoCAN.pch
Normal file
Binary file not shown.
BIN
协议资料/Release/DemoCAN.res
Normal file
BIN
协议资料/Release/DemoCAN.res
Normal file
Binary file not shown.
BIN
协议资料/Release/DemoCAN.tlog/CL.command.1.tlog
Normal file
BIN
协议资料/Release/DemoCAN.tlog/CL.command.1.tlog
Normal file
Binary file not shown.
BIN
协议资料/Release/DemoCAN.tlog/CL.read.1.tlog
Normal file
BIN
协议资料/Release/DemoCAN.tlog/CL.read.1.tlog
Normal file
Binary file not shown.
BIN
协议资料/Release/DemoCAN.tlog/CL.write.1.tlog
Normal file
BIN
协议资料/Release/DemoCAN.tlog/CL.write.1.tlog
Normal file
Binary file not shown.
2
协议资料/Release/DemoCAN.tlog/DemoCAN.lastbuildstate
Normal file
2
协议资料/Release/DemoCAN.tlog/DemoCAN.lastbuildstate
Normal file
@@ -0,0 +1,2 @@
|
||||
PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.29.30133:VCServicingVersionMFC=14.29.30136:TargetPlatformVersion=10.0.19041.0:
|
||||
Release|Win32|E:\VDES\上位机\controller2.0.1\|
|
||||
BIN
协议资料/Release/DemoCAN.tlog/link.command.1.tlog
Normal file
BIN
协议资料/Release/DemoCAN.tlog/link.command.1.tlog
Normal file
Binary file not shown.
BIN
协议资料/Release/DemoCAN.tlog/link.read.1.tlog
Normal file
BIN
协议资料/Release/DemoCAN.tlog/link.read.1.tlog
Normal file
Binary file not shown.
BIN
协议资料/Release/DemoCAN.tlog/link.write.1.tlog
Normal file
BIN
协议资料/Release/DemoCAN.tlog/link.write.1.tlog
Normal file
Binary file not shown.
BIN
协议资料/Release/DemoCAN.tlog/rc.command.1.tlog
Normal file
BIN
协议资料/Release/DemoCAN.tlog/rc.command.1.tlog
Normal file
Binary file not shown.
BIN
协议资料/Release/DemoCAN.tlog/rc.read.1.tlog
Normal file
BIN
协议资料/Release/DemoCAN.tlog/rc.read.1.tlog
Normal file
Binary file not shown.
BIN
协议资料/Release/DemoCAN.tlog/rc.write.1.tlog
Normal file
BIN
协议资料/Release/DemoCAN.tlog/rc.write.1.tlog
Normal file
Binary file not shown.
13
协议资料/Release/DemoCAN.vcxproj.FileListAbsolute.txt
Normal file
13
协议资料/Release/DemoCAN.vcxproj.FileListAbsolute.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
E:\vdes\controller\controller1.2\Release\DemoCAN.exe
|
||||
E:\vdes\controller\controller1.3-test\Release\DemoCAN.exe
|
||||
E:\vdes\controller\controller1.3\Release\DemoCAN.exe
|
||||
E:\vdes\controller\controller1.4\Release\DemoCAN.exe
|
||||
E:\vdes\controller\controller1.4.1\Release\DemoCAN.exe
|
||||
E:\vdes\controller\controller1.5.1\Release\DemoCAN.exe
|
||||
E:\vdes\controller\controller1.5.3\Release\DemoCAN.exe
|
||||
E:\vdes\controller\controller1.5.6\Release\DemoCAN.exe
|
||||
E:\vdes\controller\controller1.6.0\Release\DemoCAN.exe
|
||||
E:\vdes\controller\controller1.6.1\Release\DemoCAN.exe
|
||||
E:\vdes\controller\controller1.7.0\Release\DemoCAN.exe
|
||||
E:\VDES\上位机\controller2.0.0\Release\DemoCAN.exe
|
||||
E:\VDES\上位机\controller2.0.1\Release\DemoCAN.exe
|
||||
BIN
协议资料/Release/DemoCANDlg.obj
Normal file
BIN
协议资料/Release/DemoCANDlg.obj
Normal file
Binary file not shown.
BIN
协议资料/Release/DemoStateDlg.obj
Normal file
BIN
协议资料/Release/DemoStateDlg.obj
Normal file
Binary file not shown.
BIN
协议资料/Release/DemoVDEDlg.obj
Normal file
BIN
协议资料/Release/DemoVDEDlg.obj
Normal file
Binary file not shown.
BIN
协议资料/Release/SerialPort.obj
Normal file
BIN
协议资料/Release/SerialPort.obj
Normal file
Binary file not shown.
BIN
协议资料/Release/StdAfx.obj
Normal file
BIN
协议资料/Release/StdAfx.obj
Normal file
Binary file not shown.
BIN
协议资料/Release/USBCAN_Demo.pdb
Normal file
BIN
协议资料/Release/USBCAN_Demo.pdb
Normal file
Binary file not shown.
BIN
协议资料/Release/VC_redist.x86.exe
Normal file
BIN
协议资料/Release/VC_redist.x86.exe
Normal file
Binary file not shown.
BIN
协议资料/Release/vc142.pdb
Normal file
BIN
协议资料/Release/vc142.pdb
Normal file
Binary file not shown.
BIN
协议资料/Release/使用说明/ASM_4_1_signal.txt
Normal file
BIN
协议资料/Release/使用说明/ASM_4_1_signal.txt
Normal file
Binary file not shown.
BIN
协议资料/Release/使用说明/VDE地检使用说明.docx
Normal file
BIN
协议资料/Release/使用说明/VDE地检使用说明.docx
Normal file
Binary file not shown.
BIN
协议资料/Release/使用说明/ais_change_data_4.txt
Normal file
BIN
协议资料/Release/使用说明/ais_change_data_4.txt
Normal file
Binary file not shown.
0
协议资料/Release/使用说明/测试记录.txt
Normal file
0
协议资料/Release/使用说明/测试记录.txt
Normal file
BIN
协议资料/VDES_TCP通信协议.docx
Normal file
BIN
协议资料/VDES_TCP通信协议.docx
Normal file
Binary file not shown.
BIN
协议资料/VDES第三版地检_终端设计_1.1.docx
Normal file
BIN
协议资料/VDES第三版地检_终端设计_1.1.docx
Normal file
Binary file not shown.
BIN
协议资料/VDES第三版地检_终端设计_1.2.docx
Normal file
BIN
协议资料/VDES第三版地检_终端设计_1.2.docx
Normal file
Binary file not shown.
BIN
协议资料/VDES第三版地检_终端设计_1.3.docx
Normal file
BIN
协议资料/VDES第三版地检_终端设计_1.3.docx
Normal file
Binary file not shown.
BIN
协议资料/VDES第三版地检_终端设计_1.4.docx
Normal file
BIN
协议资料/VDES第三版地检_终端设计_1.4.docx
Normal file
Binary file not shown.
BIN
协议资料/tcp数据/TCP_AIS报文消息.bin
Normal file
BIN
协议资料/tcp数据/TCP_AIS报文消息.bin
Normal file
Binary file not shown.
BIN
协议资料/tcp数据/TCP_GNSS消息.bin
Normal file
BIN
协议资料/tcp数据/TCP_GNSS消息.bin
Normal file
Binary file not shown.
BIN
协议资料/tcp数据/TCP_VDES报文消息.bin
Normal file
BIN
协议资料/tcp数据/TCP_VDES报文消息.bin
Normal file
Binary file not shown.
BIN
协议资料/tcp数据/TCP_地检状态监控消息.bin
Normal file
BIN
协议资料/tcp数据/TCP_地检状态监控消息.bin
Normal file
Binary file not shown.
BIN
协议资料/tcp数据/TCP_地检通知消息.bin
Normal file
BIN
协议资料/tcp数据/TCP_地检通知消息.bin
Normal file
Binary file not shown.
BIN
协议资料/tcp数据/VDES报文传输的图片.jpg
Normal file
BIN
协议资料/tcp数据/VDES报文传输的图片.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
BIN
协议资料/tcp数据/VDES终端TCP消息比特流文件.zip
Normal file
BIN
协议资料/tcp数据/VDES终端TCP消息比特流文件.zip
Normal file
Binary file not shown.
21
协议资料/tcp数据/读取bin文件.py
Normal file
21
协议资料/tcp数据/读取bin文件.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
with open("TCP_VDES报文消息.bin", "rb") as f:
|
||||
data = f.read()
|
||||
print(data.hex())
|
||||
|
||||
|
||||
# 帧起始标志
|
||||
delimiter = b"####"
|
||||
|
||||
# 按标志切分
|
||||
frames = data.split(delimiter)
|
||||
|
||||
# 第一个切分出来的可能是空的(因为文件就是以 #### 开头)
|
||||
for i, frame in enumerate(frames):
|
||||
if not frame:
|
||||
continue
|
||||
# 打印时把起始标志加回去
|
||||
ais_packet = delimiter + frame
|
||||
print(f"Frame {i}:")
|
||||
print((delimiter + frame).hex())
|
||||
print("-" * 60)
|
||||
434
协议资料/vdes-tcp.py
Normal file
434
协议资料/vdes-tcp.py
Normal file
@@ -0,0 +1,434 @@
|
||||
import struct
|
||||
from enum import Enum
|
||||
from typing import Dict, Any
|
||||
|
||||
class VDESMessageType(Enum):
|
||||
"""VDES报文类型枚举"""
|
||||
DEBUG_COMMAND = 0
|
||||
LVDS_DATA = 1
|
||||
CAN_DATA = 2
|
||||
AD9361_CONTROL = 3
|
||||
WAVE_IP_CONTROL = 4
|
||||
TEST_PARAM_CONTROL = 5
|
||||
TEST_WAVE_UPLOAD = 6
|
||||
GPS_DATA = 7
|
||||
STATUS_MONITOR = 8
|
||||
VDES_PARAM_CONTROL = 9
|
||||
VDES_UPLOAD_DATA = 10
|
||||
VDES_COLLECT_DATA = 11
|
||||
VDES_DEMOD_DATA = 12
|
||||
NOTIFICATION = 13
|
||||
|
||||
class VDESUploadDataType(Enum):
|
||||
"""VDES上注数据类型枚举"""
|
||||
LONG_DATA_PARAM = 0
|
||||
LONG_DATA_CONTENT = 1
|
||||
LONG_DATA_END = 2
|
||||
SHORT_MESSAGE = 3
|
||||
EMERGENCY_MESSAGE = 4
|
||||
|
||||
class VDESTCPParser:
|
||||
"""VDES TCP协议解析器"""
|
||||
|
||||
HEADER_MAGIC = b'####'
|
||||
MAX_PACKET_SIZE = 32768
|
||||
|
||||
def __init__(self):
|
||||
self._init_parsers()
|
||||
|
||||
def _init_parsers(self):
|
||||
"""初始化各类型报文的解析方法"""
|
||||
self._parsers = {
|
||||
VDESMessageType.DEBUG_COMMAND: self._parse_debug_command,
|
||||
VDESMessageType.LVDS_DATA: self._parse_lvds_data,
|
||||
VDESMessageType.CAN_DATA: self._parse_can_data,
|
||||
VDESMessageType.AD9361_CONTROL: self._parse_ad9361_control,
|
||||
VDESMessageType.WAVE_IP_CONTROL: self._parse_wave_ip_control,
|
||||
VDESMessageType.TEST_PARAM_CONTROL: self._parse_test_param_control,
|
||||
VDESMessageType.TEST_WAVE_UPLOAD: self._parse_test_wave_upload,
|
||||
VDESMessageType.GPS_DATA: self._parse_gps_data,
|
||||
VDESMessageType.STATUS_MONITOR: self._parse_status_monitor,
|
||||
VDESMessageType.VDES_PARAM_CONTROL: self._parse_vdes_param_control,
|
||||
VDESMessageType.VDES_UPLOAD_DATA: self._parse_vdes_upload_data,
|
||||
VDESMessageType.VDES_COLLECT_DATA: self._parse_vdes_collect_data,
|
||||
VDESMessageType.VDES_DEMOD_DATA: self._parse_vdes_demod_data,
|
||||
VDESMessageType.NOTIFICATION: self._parse_notification,
|
||||
}
|
||||
|
||||
def parse_packet(self, data: bytes) -> Dict[str, Any]:
|
||||
"""
|
||||
解析TCP报文
|
||||
:param data: 原始报文数据
|
||||
:return: 解析后的字典结果
|
||||
"""
|
||||
if len(data) < 12:
|
||||
raise ValueError(f"Packet too short ({len(data)} bytes), minimum 12 bytes required")
|
||||
|
||||
# 验证报文头
|
||||
header = data[:4]
|
||||
if header != self.HEADER_MAGIC:
|
||||
raise ValueError(f"Invalid packet header: {header.hex()}")
|
||||
|
||||
# 解析报文类型和长度
|
||||
msg_type, content_len = struct.unpack('>II', data[4:12])
|
||||
content = data[12:12+content_len]
|
||||
|
||||
# 验证内容长度
|
||||
if len(content) != content_len:
|
||||
raise ValueError(f"Content length mismatch: expected {content_len}, got {len(content)}")
|
||||
|
||||
# 获取报文类型枚举
|
||||
try:
|
||||
msg_type_enum = VDESMessageType(msg_type)
|
||||
except ValueError:
|
||||
return {
|
||||
'type': msg_type,
|
||||
'type_name': f'UNKNOWN_{msg_type}',
|
||||
'content': content,
|
||||
'raw': data
|
||||
}
|
||||
|
||||
# 调用对应的解析方法
|
||||
parser = self._parsers.get(msg_type_enum)
|
||||
if parser:
|
||||
return {
|
||||
'type': msg_type_enum,
|
||||
'type_name': msg_type_enum.name,
|
||||
'content': parser(content),
|
||||
'raw': data
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'type': msg_type_enum,
|
||||
'type_name': msg_type_enum.name,
|
||||
'content': content,
|
||||
'raw': data
|
||||
}
|
||||
|
||||
def _parse_debug_command(self, content: bytes) -> Dict[str, Any]:
|
||||
"""解析调试指令报文(类型0)"""
|
||||
if len(content) < 1:
|
||||
raise ValueError("Debug command too short")
|
||||
|
||||
cmd_type = content[0]
|
||||
descriptions = {
|
||||
0: "初始化地检",
|
||||
1: "测试波形上注完成",
|
||||
2: "LVDS数据开始上注",
|
||||
3: "LVDS初始化",
|
||||
4: "AD9361重新校准",
|
||||
5: "GPS初始化"
|
||||
}
|
||||
|
||||
return {
|
||||
'command_type': cmd_type,
|
||||
'description': descriptions.get(cmd_type, f"未知指令类型: {cmd_type}")
|
||||
}
|
||||
|
||||
def _parse_lvds_data(self, content: bytes) -> Dict[str, Any]:
|
||||
"""解析LVDS数据报文(类型1)"""
|
||||
return {
|
||||
'data': content,
|
||||
'length': len(content)
|
||||
}
|
||||
|
||||
def _parse_can_data(self, content: bytes) -> Dict[str, Any]:
|
||||
"""解析CAN数据报文(类型2)"""
|
||||
return {
|
||||
'data': content,
|
||||
'length': len(content)
|
||||
}
|
||||
|
||||
def _parse_ad9361_control(self, content: bytes) -> Dict[str, Any]:
|
||||
"""解析AD9361参数控制报文(类型3)"""
|
||||
if len(content) != 13:
|
||||
raise ValueError("AD9361 control message must be 13 bytes")
|
||||
|
||||
tx_lo, tx_rate, tx_atten = struct.unpack('>QIB', content)
|
||||
return {
|
||||
'tx_lo_freq': tx_lo,
|
||||
'tx_sample_rate': tx_rate,
|
||||
'tx_attenuation': tx_atten
|
||||
}
|
||||
|
||||
def _parse_wave_ip_control(self, content: bytes) -> Dict[str, Any]:
|
||||
"""解析波形发射IP核控制报文(类型4)"""
|
||||
if len(content) < 20:
|
||||
raise ValueError("Wave IP control message too short")
|
||||
|
||||
# 解析固定部分
|
||||
channel, cic_enable, sample_rate, wave_type = struct.unpack('>BBIB', content[:7])
|
||||
freq_offset, sweep_type, sweep_bw, sweep_speed = struct.unpack('>iBII', content[7:20])
|
||||
|
||||
return {
|
||||
'channel': channel,
|
||||
'cic_enable': bool(cic_enable),
|
||||
'sample_rate': sample_rate,
|
||||
'wave_type': wave_type,
|
||||
'freq_offset': freq_offset,
|
||||
'sweep_type': sweep_type,
|
||||
'sweep_bandwidth': sweep_bw,
|
||||
'sweep_speed': sweep_speed
|
||||
}
|
||||
|
||||
def _parse_test_param_control(self, content: bytes) -> Dict[str, Any]:
|
||||
"""解析发送测试参数控制报文(类型5)"""
|
||||
if len(content) != 9:
|
||||
raise ValueError("Test param control message must be 9 bytes")
|
||||
|
||||
test_type, test_count, test_interval = struct.unpack('>BII', content)
|
||||
return {
|
||||
'test_type': test_type,
|
||||
'test_count': test_count,
|
||||
'test_interval_ms': test_interval
|
||||
}
|
||||
|
||||
def _parse_test_wave_upload(self, content: bytes) -> Dict[str, Any]:
|
||||
"""解析发送测试波形上注报文(类型6)"""
|
||||
return {
|
||||
'wave_data': content,
|
||||
'length': len(content)
|
||||
}
|
||||
|
||||
def _parse_gps_data(self, content: bytes) -> Dict[str, Any]:
|
||||
"""解析GPS解析数据报文(类型7)"""
|
||||
if len(content) < 36:
|
||||
raise ValueError("GPS data message too short")
|
||||
|
||||
fields = struct.unpack('>QiiihhhBBIBII', content[:36])
|
||||
|
||||
return {
|
||||
'utc_time': fields[0],
|
||||
'longitude': fields[1],
|
||||
'latitude': fields[2],
|
||||
'altitude': fields[3],
|
||||
'used_satellites': fields[4],
|
||||
'gps_satellites': fields[5],
|
||||
'beidou_satellites': fields[6],
|
||||
'gps_status': fields[7],
|
||||
'position_mode': fields[8],
|
||||
'hdop': fields[9],
|
||||
'speed': fields[10],
|
||||
'direction': fields[11]
|
||||
}
|
||||
|
||||
def _parse_status_monitor(self, content: bytes) -> Dict[str, Any]:
|
||||
"""解析地检状态监控报文(类型8)"""
|
||||
if len(content) < 53:
|
||||
raise ValueError("Status monitor message too short")
|
||||
|
||||
# 解析前38字节
|
||||
fields = struct.unpack('>BBIIBBBBIIIBIII', content[:38])
|
||||
|
||||
result = {
|
||||
'cpu0_usage': fields[0],
|
||||
'cpu1_usage': fields[1],
|
||||
'version': fields[2],
|
||||
'uptime': fields[3],
|
||||
'gps_status': fields[4],
|
||||
'pps_lock_status': fields[5],
|
||||
'ad9361_status': fields[6],
|
||||
'ad9361_calibration_factor': fields[7],
|
||||
'ad9361_tx_lo': fields[8],
|
||||
'ad9361_tx_rate': fields[9],
|
||||
'ad9361_tx_atten': fields[10],
|
||||
'ad9361_rx_lo': fields[11],
|
||||
'ad9361_rx_rate': fields[12],
|
||||
'ad9361_rx_gain': fields[13],
|
||||
'vdes_enable': fields[14],
|
||||
}
|
||||
|
||||
# 解析剩余部分
|
||||
pos = 38
|
||||
more_fields = struct.unpack('>BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', content[pos:pos+15])
|
||||
|
||||
result.update({
|
||||
'vdes_filter_enable': more_fields[0],
|
||||
'rac_limit_enable': more_fields[1],
|
||||
'vdes_agc_enable': more_fields[2],
|
||||
'sat_delay_comp_enable': more_fields[3],
|
||||
'upper_sat_id': more_fields[4],
|
||||
'upper_sat_cqi': more_fields[5],
|
||||
'upper_sat_amp': more_fields[6],
|
||||
'lower_sat_id': more_fields[7],
|
||||
'lower_sat_cqi': more_fields[8],
|
||||
'lower_sat_power': more_fields[9],
|
||||
'current_sat_id': more_fields[10],
|
||||
'current_slot': more_fields[11],
|
||||
'current_subframe': more_fields[12],
|
||||
'vdes_tx_link_id': more_fields[13],
|
||||
'vdes_tx_channel': more_fields[14],
|
||||
'vdes_tx_freq': more_fields[15],
|
||||
'vdes_buffer1_status': more_fields[16],
|
||||
'vdes_buffer2_status': more_fields[17],
|
||||
'vdes_demod1_enable': more_fields[18],
|
||||
'vdes_demod1_link_id': more_fields[19],
|
||||
'vdes_demod1_channel': more_fields[20],
|
||||
'vdes_demod1_freq': more_fields[21],
|
||||
'vdes_demod2_enable': more_fields[22],
|
||||
'vdes_demod2_link_id': more_fields[23],
|
||||
'vdes_demod2_channel': more_fields[24],
|
||||
'vdes_demod2_freq': more_fields[25],
|
||||
'vdes_demod3_enable': more_fields[26],
|
||||
'vdes_demod3_link_id': more_fields[27],
|
||||
'vdes_demod3_channel': more_fields[28],
|
||||
'vdes_demod3_freq': more_fields[29],
|
||||
'vdes_demod4_enable': more_fields[30],
|
||||
'vdes_demod4_link_id': more_fields[31],
|
||||
'vdes_demod4_channel': more_fields[32],
|
||||
'vdes_demod4_freq': more_fields[33],
|
||||
'ais_demod1_enable': more_fields[34],
|
||||
'ais_demod1_freq': more_fields[35],
|
||||
'ais_demod2_enable': more_fields[36],
|
||||
'ais_demod2_freq': more_fields[37],
|
||||
})
|
||||
|
||||
return result
|
||||
|
||||
def _parse_vdes_param_control(self, content: bytes) -> Dict[str, Any]:
|
||||
"""解析VDES协议参数控制报文(类型9)"""
|
||||
if len(content) < 18:
|
||||
raise ValueError("VDES param control message too short")
|
||||
|
||||
fields = struct.unpack('>BBBBIBBBiBIBBBiB', content[:18])
|
||||
|
||||
return {
|
||||
'vdes_enable': fields[0],
|
||||
'filter_enable': fields[1],
|
||||
'rac_limit_enable': fields[2],
|
||||
'agc_enable': fields[3],
|
||||
'sat_delay_comp_enable': fields[4],
|
||||
'mmsi': fields[5],
|
||||
'default_tx_link_id': fields[6],
|
||||
'default_tx_channel': fields[7],
|
||||
'default_tx_freq': fields[8],
|
||||
'tx_delay': fields[9],
|
||||
'tx_power_atten': fields[10],
|
||||
'demod1_link_id': fields[11],
|
||||
'demod1_channel': fields[12],
|
||||
'demod1_freq': fields[13],
|
||||
'rx_delay': fields[14],
|
||||
'rx_gain': fields[15],
|
||||
'clear_buffer1': fields[16],
|
||||
'clear_buffer2': fields[17],
|
||||
}
|
||||
|
||||
def _parse_vdes_upload_data(self, content: bytes) -> Dict[str, Any]:
|
||||
"""解析VDES上注数据报文(类型10)"""
|
||||
if len(content) < 1:
|
||||
raise ValueError("VDES upload data message too short")
|
||||
|
||||
data_type = content[0]
|
||||
try:
|
||||
data_type_enum = VDESUploadDataType(data_type)
|
||||
except ValueError:
|
||||
data_type_enum = None
|
||||
|
||||
result = {'data_type': data_type}
|
||||
|
||||
if data_type_enum == VDESUploadDataType.LONG_DATA_PARAM:
|
||||
if len(content) < 6:
|
||||
raise ValueError("Long data param message too short")
|
||||
target_mmsi, priority = struct.unpack('>IB', content[1:6])
|
||||
result.update({
|
||||
'target_mmsi': target_mmsi,
|
||||
'priority': priority
|
||||
})
|
||||
elif data_type_enum == VDESUploadDataType.LONG_DATA_CONTENT:
|
||||
result['data'] = content[1:]
|
||||
elif data_type_enum == VDESUploadDataType.SHORT_MESSAGE:
|
||||
if len(content) < 6:
|
||||
raise ValueError("Short message too short")
|
||||
msg_type, target_mmsi = struct.unpack('>BI', content[1:6])
|
||||
msg_data = content[6:]
|
||||
result.update({
|
||||
'message_type': msg_type,
|
||||
'target_mmsi': target_mmsi,
|
||||
'message_data': msg_data
|
||||
})
|
||||
|
||||
return result
|
||||
|
||||
def _parse_vdes_collect_data(self, content: bytes) -> Dict[str, Any]:
|
||||
"""解析VDES采集波形报文(类型11)"""
|
||||
if len(content) != 3584:
|
||||
raise ValueError("VDES collect data must be 3584 bytes")
|
||||
return {
|
||||
'wave_data': content,
|
||||
'length': len(content)
|
||||
}
|
||||
|
||||
def _parse_vdes_demod_data(self, content: bytes) -> Dict[str, Any]:
|
||||
"""解析VDES/AIS解调数据报文(类型12)"""
|
||||
if len(content) < 8:
|
||||
raise ValueError("VDES demod data message too short")
|
||||
|
||||
msg_type, sat_id, demod_id, slot, delay, snr = struct.unpack('>BBBHHh', content[:8])
|
||||
demod_data = content[8:]
|
||||
|
||||
return {
|
||||
'message_type': msg_type,
|
||||
'satellite_id': sat_id,
|
||||
'demodulator_id': demod_id,
|
||||
'slot': slot,
|
||||
'delay_us': delay,
|
||||
'snr_db': snr / 256, # 转换为浮点数
|
||||
'demod_data': demod_data
|
||||
}
|
||||
|
||||
def _parse_notification(self, content: bytes) -> Dict[str, Any]:
|
||||
"""解析消息通知报文(类型13)"""
|
||||
if len(content) < 1:
|
||||
raise ValueError("Notification message too short")
|
||||
|
||||
notif_type = content[0]
|
||||
descriptions = {
|
||||
0: "VDES协议开始执行",
|
||||
1: "VDES协议停止执行",
|
||||
2: "VDES功能初始化",
|
||||
3: "VDES开始采集波形",
|
||||
4: "VDES正在采集波形",
|
||||
5: "VDES停止采集波形",
|
||||
6: "VDES收到上行数据",
|
||||
7: "VDES与卫星建立会话成功",
|
||||
8: "VDES与卫星结束会话",
|
||||
9: "VDES发送上行测试波形",
|
||||
10: "VDES上行测试完毕",
|
||||
11: "VDES发送上行数据",
|
||||
12: "VDES解调数据"
|
||||
}
|
||||
|
||||
return {
|
||||
'notification_type': notif_type,
|
||||
'description': descriptions.get(notif_type, f"未知通知类型: {notif_type}"),
|
||||
'additional_data': content[1:] if len(content) > 1 else None
|
||||
}
|
||||
|
||||
# 使用示例
|
||||
if __name__ == "__main__":
|
||||
parser = VDESTCPParser()
|
||||
|
||||
# 示例1: 解析调试指令报文
|
||||
debug_cmd = b'####\x00\x00\x00\x00\x00\x00\x00\x01\x02'
|
||||
try:
|
||||
result = parser.parse_packet(debug_cmd)
|
||||
print("调试指令报文解析结果:")
|
||||
print(f"类型: {result['type_name']}")
|
||||
print(f"内容: {result['content']}")
|
||||
except ValueError as e:
|
||||
print(f"解析错误: {e}")
|
||||
|
||||
# 示例2: 解析GPS数据报文
|
||||
gps_data = b'####\x00\x00\x00\x07\x00\x00\x00\x24' + \
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x01' + \
|
||||
b'\x00\x00\x00\x02\x00\x00\x00\x03' + \
|
||||
b'\x00\x00\x00\x04\x00\x05\x00\x06' + \
|
||||
b'\x00\x07\x01\x02\x00\x00\x00\x08' + \
|
||||
b'\x00\x00\x00\x09\x00\x00\x00\x0A'
|
||||
try:
|
||||
result = parser.parse_packet(gps_data)
|
||||
print("\nGPS数据报文解析结果:")
|
||||
print(f"类型: {result['type_name']}")
|
||||
print(f"内容: {result['content']}")
|
||||
except ValueError as e:
|
||||
print(f"解析错误: {e}")
|
||||
353
协议资料/zhuoyan_model(1).py
Normal file
353
协议资料/zhuoyan_model(1).py
Normal file
@@ -0,0 +1,353 @@
|
||||
import socket
|
||||
import threading
|
||||
import queue
|
||||
import random
|
||||
import struct
|
||||
import time
|
||||
import math
|
||||
from datetime import datetime
|
||||
|
||||
# 全局配置
|
||||
HOST = 'localhost'
|
||||
PORT = 10
|
||||
BUFFER_SIZE = 32768
|
||||
FRAME_HEADER = b'####'
|
||||
|
||||
# 长江入海口位置 (中心点)
|
||||
YANGTZE_ESTUARY_LAT = 31.23
|
||||
YANGTZE_ESTUARY_LON = 121.47
|
||||
RANGE_NM = 5 # 5海里范围
|
||||
|
||||
# 预生成10艘船的MMSI
|
||||
SHIP_MMSIS = [random.randint(200000000, 299999999) for _ in range(10)]
|
||||
|
||||
# 报文类型定义
|
||||
MSG_TYPE_DEBUG = 0
|
||||
MSG_TYPE_LVDS = 1
|
||||
MSG_TYPE_CAN = 2
|
||||
MSG_TYPE_AD9361 = 3
|
||||
MSG_TYPE_WAVE_CTRL = 4
|
||||
MSG_TYPE_TEST_PARAM = 5
|
||||
MSG_TYPE_TEST_WAVE = 6
|
||||
MSG_TYPE_GPS = 7
|
||||
MSG_TYPE_STATUS = 8
|
||||
MSG_TYPE_VDES_CTRL = 9
|
||||
MSG_TYPE_VDES_UPLOAD = 10
|
||||
MSG_TYPE_COLLECT = 11
|
||||
MSG_TYPE_DEMOD = 12
|
||||
MSG_TYPE_NOTIFY = 13
|
||||
|
||||
# 解调器类型
|
||||
DEMOD_VDES = 0 # VDES解调器 (0-3)
|
||||
DEMOD_AIS = 4 # AIS解调器 (4-5)
|
||||
|
||||
# 通信状态定义 (Annex 2 Table 18)
|
||||
COMM_STATES = [
|
||||
{"sync_state": 0, "slot_timeout": 0, "sub_message": 0},
|
||||
{"sync_state": 1, "slot_timeout": 1, "sub_message": 1},
|
||||
{"sync_state": 2, "slot_timeout": 2, "sub_message": 2},
|
||||
{"sync_state": 3, "slot_timeout": 3, "sub_message": 3}
|
||||
]
|
||||
|
||||
class VDESTCPServer:
|
||||
def __init__(self):
|
||||
self.send_queue = queue.Queue()
|
||||
self.running = True
|
||||
self.device_state = {
|
||||
"cpu0": 50,
|
||||
"cpu1": 50,
|
||||
"version": 0x01020304,
|
||||
"uptime": int(time.time()),
|
||||
"gps_status": 1,
|
||||
"pps_lock": 1,
|
||||
"ad9361_status": 2
|
||||
}
|
||||
self.gps_params = self.generate_gps_data()
|
||||
|
||||
def start(self):
|
||||
# server_thread = threading.Thread(target=self.run_server)
|
||||
# server_thread.daemon = True
|
||||
# server_thread.start()
|
||||
|
||||
# send_thread = threading.Thread(target=self.send_data_thread)
|
||||
# send_thread.daemon = True
|
||||
# send_thread.start()
|
||||
|
||||
# server_thread.join()
|
||||
# send_thread.join()
|
||||
print(11111111111)
|
||||
print(self.build_gps_message())
|
||||
|
||||
def run_server(self):
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||
s.bind((HOST, PORT))
|
||||
s.listen()
|
||||
print(f"VDES TCP Server listening on {HOST}:{PORT}")
|
||||
|
||||
while self.running:
|
||||
conn, addr = s.accept()
|
||||
print(f"Connected by {addr}")
|
||||
client_thread = threading.Thread(target=self.handle_client, args=(conn,))
|
||||
client_thread.daemon = True
|
||||
client_thread.start()
|
||||
|
||||
def handle_client(self, conn):
|
||||
with conn:
|
||||
while self.running:
|
||||
try:
|
||||
data = conn.recv(BUFFER_SIZE)
|
||||
if not data:
|
||||
break
|
||||
|
||||
# 解析报文
|
||||
if len(data) < 12:
|
||||
print("Invalid packet size")
|
||||
continue
|
||||
|
||||
header = data[:4]
|
||||
if header != FRAME_HEADER:
|
||||
print("Invalid frame header")
|
||||
continue
|
||||
|
||||
msg_type = struct.unpack('>I', data[4:8])[0]
|
||||
msg_len = struct.unpack('>I', data[8:12])[0]
|
||||
msg_content = data[12:12+msg_len] if msg_len > 0 else b''
|
||||
|
||||
print(f"Received message type: {msg_type}, length: {msg_len}")
|
||||
|
||||
# 处理报文并准备响应
|
||||
response = self.process_message(msg_type, msg_content)
|
||||
if response:
|
||||
self.send_queue.put(response)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error handling client: {e}")
|
||||
break
|
||||
|
||||
def process_message(self, msg_type, content):
|
||||
"""处理接收到的报文并返回响应"""
|
||||
response = None
|
||||
|
||||
if msg_type == MSG_TYPE_DEBUG:
|
||||
# 调试指令报文
|
||||
if len(content) >= 1:
|
||||
cmd_type = content[0]
|
||||
print(f"Received debug command: {cmd_type}")
|
||||
# 简单响应通知报文
|
||||
response = self.build_notify_message(0, "Debug command processed")
|
||||
|
||||
elif msg_type == MSG_TYPE_AD9361:
|
||||
# AD9361参数控制
|
||||
print("Received AD9361 control params")
|
||||
response = self.build_notify_message(0, "AD9361 params updated")
|
||||
|
||||
elif msg_type == MSG_TYPE_TEST_PARAM:
|
||||
# 发送测试参数控制
|
||||
if len(content) >= 9:
|
||||
test_type, test_count, test_interval = struct.unpack('>BII', content[:9])
|
||||
print(f"Test params: type={test_type}, count={test_count}, interval={test_interval}ms")
|
||||
response = self.build_notify_message(0, "Test params accepted")
|
||||
|
||||
elif msg_type == MSG_TYPE_VDES_CTRL:
|
||||
# VDES协议参数控制
|
||||
print("Received VDES control params")
|
||||
response = self.build_notify_message(0, "VDES params updated")
|
||||
|
||||
elif msg_type == MSG_TYPE_VDES_UPLOAD:
|
||||
# VDES上注数据
|
||||
if len(content) >= 1:
|
||||
data_type = content[0]
|
||||
print(f"VDES upload data type: {data_type}")
|
||||
response = self.build_notify_message(0, "Data upload accepted")
|
||||
|
||||
return response
|
||||
|
||||
def send_data_thread(self):
|
||||
"""发送线程,定期发送GPS和解调数据报文"""
|
||||
while self.running:
|
||||
try:
|
||||
# 发送GPS数据 (每秒一次)
|
||||
self.gps_params = self.generate_gps_data()
|
||||
gps_msg = self.build_gps_message()
|
||||
self.send_queue.put(gps_msg)
|
||||
|
||||
# 发送解调数据 (随机间隔)
|
||||
if random.random() > 0.7:
|
||||
demod_msg = self.build_demod_message()
|
||||
self.send_queue.put(demod_msg)
|
||||
|
||||
# 发送状态监控数据 (每秒一次)
|
||||
status_msg = self.build_status_message()
|
||||
self.send_queue.put(status_msg)
|
||||
|
||||
# 发送队列中的响应报文
|
||||
while not self.send_queue.empty():
|
||||
msg = self.send_queue.get()
|
||||
# 在实际服务器中,这里应该发送给所有连接的客户端
|
||||
# 本示例中仅打印发送信息
|
||||
print(f"Sending message type: {struct.unpack('>I', msg[4:8])[0]}, "
|
||||
f"length: {struct.unpack('>I', msg[8:12])[0]}")
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error in send thread: {e}")
|
||||
|
||||
def build_packet(self, msg_type, content):
|
||||
"""构建完整TCP报文"""
|
||||
header = FRAME_HEADER
|
||||
type_field = struct.pack('>I', msg_type)
|
||||
length_field = struct.pack('>I', len(content))
|
||||
return header + type_field + length_field + content
|
||||
|
||||
def build_gps_message(self):
|
||||
"""构建GPS解析数据报文 (类型7)"""
|
||||
content = struct.pack('>QiiihhhBBBBBB',
|
||||
self.gps_params["utc_time"],
|
||||
self.gps_params["longitude"],
|
||||
self.gps_params["latitude"],
|
||||
self.gps_params["altitude"],
|
||||
self.gps_params["used_sats"],
|
||||
self.gps_params["gps_sats"],
|
||||
self.gps_params["beidou_sats"],
|
||||
self.gps_params["gps_status"],
|
||||
self.gps_params["fix_mode"],
|
||||
self.gps_params["hdop"],
|
||||
self.gps_params["speed"],
|
||||
self.gps_params["course"])
|
||||
return self.build_packet(MSG_TYPE_GPS, content)
|
||||
|
||||
def build_demod_message(self):
|
||||
"""构建VDES解调数据报文 (类型12)"""
|
||||
demod_id = random.randint(0, 5)
|
||||
comm_state = random.choice(COMM_STATES)
|
||||
|
||||
if demod_id <= DEMOD_VDES + 3: # VDES解调器 (0-3)
|
||||
# 根据M.2092-1 Annex5 3.10生成消息
|
||||
msg_data = self.generate_vdes_message()
|
||||
else: # AIS解调器 (4-5)
|
||||
# 根据M.1371-5 Annex8 3.1生成Message1
|
||||
msg_data = self.generate_ais_message1()
|
||||
|
||||
# 构建通信状态字段
|
||||
comm_state_field = struct.pack('>BBH',
|
||||
(comm_state["sync_state"] << 6) | (comm_state["slot_timeout"] << 3),
|
||||
comm_state["sub_message"] >> 8,
|
||||
comm_state["sub_message"] & 0xFF)
|
||||
|
||||
# 构建完整报文
|
||||
content = struct.pack('>BBHH', 12, demod_id, random.randint(0, 65535), random.randint(0, 65535))
|
||||
content += struct.pack('>H', random.randint(-12800, 12700)) # 信噪比
|
||||
content += comm_state_field
|
||||
content += msg_data
|
||||
|
||||
return self.build_packet(MSG_TYPE_DEMOD, content)
|
||||
|
||||
def build_status_message(self):
|
||||
"""构建地检状态监控报文 (类型8)"""
|
||||
# 更新设备状态
|
||||
self.device_state["cpu0"] = random.randint(40, 60)
|
||||
self.device_state["cpu1"] = random.randint(40, 60)
|
||||
self.device_state["uptime"] = int(time.time())
|
||||
|
||||
# 构建报文内容 (简化版)
|
||||
content = struct.pack('>BBIIBBBB',
|
||||
self.device_state["cpu0"],
|
||||
self.device_state["cpu1"],
|
||||
self.device_state["version"],
|
||||
self.device_state["uptime"],
|
||||
self.device_state["gps_status"],
|
||||
self.device_state["pps_lock"],
|
||||
self.device_state["ad9361_status"],
|
||||
0) # 校准因子占位
|
||||
|
||||
return self.build_packet(MSG_TYPE_STATUS, content)
|
||||
|
||||
def build_notify_message(self, msg_type, text):
|
||||
"""构建消息通知报文 (类型13)"""
|
||||
text_bytes = text.encode('utf-8')
|
||||
content = struct.pack('>B', msg_type) + text_bytes
|
||||
return self.build_packet(MSG_TYPE_NOTIFY, content)
|
||||
|
||||
def generate_gps_data(self):
|
||||
"""生成GPS数据 (长江入海口5海里范围内)"""
|
||||
# 在中心点附近5海里范围内生成随机位置
|
||||
lat, lon = self.generate_random_position()
|
||||
|
||||
return {
|
||||
"utc_time": int(time.time()),
|
||||
"longitude": int(lon * 10000000),
|
||||
"latitude": int(lat * 10000000),
|
||||
"altitude": random.randint(-50, 100),
|
||||
"used_sats": random.randint(5, 12),
|
||||
"gps_sats": random.randint(3, 8),
|
||||
"beidou_sats": random.randint(3, 8),
|
||||
"gps_status": random.randint(0, 4),
|
||||
"fix_mode": random.randint(1, 3),
|
||||
"hdop": random.randint(10, 100),
|
||||
"speed": random.randint(0, 2000), # 0.01节单位
|
||||
"course": random.randint(0, 35900) # 0.01度单位
|
||||
}
|
||||
|
||||
def generate_random_position(self):
|
||||
"""在长江入海口5海里范围内生成随机位置"""
|
||||
# 1海里 ≈ 0.0166667度 (赤道附近)
|
||||
offset_lat = (random.random() - 0.5) * RANGE_NM * 0.0166667
|
||||
offset_lon = (random.random() - 0.5) * RANGE_NM * 0.0166667
|
||||
|
||||
lat = YANGTZE_ESTUARY_LAT + offset_lat
|
||||
lon = YANGTZE_ESTUARY_LON + offset_lon
|
||||
|
||||
return lat, lon
|
||||
|
||||
def generate_vdes_message(self):
|
||||
"""生成VDES消息 (M.2092-1 Annex5 3.10)"""
|
||||
# 随机选择一种消息类型 (简化实现)
|
||||
msg_types = [0, 1, 2, 3, 4, 5]
|
||||
msg_type = random.choice(msg_types)
|
||||
|
||||
# 构建基本消息结构
|
||||
msg = struct.pack('>B', msg_type)
|
||||
|
||||
# 添加随机内容
|
||||
if msg_type == 0: # Paging
|
||||
msg += struct.pack('>I', random.randint(100000000, 999999999))
|
||||
elif msg_type == 1: # Resource request
|
||||
msg += struct.pack('>IB', random.randint(100000000, 999999999), random.randint(0, 255))
|
||||
|
||||
return msg
|
||||
|
||||
def generate_ais_message1(self):
|
||||
"""生成AIS Message1位置报告 (M.1371-5 Annex8 3.1)"""
|
||||
# 随机位置
|
||||
lat, lon = self.generate_random_position()
|
||||
|
||||
# 转换为AIS格式
|
||||
lat_ais = int((lat + 90) * 60000)
|
||||
lon_ais = int((lon + 180) * 60000)
|
||||
|
||||
# 随机选择一艘船
|
||||
mmsi = random.choice(SHIP_MMSIS)
|
||||
|
||||
# 随机通信状态
|
||||
comm_state = random.choice(COMM_STATES)
|
||||
comm_state_field = (
|
||||
(comm_state["sync_state"] << 17) |
|
||||
(comm_state["slot_timeout"] << 14) |
|
||||
comm_state["sub_message"]
|
||||
)
|
||||
|
||||
# 构建Message1 (168位/21字节)
|
||||
msg = struct.pack('>I', (1 << 26) | (random.randint(0, 3) << 24) | (mmsi >> 6))
|
||||
msg += struct.pack('>I', ((mmsi & 0x3F) << 26) | (random.randint(0, 15) << 22))
|
||||
msg += struct.pack('>I', (random.randint(0, 255) << 24) | (random.randint(0, 1023) << 14))
|
||||
msg += struct.pack('>I', (random.randint(0, 1) << 31) | (lon_ais & 0xFFFFFFF))
|
||||
msg += struct.pack('>I', (lat_ais << 4) | (random.randint(0, 4095) >> 8))
|
||||
msg += struct.pack('>I', ((random.randint(0, 4095) & 0xFF) << 24) | (random.randint(0, 3599) << 12))
|
||||
msg += struct.pack('>I', (random.randint(0, 511) << 23) | (random.randint(0, 63) << 17) | (comm_state_field & 0x1FFFF))
|
||||
|
||||
return msg
|
||||
|
||||
if __name__ == "__main__":
|
||||
server = VDESTCPServer()
|
||||
server.start()
|
||||
252
协议资料/zhuoyan_model.py
Normal file
252
协议资料/zhuoyan_model.py
Normal file
@@ -0,0 +1,252 @@
|
||||
import socket
|
||||
import struct
|
||||
import random
|
||||
import time
|
||||
import threading
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# 报文类型常量
|
||||
MSG_DEBUG = 0
|
||||
MSG_LVDS = 1
|
||||
MSG_CAN = 2
|
||||
MSG_AD9361_CTRL = 3
|
||||
MSG_WAVE_CTRL = 4
|
||||
MSG_TEST_PARAM_CTRL = 5
|
||||
MSG_TEST_WAVE_UPLOAD = 6
|
||||
MSG_GPS = 7
|
||||
MSG_STATUS_MONITOR = 8
|
||||
MSG_PROTO_PARAM_CTRL = 9
|
||||
MSG_DATA_UPLOAD = 10
|
||||
MSG_DATA_COLLECT = 11
|
||||
MSG_DEMOD_DATA = 12
|
||||
MSG_NOTIFICATION = 13
|
||||
|
||||
# 解调器编号常量
|
||||
VDES_DEMOD_RANGE = (0, 3) # VDES解调器编号0-3
|
||||
AIS_DEMOD_RANGE = (4, 5) # AIS解调器编号4-5
|
||||
|
||||
# 长江入海口坐标范围 (31.0°N - 31.5°N, 121.5°E - 122.0°E)
|
||||
YANGTZE_DELTA_CENTER = (31.23, 121.77) # 上海附近
|
||||
DELTA_RANGE = 0.05 # ±0.05度 ≈ 5海里
|
||||
|
||||
class VDESServer:
|
||||
def __init__(self, host='localhost', port=10):
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.header = b'####'
|
||||
self.running = False
|
||||
self.server_socket = None
|
||||
self.ship_mmsi = 123456789 # 船舶MMSI
|
||||
|
||||
def start(self):
|
||||
"""启动TCP服务器"""
|
||||
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.server_socket.bind((self.host, self.port))
|
||||
self.server_socket.listen(1)
|
||||
self.running = True
|
||||
print(f"VDES Server started on {self.host}:{self.port}")
|
||||
|
||||
# 接受客户端连接
|
||||
client_socket, addr = self.server_socket.accept()
|
||||
print(f"Connected by {addr}")
|
||||
|
||||
# 启动接收线程和定时发送线程
|
||||
recv_thread = threading.Thread(target=self.handle_client, args=(client_socket,))
|
||||
send_thread = threading.Thread(target=self.send_periodic_messages, args=(client_socket,))
|
||||
|
||||
recv_thread.start()
|
||||
send_thread.start()
|
||||
|
||||
recv_thread.join()
|
||||
send_thread.join()
|
||||
|
||||
def stop(self):
|
||||
"""停止服务器"""
|
||||
self.running = False
|
||||
if self.server_socket:
|
||||
self.server_socket.close()
|
||||
|
||||
def build_packet(self, msg_type, content):
|
||||
"""构建协议报文:帧头(4) + 类型(4) + 长度(4) + 内容(N)"""
|
||||
length = len(content)
|
||||
return self.header + struct.pack('>I', msg_type) + struct.pack('>I', length) + content
|
||||
|
||||
def parse_packet(self, data):
|
||||
"""解析接收到的报文"""
|
||||
if len(data) < 12 or data[:4] != self.header:
|
||||
return None, None
|
||||
|
||||
msg_type = struct.unpack('>I', data[4:8])[0]
|
||||
length = struct.unpack('>I', data[8:12])[0]
|
||||
content = data[12:12+length] if len(data) >= 12 + length else None
|
||||
return msg_type, content
|
||||
|
||||
def handle_debug_command(self, content):
|
||||
"""处理调试指令报文(类型0)"""
|
||||
cmd_type = content[0] if content else 0
|
||||
responses = {
|
||||
0: "初始化地检",
|
||||
1: "测试波形上注完成",
|
||||
2: "LVDS数据开始上注",
|
||||
3: "CAN初始化",
|
||||
4: "LVDS初始化",
|
||||
5: "AD9361重新校准",
|
||||
6: "GPS初始化"
|
||||
}
|
||||
response_msg = responses.get(cmd_type, "未知指令")
|
||||
print(f"执行调试指令: {response_msg}")
|
||||
# 返回通知报文确认
|
||||
return self.build_packet(MSG_NOTIFICATION, struct.pack('B', 0)) # 类型0: VDES协议开始执行
|
||||
|
||||
def handle_client(self, client_socket):
|
||||
"""处理客户端请求"""
|
||||
while self.running:
|
||||
try:
|
||||
data = client_socket.recv(32768)
|
||||
if not data:
|
||||
break
|
||||
|
||||
msg_type, content = self.parse_packet(data)
|
||||
if msg_type is None:
|
||||
continue
|
||||
|
||||
# 根据报文类型处理
|
||||
if msg_type == MSG_DEBUG:
|
||||
response = self.handle_debug_command(content)
|
||||
elif msg_type == MSG_AD9361_CTRL:
|
||||
response = self.build_packet(MSG_NOTIFICATION, struct.pack('B', 7)) # AD9361状态更新
|
||||
else:
|
||||
response = self.build_packet(MSG_NOTIFICATION, struct.pack('B', 3)) # 通用确认
|
||||
|
||||
client_socket.send(response)
|
||||
except Exception as e:
|
||||
print(f"处理错误: {e}")
|
||||
break
|
||||
|
||||
def send_periodic_messages(self, client_socket):
|
||||
"""定时发送状态监控和GPS报文"""
|
||||
while self.running:
|
||||
try:
|
||||
# 每秒发送GPS数据(类型7)
|
||||
gps_data = self.generate_gps_data()
|
||||
client_socket.send(self.build_packet(MSG_GPS, gps_data))
|
||||
|
||||
# 每秒发送状态监控(类型8)
|
||||
status_data = bytes([random.randint(0, 100) for _ in range(50)]) # 随机状态数据
|
||||
client_socket.send(self.build_packet(MSG_STATUS_MONITOR, status_data))
|
||||
|
||||
# 每5秒发送解调数据(类型12)
|
||||
if int(time.time()) % 5 == 0:
|
||||
demod_data = self.generate_demod_data()
|
||||
client_socket.send(self.build_packet(MSG_DEMOD_DATA, demod_data))
|
||||
|
||||
time.sleep(1)
|
||||
except Exception as e:
|
||||
print(f"发送错误: {e}")
|
||||
break
|
||||
|
||||
def generate_gps_data(self):
|
||||
"""生成长江入海口附近的GPS数据"""
|
||||
# 在长江入海口附近随机生成位置
|
||||
lat = YANGTZE_DELTA_CENTER[0] + random.uniform(-DELTA_RANGE, DELTA_RANGE)
|
||||
lon = YANGTZE_DELTA_CENTER[1] + random.uniform(-DELTA_RANGE, DELTA_RANGE)
|
||||
|
||||
# 转换为度分格式*10000000
|
||||
lat_int = int(lat * 10000000)
|
||||
lon_int = int(lon * 10000000)
|
||||
|
||||
# 其他GPS数据字段
|
||||
utc_time = int((datetime.utcnow() - datetime(1980, 1, 6)).total_seconds())
|
||||
altitude = random.randint(-10, 50) # 海拔高度(米)
|
||||
used_satellites = random.randint(5, 12)
|
||||
gps_satellites = random.randint(4, 8)
|
||||
beidou_satellites = random.randint(4, 8)
|
||||
gps_status = random.randint(1, 4) # GPS状态
|
||||
pos_mode = random.randint(1, 3) # 定位模式
|
||||
hdop = random.randint(10, 50) # 水平精度因子
|
||||
speed = random.randint(0, 2000) # 运动速度 (0.01节)
|
||||
course = random.randint(0, 35900) # 运动方向 (度*100)
|
||||
|
||||
# 打包GPS数据
|
||||
return struct.pack('>Q', utc_time) + \
|
||||
struct.pack('>i', lon_int) + \
|
||||
struct.pack('>i', lat_int) + \
|
||||
struct.pack('>i', altitude) + \
|
||||
struct.pack('>H', used_satellites) + \
|
||||
struct.pack('>H', gps_satellites) + \
|
||||
struct.pack('>H', beidou_satellites) + \
|
||||
struct.pack('B', gps_status) + \
|
||||
struct.pack('B', pos_mode) + \
|
||||
struct.pack('>I', hdop) + \
|
||||
struct.pack('>I', speed) + \
|
||||
struct.pack('>I', course)
|
||||
|
||||
def generate_demod_data(self):
|
||||
"""生成解调数据报文(类型12)"""
|
||||
demodulator_id = random.randint(0, 5)
|
||||
msg_type = 12 # 固定值12
|
||||
satellite_id = random.randint(1, 255)
|
||||
demod_data = struct.pack('B', msg_type) + struct.pack('B', satellite_id) + struct.pack('B', demodulator_id)
|
||||
|
||||
# 根据解调器编号生成数据
|
||||
if VDES_DEMOD_RANGE[0] <= demodulator_id <= VDES_DEMOD_RANGE[1]:
|
||||
# VDES解调器 (0-3): 使用M.2092-1 Annex5格式
|
||||
msg_id = random.choice([10, 11, 12, 20, 21])
|
||||
content = struct.pack('B', msg_id) + os.urandom(20) # 随机生成20字节数据
|
||||
else:
|
||||
# AIS解调器 (4-5): 使用M.1371-5 Annex8 Message1格式
|
||||
content = self.generate_ais_message1()
|
||||
|
||||
return demod_data + content
|
||||
|
||||
def generate_ais_message1(self):
|
||||
"""生成AIS Message 1(位置报告)"""
|
||||
# 在长江入海口附近随机生成位置
|
||||
lat = YANGTZE_DELTA_CENTER[0] + random.uniform(-DELTA_RANGE, DELTA_RANGE)
|
||||
lon = YANGTZE_DELTA_CENTER[1] + random.uniform(-DELTA_RANGE, DELTA_RANGE)
|
||||
|
||||
# 转换为1/10000分钟格式
|
||||
lat_min = int(lat * 60 * 10000)
|
||||
lon_min = int(lon * 60 * 10000)
|
||||
|
||||
# 其他AIS字段
|
||||
message_id = 1
|
||||
repeat_indicator = 0
|
||||
navigational_status = random.randint(0, 15) # 航行状态
|
||||
rate_of_turn = random.randint(-128, 127) # 转向率
|
||||
speed_over_ground = random.randint(0, 1022) # 对地航速 (0.1节)
|
||||
position_accuracy = 1 # 高精度
|
||||
course_over_ground = random.randint(0, 3599) # 对地航向 (0.1度)
|
||||
true_heading = random.randint(0, 359) # 真航向
|
||||
timestamp = random.randint(0, 59) # UTC秒
|
||||
maneuver_indicator = random.randint(0, 1) # 操纵指示器
|
||||
spare = 0
|
||||
raim_flag = 0 # RAIM标志
|
||||
|
||||
# 打包AIS Message 1
|
||||
return struct.pack('>B', message_id) + \
|
||||
struct.pack('>B', (repeat_indicator << 6) | (navigational_status << 2) | (rate_of_turn >> 6)) + \
|
||||
struct.pack('>B', (rate_of_turn & 0x3F) << 2) | (speed_over_ground >> 8) + \
|
||||
struct.pack('>B', speed_over_ground & 0xFF) + \
|
||||
struct.pack('>B', (position_accuracy << 7) | (lon_min >> 25)) + \
|
||||
struct.pack('>B', (lon_min >> 17) & 0xFF) + \
|
||||
struct.pack('>B', (lon_min >> 9) & 0xFF) + \
|
||||
struct.pack('>B', (lon_min >> 1) & 0xFF) + \
|
||||
struct.pack('>B', ((lon_min & 0x1) << 7) | (lat_min >> 20)) + \
|
||||
struct.pack('>B', (lat_min >> 12) & 0xFF) + \
|
||||
struct.pack('>B', (lat_min >> 4) & 0xFF) + \
|
||||
struct.pack('>B', ((lat_min & 0xF) << 4) | (course_over_ground >> 8)) + \
|
||||
struct.pack('>B', course_over_ground & 0xFF) + \
|
||||
struct.pack('>H', true_heading) + \
|
||||
struct.pack('>B', timestamp) + \
|
||||
struct.pack('>B', (maneuver_indicator << 2) | spare) + \
|
||||
struct.pack('>B', raim_flag)
|
||||
|
||||
if __name__ == "__main__":
|
||||
server = VDESServer()
|
||||
try:
|
||||
server.start()
|
||||
except PermissionError:
|
||||
print("错误:需要管理员权限绑定到端口10")
|
||||
except KeyboardInterrupt:
|
||||
server.stop()
|
||||
BIN
协议资料/~$ES第三版地检_终端设计_1.4.docx
Normal file
BIN
协议资料/~$ES第三版地检_终端设计_1.4.docx
Normal file
Binary file not shown.
BIN
协议资料/上位机.zip
Normal file
BIN
协议资料/上位机.zip
Normal file
Binary file not shown.
BIN
协议资料/测试结果/2025-08-01-10-03-50.gif
Normal file
BIN
协议资料/测试结果/2025-08-01-10-03-50.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 548 MiB |
BIN
协议资料/测试结果/VDES协议测试_卫星中继转发图片_录像.7z
Normal file
BIN
协议资料/测试结果/VDES协议测试_卫星中继转发图片_录像.7z
Normal file
Binary file not shown.
630
协议资料/测试结果/vdes_test.txt
Normal file
630
协议资料/测试结果/vdes_test.txt
Normal file
File diff suppressed because one or more lines are too long
BIN
协议资料/测试结果/vdes_test_2025_08_01_数据_单点_信源12A529EC_卫星2_会话2.jpg
Normal file
BIN
协议资料/测试结果/vdes_test_2025_08_01_数据_单点_信源12A529EC_卫星2_会话2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
BIN
协议资料/测试结果/测试图片.7z
Normal file
BIN
协议资料/测试结果/测试图片.7z
Normal file
Binary file not shown.
BIN
协议资料/测试结果/测试图片.jpg
Normal file
BIN
协议资料/测试结果/测试图片.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
1
协议资料/解析说明.txt
Normal file
1
协议资料/解析说明.txt
Normal file
@@ -0,0 +1 @@
|
||||
ais在1371-5第三章节109页,封装后放在tcp中的表16的解调数据字段。只需要模拟gps和ais vdes在2092-1文件的126页
|
||||
Reference in New Issue
Block a user