first commit

This commit is contained in:
lihansani
2026-07-13 15:37:05 +08:00
commit 8b11aa2efc
299 changed files with 206339 additions and 0 deletions

View 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()