merge: libplctag empty-path fix (null Path for an empty CIP route)
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip;
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes a parsed CIP route for libplctag's <c>Path</c> attribute. libplctag rejects an
|
||||
/// empty-string path with <c>ErrorBadData</c>; "no route" (Micro800, unrouted MicroLogix) must be
|
||||
/// expressed by omitting the attribute, i.e. <see langword="null"/>.
|
||||
/// </summary>
|
||||
internal static class LibplctagPath
|
||||
{
|
||||
/// <summary>Returns <see langword="null"/> for a null, empty or whitespace path; otherwise the path unchanged.</summary>
|
||||
/// <param name="path">The parsed CIP path.</param>
|
||||
public static string? Normalize(string? path) => string.IsNullOrWhiteSpace(path) ? null : path;
|
||||
}
|
||||
@@ -37,7 +37,7 @@ internal static class LibplctagListingReader
|
||||
internal static Tag BuildSymbolListTag(AbCipTagCreateParams deviceParams, string listingName = "@tags") => new()
|
||||
{
|
||||
Gateway = deviceParams.LibplctagGateway,
|
||||
Path = deviceParams.CipPath,
|
||||
Path = LibplctagPath.Normalize(deviceParams.CipPath),
|
||||
PlcType = MapPlcType(deviceParams.LibplctagPlcAttribute),
|
||||
Protocol = Protocol.ab_eip,
|
||||
Name = listingName,
|
||||
|
||||
@@ -18,12 +18,18 @@ internal sealed class LibplctagTagRuntime : IAbCipTagRuntime
|
||||
/// <param name="p">The tag creation parameters.</param>
|
||||
public LibplctagTagRuntime(AbCipTagCreateParams p)
|
||||
{
|
||||
_tag = new Tag
|
||||
_tag = BuildTag(p);
|
||||
}
|
||||
|
||||
/// <summary>Builds the (uninitialized) libplctag tag for <paramref name="p"/>.</summary>
|
||||
/// <param name="p">The tag creation parameters.</param>
|
||||
internal static Tag BuildTag(AbCipTagCreateParams p) =>
|
||||
new Tag
|
||||
{
|
||||
// host:port — see AbLegacyTagCreateParams/AbCipTagCreateParams.LibplctagGateway.
|
||||
// Passing p.Gateway alone drops the authored port onto libplctag's 44818 default (#534).
|
||||
Gateway = p.LibplctagGateway,
|
||||
Path = p.CipPath,
|
||||
Path = LibplctagPath.Normalize(p.CipPath),
|
||||
PlcType = MapPlcType(p.LibplctagPlcAttribute),
|
||||
Protocol = Protocol.ab_eip,
|
||||
Name = p.TagName,
|
||||
@@ -33,7 +39,6 @@ internal sealed class LibplctagTagRuntime : IAbCipTagRuntime
|
||||
// count so libplctag pulls every element in one CIP read; scalar tags pass 1.
|
||||
ElementCount = p.ElementCount > 1 ? p.ElementCount : 1,
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task InitializeAsync(CancellationToken cancellationToken) =>
|
||||
|
||||
@@ -39,7 +39,7 @@ internal sealed class LibplctagTemplateReader : IAbCipTemplateReader
|
||||
internal static Tag BuildTemplateTag(AbCipTagCreateParams deviceParams, uint templateInstanceId) => new()
|
||||
{
|
||||
Gateway = deviceParams.LibplctagGateway,
|
||||
Path = deviceParams.CipPath,
|
||||
Path = LibplctagPath.Normalize(deviceParams.CipPath),
|
||||
PlcType = MapPlcType(deviceParams.LibplctagPlcAttribute),
|
||||
Protocol = Protocol.ab_eip,
|
||||
Name = $"@udt/{templateInstanceId}",
|
||||
|
||||
@@ -17,19 +17,24 @@ internal sealed class LibplctagLegacyTagRuntime : IAbLegacyTagRuntime
|
||||
/// <param name="p">The parameters for tag creation.</param>
|
||||
public LibplctagLegacyTagRuntime(AbLegacyTagCreateParams p)
|
||||
{
|
||||
_tag = new Tag
|
||||
_tag = BuildTag(p);
|
||||
}
|
||||
|
||||
/// <summary>Builds the (uninitialized) libplctag tag for <paramref name="p"/>.</summary>
|
||||
/// <param name="p">The tag creation parameters.</param>
|
||||
internal static Tag BuildTag(AbLegacyTagCreateParams p) =>
|
||||
new Tag
|
||||
{
|
||||
// host:port — see AbLegacyTagCreateParams/AbCipTagCreateParams.LibplctagGateway.
|
||||
// Passing p.Gateway alone drops the authored port onto libplctag's 44818 default (#534).
|
||||
Gateway = p.LibplctagGateway,
|
||||
Path = p.CipPath,
|
||||
Path = LibplctagPath.Normalize(p.CipPath),
|
||||
PlcType = MapPlcType(p.LibplctagPlcAttribute),
|
||||
Protocol = Protocol.ab_eip, // PCCC-over-EIP; libplctag routes via the PlcType-specific PCCC layer
|
||||
Name = p.TagName,
|
||||
Timeout = p.Timeout,
|
||||
ElementCount = p.ElementCount > 1 ? p.ElementCount : null,
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task InitializeAsync(CancellationToken cancellationToken) =>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.AbLegacy;
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes a parsed CIP route for libplctag's <c>Path</c> attribute. libplctag rejects an
|
||||
/// empty-string path with <c>ErrorBadData</c>; "no route" (Micro800, unrouted MicroLogix) must be
|
||||
/// expressed by omitting the attribute, i.e. <see langword="null"/>.
|
||||
/// </summary>
|
||||
internal static class LibplctagPath
|
||||
{
|
||||
/// <summary>Returns <see langword="null"/> for a null, empty or whitespace path; otherwise the path unchanged.</summary>
|
||||
/// <param name="path">The parsed CIP path.</param>
|
||||
public static string? Normalize(string? path) => string.IsNullOrWhiteSpace(path) ? null : path;
|
||||
}
|
||||
Reference in New Issue
Block a user