fix: FASS2 状态机与 UDP 枢纽审查项

等锁超时、全路径签名、无锁窗口不下发、Fault 终态可等待、Pass+机构不再短路、Alarm 不杀单、catch-up 停在未完成站;VehicleCode=0/重复车号拒绝注册,Hub 已运行时不抢监听口;FileLogger 空目录可写。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
黄兆尉
2026-08-26 23:04:58 +08:00
co-authored by Cursor
parent 29a06f004f
commit e4a245e644
13 changed files with 465 additions and 48 deletions
+52 -10
View File
@@ -23,16 +23,37 @@ namespace StandardScene.Magnetic.Protocol
private static int _listenPort = 20103;
private static readonly Dictionary<ushort, long> _lastUnknownCarLogUtcTicks = new Dictionary<ushort, long>();
public static void Register(IFass2UdpCar car)
internal static bool IsRunning => _running;
internal static int ListenPort => _listenPort;
public static bool Register(IFass2UdpCar car)
{
if (car == null)
{
return;
return false;
}
if (car.VehicleCode == 0)
{
Diagnosis.Post("Fass2UdpHub 拒绝注册 VehicleCode=0,请为每台 Mag2Car 配置唯一车号", "Fass2UdpHub", true);
return false;
}
lock (SyncRoot)
{
if (CarsByCode.TryGetValue(car.VehicleCode, out var existing) &&
!ReferenceEquals(existing, car))
{
Diagnosis.Post(
$"Fass2UdpHub 拒绝覆盖 VehicleCode={car.VehicleCode}(已被另一台车占用)",
"Fass2UdpHub",
true);
return false;
}
CarsByCode[car.VehicleCode] = car;
return true;
}
}
@@ -64,9 +85,31 @@ namespace StandardScene.Magnetic.Protocol
public static void EnsureStarted(int listenPort)
{
if (listenPort > 0)
if (listenPort <= 0)
{
_listenPort = listenPort;
listenPort = _listenPort;
}
var needRestart = false;
lock (SyncRoot)
{
if (_running && listenPort != _listenPort)
{
needRestart = true;
}
else if (_running)
{
return;
}
}
if (needRestart)
{
Diagnosis.Post(
$"Fass2UdpHub 监听口 {_listenPort} → {listenPort},重启枢纽",
"Fass2UdpHub",
true);
Stop();
}
lock (SyncRoot)
@@ -76,6 +119,7 @@ namespace StandardScene.Magnetic.Protocol
return;
}
_listenPort = listenPort;
_listener = new UdpClient(_listenPort);
_running = true;
_receiveThread = new Thread(ReceiveLoop)
@@ -209,6 +253,7 @@ namespace StandardScene.Magnetic.Protocol
private static void LogUnknownCar(ushort carCode)
{
var nowTicks = DateTime.UtcNow.Ticks;
string registered;
lock (SyncRoot)
{
if (_lastUnknownCarLogUtcTicks.TryGetValue(carCode, out var lastTicks)
@@ -218,12 +263,9 @@ namespace StandardScene.Magnetic.Protocol
}
_lastUnknownCarLogUtcTicks[carCode] = nowTicks;
}
var registered = string.Join(",", CarsByCode.Keys);
if (string.IsNullOrEmpty(registered))
{
registered = "(无)";
registered = CarsByCode.Count == 0
? "(无)"
: string.Join(",", CarsByCode.Keys);
}
Diagnosis.Post(