diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1bddf7a..c4cf0f9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,5 +1,6 @@ name: Build Non-Release Branch + on: push: branches: @@ -7,6 +8,7 @@ on: - bugfix/* - hotfix/* + jobs: build: name: Build diff --git a/Pepperdash Core/Pepperdash Core/Comm/GenericSecureTcpIpServer.cs b/Pepperdash Core/Pepperdash Core/Comm/GenericSecureTcpIpServer.cs index 6703551..74ce8cb 100644 --- a/Pepperdash Core/Pepperdash Core/Comm/GenericSecureTcpIpServer.cs +++ b/Pepperdash Core/Pepperdash Core/Comm/GenericSecureTcpIpServer.cs @@ -418,11 +418,21 @@ namespace PepperDash.Core SecureServer.PortNumber = Port; } ServerStopped = false; - SecureServer.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback); - OnServerStateChange(SecureServer.State); - Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Secure Server Status: {0}, Socket Status: {1}", SecureServer.State, SecureServer.ServerSocketStatus); - ServerCCSection.Leave(); - + + // Start the listner + SocketErrorCodes status = SecureServer.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback); + if (status != SocketErrorCodes.SOCKET_OPERATION_PENDING) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Error starting WaitForConnectionAsync {0}", status); + } + else + { + ServerStopped = false; + } + OnServerStateChange(SecureServer.State); + Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Secure Server Status: {0}, Socket Status: {1}", SecureServer.State, SecureServer.ServerSocketStatus); + ServerCCSection.Leave(); + } catch (Exception ex) { @@ -758,29 +768,27 @@ namespace PepperDash.Core } else { - Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Client attempt faulty."); - if (!ServerStopped) - { - server.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback); - return; - } + Debug.Console(1, this, Debug.ErrorLogLevel.Error, "Client attempt faulty."); } } catch (Exception ex) { Debug.Console(2, this, Debug.ErrorLogLevel.Error, "Error in Socket Status Connect Callback. Error: {0}", ex); } - //Debug.Console(1, this, Debug.ErrorLogLevel, "((((((Server State bitfield={0}; maxclient={1}; ServerStopped={2}))))))", - // server.State, - // MaxClients, - // ServerStopped); - if ((server.State & ServerState.SERVER_LISTENING) != ServerState.SERVER_LISTENING && MaxClients > 1 && !ServerStopped) - { - Debug.Console(1, this, Debug.ErrorLogLevel.Notice, "Waiting for next connection"); - server.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback); - } - } + // Rearm the listner + SocketErrorCodes status = server.WaitForConnectionAsync(IPAddress.Any, SecureConnectCallback); + if (status != SocketErrorCodes.SOCKET_OPERATION_PENDING) + { + Debug.Console(0, this, Debug.ErrorLogLevel.Error, "Socket status connect callback status {0}", status); + if (status == SocketErrorCodes.SOCKET_CONNECTION_IN_PROGRESS) + { + // There is an issue where on a failed negotiation we need to stop and start the server. This should still leave connected clients intact. + server.Stop(); + Listen(); + } + } + } #endregion diff --git a/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs b/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs index 46892c7..ef57ae0 100644 --- a/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs +++ b/Pepperdash Core/Pepperdash Core/Comm/GenericSshClient.cs @@ -62,6 +62,8 @@ namespace PepperDash.Core get { return ClientStatus == SocketStatus.SOCKET_STATUS_CONNECTED; } } + private bool IsConnecting = false; + /// /// S+ helper for IsConnected /// @@ -184,6 +186,13 @@ namespace PepperDash.Core /// public void Connect() { + if (IsConnecting) + { + Debug.Console(0, this, "Connection attempt in progress. Exiting Connect()"); + return; + } + + IsConnecting = true; ConnectEnabled = true; Debug.Console(1, this, "attempting connect"); @@ -236,6 +245,7 @@ namespace PepperDash.Core //TheStream.ErrorOccurred += TheStream_ErrorOccurred; Debug.Console(1, this, "Connected"); ClientStatus = SocketStatus.SOCKET_STATUS_CONNECTED; + IsConnecting = false; return; // Success will not pass here } catch (SshConnectionException e) @@ -291,6 +301,7 @@ namespace PepperDash.Core if (Client != null) { + IsConnecting = false; Client.Disconnect(); Client = null; ClientStatus = status; @@ -303,6 +314,7 @@ namespace PepperDash.Core /// void HandleConnectionFailure() { + KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED); Debug.Console(2, this, "Client nulled due to connection failure. AutoReconnect: {0}, ConnectEnabled: {1}", AutoReconnect, ConnectEnabled); diff --git a/Pepperdash Core/Pepperdash Core/Logging/Debug.cs b/Pepperdash Core/Pepperdash Core/Logging/Debug.cs index 14c6b37..cf4d8df 100644 --- a/Pepperdash Core/Pepperdash Core/Logging/Debug.cs +++ b/Pepperdash Core/Pepperdash Core/Logging/Debug.cs @@ -91,7 +91,8 @@ namespace PepperDash.Core Level = context.Level; DoNotLoadOnNextBoot = context.DoNotLoadOnNextBoot; - CrestronConsole.PrintLine(string.Format("Program {0} will not load config after next boot. Use console command go:{0} to load the config manually", InitialParametersClass.ApplicationNumber)); + if(DoNotLoadOnNextBoot) + CrestronConsole.PrintLine(string.Format("Program {0} will not load config after next boot. Use console command go:{0} to load the config manually", InitialParametersClass.ApplicationNumber)); try { diff --git a/Pepperdash Core/Pepperdash Core/PepperDash_Core.csproj b/Pepperdash Core/Pepperdash Core/PepperDash_Core.csproj index 1d98c97..92ce8c8 100644 --- a/Pepperdash Core/Pepperdash Core/PepperDash_Core.csproj +++ b/Pepperdash Core/Pepperdash Core/PepperDash_Core.csproj @@ -49,19 +49,19 @@ False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll + ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll + ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll + ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll + ..\..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll