Skip to content

Commit

Permalink
修正Modbus消息编解码问题,单元测试通过
Browse files Browse the repository at this point in the history
  • Loading branch information
nnhy committed Dec 12, 2024
1 parent 06a6293 commit dc03474
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 32 deletions.
1 change: 1 addition & 0 deletions NewLife.Modbus/NewLife.Modbus.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NewLife.Core" Version="11.1.2024.1212-beta1042" />
</ItemGroup>

<ItemGroup>
Expand Down
10 changes: 5 additions & 5 deletions NewLife.Modbus/Protocols/ModbusAsciiMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class ModbusAsciiMessage : ModbusMessage
/// <summary>从数据读取消息</summary>
/// <param name="reader">读取器</param>
/// <returns></returns>
public override Boolean Read(SpanReader reader)
public override Boolean Read(ref SpanReader reader)
{
var str = reader.ReadString(-1, Encoding.ASCII);
if (str.Length < 1 + 2 + 2 + 2 || str[0] != ':') return false;
Expand All @@ -31,7 +31,7 @@ public override Boolean Read(SpanReader reader)
var buf = str[1..p].ToHex();
var reader2 = new SpanReader(buf) { IsLittleEndian = false };

if (!base.Read(reader2)) return false;
if (!base.Read(ref reader2)) return false;

Lrc = buf[^1];
Lrc2 = ModbusHelper.Lrc(buf, 0, buf.Length - 1);
Expand All @@ -47,17 +47,17 @@ public static ModbusAsciiMessage Read(ReadOnlySpan<Byte> data, Boolean reply = f
{
var msg = new ModbusAsciiMessage { Reply = reply };
var reader = new SpanReader(data) { IsLittleEndian = false };
return msg.Read(reader) ? msg : null;
return msg.Read(ref reader) ? msg : null;
}

/// <summary>写入消息到数据</summary>
/// <param name="writer">写入器</param>
/// <returns></returns>
public override Boolean Write(SpanWriter writer)
public override Boolean Write(ref SpanWriter writer)
{
using var pk = new OwnerPacket(256);
var writer2 = new SpanWriter(pk.GetSpan()) { IsLittleEndian = false };
if (!base.Write(writer2)) return false;
if (!base.Write(ref writer2)) return false;

var buf = pk.GetSpan()[..writer2.Position].ToArray();

Expand Down
10 changes: 5 additions & 5 deletions NewLife.Modbus/Protocols/ModbusIpMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ public class ModbusIpMessage : ModbusMessage
/// <summary>从数据读取消息</summary>
/// <param name="reader">读取器</param>
/// <returns></returns>
public override Boolean Read(SpanReader reader)
public override Boolean Read(ref SpanReader reader)
{
TransactionId = reader.ReadUInt16();
ProtocolId = reader.ReadUInt16();

var len = reader.ReadUInt16();
if (len < 1 + 1 || len > reader.FreeCapacity) return false;

return base.Read(reader);
return base.Read(ref reader);
}

/// <summary>从数据读取消息</summary>
Expand All @@ -36,13 +36,13 @@ public static ModbusIpMessage Read(ReadOnlySpan<Byte> data, Boolean reply = fals
{
var msg = new ModbusIpMessage { Reply = reply };
var reader = new SpanReader(data) { IsLittleEndian = false };
return msg.Read(reader) ? msg : null;
return msg.Read(ref reader) ? msg : null;
}

/// <summary>写入消息到数据</summary>
/// <param name="writer">写入器</param>
/// <returns></returns>
public override Boolean Write(SpanWriter writer)
public override Boolean Write(ref SpanWriter writer)
{
writer.Write(TransactionId);
writer.Write(ProtocolId);
Expand All @@ -51,7 +51,7 @@ public override Boolean Write(SpanWriter writer)
var len = 2 + (pk?.Total ?? 0);
writer.Write((UInt16)len);

return base.Write(writer);
return base.Write(ref writer);
}

/// <summary>创建响应</summary>
Expand Down
13 changes: 7 additions & 6 deletions NewLife.Modbus/Protocols/ModbusMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public override String ToString()
/// <summary>从数据读取消息</summary>
/// <param name="reader">读取器</param>
/// <returns></returns>
public virtual Boolean Read(SpanReader reader)
public virtual Boolean Read(ref SpanReader reader)
{
Host = reader.ReadByte();

Expand All @@ -61,7 +61,8 @@ public virtual Boolean Read(SpanReader reader)
return true;
}

Payload = (ArrayPacket)reader.ReadBytes(-1).ToArray();
if (reader.FreeCapacity > 0)
Payload = (ArrayPacket)reader.ReadBytes(reader.FreeCapacity).ToArray();

return true;
}
Expand All @@ -72,15 +73,15 @@ public virtual Boolean Read(SpanReader reader)
public virtual Int32 Read(ReadOnlySpan<Byte> data)
{
var reader = new SpanReader(data) { IsLittleEndian = false };
if (!Read(reader)) return -1;
if (!Read(ref reader)) return -1;

return reader.Position;
}

/// <summary>写入消息到数据</summary>
/// <param name="writer">写入器</param>
/// <returns></returns>
public virtual Boolean Write(SpanWriter writer)
public virtual Boolean Write(ref SpanWriter writer)
{
writer.Write(Host);

Expand All @@ -107,7 +108,7 @@ public virtual Boolean Write(SpanWriter writer)
public virtual Int32 Writer(Span<Byte> data)
{
var writer = new SpanWriter(data) { IsLittleEndian = false };
if (!Write(writer)) return -1;
if (!Write(ref writer)) return -1;

return writer.Position;
}
Expand All @@ -118,7 +119,7 @@ public virtual IPacket ToPacket(Int32 bufferSize = 256)
{
var pk = new OwnerPacket(bufferSize);
var writer = new SpanWriter(pk.GetSpan()) { IsLittleEndian = false };
if (!Write(writer)) return null;
if (!Write(ref writer)) return null;

pk.Resize(writer.Position);

Expand Down
20 changes: 13 additions & 7 deletions NewLife.Modbus/Protocols/ModbusRtuMessage.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using NewLife.Buffers;
using NewLife.Data;
using NewLife.Reflection;
using NewLife.Security;

namespace NewLife.IoT.Protocols;

Expand All @@ -18,10 +20,10 @@ public class ModbusRtuMessage : ModbusMessage
/// <summary>从数据读取消息</summary>
/// <param name="reader">读取器</param>
/// <returns></returns>
public override Boolean Read(SpanReader reader)
public override Boolean Read(ref SpanReader reader)
{
var p = reader.Position;
if (!base.Read(reader)) return false;
if (!base.Read(ref reader)) return false;

// 从负载数据里把Crc取出来
var pk = Payload;
Expand All @@ -32,8 +34,12 @@ public override Boolean Read(SpanReader reader)
Payload = pk.Slice(0, count - 2);
}

//reader.Position = p;
//Crc2 = ModbusHelper.Crc(stream, (Int32)(stream.Length - stream.Position - 2));
// 计算CRC
var p2 = reader.Position - 2;
var sp = reader.Span.Slice(p, p2 - p);
var buf = sp.ToArray();

Crc2 = Crc16.ComputeModbus(buf, 0, buf.Length);

return true;
}
Expand All @@ -46,16 +52,16 @@ public static ModbusRtuMessage Read(ReadOnlySpan<Byte> data, Boolean reply = fal
{
var msg = new ModbusRtuMessage { Reply = reply };
var reader = new SpanReader(data) { IsLittleEndian = false };
return msg.Read(reader) ? msg : null;
return msg.Read(ref reader) ? msg : null;
}

/// <summary>写入消息到数据</summary>
/// <param name="writer">写入器</param>
/// <returns></returns>
public override Boolean Write(SpanWriter writer)
public override Boolean Write(ref SpanWriter writer)
{
var p = writer.Position;
if (!base.Write(writer)) return false;
if (!base.Write(ref writer)) return false;

//writer.Position = p;
//Crc2 = ModbusHelper.Crc(writer);
Expand Down
2 changes: 1 addition & 1 deletion Test/Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NewLife.Core" Version="11.1.2024.1206" />
<PackageReference Include="NewLife.Core" Version="11.1.2024.1212-beta1042" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion WinModbus/WinModbus.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NewLife.Core" Version="11.1.2024.1206" />
<PackageReference Include="NewLife.Core" Version="11.1.2024.1212-beta1042" />
</ItemGroup>

<ItemGroup>
Expand Down
11 changes: 5 additions & 6 deletions XUnitTest/ModbusMessageTests.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NewLife;
using NewLife.Data;
using NewLife.IoT.Protocols;
Expand All @@ -20,7 +16,8 @@ public void Test1()
var dt = str.ToHex();

var msg = new ModbusMessage();
msg.Read(dt);
var rs = msg.Read(dt);
Assert.Equal(dt.Length, rs);
Assert.NotNull(msg);

Assert.Equal(1, msg.Host);
Expand All @@ -42,7 +39,8 @@ public void Test2()
var dt = str.ToHex();

var msg = new ModbusMessage { Reply = true };
msg.Read(dt);
var rs = msg.Read(dt);
Assert.Equal(dt.Length, rs);
Assert.NotNull(msg);

Assert.Equal(1, msg.Host);
Expand Down Expand Up @@ -76,5 +74,6 @@ public void Set()
msg.SetRequest(0x0002, 0xABCD);

Assert.Equal("00-02-AB-CD", msg.Payload.ToHex(256, "-"));
Assert.Equal("WriteRegister (0x0002, ABCD)", msg.ToString());
}
}
2 changes: 1 addition & 1 deletion XUnitTest/XUnitTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="NewLife.Core" Version="11.1.2024.1206" />
<PackageReference Include="NewLife.Core" Version="11.1.2024.1212-beta1042" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PrivateAssets>all</PrivateAssets>
Expand Down

0 comments on commit dc03474

Please sign in to comment.