fix: FASS2 状态帧校验 XOR
错误校验和的 100B 上报不再被当成合法状态解析。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -124,6 +124,24 @@ namespace StandardScene.Magnetic.Tests.Protocol
|
|||||||
Assert.Equal((ushort)500, report.Node.Distance);
|
Assert.Equal((ushort)500, report.Node.Distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TryExtractStateFrame_RejectsBadXor()
|
||||||
|
{
|
||||||
|
var frame = Fass2TestFrameBuilder.BuildStateFrame(5, 2, 7, 42);
|
||||||
|
frame[98] ^= 0xFF;
|
||||||
|
|
||||||
|
Assert.False(Fass2Protocol.TryExtractStateFrame(frame, frame.Length, out _));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ParseState_RejectsBadXor()
|
||||||
|
{
|
||||||
|
var frame = Fass2TestFrameBuilder.BuildStateFrame(5, 2, 7, 42);
|
||||||
|
frame[98] ^= 0xFF;
|
||||||
|
|
||||||
|
Assert.Throws<ArgumentException>(() => Fass2Protocol.ParseState(frame));
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void NodeMessage_ToBytes_FromBytes_RoundTrip()
|
public void NodeMessage_ToBytes_FromBytes_RoundTrip()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -141,19 +141,27 @@ namespace StandardScene.Magnetic.Protocol
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!HasValidStateChecksum(buffer, i))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
frame = new byte[StateFrameLength];
|
frame = new byte[StateFrameLength];
|
||||||
Buffer.BlockCopy(buffer, i, frame, 0, StateFrameLength);
|
Buffer.BlockCopy(buffer, i, frame, 0, StateFrameLength);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length == StateFrameLength && buffer[0] == Begin && buffer[StateFrameLength - 1] == End)
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool HasValidStateChecksum(byte[] bytes, int offset = 0)
|
||||||
|
{
|
||||||
|
if (bytes == null || offset < 0 || offset + StateFrameLength > bytes.Length)
|
||||||
{
|
{
|
||||||
frame = new byte[StateFrameLength];
|
return false;
|
||||||
Buffer.BlockCopy(buffer, 0, frame, 0, StateFrameLength);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return bytes[offset + 98] == Xor(bytes, offset + 1, 97);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Fass2StateReport ParseState(byte[] bytes)
|
public static Fass2StateReport ParseState(byte[] bytes)
|
||||||
@@ -166,6 +174,11 @@ namespace StandardScene.Magnetic.Protocol
|
|||||||
{
|
{
|
||||||
throw new ArgumentException($"invalid FASS2 state frame: begin=0x{bytes[0]:X2}, end=0x{bytes[99]:X2}");
|
throw new ArgumentException($"invalid FASS2 state frame: begin=0x{bytes[0]:X2}, end=0x{bytes[99]:X2}");
|
||||||
}
|
}
|
||||||
|
if (!HasValidStateChecksum(bytes))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
$"invalid FASS2 state xor: got=0x{bytes[98]:X2}, expect=0x{Xor(bytes, 1, 97):X2}");
|
||||||
|
}
|
||||||
|
|
||||||
var nodeBytes = new byte[25];
|
var nodeBytes = new byte[25];
|
||||||
Buffer.BlockCopy(bytes, 53, nodeBytes, 0, 25);
|
Buffer.BlockCopy(bytes, 53, nodeBytes, 0, 25);
|
||||||
|
|||||||
Reference in New Issue
Block a user