diff --git a/src/PepperDash.Core/Comm/GenericSshClient.cs b/src/PepperDash.Core/Comm/GenericSshClient.cs
index 3ba9059e..13192ed5 100644
--- a/src/PepperDash.Core/Comm/GenericSshClient.cs
+++ b/src/PepperDash.Core/Comm/GenericSshClient.cs
@@ -146,31 +146,31 @@ namespace PepperDash.Core
base(key)
{
StreamDebugging = new CommunicationStreamDebugging(key);
- CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
- Key = key;
- Hostname = hostname;
- Port = port;
- Username = username;
- Password = password;
- AutoReconnectIntervalMs = 5000;
+ CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
+ Key = key;
+ Hostname = hostname;
+ Port = port;
+ Username = username;
+ Password = password;
+ AutoReconnectIntervalMs = 5000;
ReconnectTimer = new CTimer(o =>
- {
+ {
if (ConnectEnabled)
{
Connect();
}
- }, System.Threading.Timeout.Infinite);
- }
+ }, System.Threading.Timeout.Infinite);
+ }
- ///
- /// S+ Constructor - Must set all properties before calling Connect
- ///
- public GenericSshClient()
- : base(SPlusKey)
- {
- CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
- AutoReconnectIntervalMs = 5000;
+ ///
+ /// S+ Constructor - Must set all properties before calling Connect
+ ///
+ public GenericSshClient()
+ : base(SPlusKey)
+ {
+ CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler);
+ AutoReconnectIntervalMs = 5000;
ReconnectTimer = new CTimer(o =>
{
@@ -179,18 +179,18 @@ namespace PepperDash.Core
Connect();
}
}, System.Threading.Timeout.Infinite);
- }
+ }
- ///
- /// Handles closing this up when the program shuts down
- ///
- void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
- {
- if (programEventType == eProgramStatusEventType.Stopping)
- {
- if (Client != null)
- {
- this.LogDebug("Program stopping. Closing connection");
+ ///
+ /// Handles closing this up when the program shuts down
+ ///
+ void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
+ {
+ if (programEventType == eProgramStatusEventType.Stopping)
+ {
+ if (Client != null)
+ {
+ this.LogDebug("Program stopping. Closing connection");
Disconnect();
}
}
@@ -223,10 +223,7 @@ namespace PepperDash.Core
this.LogDebug("Attempting connect");
// Cancel reconnect if running.
- if (ReconnectTimer != null)
- {
- ReconnectTimer.Stop();
- }
+ ReconnectTimer?.Stop();
// Cleanup the old client if it already exists
if (Client != null)
@@ -268,20 +265,26 @@ namespace PepperDash.Core
if (ie is SocketException)
{
- this.LogException(ie, "CONNECTION failure: Cannot reach host");
+ this.LogError("CONNECTION failure: Cannot reach host");
+ this.LogVerbose(ie, "Exception details: ");
}
if (ie is System.Net.Sockets.SocketException socketException)
{
- this.LogException(ie, "Connection failure: Cannot reach {host} on {port}",
+ this.LogError("Connection failure: Cannot reach {host} on {port}",
Hostname, Port);
+ this.LogVerbose(socketException, "SocketException details: ");
}
if (ie is SshAuthenticationException)
{
- this.LogException(ie, "Authentication failure for username {userName}", Username);
+ this.LogError("Authentication failure for username {userName}", Username);
+ this.LogVerbose(ie, "AuthenticationException details: ");
}
else
- this.LogException(ie, "Error on connect");
+ {
+ this.LogError("Error on connect: {error}", ie.Message);
+ this.LogVerbose(ie, "Exception details: ");
+ }
DisconnectLogged = true;
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
@@ -291,7 +294,7 @@ namespace PepperDash.Core
ReconnectTimer.Reset(AutoReconnectIntervalMs);
}
}
- catch(SshOperationTimeoutException ex)
+ catch (SshOperationTimeoutException ex)
{
this.LogWarning("Connection attempt timed out: {message}", ex.Message);
@@ -306,7 +309,8 @@ namespace PepperDash.Core
catch (Exception e)
{
var errorLogLevel = DisconnectLogged == true ? Debug.ErrorLogLevel.None : Debug.ErrorLogLevel.Error;
- this.LogException(e, "Unhandled exception on connect");
+ this.LogError("Unhandled exception on connect: {error}", e.Message);
+ this.LogVerbose(e, "Exception details: ");
DisconnectLogged = true;
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
if (AutoReconnect)
@@ -323,18 +327,18 @@ namespace PepperDash.Core
}
}
- ///
- /// Disconnect method
- ///
- public void Disconnect()
- {
- ConnectEnabled = false;
- // Stop trying reconnects, if we are
- if (ReconnectTimer != null)
- {
- ReconnectTimer.Stop();
- // ReconnectTimer = null;
- }
+ ///
+ /// Disconnect method
+ ///
+ public void Disconnect()
+ {
+ ConnectEnabled = false;
+ // Stop trying reconnects, if we are
+ if (ReconnectTimer != null)
+ {
+ ReconnectTimer.Stop();
+ // ReconnectTimer = null;
+ }
KillClient(SocketStatus.SOCKET_STATUS_BROKEN_LOCALLY);
}
@@ -360,7 +364,7 @@ namespace PepperDash.Core
}
catch (Exception ex)
{
- this.LogException(ex,"Exception in Kill Client");
+ this.LogException(ex, "Exception in Kill Client");
}
}
@@ -368,7 +372,7 @@ namespace PepperDash.Core
/// Kills the stream
///
void KillStream()
- {
+ {
try
{
if (TheStream != null)
@@ -384,59 +388,59 @@ namespace PepperDash.Core
{
this.LogException(ex, "Exception in Kill Stream:{0}");
}
- }
+ }
- ///
- /// Handles the keyboard interactive authentication, should it be required.
- ///
- void kauth_AuthenticationPrompt(object sender, AuthenticationPromptEventArgs e)
- {
- foreach (AuthenticationPrompt prompt in e.Prompts)
- if (prompt.Request.IndexOf("Password:", StringComparison.InvariantCultureIgnoreCase) != -1)
- prompt.Response = Password;
- }
-
- ///
- /// Handler for data receive on ShellStream. Passes data across to queue for line parsing.
- ///
- void Stream_DataReceived(object sender, ShellDataEventArgs e)
- {
+ ///
+ /// Handles the keyboard interactive authentication, should it be required.
+ ///
+ void kauth_AuthenticationPrompt(object sender, AuthenticationPromptEventArgs e)
+ {
+ foreach (AuthenticationPrompt prompt in e.Prompts)
+ if (prompt.Request.IndexOf("Password:", StringComparison.InvariantCultureIgnoreCase) != -1)
+ prompt.Response = Password;
+ }
+
+ ///
+ /// Handler for data receive on ShellStream. Passes data across to queue for line parsing.
+ ///
+ void Stream_DataReceived(object sender, ShellDataEventArgs e)
+ {
if (((ShellStream)sender).Length <= 0L)
{
return;
}
- var response = ((ShellStream)sender).Read();
-
- var bytesHandler = BytesReceived;
-
- if (bytesHandler != null)
- {
+ var response = ((ShellStream)sender).Read();
+
+ var bytesHandler = BytesReceived;
+
+ if (bytesHandler != null)
+ {
var bytes = Encoding.UTF8.GetBytes(response);
- if (StreamDebugging.RxStreamDebuggingIsEnabled)
- {
- this.LogInformation("Received {1} bytes: '{0}'", ComTextHelper.GetEscapedText(bytes), bytes.Length);
- }
+ if (StreamDebugging.RxStreamDebuggingIsEnabled)
+ {
+ this.LogInformation("Received {1} bytes: '{0}'", ComTextHelper.GetEscapedText(bytes), bytes.Length);
+ }
bytesHandler(this, new GenericCommMethodReceiveBytesArgs(bytes));
- }
-
- var textHandler = TextReceived;
- if (textHandler != null)
- {
+ }
+
+ var textHandler = TextReceived;
+ if (textHandler != null)
+ {
if (StreamDebugging.RxStreamDebuggingIsEnabled)
this.LogInformation("Received: '{0}'", ComTextHelper.GetDebugText(response));
textHandler(this, new GenericCommMethodReceiveTextArgs(response));
}
-
- }
+
+ }
- ///
- /// Error event handler for client events - disconnect, etc. Will forward those events via ConnectionChange
- /// event
- ///
- void Client_ErrorOccurred(object sender, ExceptionEventArgs e)
- {
+ ///
+ /// Error event handler for client events - disconnect, etc. Will forward those events via ConnectionChange
+ /// event
+ ///
+ void Client_ErrorOccurred(object sender, ExceptionEventArgs e)
+ {
CrestronInvoke.BeginInvoke(o =>
{
if (e.Exception is SshConnectionException || e.Exception is System.Net.Sockets.SocketException)
@@ -465,61 +469,54 @@ namespace PepperDash.Core
///
void OnConnectionChange()
{
- if (ConnectionChange != null)
- ConnectionChange(this, new GenericSocketStatusChageEventArgs(this));
+ ConnectionChange?.Invoke(this, new GenericSocketStatusChageEventArgs(this));
}
#region IBasicCommunication Members
- ///
- /// Sends text to the server
- ///
- ///
- ///
- /// SendText method
- ///
- public void SendText(string text)
- {
- try
- {
- if (Client != null && TheStream != null && IsConnected)
- {
- if (StreamDebugging.TxStreamDebuggingIsEnabled)
- this.LogInformation(
- "Sending {length} characters of text: '{text}'",
- text.Length,
- ComTextHelper.GetDebugText(text));
-
- TheStream.Write(text);
- TheStream.Flush();
- }
- else
- {
- this.LogDebug("Client is null or disconnected. Cannot Send Text");
- }
- }
- catch (ObjectDisposedException)
+ ///
+ /// Sends text to the server
+ ///
+ /// The text to send
+ public void SendText(string text)
+ {
+ try
{
- this.LogError("ObjectDisposedException sending '{message}'. Restarting connection...", text.Trim());
+ if (Client != null && TheStream != null && IsConnected)
+ {
+ if (StreamDebugging.TxStreamDebuggingIsEnabled)
+ this.LogInformation(
+ "Sending {length} characters of text: '{text}'",
+ text.Length,
+ ComTextHelper.GetDebugText(text));
+
+ TheStream.Write(text);
+ TheStream.Flush();
+ }
+ else
+ {
+ this.LogDebug("Client is null or disconnected. Cannot Send Text");
+ }
+ }
+ catch (ObjectDisposedException)
+ {
+ this.LogError("ObjectDisposedException sending '{message}'. Restarting connection...", text.Trim());
KillClient(SocketStatus.SOCKET_STATUS_CONNECT_FAILED);
ReconnectTimer.Reset();
- }
- catch (Exception ex)
- {
+ }
+ catch (Exception ex)
+ {
this.LogException(ex, "Exception sending text: '{message}'", text);
- }
- }
+ }
+ }
///
/// Sends Bytes to the server
///
- ///
- ///
- /// SendBytes method
- ///
- public void SendBytes(byte[] bytes)
- {
+ /// The bytes to send
+ public void SendBytes(byte[] bytes)
+ {
try
{
if (Client != null && TheStream != null && IsConnected)
@@ -545,38 +542,38 @@ namespace PepperDash.Core
catch (Exception ex)
{
this.LogException(ex, "Exception sending {message}", ComTextHelper.GetEscapedText(bytes));
- }
- }
- #endregion
+ }
+ }
+ #endregion
-}
+ }
-//*****************************************************************************************************
-//*****************************************************************************************************
-///
-/// Represents a SshConnectionChangeEventArgs
-///
-public class SshConnectionChangeEventArgs : EventArgs
- {
+ //*****************************************************************************************************
+ //*****************************************************************************************************
+ ///
+ /// Represents a SshConnectionChangeEventArgs
+ ///
+ public class SshConnectionChangeEventArgs : EventArgs
+ {
///
/// Connection State
///
public bool IsConnected { get; private set; }
- ///
- /// Gets or sets the UIsConnected
- ///
- public ushort UIsConnected { get { return (ushort)(Client.IsConnected ? 1 : 0); } }
+ ///
+ /// Gets or sets the UIsConnected
+ ///
+ public ushort UIsConnected { get { return (ushort)(Client.IsConnected ? 1 : 0); } }
- ///
- /// Gets or sets the Client
- ///
- public GenericSshClient Client { get; private set; }
+ ///
+ /// Gets or sets the Client
+ ///
+ public GenericSshClient Client { get; private set; }
- ///
- /// Gets or sets the Status
- ///
- public ushort Status { get { return Client.UStatus; } }
+ ///
+ /// Gets or sets the Status
+ ///
+ public ushort Status { get { return Client.UStatus; } }
///
/// S+ Constructor