From e7176c26e7282af8e47f07e7ec623e98c66c8602 Mon Sep 17 00:00:00 2001 From: Peter Butzhammer Date: Tue, 6 Feb 2024 18:19:15 +0100 Subject: [PATCH] Do not consider connection lost on some error codes --- Sharp7.Rx/S7ErrorCodes.cs | 27 +++++++++++++++++++++++++++ Sharp7.Rx/Sharp7Connector.cs | 21 +++++++++++---------- 2 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 Sharp7.Rx/S7ErrorCodes.cs diff --git a/Sharp7.Rx/S7ErrorCodes.cs b/Sharp7.Rx/S7ErrorCodes.cs new file mode 100644 index 0000000..db1b5eb --- /dev/null +++ b/Sharp7.Rx/S7ErrorCodes.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; + +namespace Sharp7.Rx +{ + public static class S7ErrorCodes + { + /// + /// This list is not exhaustive and should be considered work in progress. + /// + private static readonly HashSet notDisconnectedErrorCodes = new HashSet + { + 0x000000, // OK + 0xC00000, // CPU: Item not available + 0x900000, // CPU: Address out of range + }; + + /// + /// Some error codes indicate connection lost, in which case, the driver tries to reestablish connection. + /// Other error codes indicate a user error, like reading from an unavailable DB or exceeding + /// the DBs range. In this case the driver should not consider the connection to be lost. + /// + public static bool AssumeConnectionLost(int errorCode) + { + return !notDisconnectedErrorCodes.Contains(errorCode); + } + } +} \ No newline at end of file diff --git a/Sharp7.Rx/Sharp7Connector.cs b/Sharp7.Rx/Sharp7Connector.cs index 99c6644..3063471 100644 --- a/Sharp7.Rx/Sharp7Connector.cs +++ b/Sharp7.Rx/Sharp7Connector.cs @@ -52,7 +52,7 @@ namespace Sharp7.Rx var result = await Task.Factory.StartNew(() => s7MultiVar.Read(), CancellationToken.None, TaskCreationOptions.None, scheduler); if (result != 0) { - await EvaluateErrorCode(result); + EvaluateErrorCode(result); throw new InvalidOperationException($"Error in MultiVar request for variables: {string.Join(",", variableNames)}"); } @@ -88,7 +88,7 @@ namespace Sharp7.Rx try { var errorCode = await Task.Factory.StartNew(() => sharp7.ConnectTo(ipAddress, rackNr, cpuSlotNr), CancellationToken.None, TaskCreationOptions.None, scheduler); - var success = await EvaluateErrorCode(errorCode); + var success = EvaluateErrorCode(errorCode); if (success) { connectionStateSubject.OnNext(Enums.ConnectionState.Connected); @@ -168,7 +168,7 @@ namespace Sharp7.Rx await Task.Factory.StartNew(() => sharp7.Disconnect(), CancellationToken.None, TaskCreationOptions.None, scheduler); } - private async Task EvaluateErrorCode(int errorCode) + private bool EvaluateErrorCode(int errorCode) { if (errorCode == 0) return true; @@ -178,7 +178,9 @@ namespace Sharp7.Rx var errorText = sharp7.ErrorText(errorCode); Logger?.LogError($"Error Code {errorCode} {errorText}"); - await SetConnectionLostState(); + + if (S7ErrorCodes.AssumeConnectionLost(errorCode)) + SetConnectionLostState(); return false; } @@ -190,10 +192,9 @@ namespace Sharp7.Rx return await Connect(); } - private async Task SetConnectionLostState() + private void SetConnectionLostState() { - var state = await connectionStateSubject.FirstAsync(); - if (state == Enums.ConnectionState.ConnectionLost) return; + if (connectionStateSubject.Value == Enums.ConnectionState.ConnectionLost) return; connectionStateSubject.OnNext(Enums.ConnectionState.ConnectionLost); } @@ -219,7 +220,7 @@ namespace Sharp7.Rx if (result != 0) { - await EvaluateErrorCode(result); + EvaluateErrorCode(result); var errorText = sharp7.ErrorText(result); throw new InvalidOperationException($"Error reading {operand}{dBNr}:{startByteAddress}->{bytesToRead} ({errorText})"); } @@ -265,7 +266,7 @@ namespace Sharp7.Rx if (result != 0) { - await EvaluateErrorCode(result); + EvaluateErrorCode(result); return 0; } return (ushort)(data.Length); @@ -283,7 +284,7 @@ namespace Sharp7.Rx if (result != 0) { - await EvaluateErrorCode(result); + EvaluateErrorCode(result); return (false); } return (true);