fix(ablegacy): indirect element index up to 999 on PLC-5; clear IndirectLastName on dispose
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -862,6 +862,9 @@ public sealed class AbLegacyDriver : IDriver, IReadable, IWritable, ITagDiscover
|
||||
/// <summary>Largest word/element index an indirect source may yield (PCCC element offset is one byte).</summary>
|
||||
private const int MaxIndirectElement = AbLegacyArray.MaxElements - 1;
|
||||
|
||||
/// <summary>PLC-5 data files hold up to 1000 words (extended PCCC offset), unlike SLC/MicroLogix (256).</summary>
|
||||
private const int MaxIndirectElementPlc5 = 999;
|
||||
|
||||
/// <summary>Largest data-file number an indirect source may yield (PLC-5 allows up to 999).</summary>
|
||||
private const int MaxIndirectFile = 999;
|
||||
|
||||
@@ -877,6 +880,8 @@ public sealed class AbLegacyDriver : IDriver, IReadable, IWritable, ITagDiscover
|
||||
{
|
||||
var fileNumber = parsed.FileNumber;
|
||||
var word = parsed.WordNumber;
|
||||
var maxElement = device.Options.PlcFamily is AbLegacyPlcFamily.Plc5 or AbLegacyPlcFamily.LogixPccc
|
||||
? MaxIndirectElementPlc5 : MaxIndirectElement;
|
||||
|
||||
if (parsed.IndirectFileSource is { } fileSrc)
|
||||
{
|
||||
@@ -890,7 +895,7 @@ public sealed class AbLegacyDriver : IDriver, IReadable, IWritable, ITagDiscover
|
||||
{
|
||||
var r = await ReadIndexAsync(device, wordSrc, ct).ConfigureAwait(false);
|
||||
if (r.Status != 0) return new IndirectResolution(null, r.Status, r.TransportFault);
|
||||
if (r.Value is < 0 or > MaxIndirectElement)
|
||||
if (r.Value < 0 || r.Value > maxElement)
|
||||
return new IndirectResolution(null, AbLegacyStatusMapper.BadOutOfRange, false);
|
||||
word = (int)r.Value!;
|
||||
}
|
||||
@@ -1329,6 +1334,7 @@ public sealed class AbLegacyDriver : IDriver, IReadable, IWritable, ITagDiscover
|
||||
Runtimes.Clear();
|
||||
foreach (var r in ParentRuntimes.Values) r.Dispose();
|
||||
ParentRuntimes.Clear();
|
||||
IndirectLastName.Clear();
|
||||
// Dispose + clear the per-parent RMW gates and the per-runtime/creation locks so
|
||||
// ReinitializeAsync cycles don't orphan their SemaphoreSlim instances (each leaks a
|
||||
// wait handle once contended).
|
||||
|
||||
Reference in New Issue
Block a user